Example #1
0
def run():
    INFO('读入配置文件...')
    try:
        file = open(Configpath + '\config.json', mode='r', encoding='utf-8')
        config = json.load(file)
        file.close()
    except:
        ERROR(
            '读入配置文件或解析时发生异常,检查配置文件是否正确,默认路径为.douyin目录下的config.json。如果没有则需要复制文件 _config(将我复制改名为config.json).json 为 config.json'
        )
        return
    INFO('开始初始化所有需要监听的抖音用户')
    user = []
    user.clear()
    delay = int(config['delay'])
    for u in config['config']:
        if u.get('sec_uid'):
            user.append(dy(u))
        else:
            ERROR(f'{u}未填写sec_uid')
        if len(user) == 0:
            INFO('没有载入任何需要监听的用户')
            return
    INFO('开始轮询抖音')
    i = 0
    while True:
        for u in user:
            #print(u.vid)
            if u.check():
                for g in u.conf['Group']:
                    Send['sendGroupMsg'](g, u.msg)
                    Send['sendGroupMsg'](g, u.video)
            time.sleep(delay)
        time.sleep(5)
Example #2
0
def run_task():
    # 读入配置文件
    INFO('读入配置文件...')
    try:
        file = open(Configpath + '\config.json', mode='r', encoding='utf-8')
        config = json.load(file)
        file.close()
    except:
        ERROR(
            '读入配置文件或解析时发生异常,检查配置文件是否正确,默认路径为.LIVEBILI目录下的config.json。如果没有则需要复制文件 _config(将我复制改名为config.json).json 为 config.json 如果你已经配置好了BILI的配置文件也可将其直接复制过来使用(必须要填写roomid)'
        )
        return
    INFO('开始初始化所有需要监听的用户')
    user = []
    user.clear()
    for u in config['config']:
        if u.get('roomid'):
            user.append(Livebiliws(u))
        else:
            ERROR(f'{u}未填写roomid')
    if len(user) == 0:
        INFO('没有载入任何需要监听的用户')
        return
    INFO('开始启动ws')
    i = 0
    for u in user:
        Thread(target=u.run_forever,
               name=f'[T{i}] {u.roomid}-websocket').start()
        i += 1
    #开始刷新用户信息,间隔5秒
    for u in user:
        u.RefreshInfo()
        time.sleep(5)
Example #3
0
File: weibo.py Project: onlynull/zr
def getWeibo(index):
    idoleName = getName(index)
    weibo = Weibo(index)
    groups = groupid(index)
    at = str(groupAt(index))
    try:
        #INFO('check weibo')
        global weibo_id_array
        # 初次启动记录前十条微博id
        if firstcheck_weibo is True:
            INFO('first check weibo')
            weibo_id_array[index] = weibo.IdArray  # ******
            INFO(weibo_id_array[index])
        if firstcheck_weibo is False:
            # 取最新的前三条微博
            for idcount in range(0, 3):
                # 广告位微博id为0,忽略
                if int(weibo.IdArray[idcount]) == 0:
                    continue
                # 微博id不在记录的id列表里,判断为新微博
                if weibo.IdArray[idcount] not in weibo_id_array[index]:
                    msg = MsgChain()
                    if groupAt(index):
                        msg.joinAT(-1)
                    # 将id计入id列表
                    weibo_id_array[index].append(weibo.IdArray[idcount])
                    # 检查新微博是否是转发
                    if weibo.checkRetweet(idcount):
                        msg.joinPlain('%s 刚刚转发了一条微博:\n' % idoleName)
                        msg.joinPlain('%s\n' % weibo.getRetweetWeibo(idcount))
                    # 原创微博
                    else:
                        msg.joinPlain('%s 刚刚发了一条新微博:\n' % idoleName)
                        msg.joinPlain('%s\n' % weibo.getWeibo(idcount))
                        # 检查原创微博是否带图
                        if weibo.checkPic(idcount):
                            # 只取第一张图,pro可以直接发图,air则无
                            for pic in weibo.getPic(idcount):
                                msg.joinImg(Url=pic)
                    # msg.append(
                    #     {
                    #         'type': 'text',
                    #         'data': {'text': '\n传送门:%s\n' % weibo.getScheme(idcount)}})
                    for grpid in groups:
                        Send['sendGroupMsg'](grpid, msg)
                        time.sleep(0.5)
                    # print(msg)
    except Exception as e:
        WARN('error when getWeibo:' + str(e))
    finally:
        pass
