nonebot2插件之主持飞花令

本插件针对的是使用nonebot2+go-CQHttp为框架的QQ机器人。具体搭建方法可以参考 川川菜鸟 的《qq机器人小白教程系列》

 

本插件使用前需要创建一个计时文件.xlsx,下面的代码中默认D:\QQbot文件\计时文件-飞花令.xlsx,各位可以根据自己的实际情况在合适的文件路径下创建计时文件并更改代码中的路径。请将空表格的sheet的名字改成任意数字,单元格(1,2)、(1,4)、(1,5)键入任意数字;0;0,防止程序出错。另外定期重置表格。

请将以下飞花令规则存在cqhttp4的data\image文件里。

五个指令(均是指令开头,不需要@bot):“发 飞花令x”x可以是1-4或者自定义文字,开启飞花令;“发 加入飞花令”,其它成员加入飞花令,发起者默认是第一个,不需要发送该指令。“发 开始飞花令”,发起者开启飞花令的计时。“发 飞花令.close()”发起者在正式开始前关闭飞花令。“#诗句”,飞花令诗句。

以下是代码,本人没有系统学习过代码规范,所以略粪,如果有大佬可以优化本人将再三感谢

# -*- coding:utf-8 -*-
from nonebot.adapters.cqhttp import Message
from nonebot import on_keyword, on_notice, on_message,on_startswith
from nonebot.typing import T_State
from nonebot.adapters import Bot, Event
from nonebot import require
from aiocqhttp.exceptions import Error as CQHttpError
from nonebot.adapters.cqhttp import message, GroupMessageEvent, Message, MessageEvent
from nonebot.typing import T_State
import random,openpyxl,time,nonebot,requests
from nonebot_plugin_apscheduler import scheduler
from bs4 import BeautifulSoup
#本插件内容:飞花令开局、加入、开启、判定、计时、结算
dict2,dict3 = {},{} #dict3是当前群聊有无飞花令,dict2是当前飞花令的表格名称,list1是说过的内容,dict2是关键字,dict4是用户
f0 = openpyxl.load_workbook('D:/QQbot文件/计时文件-飞花令.xlsx')#如果没有这个文件,需要先创建一个

fhrule = on_keyword('飞花令规则',priority=98)

@fhrule.handle()
async def fhgz(bot: Bot, event: GroupMessageEvent, state: T_State):#飞花令仅在群聊中开启
    guize = '飞花令.jpg'#将飞花令规则截图存在cqhttp4的dataimage文件里
    tu = [
    {
        "type":"image",
        "data":{
            'file':f'{guize}'
            }
    }
    ]
    await fhrule.send(tu)

fhstart = on_startswith({'发 飞花令'},priority=3)

