self.room_id = room_id class DouyuLive(Live): def __init__(self, room_id): super().__init__(f'/douyu/room/{room_id}') self.platform = '斗鱼' self.room_id = room_id async def notice(room_id, msg): groups = _subscribes[str(room_id)]['subs_groups'] await broadcast(msg, groups=groups) sv = Service('直播推送') subs_path = path.join(path.dirname(__file__), 'subs.json') _subscribes = load_config(subs_path) _lives = [] for subs in _subscribes: platform = _subscribes[subs]['platform'] room_id = _subscribes[subs]['room'] latest_time = _subscribes[subs]['latest_time'] if platform == 'bilibili': bl = BiliLive(room_id) bl.latest_time = latest_time _lives.append(bl) elif platform == 'douyu': dl = DouyuLive(room_id) dl.latest_time = latest_time _lives.append(dl)
import random import asyncio from datetime import datetime from functools import partial, wraps from collections import defaultdict from TwitterAPI import TwitterAPI, TwitterResponse from nonebot import MessageSegment as ms from hoshino import util from hoshino.service import Service, Privilege as Priv cfg = util.load_config(__file__) api = TwitterAPI(cfg['consumer_key'], cfg['consumer_secret'], cfg['access_token_key'], cfg['access_token_secret']) sv = Service('twitter-poller', use_priv=Priv.ADMIN, manage_priv=Priv.SUPERUSER, visible=False) URL_TIMELINE = 'statuses/user_timeline' subr_dic = { Service('pcr-twitter', enable_on_default=True): ['priconne_redive', 'priconne_anime'], Service('pripri-twitter', enable_on_default=False, visible=False): ['pripri_anime'], Service('shiratama-twitter', enable_on_default=False, visible=False): ['shiratamacaron'], } latest_info = {} # { account: {last_tweet_id: int, profile_image: str } } for _, ids in subr_dic.items(): # initialize
thd = threading.Thread(target=wh.keep_supply) if ONLINE_MODE: print('线程启动') thd.start() #启动一个线程一直补充r18色图 thd_r18 = threading.Thread(target=r18_wh.keep_supply) if ONLINE_MODE: print('r18线程启动') thd_r18.start() #设置limiter _num_limiter = DailyNumberLimiter(DAILY_MAX_NUM) _freq_limiter = FreqLimiter(5) sv = Service('色图') @sv.on_rex(r'^来?([1-5])?[份点张]?[涩色瑟]图(.{0,10})$') async def send_common_setu(bot, event: Event): uid = event.user_id self_id = event.self_id gid = event.group_id user_priv = get_user_priv(event) is_to_delete = True if gid in g_delete_groups else False if not _num_limiter.check(uid): await bot.send(event, EXCEED_NOTICE) return if not _freq_limiter.check(uid):
import random from datetime import timedelta from nonebot import on_command from hoshino import util from hoshino.res import R from hoshino.service import Service, Privilege as Priv # basic function for debug, not included in Service('chat') @on_command('zai?', aliases=('在?', '在?', '在吗', '在么?', '在嘛', '在嘛?')) async def say_hello(session): await session.send('はい!私はいつも貴方の側にいますよ!') sv = Service('chat', manage_priv=Priv.SUPERUSER, visible=False) @sv.on_command('沙雕机器人', aliases=('沙雕機器人', ), only_to_me=False) async def say_sorry(session): await session.send('ごめんなさい!嘤嘤嘤(〒︿〒)') @sv.on_command('老婆', aliases=('waifu', 'laopo'), only_to_me=True) async def chat_waifu(session): if not sv.check_priv(session.ctx, Priv.SUPERUSER): await session.send(R.img('laopo.jpg').cqcode) else: await session.send('mua~')
import aiohttp from PIL import Image from .._res import Res as R from hoshino.service import Service from hoshino.typing import HoshinoBot, CQEvent from hoshino.util import DailyNumberLimiter, FreqLimiter from .._util import extract_url_from_event from .config import * from .data_source import detect_face, concat, KyaruHead, auto_head, gen_head conf_path = path.join(path.dirname(__file__), 'user_conf') sv = Service('接头霸王', visible=True, enable_on_default=True, bundle='接头霸王', help_=''' - [接头 XX] XX为一张图片 - [选头 1/2/3/auto] 选一张头或自动选头 '''.strip()) _nlt = DailyNumberLimiter(DAILY_MAX_NUM) _flt = FreqLimiter(5) try: with open(conf_path, 'rb') as f: user_conf_dic = pickle.load(f) except FileNotFoundError: user_conf_dic = {} @sv.on_prefix(('接头霸王', '接头')) async def concat_head(bot: HoshinoBot, ev: CQEvent):
import os import random from datetime import datetime import pytz from hoshino import nonebot from hoshino.service import Service sv = Service('kc-reminder', enable_on_default=False, help_='演习/月常远征提醒', bundle='kancolle') @sv.scheduled_job('cron', hour='13', minute='30') async def enshu_reminder(): msgs = [ '演习即将刷新!\n莫让下午的自己埋怨上午的自己:\n「演習」で練度向上!0/3', '[CQ:at,qq=all] 演习即将刷新!', ] await sv.broadcast(msgs, 'enshu_reminder', 0.2) @sv.scheduled_job('cron', day='10-14', hour='22') async def ensei_reminder(): now = datetime.now(pytz.timezone('Asia/Shanghai')) remain_days = 15 - now.day msgs = [ f'【远征提醒小助手】提醒您月常远征还有{remain_days}天刷新!', f'[CQ:at,qq=all] 月常远征还有{remain_days}天刷新!', ]
desc = item.find('.description').text.strip() link = item.find('.link').text.strip() pubDate = item.find('.pubDate').text.strip() return {"title": title, "desc": desc, "link": link, "pubDate": pubDate} def check_update(self) -> bool: #info类可以通过pubDate判断是否更新 if self.parse_xml().get('pubDate') != self._latest: self._latest = self.parse_xml().get('pubDate') return True else: return False #添加推送在此字典添加service和路由 _inf_svs = { Service('pcr国服推送'): [Info('/pcr/news-cn'), Info('/bilibili/user/dynamic/353840826')], Service('B站up动态'): [ Info('/bilibili/user/dynamic/282994'), Info('/bilibili/user/dynamic/11073'), Info('/bilibili/user/dynamic/673816') ] #Service('HoshinoIssue推送') : [Info('/github/issue/Ice-Cirno/Hoshinobot')] } _latest_path = path.join(path.dirname(__file__), 'latest_data.json') _latest_data = load_config(_latest_path) if load_config( _latest_path) else defaultdict(str) infos = []
# 公主连接Re:Dive会战管理插件 # clan == クラン == 戰隊(直译为氏族)(CLANNAD的CLAN(笑)) from typing import Callable, Dict, Tuple, Iterable from nonebot import NoneBot, on_command, CommandSession from hoshino import util from hoshino.service import Service, Privilege from hoshino.res import R from .argparse import ArgParser from .exception import * sv = Service('clanbattle', manage_priv=Privilege.ADMIN, enable_on_default=True) SORRY = 'ごめんなさい!嘤嘤嘤(〒︿〒)' _registry:Dict[str, Tuple[Callable, ArgParser]] = {} @sv.on_message('group') async def _clanbattle_bus(bot:NoneBot, ctx): # check prefix start = '' for m in ctx['message']: if m.type == 'text': start = m.data.get('text', '').lstrip() break if not start or start[0] not in '!!': return # find cmd plain_text = ctx['message'].extract_plain_text() cmd, *args = plain_text[1:].split()
import re import random import asyncio from urllib.parse import urljoin, urlparse, parse_qs try: import ujson as json except: import json from nonebot import CQHttpError, NLPSession from hoshino import aiorequests from hoshino.res import R from hoshino.service import Service sv = Service('pcr-comic') def load_index(): with open(R.get('img/priconne/comic/index.json').path, encoding='utf8') as f: return json.load(f) def get_pic_name(id_): pre = 'episode_' end = '.png' return f'{pre}{id_}{end}' @sv.on_rex(r'^官漫\s*(\d{0,4})', normalize=False) async def comic(bot, ctx, match): episode = match.group(1) if not episode: await bot.send(ctx, '请输入漫画集数 如:官漫132', at_sender=True)
###来自奇怪的雪雪 import requests import os import asyncio import aiohttp import re from io import BytesIO from PIL import Image from hoshino.service import Service from nonebot import on_command, CommandSession, MessageSegment, NoneBot sv = Service('setu_xuexue', enable_on_default=False, visible=False) ##换成你的api apikey='' r18 = '0' keyword = '' num = '1' size1200 = 'True' apiPath=r'https://api.lolicon.app/setu' params = {'apikey':apikey,'r18':r18,'keyword':keyword,'num':num,'size1200':size1200} async def get_url(): global params res = requests.get(apiPath,params = params,timeout=20) url = res.json()['data'][0]['url'] return url
from hoshino.service import Service svtw = Service('pcr-arena-reminder-tw', enable_on_default=False, help_='背刺时间提醒(台B)', bundle='pcr订阅') svjp = Service('pcr-arena-reminder-jp', enable_on_default=False, help_='背刺时间提醒(日)', bundle='pcr订阅') msg = '骑士君、准备好背刺了吗?' @svtw.scheduled_job('cron', hour='14', minute='45') async def pcr_reminder_tw(): await svtw.broadcast(msg, 'pcr-reminder-tw', 0.2) @svjp.scheduled_job('cron', hour='13', minute='45') async def pcr_reminder_jp(): await svjp.broadcast(msg, 'pcr-reminder-jp', 0.2)
import re import time from collections import defaultdict from nonebot import CommandSession, MessageSegment, get_bot from hoshino.util import silence, concat_pic, pic2b64, FreqLimiter from hoshino.service import Service, Privilege as Priv sv = Service('pcr-arena', manage_priv=Priv.ADMIN) from ..chara import Chara from . import arena DISABLE_NOTICE = '本群竞技场查询功能已禁用\n如欲开启,请与维护组联系' lmt = FreqLimiter(5) aliases = ('怎么拆', '怎么解', '怎么打', '如何拆', '如何解', '如何打', '怎麼拆', '怎麼解', '怎麼打', 'jjc查询', 'jjc查詢') aliases_b = tuple('b' + a for a in aliases) + tuple('B' + a for a in aliases) aliases_tw = tuple('台' + a for a in aliases) aliases_jp = tuple('日' + a for a in aliases) @sv.on_command('竞技场查询', aliases=aliases, deny_tip=DISABLE_NOTICE, only_to_me=False) async def arena_query(session:CommandSession): await _arena_query(session, region=1) @sv.on_command('b竞技场查询', aliases=aliases_b, deny_tip=DISABLE_NOTICE, only_to_me=False) async def arena_query_b(session:CommandSession): await _arena_query(session, region=2) @sv.on_command('台竞技场查询', aliases=aliases_tw, deny_tip=DISABLE_NOTICE, only_to_me=False)
from .data_source import Record, get_user_quota, send_msg, show from hoshino.service import Service from hoshino.util4sh import Res as R from aiocqhttp.event import Event from hoshino.priv import get_user_priv from hoshino.priv import * RECORDS = Record().get_records() sv = Service('我问你答') @sv.on_rex(r'我问(.+?)你答.{0,1000}') async def add_reply_for_self(bot, event: Event): uid = event['user_id'] gid = event.get('group_id') user_priv = get_user_priv(event) user_quata = get_user_quota(user_priv) # mirai要下载图片 await R.save_image(event) qu = event.raw_message.split('你答')[0].strip('我问').strip() ans = event.raw_message.split('你答')[1].strip() rec = Record(qu,ans,uid,gid,0) if rec.count_user_records(uid) >= user_quata: await bot.send(event, '您的额度不足,请删除记录后再来', at_sender=True) return if rec.insert_database(): await bot.send(event,'问答添加成功',at_sender=True) if rec.get_records:
""" Author: zfj Date: 2021-03-06 16:17:46 LastEditTime: 2021-03-06 16:17:46 LastEditors: zfj Description: None GitHub: https://github.com/zfjdhj """ from hoshino.service import Service from hoshino import * import json json_path = "C:/tmp/zfjdhj.github.io/zfjbot-helpWebsite/data.json" sv = Service("zfjbot-helpSearch") # 读取json文件内容,返回字典格式 with open(json_path, "r", encoding="utf8") as fp: json_data = json.load(fp) @sv.on_rex(r"^(help|帮助) (.*)$") async def search(bot, ev): global json_data reply = "" res = [] if ev["match"].group(2).strip(): keyword = ev["match"].group(2).strip() logger.info(f"help search {keyword}") # await bot.send(ev,keyword) # return
from aiocqhttp.message import MessageSegment from hoshino.service import Service from hoshino.typing import HoshinoBot, CQEvent as Event from .._interact import interact, ActSession from hoshino.util import silence from random import randint, shuffle from itertools import cycle sv = Service('俄罗斯轮盘赌') @sv.on_fullmatch(('轮盘赌', '俄罗斯轮盘赌')) async def roulette(bot: HoshinoBot, ev: Event): try: session = ActSession.from_event('俄罗斯轮盘赌', ev, max_user=3, usernum_limit=True) interact.add_session(session) await bot.send(ev, '游戏开始,目前有1位玩家,还缺1名玩家,发送"参与轮盘赌"加入游戏') except ValueError as e: await bot.finish(ev, f'{e}') @sv.on_fullmatch('参与轮盘赌') async def join_roulette(bot: HoshinoBot, ev: Event): session = interact.find_session(ev, name='俄罗斯轮盘赌') if not session: #session未创建 await bot.send(ev, '游戏未创建,发送轮盘赌或者俄罗斯轮盘赌创建游戏') return #不处理 try:
from .arena import refresh_quick_key_dic, do_query from ..chara import Chara import re import time from collections import defaultdict from nonebot import CommandSession, MessageSegment, get_bot from hoshino.util import silence, concat_pic, pic2b64, FreqLimiter from hoshino.service import Service, Privilege as Priv sv = Service('pcr-arena', manage_priv=Priv.SUPERUSER) lmt = FreqLimiter(5) aliases = ('怎么拆', '怎么解', '怎么打', '如何拆', '如何解', '如何打', '怎麼拆', '怎麼解', '怎麼打', 'jjc查询', 'jjc查詢') aliases_b = tuple('b' + a for a in aliases) + tuple( 'B' + a for a in aliases) + tuple('国' + a for a in aliases) aliases_tw = tuple('台' + a for a in aliases) aliases_jp = tuple('日' + a for a in aliases) @sv.on_command('竞技场查询', aliases=aliases, only_to_me=False, can_private=1) async def arena_query(session: CommandSession): await _arena_query(session, region=1) @sv.on_command('b竞技场查询', aliases=aliases_b, only_to_me=False, can_private=1) async def arena_query_b(session: CommandSession): await _arena_query(session, region=2)
import requests import os import json import re import random from hoshino.service import Service config_path = os.path.dirname(__file__) + '/config.json' sv = Service('damage_dragon', enable_on_default=False) @sv.on_keyword(keywords=('迫害龙王')) async def _(bot, ctx): gid = ctx.get('group_id') try: cookies = await bot.get_cookies(domain='qun.qq.com') except: await bot.send(ctx, '获取cookies失败') headers = {"cookie": cookies['cookies']} url = f'https://qun.qq.com/interactive/honorlist?gc={gid}&type=1' with requests.post(url, headers=headers) as resp: text = resp.text json_text = re.search('window.__INITIAL_STATE__=(.+?)</script>', text).group(1) data = json.loads(json_text) dragon_king = data['talkativeList'][0]['uin'] replys = [ '龙王出来喷水', # '[CQ:image,file=505BBF25835D6597848E6AD57B635E68.jpg]' ]
import random import re import string from hashlib import md5 from time import time from urllib.parse import quote_plus import aiohttp from nonebot import get_bot from hoshino.service import Service, Privilege as Priv sv = Service('tencent_ai', manage_priv=Priv.ADMIN, enable_on_default=False) try: import ujson as json except ImportError: import json bot = get_bot() cq_code_pattern = re.compile(r'\[CQ:\w+,.+\]') salt = None ################ # 请修改 app_id = '你自己的id' app_key = '你自己的key' ################ def getReqSign(params: dict) -> str: hashed_str = ''
from io import BytesIO from os import path import aiohttp from PIL import Image from .._res import Res as R from hoshino.service import Service from hoshino.typing import HoshinoBot, CQEvent from hoshino.util import DailyNumberLimiter, FreqLimiter from .._util import extract_url_from_event from .data_source import detect_face, concat, gen_head from .opencv import add from .config import * sv = Service('接头霸王') _nlt = DailyNumberLimiter(5) _flt = FreqLimiter(15) @sv.on_prefix(('接头霸王', '接头')) async def concat_head(bot: HoshinoBot, ev: CQEvent): uid = ev.user_id if not _nlt.check(uid): await bot.finish(ev, '今日已经到达上限!') if not _flt.check(uid): await bot.finish(ev, '太频繁了,请稍后再来') url = extract_url_from_event(ev) if not url: await bot.finish(ev, '请附带图片!')
# 公主连接Re:Dive会战管理插件 # clan == クラン == 戰隊(直译为氏族)(CLANNAD的CLAN(笑)) import re from typing import Callable, Dict, Tuple, Iterable from nonebot import NoneBot from hoshino import util from hoshino.service import Service, Privilege from hoshino.res import R from .argparse import ArgParser from .exception import * sv = Service('clanbattle', manage_priv=Privilege.SUPERUSER, enable_on_default=True) SORRY = 'ごめんなさい!嘤嘤嘤(〒︿〒)' _registry: Dict[str, Tuple[Callable, ArgParser]] = {} @sv.on_rex(re.compile(r'^[!!](.+)', re.DOTALL), event='group') async def _clanbattle_bus(bot: NoneBot, ctx, match): cmd, *args = match.group(1).split() cmd = util.normalize_str(cmd) if cmd in _registry: func, parser = _registry[cmd] try: args = parser.parse(args, ctx['message']) await func(bot, ctx, args) except DatabaseError as e:
import random from hoshino import aiorequests from nonebot import NoneBot from hoshino import util from hoshino.service import Service, Privilege sv = Service('deepchat', manage_priv=Privilege.SUPERUSER, enable_on_default=False, visible=False) api = util.load_config(__file__)['deepchat_api'] @sv.on_message('group') async def deepchat(bot: NoneBot, ctx): msg = ctx['message'].extract_plain_text() if not msg or random.random() > 0.040: return payload = {"msg": msg, "group": ctx['group_id'], "qq": ctx['user_id']} sv.logger.info(payload) rsp = await aiorequests.post(api, data=payload) j = await rsp.json() sv.logger.info(j) if j['msg']: await bot.send(ctx, j['msg'])
import pytz import random import math from hoshino.res import R from datetime import datetime from hoshino import util from hoshino.service import Service sv = Service('hourcall', enable_on_default=False) ''' def get_hour_call(): """从HOUR_CALLS中挑出一组时报,每日更换,一日之内保持相同""" config = util.load_config(__file__) now = datetime.now(pytz.timezone('Asia/Shanghai')) hc_groups = config["HOUR_CALLS"] g = hc_groups[ now.day % len(hc_groups) ] return config[g] ''' ''' @sv.scheduled_job('cron', hour='*') async def hour_call(): now = datetime.now(pytz.timezone('Asia/Shanghai')) if 2 <= now.hour <= 5: return # 宵禁 免打扰 msg = get_hour_call()[now.hour] await sv.broadcast(msg, 'hourcall', 0) ''' @sv.scheduled_job('cron', hour='*') async def hour_call():
import pytz from datetime import datetime, timedelta from collections import defaultdict from nonebot import get_bot from nonebot import CommandSession, MessageSegment from hoshino.util import silence, concat_pic, pic2b64 from hoshino.service import Service from .gacha import Gacha from ..chara import Chara __plugin_name__ = 'gacha' sv = Service('gacha') _last_gacha_day = -1 _user_gacha_count = defaultdict(int) # {user: gacha_count} _max_gacha_per_day = 5 gacha_10_aliases = ('十连', '十连!', '十连抽', '来个十连', '来发十连', '来次十连', '抽个十连', '抽发十连', '抽次十连', '十连扭蛋', '扭蛋十连', '10连', '10连!', '10连抽', '来个10连', '来发10连', '来次10连', '抽个10连', '抽发10连', '抽次10连', '10连扭蛋', '扭蛋10连', '十連', '十連!', '十連抽', '來個十連', '來發十連', '來次十連', '抽個十連', '抽發十連', '抽次十連', '十連轉蛋', '轉蛋十連', '10連', '10連!', '10連抽', '來個10連', '來發10連', '來次10連', '抽個10連', '抽發10連', '抽次10連', '10連轉蛋', '轉蛋10連') gacha_1_aliases = ('单抽', '单抽!', '来发单抽', '来个单抽', '来次单抽', '扭蛋单抽', '单抽扭蛋', '單抽', '單抽!', '來發單抽', '來個單抽', '來次單抽', '轉蛋單抽', '單抽轉蛋') GACHA_DISABLE_NOTICE = '本群转蛋功能已禁用\n使用【启用 gacha】以启用\n(需群管理)' GACHA_EXCEED_NOTICE = f'您今天已经抽过{_max_gacha_per_day}次了,欢迎明天再来!'
from hoshino.res import R from hoshino.service import Service sv = Service('kc-query', enable_on_default=False) from .fleet import * from .senka import * # @sv.on_command('菱饼任务', only_to_me=False) # async def hishimochi(session): # msg = R.img('kancolle/quick/菱饼2020.jpg').cqcode # await session.send(msg, at_sender=True)
import requests import os import json import re import random from hoshino.service import Service config_path = os.path.dirname(__file__)+'/config.json' sv = Service('longwang',enable_on_default=True) @sv.on_keyword(keywords=('迫害龙王')) async def _(bot,ctx): gid = ctx.get('group_id') try: cookies = await bot.get_cookies(domain='qun.qq.com') except: await bot.send(ctx,'获取cookies失败') headers = { "cookie" : cookies['cookies'] } url = f'https://qun.qq.com/interactive/honorlist?gc={gid}&type=1' with requests.post(url,headers=headers) as resp: text = resp.text json_text = re.search('window.__INITIAL_STATE__=(.+?)</script>',text).group(1) data = json.loads(json_text) dragon_king = data['talkativeList'][0]['uin'] replys = [ '龙王出来喷水', #'[CQ:image,file=505BBF25835D6597848E6AD57B635E68.jpg]' ]
import aiohttp from nonebot import on_command, CommandSession from hoshino.service import Service sv = Service('zhihu', help_='知乎') @on_command('zhihu', aliases=('知乎', '知乎日报'), only_to_me=True) async def news(session: CommandSession): STORY_URL_FORMAT = 'https://daily.zhihu.com/story/{}' async with aiohttp.request( 'GET', 'https://news-at.zhihu.com/api/4/news/latest', headers= { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36' }) as resp: data = await resp.json() stories = data.get('stories') if not stories: await session.send('暂时没有数据,或者服务无法访问') return reply = '' for story in stories: url = STORY_URL_FORMAT.format(story['id']) title = story.get('title', '未知内容') reply += f'\n{title}\n{url}\n' await session.send(reply.strip())
import nonebot from aiocqhttp import Event from apscheduler.job import Job from hoshino.service import Service from nonebot import CommandSession, Message from aiocqhttp import Event, Message from hoshino.util4sh import bot, load_config, save_config, add_cron_job, add_delay_job from collections import defaultdict from os import path from typing import List from hoshino.msghandler import handle_message from traceback import print_exc from hoshino.priv import * bot = nonebot.get_bot() sv = Service('定时命令', use_priv=ADMIN) async def task(event): if not event: return uid = event['user_id'] await bot.send(event, f'下一条消息为成员{uid}设置的定时命令执行结果') try: await handle_message(bot, event, '_') except Exception as ex: sv.logger.error(f'执行scheduled command时发生错误{ex}') for func in bot._bus._subscribers['message']: try: await func(event) except Exception as ex: