Nonebot2学习记录:从Hello,world到人工智障
最近突然捡起来之前想做个QQ机器人的想法,然后就乱学(顺便鸽掉了其他在学的东西),总之把自己写的和学的一些东西慢慢丢上来(快乐网盘)
完全新手,总之主要是写给自己看的,如有冒犯或是觉得我写的不适合当bot我即刻删文跑路(?
0.一些看前需要用到的东西
使用的语言为python,用到的bot框架是 Nonebot2 ,go-cqhttp (知道是模拟qq客户端发送消息但到底是怎么实现发送的啊.....好神奇)
入门时看的基础教程是这个大佬的视频 ,还是这个大佬的博客 ,另一个大佬的博客 ,以及Nonebot2商店里的插件源代码还有很多Google一下的大佬博客
时事碎碎念
最近(2022/5/17)Nonebot2因为可以搜这里是一个大佬写的萌新FAQ
写的时候码风混乱,会有很多冗杂和无用的地方,大概是让自己也看不懂的程度
如果上面都有了解那么请接着看下去吧
自己碎碎念
一开始一直想自己写一个消息处理框架然后啥都不会,实际上需要做的就是挂起一个窗口一直监听发送消息的端口,接着用POST和REQUEST来模拟消息发送就好了 参考这篇博客(即使如此依旧不太会)一些对上面教程的补充
视频教程里有一个没有提到的点是,Nonebot2在根目录下的pyproject.toml文件中的plugin_dirs会直接将指定文件夹里的文件直接引用,所以在编写以包形式的插件时会出现”插件已重复命名“或无法通过不引用包来禁用这一部分插件,注释掉这一行后就可以直接引用包其实这些具体设置自己也没看懂XD,慢慢用到了再详细了解好了
1.Hello,world
最基础的部分上面的教程里有讲,一些函数也有基础的了解
以下写的都是插件,如果是刚入门不知道怎么配置请务必先看上面的所有教程一步步跟着来
对于大部分的事件处理,需要用到的事件函数基本是get_message()以及get_session_id(),具体参考官方文档和ctrl进相关函数看具体实现方式(Nonebot2——之后都用N2代替了——在大部分函数下面都标了注释,理解起来挺方便)
那么来写一个每日人品的插件吧!(视频复述.jpg)
点我看超长超sv代码
import random
import ast
from datetime import date
from nonebot.plugin import on_keyword
from nonebot.adapters.onebot.v11 import Bot, Event, GroupMessageEvent
from nonebot.adapters.onebot.v11.message import Message
import re
def today_luky(num): # 随机人品的实现函数(简单的用随机数模拟一个区间的值并返回自己写的回复)
if num < 18:
return '大吉'
elif num < 53:
return '吉'
elif num < 58:
return '半吉'
elif num < 62:
return '小吉'
elif num < 65:
return '末小吉'
elif num < 71:
return '末吉'
else:
return '凶'
"""ON_KEYWORD
ON_KEYWORD是NONEBOT提供的宏,实现命令消息(如菜单、工具栏的选项消息)的消息响应函数的注册。
使用方法为ON_KEYWORD(消息ID, 响应函数名)
注册了响应函数之后,一旦主窗口接收到该命令消息,程序就会调用我们提供的消息响应函数进行处理
类似的还有ON_COMMAND,ON_MESSAGE等,均位于nonebot.plugin下(之后会直接import*)
"""
jrrp = on_keyword({'今日人品', 'jrrp'}, priority=50) # 接收关键字
"""
在上方代码中,我们注册了一个事件响应器 Matcher,它由几个部分组成:
on_keyword 注册一个消息事件响应器,并且当消息纯文本部分包含关键词时响应。
"今日人品" 指定 jrrp 参数 - 命令名
rule 补充事件响应器的匹配规则,例如to_me()——当bot被@时才执行
priority 事件响应器优先级,当接受的指令会被多个插件执行时,按照优先级从小到大的顺序逐个执行
block 是否阻止事件传递,当按优先级执行到这个插件时进行阻断,不再往后执行低优先级的插件
"""
"""handle()
简单的为事件响应器添加一个事件处理函数,这个函数将会在上一个处理函数正常返回执行完毕后立即执行。
"""
@jrrp.handle()
async def jrrp_handle(bot: Bot, event: Event):
rnd = random.Random()
rnd.seed(
int(date.today().strftime("%y%m%d")) + int(event.get_user_id())) # 为了每天获取的rp值固定,采用日期+QQ号作为随机数种子的形式来固定每个人自己的当日好感
"""event.get_user_id()
作用是获取命令发送者的QQ号,返回值为str
"""
lucknum = rnd.randint(1, 100)
with open("src/plugins/群名单.txt", encoding='utf-8') as file: # 提取白名单群文件中的群号,自己建一个就行,直接在最外面写一个Config文件里面写各个白名单群号可以
white_block = []
for line in file:
line = line.strip()
line = re.split("[ |#]", line) # 可能会有'#'注释或者空格分割
white_block.append(line[0]) # 新建一个表给它扔进去
try:
whatever, group_id, user_id = event.get_session_id().split('_')
"""event.get_session_id()
获取当前群聊id,发起人id,返回的格式为group_群聊账号_消息发起人账号
如果不是group类型的消息,将会直接返回消息发起人账号
"""
except: # 如果上面报错了,意味着发起的是私聊,返回格式为userid
group_id = None
user_id = event.get_session_id()
if group_id in white_block or group_id == None: # 判断是否为群聊白名单或者是私聊(也可以设置白名单不过没必要)
if group_id != None: # 如果消息时群聊事件,实际上有更好的解决办法,但是这里没用
reciece_message = str(event.get_message())
if len(reciece_message) > 4:
await jrrp.finish()
data = await bot.call_api('get_group_member_info', **{
'group_id': int(group_id), 'user_id': int(user_id)})
"""call_api()
调用非N2处理函数的接口,这里用到的是go-cqhttp的获取给定群聊中指定用户的个人资料
具体返回值和各个类别对应的值可以参考官方文档
这里使用的是返回的card即用户群聊昵称
如果群聊昵称为空的话可以用nickname
"""
await jrrp.finish(
Message(f"{data['card']}今日的幸运指数是{100 - lucknum}/100,\"{today_luky(lucknum)}\""))
"""
finish代表当前事件的结束,不再执行之后的代码,并立刻向当前
Message是发送消息的类型,N2官方文档也没有细说
也可以使用对应插件接口的实现方式来发送消息
例如bot.send_msg(),具体参考go-cqhttp官方文档
"""
else: # 如果是私聊,那么直接返回即可
await jrrp.finish(
Message(f"您今日的幸运指数是{100 - lucknum}/100,\"{today_luky(lucknum)}\""))
效果参考:
群聊效果
私聊效果
2.精神粮食——ldst
初步学习了怎么使用N2发送基础的消息,来开始试着做下其他功能吧——比如满足群友涩涩的渴求
首先了解下怎么发送图片,这里我们用到了go-cqhttp的CQ码来发送消息(用N2自带的Messagesegment也是可以发送的,但没看懂怎么用,接着参考这个大佬的博客 ,还有这个大佬的萌新FAQ
吧)
CQ码的格式为[CQ:功能,功能相关参数],例如想要at某个群聊用户格式就为[CQ:at,qq=对方QQ号]。这里我们用到的是发送图片,那么就是[CQ:image,file=图片地址,id=40000],如果想发送闪照形式的就可以使用'type=flash',具体参考官方文档
综上,你已经知道该怎么发送图片了,那么只需要找到一个稳定图片来源方便群友肆意滥用了~
下面举例三种办法:
1.下载精选美图到本地方便自己欣赏进行调用,缺点是库存量不能保证随机性,和可能被群友猜到的奇怪xp
2.找免费的冻嫚图片api,十分方便且满足了随机性。不足之处在于大部分api图片质量不稳定,不一定能让你的群友觉得sese
3.直接爬某蓝P,不仅能保证图片质量,也能定向搜索相关tag顺便获取群友一手xp,除了需要保持挂代理和可能被反爬没有缺点
点我看api方式
import ast
import nonebot
import requests # 需要用到GET的方式获取图片,否则一直是一张图片
from nonebot.rule import *
from nonebot import on_command
from nonebot import *
from nonebot.plugin import on_keyword
from nonebot.adapters.onebot.v11 import Bot, Event, GroupMessageEvent
from nonebot.adapters.onebot.v11.message import Message
import sqlite3
import random
import urllib3
import json
from datetime import date
setu = on_keyword({'ldst', 'sjst'}, priority=50) # 饥渴的涩涩人是不会先打出命令符的,那么只需要对关键词记录就好了
url = ("https://acg.toubiec.cn/random.php",
"https://api.r10086.com/img-api.php?type=动漫综合6",
"https://api.vvhan.com/api/acgimg",
) # 一些图片api,举了几个自己用的
@setu.handle()
async def setu_handle(bot: Bot, event: Event):
with open("src/plugins/群名单.txt", encoding='utf-8') as file: # 提取白名单群文件中的群号
white_block = []
for line in file:
line = line.strip()
line = re.split("[ |#]", line) # 可能会有'#'注释或者空格分割
white_block.append(line[0]) # 新建一个表给它扔进去
try:
whatever, group_id, user_id = event.get_session_id().split('_') # 获取当前群聊id,发起人id,返回的格式为group_groupid_userid
except: # 如果上面报错了,意味着发起的是私聊,返回格式为userid
group_id = None
user_id = event.get_session_id()
if group_id in white_block or group_id == None: # 判断是否为群聊白名单或者是私聊(也可以设置白名单不过没必要)
randomrul = random.randint(0, 2) # 可能一个图片网站会不小心重复,那么多个就不会重复了吧!
reciece_message = str(event.get_message())
if len(reciece_message) > 4:
'''
有时候句中也可能包含了'ldst',比如'这个某某某天天喜欢ldst'。
由于N2的on_keyword()针对的是句中关键词,为了避免这种情况下也会不合时宜地发送一张图片
我们可以手动判断输入的数据长度,或者判断是否和给定的关键词相同即可
实际上这部分内容可以使用N2自带的rule来提前判断,十分强大
具体接着参考大佬的博客吧
"http://blog.well404.top/2022/05/09/nonebot/%E3%80%90NoneBot2%E3%80%91%E7%AC%AC%E4%BA%8C%E7%AB%A0%EF%BC%9A%E5%9F%BA%E7%A1%80%E6%8F%92%E4%BB%B6%E7%BC%96%E5%86%99%E6%8C%87%E5%8D%97%E7%AC%AC%E5%9B%9B%E8%8A%82%E2%80%94%E2%80%94%E2%80%94%E4%BA%BA%E5%AE%B6%E6%89%8D%E6%87%92%E5%BE%97%E7%90%86%E4%BD%A0%E5%91%A2/"
'''
await setu.finish() # 出现这种情况就直接结束
await setu.send(Message(f"一天到晚只想着涩涩是吧打你哦ヽ(#`Д´)ノ")) # 自行发挥,还可以建个表拉取下每个qq涩了多少次来返回不同的“谴责”
result = requests.get(url[randomrul]) # 使用GET方法获取图片,返回的是JSON格式,发送时调用url即可
await setu.finish(Message(f"[CQ:image,file={result.url},id=400000]")) # 由于并未涉及群聊私聊的区分,直接发送即可
示例:
点我看本地发送
其实本地发送没两样,主要在如何实现随机获取图片和格式,放下简略代码就好import os
import random
train = '你的图库文件夹地址'
files = os.listdir(train)#以list形式获取当前文件夹所有文件的地址
n = len(files)#获取地址长度
ind = random.randint(0, n)#随机取个数
img_dir = os.path.join(train, files[ind])#把整个路径组合起来
dir_img = "file:///" + str(img_dir)#本地形式的图片前面需要加'file:///'
await setu.finish(Message(f"[CQ:image,file={dir_img},id=40000]"))#那么就大工告成了!
和上面类似,就不放例子了
update,建议用这个好点
前几天lolicon.app不知道为啥炸了,现在又好了,放下自己写的,这部分只用替换下api方式中的url和请求部分就好了,最后吧发送的file替换为下面的img_urllolicon网站的请求也是get,具体返回值参考官方文档
import json
import requests
url = "https://api.lolicon.app/setu/v2"
request = requests.get(url)
request = request.text #转换成文本
request_json = json.loads(request) #把json格式转换为可读的dict
img_url = request_json['data'][0]['urls']['original'].replace('i.pixiv.cat','i.pixiv.re')
'''
挺神奇,这个json格式是dict套了个list再套dict,一开始写的时候一直不知道哪里报错了
参考上面的官方文档,请求的时候支持搜索tag,同时返回值也可以自己加例如图片id号码,之类的
把i.pixiv.cat换成i.pixiv.re我也不知道为啥,cat上不去,看别的bot用的re就可以看图
'''
2.5 优化
可以看到之前的代码中判断是否为白名单群聊时,会先进入事件再判断,这就导致了我们需要查看输出日志的时候会发现多出来了很多不需要群聊的响应日志,N2对于这种情况提供了事件响应时的rule类。
这个类型会在事件响应前进行判断,这样就可以简化日志了。
举个栗子
async def reply_rule(event:Event) ->bool : # 返回一个bool变量用于判断
with open("src/plugins/群名单.txt", encoding='utf-8') as file:
white_block = []
for line in file:
line = line.strip()
line = re.split("[ |#]", line)
white_block.append(line[0])
try:
whatever, group_id, user_id = event.get_session_id().split('_') # 获取当前群聊id,发起人id,返回的格式为group_groupid_userid
except: # 如果上面报错了,意味着发起的是私聊,返回格式为userid
group_id = None
user_id = event.get_session_id()
if group_id == None or group_id in white_block:
return True
else:
return False
reply = on_message(rule=reply_rule,priority=50)
'''
例如想做一个发言次数记录的插件,但是只记录几个群聊。
如果用先进入事件判断的话会导致日志极其乱(所有所在群聊每条都会响应一次)
这样就使得你的日志输出更加简洁
'''
3.今天运势到底如何呢——抽一张塔罗牌吧!
首先建一个字典对应下各个塔罗牌及其含义
这部分看不看都行
吐槽一下,由于是直接找的百度百科,含义复制吐了这部分权当水文字好了
cards = ["愚者", "魔术师", "女祭司", "女皇", "皇帝", "教皇", "恋人", "战车", "力量", "隐者", "命运之轮", "正义", "倒吊人", "死神", "节制", "恶魔", "塔", "星星",
"月亮", "太阳", "审判", "世界"]
meanings = {
"愚者": {
0: "憧憬自然的地方、毫无目的地前行、喜欢尝试挑战新鲜事物、四处流浪。明知是毫无意义的冒险,错误的选择及失败的结果,却一意孤行,盲目地追求梦想而完全忽略现实;好冒险、寻梦人、不拘泥于传统的观念、自由奔放、一切从基础出发、四处流浪。自由恋爱、不顾及他人看法、以独特的方式获得成功、轻易坠入爱河、浪漫多彩的爱情、独特的恋人、等待交往机会。工作上具冒险心、追求新奇。热衷于事业或学业、以独特的方式取得意外的收获、由于好奇心对当前的学业产生浓厚的兴趣、把握重点、寻求捷径、倾向于自由的工作氛围、适合艺术类工作或从事自由职业。健康状况佳。旅行有意外收获。美好的梦想。",
1: "冒险的行动,追求可能性,重视梦想,无视物质的损失,离开家园,过于信赖别人,为出外旅行而烦恼。心情空虚、轻率的恋情、无法长久持续的融洽感、不安的爱情的旅程、对婚姻感到束缚、彼此忽冷忽热、不顾众人反对坠入爱河、为恋人的负心所伤、感情不专一。工作缺乏稳定性、无责任。成绩一落千丈、没有耐心、行事缺乏计划、经常迟到、猜题错误导致考试失利、考前突击无法为你带来太大的效果。因不安定的生活而生病。不能放心的旅行。不能下决心、怪癖。不切实际。"
},
"魔术师": {0: "事情的开始,行动的改变,熟练的技术及技巧,贯彻我的意志,运用自然的力量来达到野心。", 1: "意志力薄弱,起头难,走入错误的方向,知识不足,被骗和失败。"},
"女祭司": {0: "开发出内在的神秘潜力,前途将有所变化的预言,深刻地思考,敏锐的洞察力,准确的直觉。", 1: "过于洁癖,无知,贪心,目光短浅,自尊心过高,偏差的判断,有勇无谋,自命不凡。"},
"女皇": {0: "幸福,成功,收获,无忧无虑,圆满的家庭生活,良好的环境,美貌,艺术,与大自然接触,愉快的旅行,休闲。",
1: "不活泼,缺乏上进心,散漫的生活习惯,无法解决的事情,不能看到成果,耽于享乐,环境险恶,与家人发生纠纷。"},
"皇帝": {0: "光荣,权力,胜利,握有领导权,坚强的意志,达成目标,父亲的责任,精神上的孤单。", 1: "幼稚,无力,独裁,撒娇任性,平凡,没有自信,行动力不足,意志薄弱,被支配。"},
"教皇": {
0: "援助,同情,宽宏大量,可信任的人给予的劝告,良好的商量对象,得到精神上的满足,遵守规则,志愿者。信心十足,能正确理解事物本质,工作上外来压力过多,使你有被束缚的感觉。寻找新的工作方法,尽管会面对很大的阻力,但结果会证明这样做是值得的。爱情上屈从于他人的压力,只会按照对方的要求来盲目改变自己,自以为这是必要的付出,其实不过是被迫的选择。伴侣也不会对你保持忠诚,并很难满足双方真实的需要。",
1: "错误的讯息,恶意的规劝,上当,援助被中断,愿望无法达成,被人利用,被放弃。事业上多了些灵活的态度,不再刻板遵循旧有的方式,勇于创新形成自己独特的理念,为自己的真实想法而活、而工作。感情上开始正视自己对感情的真实感受与做法,尽管依旧会听取对方的意见,但以不会全盘接受。当你感到无法接受对方的意见时,会及时与其沟通,找出改善关系的做法。", },
"恋人": {0: "撮合,爱情,流行,兴趣,充满希望的未来,魅力,增加朋友。感情和肉体对爱的渴望,它暗示恋情将向彼此关系更亲密的方向发展。事业上将面临重大的抉择,它将关系到你的未来前途。",
1: "禁不起诱惑,纵欲过度,反覆无常,友情变淡,厌倦,争吵,华丽的打扮,优柔寡断。感情上表现幼稚,对成长虽有期待与希望,却希望永远躲避危险,逃避责任。事业上总保持着很高的戒心,让人感到很不舒服,不愿同你合作。"},
"战车": {
0: "努力而获得成功,胜利,克服障碍,行动力,自立,尝试,自我主张,年轻男子,交通工具,旅行运大吉。事业上显示出才能,办事卓有成效。自信而富理智的你将让客户更有信心,愿意与你共同合作。在感情上正在努力控制自己的情绪,而且控制得很好,这让你的感情发展得更顺利。",
1: "争论失败,发生纠纷,阻滞,违返规则,诉诸暴力,顽固的男子,突然的失败,不良少年,挫折和自私自利。放弃以往在事业上所坚持的,结局将会更加完美。感情上失去方向,你已经没有以往的冷静,这让对方在心中产生了不信任感,也许你要反省一下自己的所作所为了。"},
"力量": {
0: "大胆的行动,有勇气的决断,新发展,大转机,异动,以意志力战胜困难,健壮的女人。在事业上你不断突破自我,上司和客户都对你有充分的信心,成就接踵而来。在爱情上,你将发展一段真正亲密的感情,你们全心投入,相互倾诉,丝毫没有距离感。",
1: "胆小,输给强者,经不起诱惑,屈服在权威与常识之下,没有实践便告放弃,虚荣,懦弱,没有耐性。内心的恐惧使你畏首畏尾,进而遭遇事业的瓶颈,感到失去了自信。在爱情上患得患失,失去清醒的判断。"},
"隐者": {
0: "隐藏的事实,个别的行动,倾听他人的意见,享受孤独,自己的丢化,有益的警戒,年长者,避开危险,祖父,乡间生活。你在事业黄金时期引退,旁人都不了解这不过是你在为下一次黄金时期的到来进行休息。感情方面你将深刻思考自己在这段感情中的角色和地位,并探索彼此之间的关系。",
1: "无视警,憎恨孤独,自卑,担心,幼稚思想,过于慎重导致失败,偏差,不宜旅行。在事业中过多的投入已经让你不愿面对其它事情,因而事业有了突破性的进展。在感情方面,用工作繁忙来逃避这段感情的发展,对伴侣态度冷淡,因为害怕感情的发展而在关键时刻退缩,使对方心寒。"},
"命运之轮": {
0: "关键性的事件,有新的机会,因的潮流,环境的变化,幸运的开端,状况好转,问题解决,幸运之神降临。命运之轮正转到了你人生最低迷的时刻,也许你有些无法接受,但是若能以平常心来看待,这无疑是你成长的最好时机,需要认真面对。感情方面所受到的挫折近乎让你崩溃,然而你还在不断努力。虽然你面前是无数的荆棘,但坚持过去将是平坦的大道。你会发现以前所付出的无谓努力,而今反而成了你前进的动力,先前的付出终于有了回报。命运之轮是由命运女神转动的,所以你俩之前的风风雨雨都将过去,关系将进入稳定的发展阶段。",
1: "边疆的不行,挫折,计划泡汤,障碍,无法修正方向,往坏处发展,恶性循环,中断。"},
"正义": {
0: "公正、中立、诚实、心胸坦荡、表里如一、身兼二职、追求合理化、协调者、与法律有关、光明正大的交往、感情和睦。事业上你不会有其它太多的感觉,只是按照以前的计划认真地执行。你对感情生活相当满意,对于你的选择对方都是接受的态度。",
1: "失衡、偏见、纷扰、诉讼、独断专行、问心有愧、无法两全、表里不一、男女性格不合、情感波折、无视社会道德的恋情。长时间的压抑使你在事业最关键的时刻倒下了,需要认真修整一番才能再次前进。感情上你一直忍让着,然而这次你却爆发了,开始指责对方的不是,你们的感情将会有很大的波折。"},
"倒吊人": {
0: "接受考验、行动受限、牺牲、不畏艰辛、不受利诱、有失必有得、吸取经验教训、浴火重生、广泛学习、奉献的爱。当牌面正立时,你的事业会有短暂的停顿,但你很清楚其中的原因,再次确认自己的目标,做好出发的准备。感情上同样需要反省的时间,你对爱情的牺牲对会给对方很大的触动,也会成为你们关系发展的催化剂。",
1: "无谓的牺牲、骨折、厄运、不够努力、处于劣势、任性、利己主义者、缺乏耐心、受惩罚、逃避爱情、没有结果的恋情。当牌面倒立时,事业上缺乏远见,迷失了努力的目标。感情上你没有了为对方付出的念头,而对方对你的态度依旧,这使你更想逃避。你已经忽略了内心深处正确的判断力,这让你开始遇到很多失败。"},
"死神": {
0: "失败、接近毁灭、生病、失业、维持停滞状态、持续的损害、交易停止、枯燥的生活、别离、重新开始、双方有很深的鸿沟、恋情终止。事业上你将放弃一些得到的利益,并获得全新的发展机会。在感情上,你将会发生深刻的变化,将开始新的阶段,接受事实你们会有更加美好的旅程。",
1: "抱有一线希望、起死回生、回心转意、摆脱低迷状态、挽回名誉、身体康复、突然改变计划、逃避现实、斩断情丝、与旧情人相逢。事业上你在试图“两全其美”,希望能够发生奇迹。在感情上,对方已经接受了改变,而你却在逃避现实,你俩的距离正在越来越大。"},
"节制": {0: "单纯、调整、平顺、互惠互利、好感转为爱意、纯爱、深爱。你在事业上小心翼翼,因为处事理智让你的同事感到十分放心。当下你们的感情简简单单,一切都是这么的单纯、平静,正是因为彼此的沟通才让这段感情之路如此通畅。",
1: "消耗、下降、疲劳、损失、不安、不融洽、爱情的配合度不佳。在事业上,你陷入了朝令夕改的怪圈,不妨效仿一下愚人勇往直前,或许能够取得更大的成功。感情上彼此虽然还在不断尝试着沟通,但每次之后总是感觉没有收获,正因为如此你们之间的距离才会越拉越大。"},
"恶魔": {
0: "被束缚、堕落、生病、恶意、屈服、欲望的俘虏、不可抗拒的诱惑、颓废的生活、举债度日、不可告人的秘密、私密恋情。你将在事业中得到相当大的名声与财富,你心中的事业就是一切,财富就是你的目标。感情上你们开始被彼此束缚,却不希望改善这种关系,情愿忍受彼此的牵连和不满。",
1: "逃离拘束、解除困扰、治愈病痛、告别过去、暂停、别离、拒绝诱惑、舍弃私欲、别离时刻、爱恨交加的恋情。事业上理性开始支配欲望,找到真正值得努力的目标。感情上开始尝试与对方进行沟通,这让你俩的感情更加牢固。"},
"塔": {
0: "破产、逆境、被开除、急病、致命的打击、巨大的变动、受牵连、信念崩溃、玩火自焚、纷扰不断、突然分离,破灭的爱。事业上的困难显而易见,回避不是办法,要勇于挑战,尽管它貌似强大。在感情方面,突然的改变让你陷入深深的痛苦中,接受改变可以让你或你们双方在未来的人生旅途中走得更好。",
1: "困境、内讧、紧迫的状态、状况不佳、趋于稳定、骄傲自大将付出代价、背水一战、分离的预感、爱情危机。事业上开始有稳定的迹象,你不要盲目抵抗改变的发生,这只会导致更大的改变,无论你如何抵抗,改变终究会发生。在感情上双方的情绪终于平静下来,虽然沟通上还有些困难,但不会有太大的变化了,也许你做些让步,会让你们的感情更融洽。"},
"星星": {
0: "前途光明、充满希望、想象力、创造力、幻想、满足愿望、水准提高、理想的对象、美好的恋情。代表当你在事业上得到希望的能量时,前途会无比光明。在感情方面,你对自己很有信心,对两人的关系也抱有乐观的态度,相信自己能把握主动权,并努力追求对方,你们很可能就是命中注定的那一对。",
1: "挫折、失望、好高骛远、异想天开、仓皇失措、事与愿违、工作不顺心、情况悲观、秘密恋情、缺少爱的生活。在事业上,你不要全部依靠别人的给予,因为你还有希望在心中燃烧,只有靠自己才有真正的发展动力。感情方面你俩无法彼此信任,感觉无法把自己托付给对方,也许你们退一步,都冷静一下就能找出解决问题的途径,因为答案就在你们的心中。"},
"月亮": {
0: "不安、迷惑、动摇、谎言、欺骗、鬼迷心窍、动荡的爱、三角关系。在事业上,你可能有些不满足,希望能够把自己内在的力量全使出来,于是你开始想要晚上的时间。感情方面,你很敏感害怕被伤害,尽管有伴侣的承诺,你仍然犹豫不决,甚至有逃避的想法。",
1: "逃脱骗局、解除误会、状况好转、预知危险、等待、正视爱情的裂缝。在事业上,你因为外界的压力开始退缩了,并对自己的既定目标产生了怀疑。在感情上,你们之间的问题开始浮现,虽然有些痛,但是只要共同面对存在的困难,问题就解决一半了。"},
"太阳": {
0: "活跃、丰富的生命力、充满生机、精力充沛、工作顺利、贵人相助、幸福的婚姻、健康的交际。事业上会有贵人相助,将会有更好的发展机遇。在感情方面,你们已经走出坎坷的感情之路,前面将是洒满歌声和欢乐的坦途,你们将开始规划未来的生活。",
1: "消沉、体力不佳、缺乏连续性、意气消沉、生活不安、人际关系不好、感情波动、离婚。事业上竞争心太急切了,把对手都吓跑了,然而也让合作伙伴感到害怕,或许你该放松些。感情上两人间出现一些小变化,开始在乎对方的态度和自己的付出,这些怀疑也许都是没必要的。"},
"审判": {
0: "复活的喜悦、康复、坦白、好消息、好运气、初露锋芒、复苏的爱、重逢、爱的奇迹。当牌面正立时,事业上你超越了自我,在过去努力的基础上取得了成功。感情上双方都在认真学习和成长,虽然表面上的变化并不大,但内在的改变已经很大了。",
1: "一蹶不振、幻灭、隐瞒、坏消息、无法决定、缺少目标、没有进展、消除、恋恋不舍。在事业上缺乏清晰的判断,试图用物质填充精神的空虚。在感情上,不断地回忆着过去的美好时光,不愿意去正视眼前的问题,你们的关系已经是貌合神离了。"},
"世界": {0: "完成、成功、完美无缺、连续不断、精神亢奋、拥有毕生奋斗的目标、完成使命、幸运降临、快乐的结束、模范情侣。在事业上因为努力工作,所以回报丰厚。感情上,你们在彼此的承诺中持续着美好的关系。",
1: "未完成、失败、准备不足、盲目接受、一时不顺利、半途而废、精神颓废、饱和状态、合谋、态度不够融洽、感情受挫。在事业的路上有巨大的障碍,你精神不振,丧失了挑战的动力。感情上,你们不再重视承诺,只是盲目接受对方。彼此最好能沟通一下,不要让痛苦继续纠缠着你们。"}
}
会发现如果直接复制这么一大串到一个main代码里会十分的难看,这时候就可以用包的形式写这个插件了
接着来想该怎么才能触发,这里用的是draw来作为事件的触发(这个其实是群里找的一个骰娘丛雨酱的指令,但是被群友玩退群了,这个指令的输入倒是熟记于心)
那么格式就可以初步敲定为"/draw 单张塔罗牌"了,之后就是判断输入文本和输出的问题了
sv代码
前面水太多放下核心的就好了trcard = on_command("draw", priority=40)
'''
与之前所提到的on_keyword()不同,on_command()注册了一个只有当文本以规定的命令起始符+命令的形式开头的时候才会被响应
'''
args = str(event.get_message()).split() # 将命令与输入字符按空格分隔开来
try:
tarottype = args[1]
# 正常情况下接收到的文本字符串会被分隔成"/draw"与"单张塔罗牌"
except:
linshi = args[0].split('/draw')
tarottype = linshi[1]
# 也有并不喜欢打空格的人,再分一下好了
lll = ['正位', '逆位']
if tarottype == "单张塔罗牌": # 判断一下指令类型,实际上draw不一定只对塔罗牌,拓展下模拟抽游戏卡或者自设卡都行的
num_ber = random.randint(0, 21)
card_name = cards[num_ber]
pos_sion = random.randint(0, 1)
meaning = meanings[card_name][pos_sion]
'''
这里获取了之前塔罗牌的含义,引用了另一个文件里的数组
开头的时候要引用一下那个文件
随机数啥的也可以写个每天固定一张或是随便抽啥的
'''
if group_id:
await trcard.finish(Message(f"{data['card']}抽到的卡为:{card_name} {lll[pos_sion]}\n{meaning}"))
else:
await trcard.finish(Message(f"您抽到的卡为:{card_name} {lll[pos_sion]}\n{meaning}"))
示例
4.脑袋空了
就先放这几个了(主要是现在也没写多少),后面的单独发好了
写屎山ing
看别的人开发bot感觉好nb,写了几个入门插件感觉更ta们nb了
感谢你的阅读!
快去关注更加nb的软糖酱吧 github blog b站