@fhstart.handle()
async def j(bot: Bot, event: GroupMessageEvent, state: T_State):#飞花令仅在群聊中开启
    global dict2,dict3,f0
    x = str(event.message).replace('发 飞花令','').strip()#获取飞花令难度,什么也不写默认4
    grname = event.group_id
    usid = event.user_id
    try:#首先判定群里有没有正在开的飞花令,没有的话将数值设置为0
        status1 = dict3[grname]
    except KeyError:
        dict3[grname] = 0
    if dict3[grname] == 1:#如果有正在开的飞花令,不能开始新局
        try:
           await fhstart.send(Message('当前正在进行,请勿重开'))
        except TypeError:#CQHttpError:
            pass
    else:
        if grname in [915324969,957383234,799524693,571060634]:#屏蔽一些群聊中的功能,可以手动添加也可以另外设置一个口令
            pass
        else:
            if not x:
                x = '4'
            if x not in ['1','2','3','4']:
                await fhstart.send('请输入正确难度(1-4)!')
            else:#根据难度出题
                dict3[grname] = 1#判定开局,状态改为1
                atime = time.time()
                dict3[grname] = 1
                dict2[grname] = str(grname)+str(atime)
                sheet = f0.create_sheet(dict2[grname])#根据群名+创建时间建立的飞花令表格,便于复查飞花令记录,如果没有这个必要,可以直接改成群聊的名字,每次开局重置。后面的表格判定也都直接改成判定以这个群号为名称的表格的状态,而不需要遍历。
                if x == '1':
                    b = random.choice(['风', '花', '月', '人', '春', '天', '河', '红', '白', '秋', '水', '江', '海', '如', '中', '上', '下', '一', '日', '不', '无', '明', '山', '云', '大', '小', '我', '时', '有', '长', '何', '空', '心', '来', '去', '里', '为', '君', '知', '见', '在', '相', '年', '自', '此'])
                elif x == '2':
                    b = random.choice(['安', '百', '半', '杯', '北', '碧', '别', '波', '残', '草', '尘', '成', '城', '愁', '出', '处', '从', '翠', '当', '到', '道', '得', '地', '东', '独', '断', '对', '发', '方', '方位+风', '飞', '非', '风+季节/+时间点', '复', '高', '歌', '个位数+个位数', '更', '孤', '古', '故','关', '光', '归', '国', '过', '寒', '好', '合', '荷/芙蓉/蕖', '后', '黄', '回', '几', '家', '间', '将', '今', '尽', '近', '惊', '酒', '旧', '开', 
                    '看', '可', '客', '老', '冷', '离', '连', '林', '流', '龙', '楼', '路', '露', '落', '绿', '马', '满', '门', '梦', '明+月', '莫', '木', '暮', '南','难', '能', '鸟', '平', '起', '气', '千', '前', '桥', '青', '清', '情', '然', '入', '三', '色', '少', '谁', '身', '深', '生', '声', '十', '石', '时间点+季节/+时间点', '似', '是', '书', '树', '数字+花', '数字+年', '数字+月', '双', '霜', '思', '随', '岁', '台', '同', '头', '外', '晚', '万', '望',
                    '微', '文', '闻', '五', '西', '溪', '闲', '乡', '香', '晓', '新', '行', '须', '雪', '烟', '颜色+花', '阳', '野', '叶', '夜', '衣', '已', '意', '吟', '应', '影', '游', '与', '雨', '玉', '欲', '远', '照', '终', '重', '竹', '子', '醉','黑山/阴山/塞/天山/昆仑/长城','消/销/萧/潇/宵/霄','血/肉/骨/肤','才/刚/方/正','方/圆/规/矩','指定植物+花','花+植物器官/+植物种类','区划地形+区划地形','区划地形+方位','颜色+植物器官/+植物种类'])
                elif x == '3':
                    b = random.choice(['八', '冰', '病', '不+尽', '采', '彩', '蚕', '曾', '常', '沉', '池', '赤', '川', '船', '窗', '吹', '垂', '春+花', '辞', '大+江', '待', '但', '灯', '灯', '低', '帝', '点', '叠字(或连续两个一样的字)', '动', '都', '儿', '而', '二', '方位+方位', '方位+海', '风+雨', '峰', '浮', '阁', '隔', '功', '宫', '共', '观', '还', '汉', '恨', '鸿', '忽', '胡', '湖', '画', '荒', '昏', '火', '寄', '佳', '剑', '皆', '接', '节', '锦', 
                    '景', '镜', '九', '菊', '觉', '堪', '口', '哭', '兰', '浪', '乐', '帘', '柳', '六', '乱', '漫', '眉', '梅', '美', '面', '鸣', '目', '念', '暖', '蓬', '片', '破', '七', '旗', '浅', '墙', '琴', '晴', '曲', '全', '泉', '犬', '人+不', '诗', '时间点+花', '时间点+月', '食', '始', '世', '手', '数字+百', '数字+季节/+时间点', '数字+里', '数字+千', '数字+人', '数字+日', '数字+万', '数字+颜色', '说', '丝', '死', '四', '素', '堂',
                    '同一个字重复出现但不连在一起', '桐', '童', '土', '王', '问', '舞', '雾', '细', '霞', '夏', '想', '笑', '斜', '星', '休', '寻', '言', '颜色+水/+江', '颜色+云', '眼', '雁', '燕','杨', '也', '依', '疑', '音', '银', '悠', '于', '于', '语', '怨', '愿', '早', '章', '真', '征', '正', '枝', '只','州', '烛', '转', '紫', '足','最', '户', '映', '数字+十', 
                    '松', '凤', '指', '却', '柔', '定', '落+花', '流+水/+江', '季节+水/+江', '不+闻/+见', '惟/唯/剩/仅', '花+无/+不', '小楼/西楼/高楼/楼高', '城外/门前/枝头/天下/山中/海上', '岩/涯/崖/岭/谷/壁/巅/顶', '季节+雨/+雪', '箫/笛/笙/箜篌/筝','鼓/瑟/钟/琵琶/磬', '妆/容/粉/黛', '姿/服/裳/袍', '日+颜色/+季节', '云+颜色/+季节', '数字+心/+情', '离+别/+人', '无边/无语/无言/不语/不见/不闻', '烽/漠/榆/旌', '画/图/点/墨', '时间点+雨/+风','接/发/留/住',
                    '数字+颜色','江+季节/+时间点','泽/黄鹤/洞庭/潇/湘','梨/李/瓜/海棠/枣','鬼/魂/魄/灵','人+月/+时间点','不+无/+不','逢/遇/适/邂逅','颜色+月/日','徘徊/盘桓/踌躇/踟蹰/踯躅','指定植物+植物器官','植物种类+月/+季节','指定植物+月/+季节','植物器官+数字','植物器官+月/+季节','指定植物+指定植物','植物器官+植物器官/+植物种类','区划地形+季节/+时间点','区划地形+数字','指定动物+颜色'])
                elif x == '4':
                    b = random.choice(['哀', '爱', '岸', '把', '薄', '杯', '边', '别', '鬓', '兵', '病', '彩/蛋/农/校/科/技/协/会', '残', '蚕', '草', '曾', '车', '沉', '陈', '晨/旦/曙/早/晓', '城', '池', '迟', '尺', '虫', '初', '楚', '朝', '吹', '垂', '词', '辞', '此', '从', '翠', '打', '旦', '淡', '当', '登', '底', '点', '雕', '蝶', '冬', '豆', '杜', '儿', '帆', '翻', '方位+方位', '芳', '飞', '肥', '取/赢/赏/功','分', '纷', '枫', '逢', '夫', '拂', '复',
                    '敢', '更', '鼓', '故', '顾', '关', '光', '桂', '国', '还', '好', '号', '浩', '和', '河汉/星汉/银汉/银河/银潢/星河/星汉', '黑', '侯', '乎', '呼', '胡', '户', '华', '化', '黄+河', '悔', '昏', '鸡', '急', '记', '季节+月', '家', '间', '建康/建邺/建业/宁/金陵', '渐', '脚', '金', '经', '惊', '镜', '旧', '举', '卷', '绝', '槛', '可', '客', '口', '哭', '狂', '来+往/+去', '栏', '阑', '蓝', '郎', '乐', '泪', '梨', '篱', '立', '丽', '连', '怜',
                    '帘', '莲', '零', '留', '落', '麦', '忙', '茫', '没', '眉', '梅+花', '门', '眠', '眠/寐/醒/寝', '名', '名', '鸣', '磨', '莫', '木', '泥', '娘', '牛', '弄', '女', '怕', '旁', '萍', '破', '其', '旗', '气', '泣', '浅', '强', '清明/元宵/元夜/春社', '穷', '泉', '然', '若', '桑', '沙', '山+水','裳', '舍', '谁', '身', '深', '神', '胜', '石', '识', '食', '事', '是', '首', '数字+季节', '双', '送', '所', '苔', '滩', '潭', '叹', '涕',
                    '天孙/河鼓/牵牛/织女/黄姑/鹊', '铁', '听', '庭', '停', '同', '桐', '头', '王', '往', '未', '问', '翁', '卧', '吴', '夕', '夕阳/斜阳/落日/日暮', '兮', '息', '稀', '细', '闲', '弦', '乡', '相', '向', '晓', '歇', '斜', '辛', '行', '杏', '兄', '休', '寻', '压', '涯', '颜', '颜色+山', '颜色+颜色', '雁', '燕', '扬州/杭州/苏州/姑苏', '阳', '杨+柳', '遥', '衣/襟/裳/冠/冕', '亦', '阴', '饮', '应', '幽', '犹', '又', '右', '鱼',
                    '羽', '元', '原', '岳','在', '赠', '长+江', '折', '征', '之', '枝', '至', '终', '钟', '舟', '烛', '妆', '字', '总', '最', '左', '作', '染', '进', '腹','取/赢/赏/功','秦/晋/京/津/齐/鲁','关/轮台/燕然/贺兰/燕山/青海','雀/乌/子规/鹧鸪/鹦鹉/莺/鸳','弓/箭/刀/矢/剑/戟','衰/老/朽/弱','恶/苦/贬/谪','仙/神/东君/社','月+方位/+时间点','花+方位/+时间点','方位+季节/+时间点','不+无/+不','徘徊/盘桓/踌躇/踟蹰/踯躅','枕/倚/凭/扶','独+立/+数字','园/圃/场/原','花+植物器官/+植物种类',
                    '指定植物+数字','区划地形+方位','指定动物+数字','指定植物+颜色','颜色+植物器官/+植物种类','指定动物+指定动物','指定动物+指定植物','指定动物+月/+季节','区划地形+颜色','指定植物+花','植物器官+月/+季节','区划地形+区划地形','指定植物+指定植物','区划地形+数字'])
                else:
                    for i in x:
                        if i in ['。',',','?','!','、',';',':','“','《','(']:
                            success = False
                            break
                        else:
                            success = True
                    if success:
                        b = x
                    else:
                        await fhstart.send('请输入正确难度(1-5)!如果是自选主题,请注意格式,详见“飞花令规则”!')
                        b = False
                if b:
                    sheet.append(['group',grname,atime,'飞花令',-1,'',b])#单元格(1,5)存储本局飞花令的状态,-1未开始,0已结束,1-n代表参与者的顺序
                    sheet.append(['group',grname,atime,'参加',1,usid,'0'])#飞花令的发起者默认顺序为1,发起者ID录入这一行的F格
                    await fhstart.send('请在十分钟内找到至少其他1人才能正式开始哦,如果要参与,请发送‘发 加入飞花令’加入飞花名单,如果凑齐人数且在开局10分钟内,发起者均可发送‘发 开始飞花令’开启飞花之旅。')
                    f0.save('D:/QQbot文件/计时文件-飞花令.xlsx')