Example #4
0
 def SendFriendMsg(self,FriendId,Msg: MsgChain):
     INFO(f'发送私聊消息[{str(FriendId)}] <- {Msg.GetCQ()}')
     if Msg.Quote:
         mes = '[CQ:reply,id=' + str(Msg.Quote) + ']' + Msg.GetCQ()
     else:
         mes = Msg.GetCQ()
     s = {
         'access_token':self.access_token,
         'user_id':FriendId,
         'message':mes
     }
     j = self.GET('send_private_msg',data=s)
     INFO(str(j))
     return j
Example #5
0
 def SendGroupMsg(self,GroupId, Msg: MsgChain):
     INFO(f'发送群消息[{str(GroupId)}] <- {Msg.GetCQ()}')
     if Msg.Quote:
         mes = '[CQ:reply,id=' + str(Msg.Quote) + ']' + Msg.GetCQ()
     else:
         mes = Msg.GetCQ()
     s = {
         'access_token':self.access_token,
         'group_id':GroupId,
         'message':mes
     }
     j = self.GET('send_group_msg',data=s)
     INFO(str(j))
     return j
Example #6
0
 def OnLIVE(self, data):
     '''开播调用'''
     INFO(
         f'{self.roomid}[{self.info.get("showname",self.info.get("name"))}]收到开播推送'
     )
     if not self.status:
         for group in self.info['Group']:
             msg = MsgChain()
             if group['ATall']:
                 msg.joinAT(-1)
             msg.joinPlain(
                 f'你的小可爱{self.info.get("showname",self.info.get("name"))}开播啦~'
             )
             if self.title:
                 msg.joinPlain(f'\n【{self.title}】')
             if group['sendPic']:
                 ''''''
             if group['sendUrl']:
                 msg.joinPlain(f'\nhttps://live.bilibili.com/{self.roomid}')
             Send['sendGroupMsg'](group['id'], msg)
             time.sleep(0.2)
     self.status = True
     #保存开播日志在弹幕表中
     if self.info.get('savedanmu'):
         self.SQL.savedanmu(
             time.time() * 1000,  #时间
             'null',  #用户名
             'null',  #用户uid
             'LIVE'  #弹幕
         )
Example #7
0
 def check(self):
     '''检查是否更新'''
     j = self.Getaweme()
     if not self.vid and len(j) != 1:
         for v in j:
             self.vid.append(v.get('video', {}).get('vid'))
         return False
     if j:
         for v in j:
             video = v.get('video', {})
             vid = video.get('vid')
             if vid in self.vid:
                 #当前视频在本地记录过,直接跳出循环既可
                 pass
             else:
                 #未记录,表示为新视频
                 INFO(f'用户{self.conf.get("showname",self.name)}有新作品了')
                 self.msg = MsgChain()
                 self.msg.joinPlain(
                     f'【抖音】{self.conf.get("showname",self.name)}更新视频啦~\n{v.get("desc")}'
                 )
                 self.msg.joinImg(Url=video.get('origin_cover', {}).get(
                     'url_list', ['1'])[0])
                 self.msg.joinPlain(
                     video.get('play_addr', {}).get('url_list', ['1'])[1])
                 self.video = MsgChain().joinVideo(Url=video.get(
                     'play_addr', {}).get('url_list', ['1'])[1])
                 self.vid.append(vid)
                 return True
     return False
