zhenxun_bot/plugins/russian/__init__.py
2021-06-21 09:53:33 +08:00

352 lines
18 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from nonebot import on_command
import random
import asyncio
from nonebot.adapters.cqhttp import GROUP, Bot, GroupMessageEvent, Message
from nonebot.typing import T_State
from util.utils import get_message_text, is_number, get_message_at
from models.group_member_info import GroupInfoUser
from util.init_result import at
from models.russian_user import RussianUser
from models.bag_user import BagUser
from services.log import logger
import time
from .data_source import rank
__plugin_name__ = '俄罗斯轮盘'
__plugin_usage__ = '''俄罗斯轮盘帮助:
开启游戏:装弹 [子弹数] [金额](默认200金币) [at](指定决斗对象,为空则所有群友都可接受决斗)
示例:装弹 1 10
接受对决:接受对决/拒绝决斗
开始对决开枪轮流开枪30秒未开枪另一方可使用结算命令结束对决并胜利
结算结算当某一方30秒未开枪可使用该命令强行结束对决并胜利
我的战绩:我的战绩
排行榜:胜场排行/败场排行/欧洲人排行/慈善家排行
【注:同一时间群内只能有一场对决】
'''
rs_player = {}
rssian = on_command('俄罗斯轮盘', aliases={'装弹', '俄罗斯转盘'}, permission=GROUP, priority=5, block=True)
accept = on_command('接受对决', aliases={'接受决斗', '接受挑战'}, permission=GROUP, priority=5, block=True)
refuse = on_command('拒绝对决', aliases={'拒绝决斗', '拒绝挑战'}, permission=GROUP, priority=5, block=True)
shot = on_command('开枪', aliases={'', '', ''}, permission=GROUP, priority=5, block=True)
settlement = on_command('结算', permission=GROUP, priority=5, block=True)
record = on_command('我的战绩', permission=GROUP, priority=5, block=True)
rssian_rank = on_command('胜场排行', aliases={'胜利排行', '败场排行', '失败排行',
'欧洲人排行', '慈善家排行'}, permission=GROUP, priority=5, block=True)
@accept.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
global rs_player
try:
if rs_player[event.group_id][1] == 0:
await accept.finish('目前没有发起对决,你接受个啥?速速装弹!', at_sender=True)
except KeyError:
await accept.finish('目前没有进行的决斗,请发送 装弹 开启决斗吧!', at_sender=True)
if rs_player[event.group_id][2] != 0:
if rs_player[event.group_id][1] == event.user_id or rs_player[event.group_id][2] == event.user_id:
await accept.finish(f'你已经身处决斗之中了啊,给我认真一点啊!', at_sender=True)
else:
await accept.finish('已经有人接受对决了,你还是乖乖等待下一场吧!', at_sender=True)
if rs_player[event.group_id][1] == event.user_id:
await accept.finish('请不要自己枪毙自己!换人来接受对决...', at_sender=True)
if rs_player[event.group_id]['at'] != 0 and rs_player[event.group_id]['at'] != event.user_id:
await accept.finish(Message(f'这场对决是邀请 {at(rs_player[event.group_id]["at"])}的,不要捣乱!'), at_sender=True)
if time.time() - rs_player[event.group_id]['time'] > 30:
rs_player[event.group_id] = {}
await accept.finish('这场对决邀请已经过时了,请重新发起决斗...', at_sender=True)
user_money = await BagUser.get_gold(event.user_id, event.group_id)
if user_money < rs_player[event.group_id]['money']:
if rs_player[event.group_id]['at'] != 0 and rs_player[event.group_id]['at'] == event.user_id:
rs_player[event.group_id] = {}
await accept.finish('你的金币不足以接受这场对决!对决还未开始便结束了,请重新装弹!', at_sender=True)
else:
await accept.finish('你的金币不足以接受这场对决!', at_sender=True)
player2_name = (await GroupInfoUser.select_member_info(event.user_id, event.group_id)).user_name
rs_player[event.group_id][2] = event.user_id
rs_player[event.group_id]['player2'] = player2_name
rs_player[event.group_id]['time'] = time.time()
await accept.send(Message(f'{player2_name}接受了对决!\n'
f'{at(rs_player[event.group_id][1])}先开枪!'))
@refuse.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
global rs_player
try:
if rs_player[event.group_id][1] == 0:
await accept.finish('你要拒绝啥?明明都没有人发起对决的说!', at_sender=True)
except KeyError:
await refuse.finish('目前没有进行的决斗,请发送 装弹 开启决斗吧!', at_sender=True)
if rs_player[event.group_id]['at'] != 0 and event.user_id != rs_player[event.group_id]['at']:
await accept.finish('又不是找你决斗,你拒绝什么啊!气!', at_sender=True)
if rs_player[event.group_id]['at'] == event.user_id:
at_player_name = (await GroupInfoUser.select_member_info(event.user_id, event.group_id)).user_name
await accept.send(Message(f'{at(rs_player[event.group_id][1])}\n'
f'{at_player_name}拒绝了你的对决!'))
rs_player[event.group_id] = {}
@settlement.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
global rs_player
if not rs_player.get(event.group_id) or rs_player[event.group_id][1] == 0 or rs_player[event.group_id][2] == 0:
await settlement.finish('比赛并没有开始...无法结算...', at_sender=True)
if event.user_id != rs_player[event.group_id][1] and event.user_id != rs_player[event.group_id][2]:
await settlement.finish('吃瓜群众不要捣乱!黄牌警告!', at_sender=True)
if time.time() - rs_player[event.group_id]['time'] <= 30:
await settlement.finish(f'{rs_player[event.group_id]["player1"]}'
f' {rs_player[event.group_id]["player2"]} 比赛并未超时,请继续比赛...')
win_name = rs_player[event.group_id]["player1"] if \
rs_player[event.group_id][2] == rs_player[event.group_id]['next'] else \
rs_player[event.group_id]["player2"]
await settlement.send(f'这场对决是 {win_name} 胜利了')
await end_game(bot, event)
@rssian.args_parser
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
msg = get_message_text(event.json())
if msg in ['取消', '算了']:
await rssian.finish('已取消操作...')
try:
if rs_player[event.group_id][1] != 0:
await rssian.finish('决斗已开始...', at_sender=True)
except KeyError:
pass
if not is_number(msg):
await rssian.reject('输入子弹数量必须是数字啊喂!')
if int(msg) < 1 or int(msg) > 6:
await rssian.reject('子弹数量必须大于0小于7')
state['bullet_num'] = int(msg)
@rssian.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
global rs_player
msg = get_message_text(event.json())
if msg == '帮助':
await rssian.finish(__plugin_usage__)
try:
if rs_player[event.group_id][1] and not rs_player[event.group_id][2] and \
time.time() - rs_player[event.group_id]['time'] <= 30:
await rssian.finish(f'现在是 {rs_player[event.group_id]["player1"]} 发起的对决\n请等待比赛结束后再开始下一轮...')
if rs_player[event.group_id][1] and rs_player[event.group_id][2] and\
time.time() - rs_player[event.group_id]['time'] <= 30:
await rssian.finish(f'{rs_player[event.group_id]["player1"]}'
f' {rs_player[event.group_id]["player2"]}的对决还未结束!')
if rs_player[event.group_id][1] and rs_player[event.group_id][2] and\
time.time() - rs_player[event.group_id]['time'] > 30:
await shot.send('决斗已过时,强行结算...')
await end_game(bot, event)
return
if not rs_player[event.group_id][2] and time.time() - rs_player[event.group_id]['time'] > 30:
rs_player[event.group_id][1] = 0
rs_player[event.group_id][2] = 0
rs_player[event.group_id]['at'] = 0
except KeyError:
pass
if msg:
msg = msg.split(' ')
if len(msg) == 1:
msg = msg[0]
if is_number(msg) and not (int(msg) < 1 or int(msg) > 6):
state['bullet_num'] = int(msg)
else:
money = msg[1].strip()
msg = msg[0].strip()
if is_number(msg) and not (int(msg) < 1 or int(msg) > 6):
state['bullet_num'] = int(msg)
if is_number(money) and 0 < int(money) <= 1000:
state['money'] = int(money)
state['at'] = get_message_at(event.json())
@rssian.got("bullet_num", prompt='请输入装填子弹的数量!(最多6颗)')
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
global rs_player
bullet_num = state['bullet_num']
at_ = state['at']
money = state['money'] if state.get('money') else 200
user_money = await BagUser.get_gold(event.user_id, event.group_id)
if bullet_num < 0 or bullet_num > 6:
await rssian.reject('子弹数量必须大于0小于7速速重新装弹')
if money > 1000:
await rssian.finish('太多了单次金额不能超过1000', at_sender=True)
if money > user_money:
await rssian.finish('你没有足够的钱支撑起这场挑战', at_sender=True)
player1_name = (await GroupInfoUser.select_member_info(event.user_id, event.group_id)).user_name
if at_:
at_ = at_[0]
at_player_name = (await GroupInfoUser.select_member_info(at_, event.group_id)).user_name
msg = f'{player1_name}{at(at_)} 发起了决斗!请 {at_player_name} 在30秒内回复接受对决 or ‘拒绝对决’,超时此次决斗作废!'
else:
at_ = 0
msg = '若30秒内无人接受挑战则此次对决作废【首次游玩请发送 ’俄罗斯轮盘帮助‘ 来查看命令】'
rs_player[event.group_id] = {1: event.user_id,
'player1': player1_name,
2: 0,
'player2': '',
'at': at_,
'next': event.user_id,
'money': money,
'bullet': random_bullet(bullet_num),
'bullet_num': bullet_num,
'null_bullet_num': 7 - bullet_num,
'index': 0,
'time': time.time()}
await rssian.send(Message(('' * bullet_num)[:-1] + f',装填完毕\n挑战金额:{money}\n'
f'第一枪的概率为:{str(float(bullet_num) / 7.0 * 100)[:5]}%\n'
f'{msg}'))
@shot.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
global rs_player
try:
if time.time() - rs_player[event.group_id]['time'] > 30:
if rs_player[event.group_id][2] == 0:
rs_player[event.group_id][1] = 0
await shot.finish('这场对决已经过时了,请重新装弹吧!', at_sender=True)
else:
await shot.send('决斗已过时,强行结算...')
await end_game(bot, event)
return
except KeyError:
await shot.finish('目前没有进行的决斗,请发送 装弹 开启决斗吧!', at_sender=True)
if rs_player[event.group_id][1] == 0:
await shot.finish('没有对决,也还没装弹呢,请先输入 装弹 吧!', at_sender=True)
if rs_player[event.group_id][1] == event.user_id and rs_player[event.group_id][2] == 0:
await shot.finish('baka你是要枪毙自己嘛笨蛋', at_sender=True)
if rs_player[event.group_id][2] == 0:
await shot.finish('请这位勇士先发送 接受对决 来站上擂台...', at_sender=True)
player1_name = rs_player[event.group_id]['player1']
player2_name = rs_player[event.group_id]['player2']
if rs_player[event.group_id]['next'] != event.user_id:
if event.user_id != rs_player[event.group_id][1] and event.user_id != rs_player[event.group_id][2]:
await shot.finish(random.choice([
f'不要打扰 {player1_name}{player2_name} 的决斗啊!',
'给我好好做好一个观众!不然小真寻就要生气了',
f'不要捣乱啊baka{(await GroupInfoUser.select_member_info(event.user_id, event.group_id)).user_name}'
]), at_sender=True)
await shot.finish(f'你的左轮不是连发的!该 '
f'{(await GroupInfoUser.select_member_info(int(rs_player[event.group_id]["next"]), event.group_id)).user_name} 开枪了')
if rs_player[event.group_id]['bullet'][rs_player[event.group_id]['index']] != 1:
await shot.send(Message(random.choice([
'呼呼,没有爆裂的声响,你活了下来',
'虽然黑洞洞的枪口很恐怖,但好在没有子弹射出来,你活下来了',
'\"\",你没死,看来运气不错',
]) + f'\n下一枪中弹的概率'
f'{str(float((rs_player[event.group_id]["bullet_num"])) / float(rs_player[event.group_id]["null_bullet_num"] - 1 + rs_player[event.group_id]["bullet_num"]) * 100)[:5]}%\n'
f'轮到 {at(rs_player[event.group_id][1] if event.user_id == rs_player[event.group_id][2] else rs_player[event.group_id][2])}'))
rs_player[event.group_id]["null_bullet_num"] -= 1
rs_player[event.group_id]['next'] = rs_player[event.group_id][1] if \
event.user_id == rs_player[event.group_id][2] else rs_player[event.group_id][2]
rs_player[event.group_id]['time'] = time.time()
rs_player[event.group_id]['index'] += 1
else:
await shot.send(random.choice([
'\"嘭!\",你直接去世了',
'眼前一黑,你直接穿越到了异世界...(死亡)',
'终究还是你先走一步...',
]) + f'\n{rs_player[event.group_id]["index"] + 1} 发子弹送走了你...', at_sender=True)
win_name = player1_name if event.user_id == rs_player[event.group_id][2] else player2_name
await asyncio.sleep(0.5)
await shot.send(f'这场对决是 {win_name} 胜利了')
await end_game(bot, event)
async def end_game(bot: Bot, event: GroupMessageEvent):
global rs_player
player1_name = rs_player[event.group_id]['player1']
player2_name = rs_player[event.group_id]['player2']
if rs_player[event.group_id]['next'] == rs_player[event.group_id][1]:
win_user_id = rs_player[event.group_id][2]
lose_user_id = rs_player[event.group_id][1]
win_name = player2_name
lose_name = player1_name
else:
win_user_id = rs_player[event.group_id][1]
lose_user_id = rs_player[event.group_id][2]
win_name = player1_name
lose_name = player2_name
rand = random.randint(0, 5)
money = rs_player[event.group_id]['money']
if money > 10:
fee = int(money * float(rand) / 100)
fee = 1 if fee < 1 and rand != 0 else fee
else:
fee = 0
await RussianUser.add_count(win_user_id, event.group_id, 'win')
await RussianUser.add_count(lose_user_id, event.group_id, 'lose')
await RussianUser.money(win_user_id, event.group_id, 'win', money - fee)
await RussianUser.money(lose_user_id, event.group_id, 'lose', money)
await BagUser.add_gold(win_user_id, event.group_id, money - fee)
await BagUser.spend_gold(lose_user_id, event.group_id, money)
win_user = await RussianUser.ensure(win_user_id, event.group_id)
lose_user = await RussianUser.ensure(lose_user_id, event.group_id)
bullet_str = ''
for x in rs_player[event.group_id]['bullet']:
bullet_str += '__ ' if x == 0 else '| '
logger.info(f'俄罗斯轮盘:胜者:{win_name} - 败者:{lose_name} - 金币:{money}')
await bot.send(event, message=f'结算:\n'
f'\t胜者:{win_name}\n'
f'\t赢取金币:{money - fee}\n'
f'\t累计胜场:{win_user.win_count}\n'
f'\t累计赚取金币:{win_user.make_money}\n'
f'-------------------\n'
f'\t败者:{lose_name}\n'
f'\t输掉金币:{money}\n'
f'\t累计败场:{lose_user.fail_count}\n'
f'\t累计输掉金币:{lose_user.lose_money}\n'
f'-------------------\n'
f'哼哼,真寻从中收取了 {float(rand)}%({fee}金币) 作为手续费!\n'
f'子弹排列:{bullet_str[:-1]}')
rs_player[event.group_id] = {}
@record.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
user = await RussianUser.ensure(event.user_id, event.group_id)
await record.send(f'俄罗斯轮盘\n'
f'胜利场次:{user.win_count}\n'
f'失败场次:{user.fail_count}\n'
f'赚取金币:{user.make_money}\n'
f'输掉金币:{user.lose_money}', at_sender=True)
@rssian_rank.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
if state["_prefix"]["raw_command"] in ['胜场排行', '胜利排行']:
await rssian_rank.finish(await rank(event.group_id, 'win_rank'))
if state["_prefix"]["raw_command"] in ['败场排行', '失败排行']:
await rssian_rank.finish(await rank(event.group_id, 'lose_rank'))
if state["_prefix"]["raw_command"] == '欧洲人排行':
await rssian_rank.finish(await rank(event.group_id, 'make_money'))
if state["_prefix"]["raw_command"] == '慈善家排行':
await rssian_rank.finish(await rank(event.group_id, 'spend_money'))
# 随机子弹排列
def random_bullet(num: int) -> list:
bullet_lst = [0, 0, 0, 0, 0, 0, 0]
for i in random.sample([0, 1, 2, 3, 4, 5, 6], num):
bullet_lst[i] = 1
return bullet_lst