async def gjzxq(b):#将几种特殊类型的飞花令拆解成可以判定的单字
    dict1 = {'数字':['一','二','三','四','五','六','七','八','九','十','零','百','千','万','亿','两','数','半'],'个位数':['一','二','三','四','五','六','七','八','九','零'],'颜色':['红','橙','黄','绿','青','蓝','紫','粉','黑','白','碧','褐','赤','灰','金','银','玄'],'方位':['东','南','西','北','中','上','下','左','右','里','外','内','前','后'],'季节':['春','夏','秋','冬'],'时间点':['朝','夕','暮','夜','晚','午','晓','晡','昨','明日','一更','二更','三更','四更','五更','昏'],'指定植物':['桃','杏','梨','李','棠','梅','苔','蕨','樱','松','柏','杨','柳','芦','蒿','蓼','榔','棣','莪','萍','苹','蘋','葭','兰','竹','菊','豆','麦','荻','稻','粟','荷','莲','芙','槿','蒲','桂','槐','桑','榆','藕','薇','枫','榴','牡丹'],'植物器官':['根','茎','叶','实','种','萼','枝','芽','苗','花'],'指定动物':['鹤','鸳','燕','雁','鸿','鸥','鹭','鹂','鸪','鹃','莺','犬','牛','羊','鹦','马','鸡','鸭','鹅','猿','鹿','雀','鹊','鱼','虫','子规','蝶','蜂','蝉','蟾','蚁','虾','蟆','蚕','蜻蜓','鸾','蛇','狼','狸','鸦','蜉','狐','豚'],'植物种类':['树','草','藤','木'],'区划地形':['州','乡','村','阴','阳','山','河','湖','海','谷','山','原','江'],'酒器':['斗','樽','碗','杯','斛','壶','瓮','盏']}
    listb = []
    if '叠字' in b:
        b = '叠字'
    elif '重复' in b:
        b = '重复'
    elif len(b) <3:
        b = b.split()
    elif '+' in b and '/' not in b:
        b = b.split('+')
        for i in b:
            if len(i)>1:
                i = dict1[i]
                listb.append(i)
            else:
                listb.append(i.split())
        if listb:
            b = listb
    elif '/' in b and '+' not in b:
        b = b.split('/')
        for i in b:
            listb.append(i.split())
        if listb:
            b = listb
    else:
        b = b.split('/+')
        for i in b:
            if '+' in i:
                a = i.split('+')
                for i2 in a:
                    if len(i2)<2:
                        listb.append(i2.split())
                    else:
                        listb.append(dict1[i2])
            else:
                if len(i)<2:
                    listb.append(i.split())
                else:
                    listb.append(dict1[i])
        if listb:
            b = listb
    return b