Example #8
0
def run():
    #读取配置文件
    try:
        file = open(path,  mode='r', encoding='utf-8')
        #转化yml配置数据
        data = yaml.load(file, Loader=yaml.FullLoader)
        file.close()
        #print(data)
    except Exception as e:
        ERROR(f'读入配置文件时发生异常,无法继续运行Acfun模块。异常信息:{e.__doc__} 文件:{e.__traceback__.tb_frame.f_globals["__file__"]} 行号:{str(e.__traceback__.tb_lineno)}')
        return
    #实例化所有需要监听的对象放进列表里
    user = []
    for u in data['user']:
        INFO('初始化用户:'+u['uid'])
        us = Acfun(u)
        user.append(us)
    #开始循环执行
    while True:
        i = 0
        l = len(user)
        while i < l:
            try:#获取信息
                user[i].Getinfo()
                user[i].GetDynamic()
                #判断
                if user[i].IsNewLive():#开播
                    INFO(f'主播{user[i].Name}开播了~')
                    SendGroupsMsg(user[i].user['group'],user[i].LiveLoad())
                if user[i].IsNewVideo():#有新视频
                    INFO(f'主播{user[i].Name}有新视频了~')
                    SendGroupsMsg(user[i].user['group'],user[i].VideoLoad())
                if user[i].IsNewDynamic():#有新动态
                    INFO(f'主播{user[i].Name}有新动态了~')
                    SendGroupsMsg(user[i].user['group'],user[i].DynamincLoad())
                pass
            except Exception as e:
                ERROR(f'处理时发现异常,跳过!。异常信息:{e.__doc__} 文件:{e.__traceback__.tb_frame.f_globals["__file__"]} 行号:{str(e.__traceback__.tb_lineno)}')
                pass
            i = i + 1
            time.sleep(data.get('delay',5))
        time.sleep(2)
Example #9
0
def on_GroupMessage(Message: MsgChain, sender: GroupInfo):
    if Message.GetCQ().startswith('我想吃'):
        try:
            INFO('出现食谱查询指令:'+Message.GetCQ())
            name =  Message.GetCQ()[3:]
            if name.isnumeric():
                Send['sendGroupMsg'](sender.GroupId,MsgChain().joinPlain(Getfangfa(name)))
            else:
                Send['sendGroupMsg'](sender.GroupId,MsgChain().joinImg(Path=合成图片(Getname(name))))
        except:
            ERROR('食谱查询异常')
Example #10
0
 def __init__(self, user: UserData) -> None:
     self.user = user
     if self.user.StartVideo:
         self.video = bilibili_video(uid=self.user.uid)
     if self.user.StartDynamic:
         self.dynamic = bilibii_dynamic(uid=self.user.uid)
     if self.user.StartLive:
         self.live = bilibili_live(uid=self.user.uid, roomid=self.user.roomid)
         # 更新昵称
         if self.live.RoomStatus:
             self.user.uname = self.live.roominfo.uname
     INFO(f'用户:{self.user.GetName()}[{self.user.uid}] 初始化完成!')
Example #11
0
 def Send(self,target:int,Msg: MsgChain,m = 'sendGroupMessage'):
     '''发送一条消息(可以为指定发送群消息还是私聊消息),消息为消息链类型,封装的类型'''
     try:
         #语音文件单独处理,后期可能会修改
         if len(Msg.msg) == 1 and Msg.msg[0]['type'] == 'Voice':
             #因为语音只能单独发送
             if Msg.msg[0]['url'] and not Msg.msg[0]['voiceId']:
                 #进行上传并赋值
                 fname=f'./data/{str(time.time()*1000)}.mp3'
                 with open( fname,'wb' ) as f:
                     f.write(requests.get(Msg.msg[0]['url']).content)
                 Msg.msg[0]['voiceId'] = self.uploadVoice(fname)['voiceId']
     except:
         pass
     INFO(f'发送{"群" if m == "sendGroupMessage" else "私聊"}消息[{str(target)}] <- {Msg.GetCQ()}')
     s = {'sessionKey': self.sessionstr, 'target': 
         target,'quote':Msg.Quote, 'messageChain': Msg.msg}
     ss = json.dumps(s)
     j = self.POST(m, ss)
     INFO(str(j))
     if j.get('code') == 6:
         #指定文件不存在,出现于发送本地图片
         #表示我发送的图片路径对于机器人而言并找不到,直接读取发送文件
         try:
             mesg = MsgChain()
             for msg in Msg.msg:
                 if msg['type'] == 'Image':
                     p = msg['path']
                     img = self.uploadImage(p,'group' if m == 'sendGroupMessage' else 'friend')
                     if img:
                         mesg.joinImg(ImageId=img['imageId'],
                         #Url=img['url']
                         )
                 else:   #来点魔法,但这样使用会导致下一步发送消息时日志输出缺失
                     mesg.msg.append(msg.copy())
             return self.Send(target,mesg,m)
         except Exception as e:
             ERROR(f'mirai在上传图片时发生错误:异常信息:{e.__doc__} 文件:{e.__traceback__.tb_frame.f_globals["__file__"]} 行号:{str(e.__traceback__.tb_lineno)}')
     else: return j
