update 0.0.6.2

This commit is contained in:
HibiKi
2021-11-23 21:44:59 +08:00
parent c802dfda22
commit 3de487fb24
251 changed files with 14413 additions and 14002 deletions
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
-414
View File
@@ -1,414 +0,0 @@
from nonebot import on_command, on_notice
from nonebot.adapters.cqhttp import (
Bot,
GroupMessageEvent,
PokeNotifyEvent,
MessageEvent,
)
from nonebot.typing import T_State
from .data_source import (
check_gold,
generate_send_redbag_pic,
open_redbag,
generate_open_redbag_pic,
return_gold,
)
from nonebot.adapters.cqhttp.permission import GROUP
from nonebot.message import run_preprocessor, IgnoredException
from nonebot.matcher import Matcher
from utils.utils import get_message_text, is_number, scheduler
from utils.message_builder import image
from services.log import logger
from configs.path_config import IMAGE_PATH
from nonebot.permission import SUPERUSER
from nonebot.rule import to_me
from datetime import datetime, timedelta
from configs.config import NICKNAME
from apscheduler.jobstores.base import JobLookupError
import random
import time
__zx_plugin_name__ = "金币红包"
__plugin_usage__ = """
usage:
在群内发送指定金额的红包,拼手气项目
指令:
塞红包 [金币数] ?[红包数=5]: 塞入红包
开/抢/*戳一戳*: 打开红包
退回: 退回未开完的红包,必须在一分钟后使用
示例:塞红包 1000
示例:塞红包 1000 10
""".strip()
__plugin_des__ = "运气项目又来了"
__plugin_cmd__ = ["塞红包 [金币数] ?[红包数=5]", "开/抢", "退回"]
__plugin_version__ = 0.1
__plugin_author__ = "HibiKier"
__plugin_settings__ = {
"level": 5,
"default_status": True,
"limit_superuser": False,
"cmd": ["金币红包", "塞红包"],
}
__plugin_resources__ = {
"prts": IMAGE_PATH
}
gold_redbag = on_command(
"塞红包", aliases={"金币红包"}, priority=5, block=True, permission=GROUP
)
open_ = on_command("开", aliases={"抢"}, priority=5, block=True, permission=GROUP)
poke_ = on_notice(priority=6, block=False)
return_ = on_command("退回", aliases={"退还"}, priority=5, block=True, permission=GROUP)
festive_redbag = on_command(
"节日红包", priority=5, block=True, permission=SUPERUSER, rule=to_me()
)
redbag_data = {}
festive_redbag_data = {}
# 阻断其他poke
@run_preprocessor
async def _(matcher: Matcher, bot: Bot, event: PokeNotifyEvent, state: T_State):
try:
if matcher.type == "notice" and event.self_id == event.target_id:
flag1 = True
flag2 = True
try:
if festive_redbag_data[event.group_id]["user_id"]:
if (
event.user_id
in festive_redbag_data[event.group_id]["open_user"]
):
flag1 = False
except KeyError:
flag1 = False
try:
if redbag_data[event.group_id]["user_id"]:
if event.user_id in redbag_data[event.group_id]["open_user"]:
flag2 = False
except KeyError:
flag2 = False
if flag1 or flag2:
if matcher.module == "poke":
raise IgnoredException("目前正在抢红包...")
else:
if matcher.module == "gold_redbag":
raise IgnoredException("目前没有红包...")
except AttributeError:
pass
@gold_redbag.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
global redbag_data, festive_redbag_data
try:
if time.time() - redbag_data[event.group_id]["time"] > 60:
amount = (
redbag_data[event.group_id]["amount"]
- redbag_data[event.group_id]["open_amount"]
)
await gold_redbag.send(
f'{redbag_data[event.group_id]["nickname"]}的红包过时未开完,退还{amount}金币...'
)
redbag_data[event.group_id] = {}
else:
await gold_redbag.finish(
f'目前 {redbag_data[event.group_id]["nickname"]} 的红包还没有开完噢,'
f'还剩下 {len(redbag_data[event.group_id]["redbag"])} 个红包!'
f'(或等待{str(60 - time.time() + redbag_data[event.group_id]["time"])[:2]}秒红包过时)'
)
except KeyError:
pass
msg = get_message_text(event.json())
msg = msg.split()
if len(msg) == 1:
flag, amount = await check_gold(event.user_id, event.group_id, msg[0])
if not flag:
await gold_redbag.finish(amount)
num = 5
else:
amount = msg[0]
num = msg[1]
flag, amount = await check_gold(event.user_id, event.group_id, amount)
if not flag:
await gold_redbag.finish(amount, at_sender=True)
if not is_number(num) or int(num) < 1:
await gold_redbag.finish("红包个数给我输正确啊!", at_sender=True)
group_member_num = (await bot.get_group_info(group_id=event.group_id))['member_count']
num = int(num)
if num > group_member_num:
await gold_redbag.send('你发的红包数量也太多了,已经为你修改成与本群人数相同的红包数量...')
num = group_member_num
nickname = event.sender.card if event.sender.card else event.sender.nickname
flag, result = init_redbag(
event.user_id, event.group_id, nickname, amount, num, int(bot.self_id)
)
if not flag:
await gold_redbag.finish(result, at_sender=True)
else:
await gold_redbag.send(
f"{nickname}发起了金币红包\n金额:{amount}\n数量:{num}\n"
+ image(
b64=await generate_send_redbag_pic(
redbag_data[event.group_id]["user_id"]
)
)
)
logger.info(
f"USER {event.user_id} GROUP {event.group_id} 塞入 {num} 个红包,共 {amount} 金币"
)
@open_.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
global redbag_data, festive_redbag_data
msg = get_message_text(event.json())
msg = (
msg.replace("!", "")
.replace("!", "")
.replace(",", "")
.replace(",", "")
.replace(".", "")
.replace("。", "")
)
if msg:
if '红包' not in msg:
return
flag1 = True
flag2 = True
open_flag1 = True
open_flag2 = True
try:
if festive_redbag_data[event.group_id]["user_id"]:
if event.user_id in festive_redbag_data[event.group_id]["open_user"]:
open_flag1 = False
except KeyError:
open_flag1 = False
flag1 = False
try:
if redbag_data[event.group_id]["user_id"]:
if event.user_id in redbag_data[event.group_id]["open_user"]:
open_flag2 = False
except KeyError:
flag2 = False
if not flag1 and not flag2:
await open_.finish("目前没有红包可以开...", at_sender=True)
if open_flag1 or open_flag2:
try:
await open_.send(
image(b64=await get_redbag_img(event.user_id, event.group_id)),
at_sender=True,
)
except KeyError:
await open_.finish("真贪心,明明已经开过这个红包了的说...", at_sender=True)
else:
await open_.finish("真贪心,明明已经开过这个红包了的说...", at_sender=True)
@poke_.handle()
async def _poke_(bot: Bot, event: PokeNotifyEvent, state: T_State):
global redbag_data, festive_redbag_data
if event.self_id == event.target_id:
flag1 = True
flag2 = True
try:
if event.user_id in festive_redbag_data[event.group_id]["open_user"]:
flag1 = False
except KeyError:
flag1 = False
try:
if event.user_id in redbag_data[event.group_id]["open_user"]:
flag2 = False
except KeyError:
flag2 = False
if not flag1 and not flag2:
return
await poke_.send(
image(b64=await get_redbag_img(event.user_id, event.group_id)),
at_sender=True,
)
@return_.handle()
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
global redbag_data
try:
if redbag_data[event.group_id]["user_id"] != event.user_id:
await return_.finish("不是你的红包你退回什么!", at_sender=True)
if time.time() - redbag_data[event.group_id]["time"] <= 60:
await return_.finish(
f'你的红包还没有过时,在 {str(60 - time.time() + redbag_data[event.group_id]["time"])[:2]} '
f"秒后可以退回..",
at_sender=True,
)
await return_gold(
event.user_id,
event.group_id,
redbag_data[event.group_id]["amount"]
- redbag_data[event.group_id]["open_amount"],
)
await return_.send(
f"已成功退还了 "
f"{redbag_data[event.group_id]['amount'] - redbag_data[event.group_id]['open_amount']} "
f"金币",
at_sender=True,
)
logger.info(
f"USER {event.user_id} GROUP {event.group_id} 退回了"
f"红包 {redbag_data[event.group_id]['amount'] - redbag_data[event.group_id]['open_amount']} 金币"
)
redbag_data[event.group_id] = {}
except KeyError:
await return_.finish("目前没有红包可以退回...", at_sender=True)
@festive_redbag.handle()
async def _(bot: Bot, event: MessageEvent, state: T_State):
global redbag_data
msg = get_message_text(event.json())
if msg:
msg = msg.split()
amount = 0
num = 0
greetings = "恭喜发财 大吉大利"
gl = []
if (lens := len(msg)) < 2:
await festive_redbag.finish("参数不足,格式:节日红包 [金额] [数量] [祝福语](可省) [指定群](可省)")
if lens > 1:
if not is_number(msg[0]):
await festive_redbag.finish("金额必须要是数字!", at_sender=True)
amount = int(msg[0])
if not is_number(msg[1]):
await festive_redbag.finish("数量必须要是数字!", at_sender=True)
num = int(msg[1])
if lens > 2:
greetings = msg[2]
if lens > 3:
for i in range(3, lens):
if not is_number(msg[i]):
await festive_redbag.finish("指定的群号必须要是数字啊!", at_sender=True)
gl.append(int(msg[i]))
if not gl:
gl = await bot.get_group_list(self_id=int(bot.self_id))
gl = [g["group_id"] for g in gl]
for g in gl:
try:
scheduler.remove_job(f"festive_redbag_{g}")
await end_festive_redbag(bot, g)
except JobLookupError:
pass
init_redbag(int(bot.self_id), g, f"{NICKNAME}", amount, num, int(bot.self_id), 1)
scheduler.add_job(
end_festive_redbag,
"date",
run_date=str(datetime.now() + timedelta(hours=24)).split(".")[0],
id=f"festive_redbag_{g}",
args=[bot, g],
)
try:
await bot.send_group_msg(
group_id=g,
message=f"{NICKNAME}发起了金币红包\n金额:{amount}\n数量:{num}\n"
+ image(
b64=await generate_send_redbag_pic(int(bot.self_id), greetings)
),
)
except AttributeError:
pass
# 红包数据初始化
def init_redbag(
user_id: int,
group_id: int,
nickname: str,
amount: int,
num: int,
bot_self_id: int,
mode: int = 0,
):
global redbag_data, festive_redbag_data
data = redbag_data if mode == 0 else festive_redbag_data
if not data.get(group_id):
data[group_id] = {}
try:
if data[group_id]["user_id"] and user_id != bot_self_id:
return False, f'{data[group_id]["nickname"]}的红包还没抢完呢...'
except KeyError:
pass
data[group_id]["user_id"] = user_id
data[group_id]["nickname"] = nickname
data[group_id]["amount"] = amount
data[group_id]["num"] = num
data[group_id]["open_amount"] = 0
data[group_id]["time"] = time.time()
data[group_id]["redbag"] = random_redbag(amount, num)
data[group_id]["open_user"] = []
if mode == 0:
redbag_data = data
else:
festive_redbag_data = data
return True, ""
# 随机红包排列
def random_redbag(amount: int, num: int) -> list:
redbag_lst = []
for _ in range(num - 1):
tmp = int(amount / random.choice(range(3, num + 3)))
redbag_lst.append(tmp)
amount -= tmp
redbag_lst.append(amount)
return redbag_lst
# 返回开红包图片
async def get_redbag_img(user_id: int, group_id: int):
global redbag_data, festive_redbag_data
data = redbag_data
mode = 0
if festive_redbag_data.get(group_id):
try:
if user_id not in festive_redbag_data[group_id]["open_user"]:
data = festive_redbag_data
mode = 1
except KeyError:
pass
amount, data = await open_redbag(user_id, group_id, data)
text = (
f"已领取"
f'{data[group_id]["num"] - len(data[group_id]["redbag"])}'
f'/{data[group_id]["num"]}个,'
f'共{data[group_id]["open_amount"]}/{data[group_id]["amount"]}金币'
)
logger.info(
f"USER {user_id} GROUP {group_id} 抢到了 {data[group_id]['user_id']} 的红包,获取了{amount}金币"
)
b64 = await generate_open_redbag_pic(
data[group_id]["user_id"], data[group_id]["nickname"], amount, text
)
if data[group_id]["open_amount"] == data[group_id]["amount"]:
data[group_id] = {}
if mode == 0:
redbag_data = data
else:
festive_redbag_data = data
return b64
async def end_festive_redbag(bot: Bot, group_id: int):
global festive_redbag_data
message = (
f"{NICKNAME}的节日红包过时了,一共开启了 "
f"{festive_redbag_data[group_id]['num'] - len(festive_redbag_data[group_id]['redbag'])}"
f" 个红包,共 {festive_redbag_data[group_id]['open_amount']} 金币"
)
await bot.send_group_msg(group_id=group_id, message=message)
festive_redbag_data[group_id] = {}
-96
View File
@@ -1,96 +0,0 @@
from models.bag_user import BagUser
from utils.utils import is_number, get_local_proxy
from utils.image_utils import CreateImg
from utils.user_agent import get_user_agent
from configs.path_config import IMAGE_PATH
from ..models.redbag_user import RedbagUser
import random
import os
import aiohttp
from io import BytesIO
import asyncio
# 检查金币数量合法性,并添加记录数据
async def check_gold(user_id: int, group_id: int, amount: str):
if is_number(amount):
amount = int(amount)
user_gold = await BagUser.get_gold(user_id, group_id)
if amount < 1:
return False, '小气鬼,要别人倒贴金币给你嘛!'
if user_gold < amount:
return False, '没有金币的话请不要发红包...'
await BagUser.spend_gold(user_id, group_id, amount)
await RedbagUser.add_redbag_data(user_id, group_id, 'send', amount)
return True, amount
else:
return False, '给我好好的输入红包里金币的数量啊喂!'
# 金币退回
async def return_gold(user_id: int, group_id: int, amount: int):
await BagUser.add_gold(user_id, group_id, amount)
# 开红包
async def open_redbag(user_id: int, group_id: int, redbag_data: dict):
amount = random.choice(redbag_data[group_id]['redbag'])
redbag_data[group_id]['redbag'].remove(amount)
redbag_data[group_id]['open_user'].append(user_id)
redbag_data[group_id]['open_amount'] += amount
await RedbagUser.add_redbag_data(user_id, group_id, 'get', amount)
await BagUser.add_gold(user_id, group_id, amount)
return amount, redbag_data
# 随机红包图片
async def generate_send_redbag_pic(user_id: int, msg: str = '恭喜发财 大吉大利'):
random_redbag = random.choice(os.listdir(f"{IMAGE_PATH}/prts/redbag_2"))
redbag = CreateImg(0, 0, font_size=38, background=f'{IMAGE_PATH}/prts/redbag_2/{random_redbag}')
ava = CreateImg(65, 65, background=BytesIO(await get_pic(user_id)))
await asyncio.get_event_loop().run_in_executor(None, ava.circle)
redbag.text((int((redbag.size[0] - redbag.getsize(msg)[0]) / 2), 210), msg, (240, 218, 164))
redbag.paste(ava, (int((redbag.size[0] - ava.size[0])/2), 130), True)
return redbag.pic2bs4()
# 开红包图片
async def generate_open_redbag_pic(user_id: int, send_user_nickname: str, amount: int, text: str):
return await asyncio.create_task(_generate_open_redbag_pic(user_id, send_user_nickname, amount, text))
# 获取QQ头像
async def get_pic(qq):
url = f'http://q1.qlogo.cn/g?b=qq&nk={qq}&s=160'
async with aiohttp.ClientSession(headers=get_user_agent()) as session:
async with session.get(url, proxy=get_local_proxy(), timeout=5) as response:
return await response.read()
# 开红包图片
async def _generate_open_redbag_pic(user_id: int, send_user_nickname: str, amount: int, text: str):
send_user_nickname += '的红包'
amount = str(amount)
head = CreateImg(1000, 980, font_size=30, background=f'{IMAGE_PATH}/prts/redbag_12.png')
size = CreateImg(0, 0, font_size=50).getsize(send_user_nickname)
# QQ头像
ava_bk = CreateImg(100 + size[0], 66, color='white', font_size=50)
ava = CreateImg(66, 66, background=BytesIO(await get_pic(user_id)))
ava_bk.paste(ava)
ava_bk.text((100, 7), send_user_nickname)
# ava_bk.show()
ava_bk_w, ava_bk_h = ava_bk.size
head.paste(ava_bk, (int((1000 - ava_bk_w) / 2), 300))
# 金额
size = CreateImg(0, 0, font_size=150).getsize(amount)
price = CreateImg(size[0], size[1], font_size=150)
price.text((0, 0), amount, fill=(209, 171, 108))
# 金币中文
head.paste(price, (int((1000 - size[0]) / 2) - 50, 460))
head.text((int((1000 - size[0]) / 2 + size[0]) - 50, 500 + size[1] - 70), '金币', fill=(209, 171, 108))
# 剩余数量和金额
head.text((350, 900), text, (198, 198, 198))
return head.pic2bs4()
Regular → Executable
+1 -1
View File
@@ -1 +1 @@
from .goods_info import *
from .goods_info import *
View File
-73
View File
@@ -1,73 +0,0 @@
from services.db_context import db
from typing import List
class RedbagUser(db.Model):
__tablename__ = "redbag_users"
id = db.Column(db.Integer(), primary_key=True)
user_qq = db.Column(db.BigInteger(), nullable=False)
group_id = db.Column(db.BigInteger(), nullable=False)
send_redbag_count = db.Column(db.Integer(), default=0)
get_redbag_count = db.Column(db.Integer(), default=0)
spend_gold = db.Column(db.Integer(), default=0)
get_gold = db.Column(db.Integer(), default=0)
_idx1 = db.Index("redbag_group_users_idx1", "user_qq", "group_id", unique=True)
@classmethod
async def add_redbag_data(cls, user_qq: int, group_id: int, itype: str, money: int):
"""
说明:
添加收发红包数据
参数:
:param user_qq: qq号
:param group_id: 群号
:param itype: 收或发
:param money: 金钱数量
"""
query = cls.query.where((cls.user_qq == user_qq) & (cls.group_id == group_id))
user = await query.with_for_update().gino.first() or await cls.create(
user_qq=user_qq,
group_id=group_id,
)
if itype == "get":
await user.update(
get_redbag_count=user.get_redbag_count + 1,
get_gold=user.get_gold + money,
).apply()
else:
await user.update(
send_redbag_count=user.send_redbag_count + 1,
spend_gold=user.spend_gold + money,
).apply()
@classmethod
async def ensure(cls, user_qq: int, group_id: int) -> bool:
"""
说明:
获取用户对象
参数:
:param user_qq: qq号
:param group_id: 群号
"""
query = cls.query.where((cls.user_qq == user_qq) & (cls.group_id == group_id))
user = await query.gino.first() or await cls.create(
user_qq=user_qq,
group_id=group_id,
)
return user
@classmethod
async def get_user_all(cls, group_id: int = None) -> List["RedbagUser"]:
"""
说明:
获取所有用户对象
参数:
:param group_id: 群号
"""
if not group_id:
query = await cls.query.gino.all()
else:
query = await cls.query.where((cls.group_id == group_id)).gino.all()
return query
Regular → Executable
View File
Regular → Executable
View File
View File
View File
Regular → Executable
View File
Regular → Executable
View File