fhjoin = on_startswith({'发 加入飞花令'},priority=72)

@fhjoin.handle()
async def j2(bot: Bot, event: GroupMessageEvent, state: T_State):
    f0 = openpyxl.load_workbook('D:/QQbot文件/计时文件-飞花令.xlsx')#如果没有这个文件,需要先创建一个
    grname = event.group_id
    usid = event.user_id
    sheetlist = f0.sheetnames
    for sheets in sheetlist:
        success = False
        sheet = f0[sheets]
        if str(grname) not in sheets:
            continue
        elif sheet.cell(1,5).value > 0:
            success = True
            await fhjoin.send('当前本群有飞花令正在进行,不能中途加入!')
            break
        elif sheet.cell(1,5).value == -1:
            success = True
            shunxu = sheet.max_row#因为第一行是基本信息,所以在加入之前的最后一行就是加入者的序号
            if shunxu > 18:
                await fhjoin.send('人数已经达到18人,不可再加入!')
            else:
                success = False
                for i in range(2,sheet.max_row+1):
                    if sheet.cell(i,6).value == usid:
                        await fhjoin.send('你已经加入这局飞花令啦!')
                        success = True
                        break
                if not success:
                    success = True
                    await fhjoin.send(f'加入成功!请等待发起者开始。\n你的序号是:{shunxu}')
                    sheet.append(['group',grname,time.time(),'参加',shunxu,usid,'0'])
                    f3 = open("D:/QQbot文件/计时文件.txt",'w',encoding='utf-8')
                    f3.write(str(time.time()))
                    f3.close()
                    f0.save('D:/QQbot文件/计时文件-飞花令.xlsx')
            break
    if not success or event.user_id in [2538372982,1540689041]:
        await fhjoin.send('当前没有正在发起的飞花令,请发送‘发 飞花令x’发起新的飞花令。')