Example #12
0
def Import_module(modeule: list):
    '''安装列表内的模块'''
    # 导入模块
    # 包名为目录名,模块为文件夹下的__init__.py,启动后会调用执行一次__init__下的Main函数,
    # 如果不存Main函数将不会执行此模块任何方法
    for t in modeule:
        m = __import__(name=t)
        if 'Main' in dir(m):
            INFO('安装模块:' + str(m))
            tasks.append(m)
        else:
            ERROR('模块:' + str(m) + '未找到Main')
            ERROR(dir(m))
Example #13
0
 def __Getsessionstr__(self):
     '''获取sessionstr'''
     data = {'authKey': self.authkey}
     r = self.POST('auth', json.dumps(data))
     if r['code'] == 0:
         self.sessionstr = r['session']
         INFO(f'session:{self.sessionstr}')
     else:
         #err = '错误的MIRAI API HTTP auth key'
         ERROR(r['msg'])
         return False
     
     '''获取到session,绑定机器人'''
     data = {'sessionKey': self.sessionstr, 'qq': int(self.BOTQQ)}
     r = self.POST('verify', json.dumps(data))
     if r['code'] == 0:
         INFO("绑定机器人成功")
         super().__init__(self.host.replace('http','ws')+'all?sessionKey='+self.sessionstr)
     else:
         err = r['msg']
         ERROR(err)
         return False
     return True
Example #14
0
File: Acfun.py Project: onlynull/zr
 def IsNewDynamic(self) -> bool:
     '''判断动态是否更新'''
     if self.OldDynamic.get('resourceId') != None and self.Dynamic[0].get(
             'resourceId') != None:
         if self.OldDynamic['resourceId'] != self.Dynamic[0]['resourceId']:
             self.OldDynamic = self.Dynamic[0]
             if self.OldDynamic.get('resourceId') in self.DynamicID:
                 INFO(f'用户{self.Name}似乎删除了一条动态,清空列表,等待下次查询时刷新')
                 self.DynamicID = None
                 return False
             else:
                 self.DynamicID = None
                 return True
     return False
Example #15
0
File: Acfun.py Project: onlynull/zr
 def IsNewVideo(self) -> bool:
     '''判断视频是否更新'''
     if self.OldVideo.get('dougaId') != None and self.Video[0].get(
             'dougaId') != None:
         #当两个值都不能为空时才能作为有效的数据进行判断
         if self.OldVideo['dougaId'] != self.Video[0]['dougaId']:
             #两个数据不相同,表明视频列表被刷新,更新Oldvideo数据,并判断此次最新一条是否为删除原第一条数据后的第二条,尝试在旧列表中寻找他
             self.OldVideo = self.Video[0]
             if self.OldVideo.get('dougaId') in self.VideoID:
                 #表示此条并非最新,而是第一条数据被删除,他成为的第一条,不能算是新动态,清空列表,等待下次获取动态时刷新他
                 INFO(f'用户{self.Name}似乎删除了一条视频,清空列表,等待下次查询时刷新')
                 self.VideoID = None  #动态数据有变动,清空列表,等待下次刷新
                 return False
             else:
                 self.VideoID = None  #动态数据有变动,清空列表,等待下次刷新
                 return True
     return False
Example #16
0
 def OnPREPARING(self, data):
     '''下播调用'''
     INFO(
         f'{self.roomid}[{self.info.get("showname",self.info.get("name"))}]收到下播推送'
     )
     #self.SendMSG(f'你的小可爱{self.info.get("showname","None")}开播啦~\nhttps://live.bilibili.com/{self.roomid}')
     self.status = False
     self.SendMSG(MsgChain().joinPlain(
         f'你的小可爱{self.info.get("showname",self.info.get("name"))}下播啦~'))
     #保存下播日志在弹幕表中
     if self.info.get('savedanmu'):
         self.SQL.savedanmu(
             time.time() * 1000,  #时间
             'null',  #用户名
             'null',  #用户uid
             'PREPARING'  #弹幕
         )
