async def query(self, send_handler, msg, receiver_id): res = re.search(r'^活动(\d+)(\s+(日服|国际服|台服|国服|韩服))?$', msg.strip()) if res: detail = self._detail_ver2(int(res.group(1)), self._server[res.group(3) or '国服']) if detail is not None: await send_handler(receiver_id, MultiMsg(detail)) else: await send_handler( receiver_id, MultiMsg([ StringMsg('没有这个活动'), ImageMsg({ 'file': f'kkr/{random.choice(["hanpi1", "hanpi2", "hanpi3"])}' }) ])) return True constraints = self._parse_query_command(msg.strip()) if constraints is not None: results = self.event_table.select('id', 'eventType', 'eventName', 'bannerAssetBundleName', **constraints) if results: images = [[ ImageProcesser.open_nontransparent( os.path.join(const.asset_event_path, 'jp', f'{r[3]}.png')) or ImageProcesser.white_padding(420, 140), ] for r in results] texts = [f'{r[0]}: {r[2]}' for r in results] MAX_NUM = 32 file_names = [ ImageProcesser.thumbnail( images=images[i * MAX_NUM:min((i + 1) * MAX_NUM, len(images))], labels=texts[i * MAX_NUM:min((i + 1) * MAX_NUM, len(images))], label_style={ 'font_size': 20, 'font_type': 'default_font.ttf' }, col_space=20, row_space=20) for i in range((len(images) - 1) // MAX_NUM + 1) ] [ await send_handler(receiver_id, ImageMsg({'file': f})) for f in file_names ] else: await send_handler( receiver_id, MultiMsg([ StringMsg('kkr找不到'), ImageMsg({'file': f'kkr/tuxie'}) ])) return True return False
async def query_pixiv(self, send_handler, msg, receiver_id, enable_r18=False): res = re.search(r'^看看(.*)?图$', msg.strip()) if res: mmap = { '帅': 'female', '妹子': 'male', '露佬': 'kyaru', } if enable_r18: mmap['色'] = 'daily_r18' file_path, meta = PixivCursor.get_one({'mode': mmap.get(res.group(1), 'daily')}, receiver_id) global COMPRESS_IMAGE msg = [] if isinstance(file_path, list): if file_path: for file in file_path[:3]: if COMPRESS_IMAGE: f = ImageProcesser.compress(os.path.join('/root/pixiv/', file), isabs=True) msg.append(ImageMsg({'file': f})) elif file_path: if COMPRESS_IMAGE: file_path = ImageProcesser.compress(os.path.join('/root/pixiv/', file_path), isabs=True) msg.append(ImageMsg({'file': file_path})) if msg: msg.insert(0, StringMsg(f'id: {meta["id"]}\nauthor: {meta["user"]["id"]}, {meta["user"]["name"]}\n')) await send_handler(receiver_id, MultiMsg(msg)) else: await send_handler(receiver_id, MultiMsg([StringMsg('kkr找不到'), ImageMsg({'file': f'kkr/tuxie'})])) return True else: return False
async def _seer(self, context, first=None): if first: for p in first: await self._send_p(first, StringMsg('请给我一个你想查验的人的QQ号(查1名场上的玩家)或者2个1~3之间的数字(使用一个空格隔开)(查2张沉底的身份牌)')) return msg = context['raw_message'] uid = str(context['sender']['user_id']) msg = msg.strip() if msg.find(' ') >= 0: msg = msg.split(' ') if len(msg) == 2: p1, p2 = int(msg[0]), int(msg[1]) if p1 >= 1 and p1 <= 3 and p2 >= 1 and p2 <= 3: p1 = self.formation[p1] p2 = self.formation[p2] await self._send_p(uid, StringMsg(f'身份1是{p1}: {OneNightState._CHARS[p1]}')) await self._send_p(uid, StringMsg(f'身份2是{p2}: {OneNightState._CHARS[p2]}')) self.sub_stage += 1 return else: if msg in self.players and msg != uid: p = self.players[msg] await self._send_p(uid, StringMsg(f'身份是{p}: {OneNightState._CHARS[p]}')) self.sub_stage += 1 return await self._send_p(uid, StringMsg('您的输入不合法,请检查'))
async def on_chat(self, context): if context['raw_message'] == '结束': if self._confirm_quit: self.leave('chat') else: await self._send_g(StringMsg('再次输入以确认结束')) self._confirm_quit = True return elif context['raw_message'] == '说明': await self._send_g(StringMsg(OneNightState._RULE)) self._confirm_quit = False if self._stage == 0: await self._on_stage_0(context) elif self._stage == 2: await self._on_stage_2(context)
async def game_judge(self, context): msg = context['raw_message'] gid = context['group_id'] if msg == '玩一夜狼': await self.hdlr.bot.send_group_msg(gid, StringMsg('输入"加入"加入游戏,输入"开始"开始游戏,输入"说明"查阅游戏规则,输入"退出"以退出游戏,输入"结束"以结束游戏,发言完毕后输入"查看结果"以结束游戏')) self.leave('1night') return True
async def _on_stage_2(self, context): msg = context['raw_message'] if msg == '查看结果': s = '' for k, v in self.players.items(): s += f'{k}的身份是{v}\n' s += f'沉底的身份是:{str(self.formation)}' await self._send_g(StringMsg(s)) self.leave('chat')
async def _robber(self, context, first=None): if first: for p in first: await self._send_p(first, StringMsg('请给我一个你想抢的人的QQ号')) return msg = context['raw_message'] uid = str(context['sender']['user_id']) msg = msg.strip() if msg in self.players and msg != uid: p = self.players[msg] self.players[msg] = self.players[uid] self.players[uid] = p await self._send_p(uid, StringMsg(f'你抢来的身份是{p}: {OneNightState._CHARS[p]}')) if 'wolf' in p: await self._send_p(uid, StringMsg('注意你的胜利条件已经变化')) self.sub_stage += 1 return await self._send_p(uid, StringMsg('您的输入不合法,请检查'))
async def start(self): self.pn = len(self.players) self.formation = copy.deepcopy(OneNightState._FORMATION[self.pn]) self.private_subscribe = Private(self.players.keys()) self.hdlr.subscribe(self.private_subscribe, self.on_p_chat) wolves = [] for p in self.players.keys(): char = random.choice(self.formation) if 'wolf' in char: wolves.append(p) self.formation.remove(char) self.players[p] = char self.reverse_players[char].add(p) await self._send_p(p, StringMsg('你的身份是' + OneNightState._CHARS[char])) for p in wolves: await self._send_p(p, StringMsg('其他狼人玩家的QQ号是:%s' % (str(wolves)))) self._stage = 1 await self._send_g(StringMsg('身份发放完毕,现在天黑请闭眼')) self.sub_stage = 0 self._on_stage_1()
async def _on_stage_0(self, context): msg = context['raw_message'] uid = str(context['sender']['user_id']) if msg == '开始': if len(self.players) < 3: await self._send_g(StringMsg('人数不足无法开始游戏,需要至少3人')) else: await self.start() elif msg == '加入': if uid in self.players: await self._send_g(StringMsg('请勿重复加入')) else: self.players[uid] = 'default' await self._send_g(StringMsg(f'{uid} 加入成功 现在有{len(self.players)}个玩家')) elif msg == '退出': if uid not in self.players: await self._send_g(MultiMsg([StringMsg('没加入退个锤子'), ImageMsg({'file': f'kkr/worinima'})])) else: self.players.pop(uid) await self._send_g(StringMsg(f'{uid} 退出成功 现在有{len(self.players)}个玩家'))
async def change_back_jpg(self, send_handler, msg, receiver_id, sender_id, logger=None): sender_id = str(sender_id) back_num = re.compile(r'^底图([0-9]*)$').findall(msg) back_num = int(back_num[0]) if back_num else None if back_num and back_num in ImageProcesser.CUR_BACK_PIC_SET: self.logger.info(f'{sender_id} change back {back_num} success') user_profile[sender_id]['cur_back_pic'] = int(back_num) await send_handler(receiver_id, StringMsg('已修改')) with open(os.path.join(const.user_profile_path, 'user_profile.json'), 'w', encoding='utf-8') as f: json.dump(user_profile, f, ensure_ascii=False) return True
async def _troublemaker(self, context, first=None): if first: for p in first: await self._send_p(first, StringMsg('请给我2个你想交换身份的人的QQ号(使用一个空格隔开)')) return msg = context['raw_message'] uid = str(context['sender']['user_id']) msg = msg.strip() if msg.find(' ') >= 0: msg = msg.split(' ') if len(msg) == 2: p1, p2 = msg[0], msg[1] if p1 in self.players and p2 in self.players: p = self.players[p1] self.players[p1] = self.players[p2] self.players[p2] = p await self._send_p(uid, StringMsg('交换成功')) self.sub_stage += 1 return await self._send_p(uid, StringMsg('您的输入不合法,请检查'))
async def fixed_roomcode_reply(self, send_handler, msg, receiver_id, sender_id, submit_permission=False, logger=None): if msg == 'ycm' or msg == '有车吗': rl = self._query_room_number() if rl is None: await send_handler(receiver_id, StringMsg('查车失败,芽佬快看看怎么啦 QAQ')) elif rl: await send_handler(receiver_id, StringMsg('\n\n'.join(rl))) else: await send_handler(receiver_id, MultiMsg([ImageMsg({'file': f'kkr/{random.choice(self.preset_keywords["憨批"])}'}), StringMsg('哈哈,没车')])) return True else: if submit_permission or user_profile[str(sender_id)].get('authority') == 'admin': res = re.search(r'^([0-9]{5,6})(\s+.+)*(\s+[Qq][0-4])(\s+.+)*$', msg.strip()) if res: room_code = res.group(1) flag, msg = self._submit_room_number(room_code, sender_id, msg) if flag: await send_handler(receiver_id, MultiMsg([ImageMsg({'file': f'kkr/nb'}), StringMsg('上传车牌啦!')])) else: await send_handler(receiver_id, StringMsg(f'kkr坏了,芽佬快看看QAQ {msg}')) return True return False
async def query_gacha(self, send_handler, msg, receiver_id): res = re.search(r'^卡池(\d+)(\s+(日服|国际服|台服|国服|韩服))?$', msg.strip()) if res: detail = gacha._detail(int(res.group(1)), gacha._server[res.group(3) or '国服']) if detail is not None: await send_handler(receiver_id, MultiMsg(detail)) else: await send_handler(receiver_id, MultiMsg([StringMsg('没有这个卡池'), ImageMsg({'file': f'kkr/{random.choice(self.preset_keywords["憨批"])}'})])) return True constraints = gacha._parse_query_command(msg.strip()) if constraints is not None: if constraints == {}: results = gacha.gacha_table.select_or('id', 'type', 'gachaName', 'bannerAssetBundleName', 'resourceName', type=['permanent', 'limited'], fixed4star=[1]) else: results = gacha.gacha_table.select('id', 'type', 'gachaName', 'bannerAssetBundleName', 'resourceName', **constraints) if results: images = [[ ImageProcesser.open_nontransparent(os.path.join(const.asset_gacha_path, 'jp', f'{r[3]}.png')) or ImageProcesser.open_nontransparent(os.path.join(const.asset_gacha_path, r[4], 'jp', 'logo.png')) or ImageProcesser.white_padding(420, 140), ] for r in results] texts = [f'{r[0]}: {r[2]} ({gacha._type[r[1]]})' for r in results] MAX_NUM = 32 file_names = [ImageProcesser.thumbnail(images=images[i * MAX_NUM: min((i + 1) * MAX_NUM, len(images))], image_style={'height': 140}, labels=texts[i * MAX_NUM: min((i + 1) * MAX_NUM, len(images))], label_style={'font_size': 20, 'font_type': 'default_font.ttf'}, col_space=20, row_space=20 ) for i in range((len(images) - 1) // MAX_NUM + 1)] [await send_handler(receiver_id, ImageMsg({'file': f})) for f in file_names] else: await send_handler(receiver_id, MultiMsg([StringMsg('kkr找不到'), ImageMsg({'file': f'kkr/tuxie'})])) return True return False
async def fixed_reply(self, send_handler, msg, receiver_id, logger=None): be_at = False if '[CQ:at,qq=2807901929]' in msg: be_at = True if msg == '使用说明': await send_handler(receiver_id, ImageMsg({'file': ImageProcesser.manual()})) return True if msg == '底图目录': file_name = ImageProcesser.get_back_pics() await send_handler(receiver_id, ImageMsg({'file': file_name})) return True if be_at: m = re.compile(r'^(我){0,1}.*?([日草操]|cao|ri).*?([你]|kkr|kokoro){0,1}(.*)$').findall(msg.strip().lower()) self.logger.info('be_at %s', m) if m: m = m[0] verb = m[1] obj = m[2] subj = m[0] obj2 = m[3] if not subj: subj = 'kkr也' if obj in ['kkr', 'kokoro']: subj = obj obj = '你' final_s = f'{subj}{verb}{obj}{obj2}' fn = ImageProcesser.image_merge(47, final_s) await send_handler(receiver_id, ImageMsg({'file': fn})) return True else: file_path, meta = PixivCursor.get_one({'mode': 'kkr'}, receiver_id) global COMPRESS_IMAGE if isinstance(file_path, list): if file_path: for file in file_path[:3]: if COMPRESS_IMAGE: f = ImageProcesser.compress(os.path.join('/root/pixiv/', file), isabs=True) await send_handler(receiver_id, ImageMsg({'file': f})) return True else: if file_path is None: await send_handler(receiver_id, MultiMsg([StringMsg('kkr被看光了'), ImageMsg({'file': f'kkr/tuxie'})])) else: if COMPRESS_IMAGE: file_path = ImageProcesser.compress(os.path.join('/root/pixiv/', file_path), isabs=True) await send_handler(receiver_id, ImageMsg({'file': file_path})) return True return False
def _detail_ver2(self, eid, server): res = self.event_table.select_by_single_value('bannerAssetBundleName', id=eid) if res: banner_asset_bundle_name, = res[0] if banner_asset_bundle_name: detail = [] with open(os.path.join(const.datapath, 'json', 'events', f'{eid}.json'), 'r', encoding='utf-8') as f: event_data = json.load(f) if event_data["startAt"][server]: file_path = f'assets/events/{self._server_name[server]}/{banner_asset_bundle_name}.png' if os.access( os.path.join(const.asset_event_path, self._server_name[server], f'{banner_asset_bundle_name}.png'), os.R_OK): detail.append(ImageMsg({'file': file_path})) detail.append( StringMsg('\n' + '\n'.join([ f'{key}: {value}' for key, value in { '标题': event_data['eventName'][server], '种类': self._type[event_data['eventType']], '开始时间': f'{(datetime.datetime.utcfromtimestamp(int(event_data["startAt"][server]) // 1000) + datetime.timedelta(hours=8)).strftime("%Y-%m-%d %H:%M:%S")}(北京时间)', '结束时间': f'{(datetime.datetime.utcfromtimestamp(int(event_data["endAt"][server]) // 1000) + datetime.timedelta(hours=8)).strftime("%Y-%m-%d %H:%M:%S")}(北京时间)', }.items() ]))) detail.append(StringMsg('\n属性: ')) [(detail.append( ImageMsg({'file': f'assets/res/{a["attribute"]}.png'})), detail.append(StringMsg(f'+{a["percent"]}%'))) for a in event_data['attributes']] detail.append(StringMsg('\n角色: ')) images = [[ ImageProcesser.open_nontransparent( os.path.join(const.asset_resource_path, f'chara_icon_{c["characterId"]}.png')) ] for c in event_data['characters']] texts = [ f'+{c["percent"]}%' for c in event_data['characters'] ] character_filename = ImageProcesser.thumbnail( images=images, labels=texts, col_num=len(images), row_space=5, ) detail.append(ImageMsg({'file': character_filename})) detail.append(StringMsg('\n奖励: ')) cards = self.card_table.select( 'id', 'resourceSetName', 'rarity', 'attribute', 'bandId', id=event_data['rewardCards']) rewards_filename = ImageProcesser.thumbnail( images=[ ImageProcesser.merge_image(c[1], c[2], c[3], c[4], thumbnail=True, trained=False) for c in cards ], labels=[str(c[0]) for c in cards], col_num=len(cards), row_space=5, ) detail.append(ImageMsg({'file': rewards_filename})) if self._event_gacha[server].get(str(eid)): detail.append(StringMsg('\n关联卡池: ')) for gacha_id in self._event_gacha[server][str(eid)]: with open(os.path.join(const.datapath, 'json', 'gachas', f'{gacha_id}.json'), 'r', encoding='utf-8') as f: gacha_data = json.load(f) new_cards = [ card for card in gacha_data['newCards'] if gacha_data['details'][server][str(card)] ['pickup'] ] if new_cards: file_path = f'assets/gachas/{self._server_name[server]}/{gacha_data["bannerAssetBundleName"]}.png' if os.access( os.path.join( const.asset_gacha_path, self._server_name[server], f'{gacha_data["bannerAssetBundleName"]}.png' ), os.R_OK): detail.append(ImageMsg({'file': file_path})) detail.append( StringMsg('\n' + '\n'.join([ f'{key}: {value}' for key, value in { '标题': gacha_data['gachaName'][server], '种类': self._gacha_type[ gacha_data['type']], 'ID': str(gacha_id), }.items() ]))) detail.append(StringMsg('\nPICK UP: ')) cards = self.card_table.select( 'id', 'resourceSetName', 'rarity', 'attribute', 'bandId', id=new_cards) pickups_filename = ImageProcesser.thumbnail( images=[ ImageProcesser.merge_image( c[1], c[2], c[3], c[4], thumbnail=True, trained=False) for c in cards ], labels=[str(c[0]) for c in cards], col_num=len(cards), row_space=5, ) detail.append( ImageMsg({'file': pickups_filename})) else: detail = [ StringMsg('活动尚未开始,查查日服吧'), ImageMsg({'file': f'kkr/spin'}) ] return detail
def _detail(self, eid, server): banner_asset_bundle_name, = self.event_table.select_by_single_value( 'bannerAssetBundleName', id=eid)[0] if banner_asset_bundle_name: detail = [] with open(os.path.join(const.datapath, 'json', 'events', f'{eid}.json'), 'r', encoding='utf-8') as f: event_data = json.load(f) if event_data["startAt"][server]: file_path = f'assets/events/{self._server_name[server]}/{banner_asset_bundle_name}.png' if os.access( os.path.join(const.asset_event_path, self._server_name[server], f'{banner_asset_bundle_name}.png'), os.R_OK): detail.append(ImageMsg({'file': file_path})) detail.append( StringMsg('\n' + '\n'.join([ f'{key}: {value}' for key, value in { '标题': event_data['eventName'][server], '种类': self._type[event_data['eventType']], '开始时间': f'{(datetime.datetime.utcfromtimestamp(int(event_data["startAt"][server]) // 1000) + datetime.timedelta(hours=8)).strftime("%Y-%m-%d %H:%M:%S")}(北京时间)', '结束时间': f'{(datetime.datetime.utcfromtimestamp(int(event_data["endAt"][server]) // 1000) + datetime.timedelta(hours=8)).strftime("%Y-%m-%d %H:%M:%S")}(北京时间)', }.items() ]))) detail.append(StringMsg('\n属性: ')) [(detail.append( ImageMsg({'file': f'assets/res/{a["attribute"]}.png'})), detail.append(StringMsg(f'+{a["percent"]}%'))) for a in event_data['attributes']] detail.append(StringMsg('\n角色: ')) c0 = event_data['characters'][0] for c in event_data['characters'][1:]: if c['percent'] != c0['percent']: [(detail.append( ImageMsg({ 'file': f'assets/res/chara_icon_{c["characterId"]}.png' })), detail.append(StringMsg(f'+{c["percent"]}%'))) for c in event_data['characters']] c0 = None break else: [ detail.append( ImageMsg({ 'file': f'assets/res/chara_icon_{c["characterId"]}.png' })) for c in event_data['characters'] ] detail.append(StringMsg(f'+{c0["percent"]}%')) detail.append(StringMsg('\n奖励: ')) cards = self.card_table.select('id', 'resourceSetName', 'rarity', 'attribute', 'bandId', id=event_data['rewardCards']) filenames = [ ImageProcesser.merge_image(c[1], c[2], c[3], c[4], thumbnail=True, trained=False, return_fn=True) for c in cards ] [detail.append(ImageMsg({'file': f})) for f in filenames] [ detail.append( StringMsg( f'(卡牌id: {",".join([str(c[0]) for c in cards])})')) ] else: detail.append(StringMsg('活动尚未开始')) return detail
async def query_card(self, send_handler, msg, receiver_id): # send_handler: Bot send handler res = re.search(r'^无框(\d+)(\s+(特训前|特训后))?$', msg.strip()) if res: result = self.card_table.select_by_single_value('resourceSetName', id=int( res.group(1))) if result: resource_set_name = result[0][0] if res.group(3) == '特训前': if os.access( os.path.join( const.asset_card_path, f'{resource_set_name}_card_normal.png'), os.R_OK): file_path = f'assets/cards/{resource_set_name}_card_normal.png' elif res.group(3) == '特训后': if os.access( os.path.join( const.asset_card_path, f'{resource_set_name}_card_after_training.png' ), os.R_OK): file_path = f'assets/cards/{resource_set_name}_card_after_training.png' else: file_path = f'assets/cards/{resource_set_name}_card_normal.png' \ if os.access(os.path.join(const.asset_card_path, f'{resource_set_name}_card_normal.png'), os.R_OK) \ else f'assets/cards/{resource_set_name}_card_after_training.png' \ if os.access(os.path.join(const.asset_card_path, f'{resource_set_name}_card_after_training.png'), os.R_OK) \ else '' if file_path: await send_handler(receiver_id, ImageMsg({'file': file_path})) else: await send_handler( receiver_id, MultiMsg([ StringMsg('没有这张卡'), ImageMsg({ 'file': f'kkr/{random.choice(["hanpi1", "hanpi2", "hanpi3"])}' }) ])) return True res = re.search(r'^查卡(\d+)(\s+(特训前|特训后))?$', msg.strip()) if res: description, resource_set_name, rarity, attribute, band_id = self._detail( cid=int(res.group(1))) if resource_set_name: if res.group(3) == '特训前': file_path = ImageProcesser.merge_image(resource_set_name, rarity, attribute, band_id, thumbnail=False, trained=False) elif res.group(3) == '特训后': file_path = ImageProcesser.merge_image(resource_set_name, rarity, attribute, band_id, thumbnail=False, trained=True) else: file_path = ImageProcesser.merge_image(resource_set_name, rarity, attribute, band_id, thumbnail=False, trained=False) \ or ImageProcesser.merge_image(resource_set_name, rarity, attribute, band_id, thumbnail=False, trained=True) if file_path: await send_handler( receiver_id, MultiMsg([ ImageMsg({'file': file_path}), StringMsg(description) ])) else: await send_handler( receiver_id, MultiMsg([ StringMsg('没有这张卡'), ImageMsg({ 'file': f'kkr/{random.choice(["hanpi1", "hanpi2", "hanpi3"])}' }) ])) return True constraints = self._parse_query_command(msg.strip()) if constraints: if constraints == '露佬': await send_handler( receiver_id, MultiMsg([ StringMsg('再查露佬头都给你锤爆\n'), ImageMsg({'file': 'kkr/lulao'}) ])) return True results = self.card_table.select('id', 'resourceSetName', 'rarity', 'attribute', 'bandId', 'skillId', 'type', **constraints) if results: images = [[ ImageProcesser.merge_image(r[1], r[2], r[3], r[4]) or ImageProcesser.white_padding(180, 180), ImageProcesser.merge_image( r[1], r[2], r[3], r[4], trained=True) or ImageProcesser.white_padding(180, 180) ] for r in results] # images = [ImageProcesser.merge_image(r[1], r[2], r[3], r[4]) or ImageProcesser.white_padding(180, 180) for r in results] texts = [ str(r[0]) + f'({self._skill_types.get(r[5], "未知")}, {self._types.get(r[6], "未知")})' for r in results ] # fragment MAX_NUM = 32 file_names = [ ImageProcesser.thumbnail( images=images[i * MAX_NUM:min((i + 1) * MAX_NUM, len(images))], labels=texts[i * MAX_NUM:min((i + 1) * MAX_NUM, len(images))], label_style={'font_size': 20}, col_space=20, row_space=20, ) for i in range((len(images) - 1) // MAX_NUM + 1) ] [ await send_handler(receiver_id, ImageMsg({'file': f})) for f in file_names ] else: await send_handler( receiver_id, MultiMsg([ StringMsg('kkr找不到'), ImageMsg({'file': f'kkr/tuxie'}) ])) return True return False
async def get_status(self): self.logger.info('get_status') info = await self.server.get_status() self.logger.info('on_get_status %s', info) await self.send_private_msg(444351271, StringMsg(str(info)))
async def on_stage_2_enter(self): await self._send_g(MultiMsg([StringMsg('所有人行动完毕,天亮了。现在是自由讨论时间,讨论完毕后,输入"查看结果"以查看游戏结果'), ImageMsg({'file': f'kkr/want'})]))
def _detail(self, eid, server): res = self.gacha_table.select_by_single_value('bannerAssetBundleName', 'resourceName', id=eid) if res: detail = [] banner_asset_bundle_name, resourceName = res[0] with open(os.path.join(const.datapath, 'json', 'gachas', f'{eid}.json'), 'r', encoding='utf-8') as f: gacha_data = json.load(f) if gacha_data["publishedAt"][server]: file_path = f'assets/gachas/{self._server_name[server]}/{banner_asset_bundle_name}.png' if os.access( os.path.join(const.asset_gacha_path, self._server_name[server], f'{banner_asset_bundle_name}.png'), os.R_OK): detail.append(ImageMsg({'file': file_path})) else: file_path = f'assets/gachas/{resourceName}/{self._server_name[server]}/logo.png' if os.access( os.path.join(const.asset_gacha_path, resourceName, self._server_name[server], 'logo.png'), os.R_OK): detail.append(ImageMsg({'file': file_path})) detail.append( StringMsg('\n' + '\n'.join([ f'{key}: {value}' for key, value in { '标题': gacha_data['gachaName'][server], '种类': self._type[gacha_data['type']], '开始时间': f'{(datetime.datetime.utcfromtimestamp(int(gacha_data["publishedAt"][server]) // 1000) + datetime.timedelta(hours=8)).strftime("%Y-%m-%d %H:%M:%S")}(北京时间)', '结束时间': f'{(datetime.datetime.utcfromtimestamp(int(gacha_data["closedAt"][server]) // 1000) + datetime.timedelta(hours=8)).strftime("%Y-%m-%d %H:%M:%S")}(北京时间)', }.items() ]))) new_cards = [ card for card in gacha_data['newCards'] if gacha_data['details'][server][str(card)]['pickup'] ] if new_cards: detail.append(StringMsg('\nPICK UP: ')) cards = self.card_table.select('id', 'resourceSetName', 'rarity', 'attribute', 'bandId', id=gacha_data['newCards']) rewards_filename = ImageProcesser.thumbnail( images=[ ImageProcesser.merge_image(c[1], c[2], c[3], c[4], thumbnail=True, trained=False) for c in cards ], labels=[str(c[0]) for c in cards], col_num=len(cards), row_space=5, ) detail.append(ImageMsg({'file': rewards_filename})) detail.append( StringMsg(f'\n描述: {gacha_data["description"][server]}')) if self._gacha_event[server].get(str(eid)): detail.append(StringMsg('\n关联活动: ')) for event_id in self._gacha_event[server][str(eid)]: with open(os.path.join(const.datapath, 'json', 'events', f'{event_id}.json'), 'r', encoding='utf-8') as f: event_data = json.load(f) file_path = f'assets/events/{self._server_name[server]}/{event_data["bannerAssetBundleName"]}.png' if os.access( os.path.join( const.asset_event_path, self._server_name[server], f'{event_data["bannerAssetBundleName"]}.png' ), os.R_OK): detail.append(ImageMsg({'file': file_path})) detail.append( StringMsg('\n' + '\n'.join([ f'{key}: {value}' for key, value in { '标题': event_data['eventName'][server], '种类': self._event_type[ event_data['eventType']], 'ID': str(event_id), }.items() ]))) detail.append(StringMsg('\n奖励: ')) cards = self.card_table.select( 'id', 'resourceSetName', 'rarity', 'attribute', 'bandId', id=event_data['rewardCards']) rewards_filename = ImageProcesser.thumbnail( images=[ ImageProcesser.merge_image(c[1], c[2], c[3], c[4], thumbnail=True, trained=False) for c in cards ], labels=[str(c[0]) for c in cards], col_num=len(cards), row_space=5, ) detail.append(ImageMsg({'file': rewards_filename})) else: detail = [ StringMsg('卡池未开放,查查别的服务器吧'), ImageMsg({'file': f'kkr/spin'}) ] return detail
async def query_user_gacha(self, send_handler, msg, receiver_id, logger=None): if msg == '更新抽卡数据': l = self.bilibili_drawcard_spider.fetch_once() if not l is None: await send_handler(receiver_id, MultiMsg([ImageMsg({'file': f'kkr/nb'}), StringMsg(f'又有新的{l}个出货记录了!')])) else: await send_handler(receiver_id, StringMsg('更新失败,芽佬快看看怎么啦 QAQ')) return True else: res = re.search(r'^查抽卡名字 (.*?)$', msg) self.logger.info(f'{msg}, {res}') ret = [] query = False if res: self.logger.info(f'query gacha user {res.group(1)}') query = True ret = self.bilibili_drawcard_spider.get_data_by_username(res.group(1)) else: res = re.search(r'^查抽卡id (.*?)$', msg) if res: uid = int(res.group(1)) self.logger.info(f'query gacha user {uid}') query = True ret = self.bilibili_drawcard_spider.get_data_by_uid(uid) if not query: return False if not ret: await send_handler(receiver_id, MultiMsg([ImageMsg({'file': f'kkr/{random.choice(self.preset_keywords["憨批"])}'}), StringMsg('没出货查什么查')])) return True images = [] texts = [] stringmsg = [] # self.logger.info(f'gacha result {ret}') too_large = False if len(ret) > 50: ret = ret[:50] too_large = True for (i, d) in enumerate(ret): card_id = d.situation_id r = card.card_table.select_by_single_value('id', 'resourceSetName', 'rarity', 'attribute', 'bandId', 'skillId', 'type', id=card_id)[0] if r: images.append(ImageProcesser.merge_image(r[1], r[2], r[3], r[4]) or ImageProcesser.white_padding(180, 180)) t = time.strftime('%Y/%m/%d %H:%M:%S', time.localtime(d.gacha_at // 1000)) s = f'{t}' texts.append(s) stringmsg.append(f'{t}: {d.user_name}({d.user_id}) ==< {d.gacha_name}') if (i+1) % 10 == 0: file_name = ImageProcesser.thumbnail(images=images, labels=texts, col_space=40) await send_handler(receiver_id, MultiMsg([ImageMsg({'file': file_name}), StringMsg('\n'.join(stringmsg))])) images = [] texts = [] stringmsg = [] if images: file_name = ImageProcesser.thumbnail(images=images, labels=texts, col_space=40) await send_handler(receiver_id, MultiMsg([ImageMsg({'file': file_name}), StringMsg('\n'.join(stringmsg))])) if too_large: await send_handler(receiver_id, MultiMsg([ImageMsg({'file': f'kkr/nb'}), StringMsg('出货的也太多了,kkr好累!下次再查吧!')])) return True