fhbegin = on_startswith({'发 开始飞花令'},priority=73)

@fhbegin.handle()
async def j3(bot: Bot, event: GroupMessageEvent, state: T_State):
    f0 = openpyxl.load_workbook('D:/QQbot文件/计时文件-飞花令.xlsx')#如果没有这个文件,需要先创建一个
    grname = event.group_id
    usid = event.user_id
    sheetlist = f0.sheetnames
    for sheets in sheetlist:
        success = False
        sheet = f0[sheets]
        if str(grname) not in sheets:
            continue
        elif sheet.cell(1,5).value > 0:
            success = True
            await fhbegin.send('当前本群有飞花令正在进行,请勿重开!')
            break
        elif sheet.cell(1,5).value == -1:
            success = True
            if sheet.cell(3,6).value:
                if sheet.cell(2,6).value == usid:#(2,6)是发起者的ID,只有发起者可以开始飞花令。
                    sheet.cell(1,5).value = 1
                    await fhbegin.send('飞花令即将开始,本次主题:'+sheet.cell(1,7).value)
                    atlist = f'[CQ:at,qq={sheet.cell(2,6).value}]'
                    atlist1 = '从' + atlist + '你那儿,开始!'
                    for i in range(3,sheet.max_row+1):
                        atlist = atlist + f'[CQ:at,qq={sheet.cell(i,6).value}]'#按照顺序一次@每一个人
                    atlist = '顺序:' + atlist
                    time2 = time.time()
                    sheet.append(['group',grname,time2,'',-1,sheet.cell(2,6).value])#群,群号,时间,飞花令内容(等待参与者说出再添加),状态:-1未作答且尚未超时,0超时没说出淘汰,1说对,这个人的ID
                    f0.save('D:/QQbot文件/计时文件-飞花令.xlsx')
                    await fhbegin.send(Message(atlist1))#随后@第一个人开始
                    await fhbegin.send(Message(atlist))
                    break
                else:
                    await fhbegin.send('你不是发起者,无权限开始!')
            else:
                await fhbegin.send('只有你一个人参加,不能开始!')
    if not success or event.user_id==1540689041:
        await fhbegin.send('当前本群无飞花令正在等待,不能开始!')

feihua = on_startswith({'#','#'},priority=74)#以‘#’开头为飞花令识别关键词