Example #17
0
 def run_forever(self):
     '''阻塞运行连接ws,并接受消息'''
     try:
         #检查sessionstr是否可用
         j = self.GET('config','sessionKey='+self.sessionstr)
         if j.get('sessionKey') == self.sessionstr:
             pass
         elif j.get('code') == 3:
             #sessionstr失效
             INFO(f'{j["msg"]},重新获取')
             self.__Getsessionstr__()
         else:
             ERROR(j['msg'])
             return True
         return self.ws.run_forever(ping_interval=30,ping_timeout=3)
     except:
         ERROR(f'mirai_api_http在ws连接时发生异常。')
         return True
Example #18
0
File: weibo.py Project: onlynull/zr
def Main(sendGroupMsg, SendFriendMsg):
    Send['sendGroupMsg'] = sendGroupMsg
    Send['SendFriendMsg'] = SendFriendMsg
    INFO('微博启动')
    # 打开json文件
    try:
        fb = open(
            os.path.dirname(os.path.realpath(__file__)) + '\ini.json', 'rb')
        data = json.load(fb)
        fb.close()
    except:
        ERROR(
            '读入配置文件或解析时发生异常,检查配置文件是否正确,默认路径为.BILI目录下的ini.json。如果没有则需要复制文件 _ini(将我复制改名为ini.json).json 为 ini.json'
        )
        return
    while True:
        chaWeribo(data)
        time.sleep(20)
Example #19
0
 def mute(self, Group, QQID, time):
     '''
     设置禁言
     QQID > 0 时为群成员禁言设置,否则为全体禁言设置
     time > 0 时为禁言时长(全体禁言直接填1既可),否则为解除禁言
     '''
     INFO(f'设置禁言:Gropu:{Group},QQ:{QQID},TIME:{time}')
     s = {'sessionKey': self.sessionstr, 'target': Group,}
     if QQID > 0:
         #禁言或者解除群员禁言
         if time > 0:
             path = 'mute'
             s['memberId'] = QQID
             s['time'] = time
         else:
             path = 'unmute'
             s['memberId'] = QQID
     else:
         #全体禁言或解除
         if time > 0:
             path = 'muteAll'
         else:
             path = 'unmuteAll'
     print(self.POST(path,s))
Example #20
0
def run_task():
    #循环的在try下运行
    while True:
        try:
            # 读入配置文件
            INFO('读入配置文件...')
            try:
                file = open(Configpath, mode='r', encoding='utf-8')
                config = json.load(file)
                file.close()
            except:
                ERROR('读入配置文件或解析时发生异常,检查配置文件是否正确,默认路径为.BILI目录下的config.json。如果没有则需要复制文件 _config(将我复制改名为config.json).json 为 config.json')
                return
            # 初始化
            INFO('开始初始化所有需要监听的用户')
            user = []
            user.clear()
            delay = config['delay']
            forward_draw = config.get('forward_draw',False)
            for u in config['config']:
                user.append(bilibili_user(UserData(uid=u['uid'], uname=u.get('uname'), showname=u.get('showname'),roomid=u.get('roomid'),PushGroupInfo=u['Group'],
                                                StartDynamic=u['StartDynamic'], StartLive=u['StartLive'], Startvideo=u['Startvideo'])))
                sleep(0.2)
            INFO('所有用户初始化完成')
            INFO('开始执行监听任务')
            INFO('用户列表:'+','.join(list(map(str,[u.user.uid for u in user]))))
            if len(user) == 0:
                INFO('没有载入任何需要监听的用户')
                return
            #执行任务
            while True:
                #循环执行任务!
                errN = 0    #用于记录异常次数,超过十次则跳出while True 循环重新加载
                try:
                    for u in user:
                        #延迟
                        sleep(delay)

                        #检查是否投稿
                        if u.user.StartVideo:   #是否启用视频监听
                            Y,Data = u.video.IsNewVideo()
                            if Y:
                                INFO(f'{u.user.GetName()}更新了视频,准备推送。')
                                for group in u.user.PushGroupInfo:
                                    msg = MsgChain()
                                    if group.get('ATall'):
                                        msg.joinAT(-1)
                                    msg.joinPlain(f'你的小可爱{u.user.GetName(Data.owner_name)}有新的作品发布了哟~\n{Data.title}\n{Data.desc}\n')
                                    if group.get('sendPic'):
                                        msg.joinImg(Url=Data.pic) 
                                    if group.get('sendUrl'):
                                        msg.joinPlain('https://www.bilibili.com/video/'+str(Data.bvid))
                                    Send['sendGroupMsg'](group.get('id',0),msg)

                        #检查是否开播
                        if u.user.StartLive:    #是否启用直播监听
                            Y=u.live.IsLive()
                            if Y:
                                INFO(f'{u.user.GetName()}开播了,准备推送。')
                                for group in u.user.PushGroupInfo:
                                    msg = MsgChain()
                                    if group.get('ATall'):
                                        msg.joinAT(-1)
                                    msg.joinPlain(f'你的小可爱{u.user.GetName()}开播啦~\n{u.live.roominfo.title}\n{u.live.roominfo.area}')
                                    if group.get('sendPic'):
                                        msg.joinImg(Url=u.live.roominfo.pic) 
                                    if group.get('sendUrl'):
                                        msg.joinPlain('https://live.bilibili.com/'+str(u.live.roominfo.roomid))
                                    Send['sendGroupMsg'](group.get('id',0),msg)

                        #检查是否发布新动态
                        if u.user.StartDynamic: #是否启用动态监听
                            Y,Data = u.dynamic.IsNewDynamic()
                            if Y:
                                INFO(f'{u.user.GetName()}更新了动态,准备推送。')
                                #检查是否为转发的抽奖动态
                                if Data.orig_type == 2 and Data.title.find('互动抽奖') != -1 and forward_draw == False:
                                    INFO(f'{u.user.GetName()}的动态内容为转发内容:{Data.title}。\n被判断为转发的抽奖动态,不发送。如果需要发送请在设置里把 forward_draw改为true。如果没有此选项在delay下面添加既可')
                                else:
                                    for group in u.user.PushGroupInfo:
                                        msg = MsgChain()
                                        if group.get('ATall'):
                                            msg.joinAT(-1)
                                        msg.joinPlain(f'你的小可爱{u.user.GetName(Data.uname)}{Data.msg}\n{Data.title}')
                                        if group.get('sendPic'):
                                            for pic in Data.pic:
                                                msg.joinImg(Url=pic)
                                        if group.get('sendUrl'):
                                            msg.joinPlain('https://t.bilibili.com/'+str(Data.dynamic_id))
                                        Send['sendGroupMsg'](group.get('id',0),msg)
                except Exception as e:
                    ERROR(f'执行任务期间发生异常,异常信息:{e.__doc__} 文件:{e.__traceback__.tb_frame.f_globals["__file__"]} 行号:{str(e.__traceback__.tb_lineno)}')
                    errN += 1
                if errN == 10:
                    #for循环体出现10次异常,重启任务
                    break
                #循环固定延时
                time.sleep(2)
        except Exception as e:
            ERROR(f'运行时发生异常,将重新启动任务。异常信息:{e.__doc__} 文件:{e.__traceback__.tb_frame.f_globals["__file__"]} 行号:{str(e.__traceback__.tb_lineno)}')
            #防止一直出错
            time.sleep(10)
Example #21
0
 def on_open(self):
     INFO(self.mode + '_websocket连接成功')
Example #22
0
from msgType import MsgChain, GroupInfo, SenderInfo
from Bot_mirai_cq import on_FriendMessage, on_GroupMessage, mirai, cq
from Log import INFO, ERROR
import threading
import yaml, json
import time
from webserver import zr, apichecklogin, checklogin, request

INFO('开始运行...')
#对,这就是记录版本号的地方,你自己不要改乱了(仅表示发行版本)
INFO('版本号:V 1.1')

#用于存放导入成功的模块
tasks = []


def Import_module(modeule: list):
    '''安装列表内的模块'''
    # 导入模块
    # 包名为目录名,模块为文件夹下的__init__.py,启动后会调用执行一次__init__下的Main函数,
    # 如果不存Main函数将不会执行此模块任何方法
    for t in modeule:
        m = __import__(name=t)
        if 'Main' in dir(m):
            INFO('安装模块:' + str(m))
            tasks.append(m)
        else:
            ERROR('模块:' + str(m) + '未找到Main')
            ERROR(dir(m))

Example #23
0
 def OnCHANGE(self, data):
     '''房间信息:修改标题,修改分区'''
     self.title = data['data']['title']
     self.area = f'{data["data"]["area_name"]}·{data["data"]["parent_area_name"]}'
     INFO(f'{self.roomid}修改分区或标题 【{self.title}】 {self.area}')
     self.SendMSG(MsgChain().joinPlain(f'{self.title}\n{self.area}'))