@feihua.handle()
async def shici(bot: Bot, event: GroupMessageEvent, state: T_State):
    global dict2
    f0 = openpyxl.load_workbook('D:/QQbot文件/计时文件-飞花令.xlsx')#如果没有这个文件,需要先创建一个
    grname = event.group_id
    usid = event.user_id
    msg = str(event.message).replace('#','').replace('#','').strip()
    try:
        sheet = f0[dict2[grname]]#根据dict2确定大开哪个表格
        success = False
        if usid == sheet.cell(sheet.max_row,6).value:#当前最后一个人总是保持当前要进行飞花令的人。
            success = True
            panding = await fhpanding(msg,grname) #使用函数判定这句诗句是否合规
            if not panding:#如果说对了,判定=arc=false
                shiju = msg.replace(',','').replace('。','').replace('、','')
                sheet.cell(sheet.max_row,5).value = 1#已经说对,状态更改为1
                sheet.cell(sheet.max_row,4).value = msg#已经说对,将诗句存档
                sheet.cell(sheet.max_row,7).value = shiju
                status_code = sheet.cell(1,5).value
                for i in range(2,20):
                    if sheet.cell(i,4).value == '参加' and sheet.cell(i,5).value == status_code:#找到当前是谁
                        if sheet.cell(status_code+2,4).value == '参加':
                            status_code += 1
                        else:
                            status_code = 1
                        while sheet.cell(status_code+1,5).value<0:#跳过被淘汰的人,因为如果还有人说对诗句,说明场上至少还有两个人,不会陷入无限循环
                            status_code += 1
                            if sheet.cell(status_code+1,4).value != '参加':
                                status_code = 1
                        sheet.cell(1,5).value = status_code#更改飞花令状态为下一顺位。
                        atid = sheet.cell(status_code+1,6).value
                        msg = f'[CQ:at,qq={atid}]' + '该你了'
                        await feihua.send(Message(msg))
                        sheet.append(['group',grname,time.time(),'',-1,atid])#下一轮计时开始
                        sheet.cell(1,5).value = status_code
                        f0.save('D:/QQbot文件/计时文件-飞花令.xlsx')
                        break
            else:
                await feihua.send(panding)
        if not success:
            await feihua.send('请勿干扰飞花秩序。')
    except CQHttpError and KeyError:
        if event.group_id not in [957383234,965324969,762756338]:
            await feihua.send('这是一条报错消息')
            pass

async def fhpanding(msg,grname):
    global dict2
    f0 = openpyxl.load_workbook('D:/QQbot文件/计时文件-飞花令.xlsx')#如果没有这个文件,需要先创建一个
    sheet = f0[dict2[grname]]
    b = await gjzxq(sheet.cell(1,7).value)#如果是特殊飞花令,将得到所有判定字,如果是普通飞花令,将得到一个只有1个元素的列表
    a,msg2 = 0,''
    shiju = msg.replace(',','').replace('。','').replace('、','')
    success = False
    if b == '叠字':#两个比较特殊的情况,叠字和重复出现但不相邻的字
        for i in range(len(msg)-1):
            if msg[i] == msg[i+1]:
                diezi = msg[i] + msg[i+1]
                success = True
                for row in range(4,sheet.max_row+1):#叠字的规则中还有一条:已经说过的叠字不能再说
                    if not sheet.cell(row,4).value:
                        pass
                    elif diezi in sheet.cell(row,4).value:
                        success = False
                        break
                break
    elif b == '重复':
        for i in range(len(msg)):
            for j in range(len(msg)):
                if i-j > 1 and msg[i] == msg[j]:#不相邻且相同
                    chongfu = msg[i]
                    diezi = msg[i] + msg[j]
                    success = True
                    for row in range(4,sheet.max_row+1):
                        if not sheet.cell(row,4).value:
                            pass
                        elif chongfu in sheet.cell(row,4).value and diezi not in sheet.cell(row,4).value:#有关键字但没有重复出现,如果将关键字去掉后少了两个字以上,说明重复了。
                            a = len(sheet.cell(row,4).value)
                            b = len(sheet.cell(row,4).value.replace('chongfu',''))
                            if a-b >1:
                                success = False
                            break
                    break
            if success:
                break
    else:
        if len(b) == 1:#单关键字,只要在,就判定合规
            if b[0] in msg:
                success = True
        elif len(b) == 2:#双关键字,两个都在,才能判定合规
            for i in b[1]:
                if i in msg:
                    success = True
                    msg2 = msg.replace(i,'')
                    if b[1]!=b[0] and len(msg)-len(msg2)>1:
                        msg2 = msg2 + i
                    break
            if success:
                success2 = False
                for j in b[0]:
                    if j in msg2:
                        success2 = True
                        break
                if not success2:
                    success = False
        elif len(b) == 3: #一个关键字+另外两个关键字任选一个
            for i in b[0]:
                if i in msg:
                    success = True
                    msg2 = msg.replace('i','')
                    break
            if success:
                success2 = False
                for j in b[1]:
                    if j in msg2:
                        success2 = True
                        break
                if not success2:
                    for i in b[2]:
                        if i in msg2:
                            success2 = True
                    if not success2:
                        success = False
        else:
            for i in b:#多个关键词任选其一的情况,只需要一个在就行
                if i[0] in msg:
                    success = True
                    break
    if not success:
        arc = '没有关键字或在叠字飞花令中关键字重复,请在剩余时间内说出正确诗句!'
    else:
        if b != '重复' and b != '叠字':
            for i in range(4,sheet.max_row+1):#判断诗句有无说过。比如说过了‘天若有情天亦老,人间正道是沧桑’,可以说‘衰兰送客咸阳道,天若有情天亦老’,但不可以只说‘天若有情天亦老’,反之亦然。
                if not sheet.cell(i,7).value:
                    pass
                elif sheet.cell(i,7).value in shiju or shiju in sheet.cell(i,7).value:
                    arc = '说过了,请在剩余时间内说其它诗句!'
                    success = False
                    break
    if success:
        if len(shiju) < 5 or len(shiju) > 20 or len(shiju)==4 and ',' in msg[:4]:#判定诗句长度是否符合规范
            arc = ('字数错误,请在剩余时间内补全或删简!')
            success = False
        else:#重头戏,通过古诗文网搜索判断诗句是否正确
            headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'}
            arc = requests.get('https://so.gushiwen.cn/search.aspx?value='+msg + '&valuej=' + msg[0],headers=headers)
            htm = BeautifulSoup(arc.text,'html.parser')
            try:
                cd = htm.find('textarea')
                cdtext = cd.text
            except AttributeError:#这个是防止一些诗句有两个版本导致搜索结果界面显示不同
                cd = htm.find('head')
                cdtext = cd.text
            cdtext=cdtext.split("——")[0]
            a = 0
            for i in shiju:
                if i in cdtext:
                    a = a + 1
            cdtext1 = cdtext.replace(shiju[:2],'').replace(shiju[2:5],'')
            if a != len(shiju) or cdtext==cdtext1:
                success = False
            elif a == len(shiju):#如果诗句和结果完全匹配,判断诗句是否完整判定方法是最后一个字后面是不是标点符号。
                success = False
                for i2 in range(len(cdtext)):
                    if cdtext[i2] == shiju[-1] and cdtext[i2+1] in [',','。','!','?','、',';',',','?',';','》','”']:
                        success = True
                        break
            if not success:
                arc = '诗句不完整或不正确,请在剩余时间内调整答案!'
    if success:
        arc = False
    return arc#只有没有说对arc才有值,说对了arc=false

require('nonebot_plugin_apscheduler').scheduler

@scheduler.scheduled_job('interval', seconds = 5)
async def co4():
    global dict3,dict2
    f0 = openpyxl.load_workbook('D:/QQbot文件/计时文件-飞花令.xlsx')#如果没有这个文件,需要先创建一个
    bot = nonebot.get_bots()['3635837386']
    listsheet =f0.sheetnames
    list2 = []
    for i in listsheet:
        sheet = f0[i]
        if sheet.cell(1,5).value != 0:
            dict3[sheet.cell(1,2).value] = 1
            dict2[sheet.cell(1,2).value] = i
            list2.append(sheet.cell(1,2).value)
    kys = list(dict2.keys())
    for ky in kys:
        if ky not in list2:
            del dict2[ky]
            del dict3[ky]
    for ix in range(len(listsheet)):
        fui = -1 - ix
        sheet =f0[listsheet[fui]]
        a5b = sheet.cell(sheet.max_row,3).value
        a5a = str(sheet.cell(sheet.max_row,2).value)
        a5d = sheet.cell(sheet.max_row,5).value
        status_code = sheet.cell(1,5).value
        timeline = time.time()
        if status_code == -1:
            if timeline - sheet.cell(1,3).value > 600:
                sheet.cell(1,5).value = 0
                await bot.call_api('send_group_msg',**{
                    'group_id':a5a,
                    'message':'由于10分钟未开始,飞花令结束,如果还有人想玩请重新发送‘发 飞花令x’开局。'
                    })
                dict3[sheet.cell(1,2).value] = 0
                dict2[sheet.cell(1,2).value] = 0
                f0.save('D:/QQbot文件/计时文件-飞花令.xlsx')
        elif a5d == 0:
            pass
        elif status_code > 0:
            if timeline - a5b > 29.3 and timeline - a5b < 35:
                await bot.call_api('send_group_msg',**{
                    'group_id':a5a,
                    'message':f'[CQ:at,qq={sheet.cell(sheet.max_row,6).value}]还有30秒'
                    })
            elif timeline - a5b > 49.3 and timeline - a5b < 55:
                await bot.call_api('send_group_msg',**{
                    'group_id':a5a,
                    'message':f'[CQ:at,qq={sheet.cell(sheet.max_row,6).value}]还有10秒'
                    })
            elif timeline - a5b > 60:
                await bot.call_api('send_group_msg',**{
                    'group_id':a5a,
                    'message':f'[CQ:at,qq={sheet.cell(sheet.max_row,6).value}]时间到,'
                    })
                sheet.cell(sheet.max_row,5).value = 0
                grname = sheet.cell(1,2).value
                status_code,sc2 = sheet.cell(1,5).value,sheet.cell(1,5).value
                val,alv = -1,0
                for lines in range(2,20):
                    if sheet.cell(lines,4).value == '参加' and sheet.cell(lines,5).value<=val:
                        val = sheet.cell(lines,5).value-1
                    elif sheet.cell(lines,4).value == '参加' and sheet.cell(lines,5).value > 0:
                        alv += 1
                        if status_code < lines-1 and sheet.cell(lines,5).value>0:
                            sheet.cell(1,5).value = sheet.cell(lines,5).value
                            status_code = 21
                    elif sheet.cell(lines,4).value != '参加':
                        break
                sheet.cell(sc2+1,5).value = val
                if alv <= 2:
                    sheet.cell(1,5).value =0
                    f0.save('D:/QQbot文件/计时文件-飞花令.xlsx')
                    reply = await fhjiesuan(grname)
                    del dict3[grname]
                    del dict2[grname]
                    await bot.call_api('send_group_msg',**{
                        'group_id':a5a,
                        'message':f'{reply}'
                        })
                else:
                    if status_code == 21:
                        atid = sheet.cell(sheet.cell(1,5).value+1,6).value
                        status_code = sheet.cell(sheet.cell(1,5).value+1,5).value
                    else:
                        for iy in range(2,sc2):
                            if sheet.cell(iy,5).value > 0:
                                sheet.cell(1,5).value = sheet.cell(iy,5).value
                                atid = sheet.cell(iy,6).value
                                status_code = sheet.cell(iy,5).value
                                break
                    msg = f'[CQ:at,qq={atid}]' + '该你了'
                    await bot.call_api('send_group_msg',**{
                        'group_id':a5a,
                        'message':msg
                        })
                    sheet.append(['group',sheet.cell(1,2).value,time.time(),'',-1,atid])
                    sheet.cell(1,5).value = status_code
                    f0.save('D:/QQbot文件/计时文件-飞花令.xlsx')
                    break

async def fhjiesuan(grname):
    global dict2,f0
    sheet0 = f0[dict2[grname]]
    list1,dict1,dict4 = [],{},{}#list1:排名,dict1,名次对应的人,dict2,人对应的分数
    msg = '本局飞花令结束!排名如下:'
    for i in range(2,20):
        if sheet0.cell(i,4).value == '参加':
            list1.append(sheet0.cell(i,5).value)#先把负数排名放进来,最后一个人没有负数排名
            dict1[sheet0.cell(i,5).value] = sheet0.cell(i,6).value
            dict4[sheet0.cell(i,6).value] = 0
        else:
            break
    list1.sort()#排序,由于只有数字,自然会排成-x,-x+1…………,正数排名的那个人(这个人的名次应该是-len(list1))
    dict1[-len(list1)] = dict1[list1[-1]]#将dict1里的正数排名的那个人改成负数排名
    del dict1[list1[-1]]
    list1[-1] = -len(list1)#把list里的正数排名改成负数
    list1.sort()
    a = 0
    for i in range(4,sheet0.max_row+1):#根据正文的第5列的数据计算每个人的诗句总数
        if sheet0.cell(i,4).value != '参加' and sheet0.cell(i,5).value==1:
            a = a + 1
            dict4[sheet0.cell(i,6).value] = dict4[sheet0.cell(i,6).value] + 1
    for i in list1:
        msg = msg + '\n第' + str(i+1+len(list1)) + '名:' + f'[CQ:at,qq={dict4[dict1[i]]}]' + ':' + str(dict4[dict1[i]]) + '分'
    return msg

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值