mirror of
https://github.com/zhenxun-org/zhenxun_bot.git
synced 2025-12-14 13:42:56 +08:00
first_commit .gitignore
This commit is contained in:
parent
df4e3aea45
commit
155f62c08a
14
.env.dev
Normal file
14
.env.dev
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
|
||||||
|
SUPERUSERS=["775757368"]
|
||||||
|
COMMAND_START=[""]
|
||||||
|
|
||||||
|
SESSION_RUNNING_EXPRESSION="别急呀,小真寻要宕机了!QAQ"
|
||||||
|
|
||||||
|
NICKNAME=["A"]
|
||||||
|
|
||||||
|
SESSION_EXPIRE_TIMEOUT=30
|
||||||
|
|
||||||
|
DEBUG=true
|
||||||
|
# 服务器和端口
|
||||||
|
HOST = 127.0.0.1
|
||||||
|
PORT = 8080
|
||||||
94
bot.py
Normal file
94
bot.py
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
import nonebot
|
||||||
|
from nonebot.adapters.cqhttp import Bot as CQHTTPBot
|
||||||
|
from services.db_context import init, disconnect
|
||||||
|
nonebot.init()
|
||||||
|
driver = nonebot.get_driver()
|
||||||
|
driver.register_adapter("cqhttp", CQHTTPBot)
|
||||||
|
config = driver.config
|
||||||
|
driver.on_startup(init)
|
||||||
|
driver.on_shutdown(disconnect)
|
||||||
|
nonebot.load_builtin_plugins()
|
||||||
|
nonebot.load_plugins("plugins")
|
||||||
|
nonebot.load_plugins("plugins/shop")
|
||||||
|
nonebot.load_plugins("plugins/genshin")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
nonebot.run()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# None
|
||||||
|
# ---------------------
|
||||||
|
# 775757368 print(event.get_user_id())
|
||||||
|
# 775757368 print(event.get_session_id())
|
||||||
|
# 天气 print(event.get_message())
|
||||||
|
# message.group.normal print(event.get_event_name())
|
||||||
|
# 天气 print(event.get_plaintext())
|
||||||
|
# -------
|
||||||
|
# 863633108 print(event.group_id)
|
||||||
|
# 775757368 print(event.user_id)
|
||||||
|
# 1851212230 print(event.message_id)
|
||||||
|
|
||||||
|
# event
|
||||||
|
# [request.group.invite]: {
|
||||||
|
# 'time': 1612430661, 'self_id': 3054557284, 'post_type': 'request', 'request_type': 'group', 'sub_type': 'invite',
|
||||||
|
# 'group_id': 863633108, 'user_id': 775757368, 'comment': '', 'flag': '1612430661235986'}
|
||||||
|
|
||||||
|
# [request.friend]: {'time': 1612431762, 'self_id': 3054557284, 'post_type': 'request',
|
||||||
|
# 'request_type': 'friend', 'user_id': 3238573864, 'comment': '', 'flag': '1612431762000000'}
|
||||||
|
|
||||||
|
|
||||||
|
# [notice.group_decrease.leave]: {'time': 1612620312,
|
||||||
|
# 'self_id': 3054557284, 'post_type': 'notice', 'notice_type': 'group_decrease',
|
||||||
|
# 'sub_type': 'leave', 'user_id': 3238573864, 'group_id': 863633108, 'operator_id': 3238573864}
|
||||||
|
|
||||||
|
# [notice.group_increase.approve]: {'time': 1612620506,
|
||||||
|
# 'self_id': 3054557284, 'post_type': 'notice', 'notice_type': 'group_increase',
|
||||||
|
# 'sub_type': 'approve', 'user_id': 3238573864, 'group_id': 863633108, 'operator_id': 0}
|
||||||
|
|
||||||
|
# get_group_list
|
||||||
|
# [{'group_id': 210287674, 'group_name': '豪爹头号粉丝⑧群', 'max_member_count': 200, 'member_count': 14},
|
||||||
|
# {'group_id': 863633108, 'group_name': 'Amireux、这里是、可…', 'max_member_count': 200, 'member_count': 4}]
|
||||||
|
|
||||||
|
# 消息event
|
||||||
|
# {"time": 1613886297, "self_id": 3054557284, "post_type": "message", "sub_type": "normal", "user_id": 3238573864,
|
||||||
|
# "message_type": "group", "message_id": 1933353523, "message": [{"type": "text", "data": {"text": "666"}}],
|
||||||
|
# "raw_message": "A666", "font": 0, "sender": {"user_id": 3238573864, "nickname":
|
||||||
|
# "\u53ef\u7231\u7684\u5c0f\u771f\u5bfb", "sex": "unknown", "age": 0, "card": "", "area": "", "level": "",
|
||||||
|
# "role": "member/admin/owner", "title": ""}, "to_me": true, "reply": null, "group_id": 863633108, "anonymous": null}
|
||||||
|
|
||||||
|
# bilibili转发
|
||||||
|
# {"app":"com.tencent.miniapp_01","configs":{"autoSize":0,"ctime":1613992391,"forward":1,"height":0,"
|
||||||
|
# token":"f7f529900be6af62f4d864f8a92c94c9","type":"normal","width":0},"desc":"哔哩哔哩",
|
||||||
|
# "extra":{"app_type":1,"appid":100951776,"uin":775757368},"meta":{"detail_1":{"appid":"1109937557",
|
||||||
|
# "desc":"B 站 用 户 三 连 现 状","gamePoints":"","gamePointsUrl":"","host":{"nick":"这里是","uin":775757368},
|
||||||
|
# "icon":"http://miniapp.gtimg.cn/public/appicon/432b76be3a548fc128acaa6c1ec90131_200.jpg",
|
||||||
|
# "preview":"pubminishare-30161.picsz.qpic.cn/4f5a19fb-42d5-4bb5-bc0a-b92fa5a06519",
|
||||||
|
# "qqdocurl":"https://b23.tv/qDvchc?share_medium=android&share_source=qq&bbid=XYDEA6CD35717661AE594D9DD99A5E852E414&ts=1613992387314",
|
||||||
|
# "scene":1036,"shareTemplateData":{},"shareTemplateId":"8C8E89B49BE609866298ADDFF2DBABA4","showLittleTail":"","title":"哔哩哔哩",
|
||||||
|
# "url":"m.q.qq.com/a/s/130c1f9c2af58430805ebfda192caa9a"}},"needShareCallBack":false,"prompt":"[QQ小程序]哔哩哔哩","ver":"1.0.0.19",
|
||||||
|
# "view":"view_8C8E89B49BE609866298ADDFF2DBABA4"}
|
||||||
|
|
||||||
|
#event
|
||||||
|
# [notice.group_decrease.kick_me]: {'time': 1614143313, 'self_id': 3054557284, 'post_type': 'notice',
|
||||||
|
# 'notice_type': 'group_decrease', 'sub_type': 'kick_me', 'user_id': 3054557284, 'group_id': 863633108,
|
||||||
|
# 'operator_id': 775757368}
|
||||||
|
|
||||||
|
# [request.group.add]: {'time': 1614851972, 'self_id': 3238573864, 'post_type': 'request', 'request_type': 'group',
|
||||||
|
# 'sub_type': 'add', 'group_id': 774261838, 'user_id': 3054557284, 'comment': '问题:为啥加群鸭?\n答案:哈哈哈',
|
||||||
|
# 'flag': '1614851972274444'}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
BIN
configs/__pycache__/config.cpython-39.pyc
Normal file
BIN
configs/__pycache__/config.cpython-39.pyc
Normal file
Binary file not shown.
BIN
configs/__pycache__/path_config.cpython-39.pyc
Normal file
BIN
configs/__pycache__/path_config.cpython-39.pyc
Normal file
Binary file not shown.
154
configs/config.py
Normal file
154
configs/config.py
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
from .utils.util import get_config_data
|
||||||
|
try:
|
||||||
|
import ujson as json
|
||||||
|
except ModuleNotFoundError:
|
||||||
|
import json
|
||||||
|
|
||||||
|
|
||||||
|
# 是否使用配置文件
|
||||||
|
USE_CONFIG_FILE = True
|
||||||
|
|
||||||
|
|
||||||
|
# API KEY(必要)
|
||||||
|
LOLICON_KEY: str = "336595836015174952daa2" # lolicon
|
||||||
|
RSSHUBAPP: str = "https://docs.rsshub.app/" # rsshub
|
||||||
|
# 图灵
|
||||||
|
TL_KEY = ["4474710fabbf4540bfaa569c192bb457", "6f4c0920d2ff4962b5cbd8148aef771b",
|
||||||
|
"f5595738894042fb9fad88ecdc4acf41", "c24400595fed48f9a5c5bc3ff03a3267", "efab135b75d84b02a59115f5b571f277"]
|
||||||
|
|
||||||
|
# 数据库(必要)
|
||||||
|
bind = 'postgresql://hibiki:KEWang130123@hibiki0v0.cn:5432/hibikibot'
|
||||||
|
sql_name = ''
|
||||||
|
user = ''
|
||||||
|
password = ''
|
||||||
|
address = ''
|
||||||
|
port = ''
|
||||||
|
database = ''
|
||||||
|
|
||||||
|
|
||||||
|
# 公开图库列表
|
||||||
|
IMAGE_DIR_LIST = ["色图", "美图", "萝莉", "壁纸"]
|
||||||
|
|
||||||
|
# 对被ban用户发送的消息
|
||||||
|
BAN_RESULT = "才不会给你发消息."
|
||||||
|
|
||||||
|
|
||||||
|
# 插件配置
|
||||||
|
MAXINFO_REIMU: int = 7 # 上车(reimu)功能查找目的地的最大数
|
||||||
|
COUNT_PER_DAY_REIMU: int = 5 # 每日上车(reimu)次数限制
|
||||||
|
MAXINFO_BT: int = 10 # bt功能单次查找最大数
|
||||||
|
MAXINFO_PRIVATE_ANIME: int = 20 # 私聊搜索动漫返回的最大数量
|
||||||
|
MAXINFO_GROUP_ANIME: int = 5 # 群搜索动漫返回的最大数量
|
||||||
|
MAX_FIND_IMG_COUNT = 3 # 识图最大返回数
|
||||||
|
|
||||||
|
ADMIN_DEFAULT_AUTH = 5 # 默认群管理员权限
|
||||||
|
|
||||||
|
MAX_SIGN_GOLD = 200 # 签到好感度加成额外获得的最大金币数
|
||||||
|
|
||||||
|
INITIAL_SETU_PROBABILITY = 0.7 # 色图概率
|
||||||
|
FUDU_PROBABILITY = 0.7 # 复读概率
|
||||||
|
|
||||||
|
INITIAL_OPEN_CASE_COUNT = 20 # 初始开箱次数
|
||||||
|
MUTE_DEFAULT_COUNT = 10 # 刷屏禁言默认检测次数
|
||||||
|
MUTE_DEFAULT_TIME = 7 # 刷屏检测默认规定时间
|
||||||
|
|
||||||
|
MUTE_DEFAULT_DURATION = 10 # 刷屏检测默禁言时长(分钟)
|
||||||
|
|
||||||
|
# 注:即在 MALICIOUS_CHECK_TIME 时间内触发相同命令 MALICIOUS_BAN_COUNT 将被ban MALICIOUS_BAN_TIME 分钟
|
||||||
|
MALICIOUS_BAN_TIME = 30 # 恶意命令触发检测触发后ban的时长(分钟)
|
||||||
|
MALICIOUS_BAN_COUNT = 4 # 恶意命令触发检测最大触发次数
|
||||||
|
MALICIOUS_CHECK_TIME = 5 # 恶意命令触发检测规定时间内(秒)
|
||||||
|
|
||||||
|
# LEVEL
|
||||||
|
DELETE_IMG_LEVEL: int = 7 # 删除图片权限
|
||||||
|
MOVE_IMG_LEVEL: int = 7 # 移动图片权限
|
||||||
|
UPLOAD_LEVEL: int = 6 # 上传图片权限
|
||||||
|
BAN_LEVEL: int = 5 # BAN权限
|
||||||
|
OC_LEVEL: int = 2 # 开关群功能权限
|
||||||
|
MUTE_LEVEL: int = 5 # 更改禁言设置权限
|
||||||
|
|
||||||
|
# 需要为哪些群更新最新版gocq吗?(上传最新版gocq)
|
||||||
|
# 示例:[434995955, 239483248]
|
||||||
|
UPDATE_GOCQ_GROUP = []
|
||||||
|
|
||||||
|
# 代理
|
||||||
|
system_proxy = 'http://127.0.0.1:7890'
|
||||||
|
buff_proxy = ''
|
||||||
|
|
||||||
|
# 是否存储色图
|
||||||
|
DOWNLOAD_SETU = True
|
||||||
|
# 是否使用本地色图
|
||||||
|
LOCAL_SETU = True
|
||||||
|
# 是否自动同意好友添加
|
||||||
|
AUTO_ADD_FRIEND = True
|
||||||
|
|
||||||
|
|
||||||
|
# 模块与对应命令
|
||||||
|
# 用于生成帮助图片 和 开关功能
|
||||||
|
plugins2name_dict = {
|
||||||
|
'sign_in': ['签到'],
|
||||||
|
'send_img': ['发送图片', '萝莉', '美图', '壁纸'],
|
||||||
|
'send_setu': ['色图', '涩图', '瑟图', '查色图'],
|
||||||
|
'white2black': ['黑白图', '黑白草图'],
|
||||||
|
'coser': ['coser', 'cos'],
|
||||||
|
'quotations': ['语录'],
|
||||||
|
'jitang': ['鸡汤'],
|
||||||
|
'send_dinggong_voice': ['骂我', '骂老子', '骂劳资'],
|
||||||
|
'open_cases': ['开箱', '我的开箱', '群开箱统计', '我的金色'],
|
||||||
|
'luxun': ['鲁迅说过', '鲁迅说'],
|
||||||
|
'fake_msg': ['假消息'],
|
||||||
|
'buy': ['购买', '购买道具'],
|
||||||
|
'my_gold': ['我的金币'],
|
||||||
|
'my_props': ['我的道具'],
|
||||||
|
'shop_help': ['商店'],
|
||||||
|
'nonebot_plugin_cocdicer': ['骰子娘'],
|
||||||
|
'update_pic': ['图片', '操作图片', '修改图片'],
|
||||||
|
'search_buff_skin_price': ['查询皮肤'],
|
||||||
|
'weather': ['天气', '查询天气', '天气查询'],
|
||||||
|
'yiqing': ['疫情', '疫情查询', '查询疫情'],
|
||||||
|
'what_anime': ['识番'],
|
||||||
|
'search_anime': ['搜番'],
|
||||||
|
'songpicker2': ['点歌'],
|
||||||
|
'epic': ['epic'],
|
||||||
|
'pixiv': ['pixiv', 'p站排行', '搜图'],
|
||||||
|
'poke': ['戳一戳'],
|
||||||
|
'draw_card': ['游戏抽卡', '原神一井', '原神来一井', '方舟一井', '方舟来一井'],
|
||||||
|
'ai': ['ai', 'Ai', 'AI', 'aI'],
|
||||||
|
'one_friend': ['我有一个朋友', '我有一个朋友想问问'],
|
||||||
|
'translate': ['翻译', '英翻', '翻英', '日翻', '翻日', '韩翻', '翻韩'],
|
||||||
|
'nonebot_plugin_picsearcher': ['识图'],
|
||||||
|
'almanac': ['原神黄历', '黄历'],
|
||||||
|
'material_remind': ['今日素材', '天赋材料'],
|
||||||
|
'qiu_qiu_translation': ['丘丘翻译', '丘丘一下', '丘丘语翻译'],
|
||||||
|
'query_resource_points': ['原神资源查询', '原神资源列表'],
|
||||||
|
}
|
||||||
|
|
||||||
|
# 群管理员功能 与 对应权限
|
||||||
|
admin_plugins_auth = {
|
||||||
|
'admin_bot_manage': OC_LEVEL,
|
||||||
|
'ban': BAN_LEVEL,
|
||||||
|
'delete_img': DELETE_IMG_LEVEL,
|
||||||
|
'move_img': MOVE_IMG_LEVEL,
|
||||||
|
'upload_img': UPLOAD_LEVEL,
|
||||||
|
'admin_help': 1,
|
||||||
|
'mute': MUTE_LEVEL,
|
||||||
|
}
|
||||||
|
|
||||||
|
# 配置文件应用
|
||||||
|
if USE_CONFIG_FILE:
|
||||||
|
config = get_config_data()
|
||||||
|
if config:
|
||||||
|
for key in config.keys():
|
||||||
|
if isinstance(config[key], str):
|
||||||
|
config[key] = config[key].strip()
|
||||||
|
if key.find('proxy') != -1:
|
||||||
|
if not config[key]:
|
||||||
|
config[key] = None
|
||||||
|
# if not configs[key] and key.find("PATH") == -1:
|
||||||
|
# configs[key] = None
|
||||||
|
globals().update(config)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
66
configs/path_config.py
Normal file
66
configs/path_config.py
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
from .utils.util import get_config_data
|
||||||
|
from pathlib import Path
|
||||||
|
from configs.config import USE_CONFIG_FILE
|
||||||
|
|
||||||
|
# 图片路径
|
||||||
|
IMAGE_PATH = Path("resources/img/")
|
||||||
|
# 音频路径
|
||||||
|
VOICE_PATH = Path("resources/voice/")
|
||||||
|
# 文本路径
|
||||||
|
TXT_PATH = Path("resources/txt/")
|
||||||
|
# 日志路径
|
||||||
|
LOG_PATH = Path("log/")
|
||||||
|
# 字体路径
|
||||||
|
TTF_PATH = Path("resources/ttf/")
|
||||||
|
# 数据路径
|
||||||
|
DATA_PATH = Path("data/")
|
||||||
|
# 抽卡数据路径
|
||||||
|
DRAW_PATH = Path("data/draw_card/")
|
||||||
|
# 临时图片路径
|
||||||
|
TEMP_PATH = Path("resources/img/temp/")
|
||||||
|
|
||||||
|
|
||||||
|
def init_path():
|
||||||
|
global IMAGE_PATH, VOICE_PATH, TXT_PATH, LOG_PATH, TTF_PATH, DATA_PATH, DRAW_PATH, TEMP_PATH
|
||||||
|
if USE_CONFIG_FILE:
|
||||||
|
data = get_config_data()
|
||||||
|
if data.get('IMAGE_PATH'):
|
||||||
|
IMAGE_PATH = Path(data['IMAGE_PATH'])
|
||||||
|
if data.get('VOICE_PATH'):
|
||||||
|
VOICE_PATH = Path(data['VOICE_PATH'])
|
||||||
|
if data.get('TXT_PATH'):
|
||||||
|
TXT_PATH = Path(data['TXT_PATH'])
|
||||||
|
if data.get('LOG_PATH'):
|
||||||
|
LOG_PATH = Path(data['LOG_PATH'])
|
||||||
|
if data.get('TTF_PATH'):
|
||||||
|
TTF_PATH = Path(data['TTF_PATH'])
|
||||||
|
if data.get('DATA_PATH'):
|
||||||
|
DATA_PATH = Path(data['DATA_PATH'])
|
||||||
|
if data.get('DRAW_PATH'):
|
||||||
|
DRAW_PATH = Path(data['DRAW_PATH'])
|
||||||
|
if data.get('TEMP_PATH'):
|
||||||
|
TEMP_PATH = Path(data['TEMP_PATH'])
|
||||||
|
IMAGE_PATH.mkdir(parents=True, exist_ok=True)
|
||||||
|
VOICE_PATH.mkdir(parents=True, exist_ok=True)
|
||||||
|
TXT_PATH.mkdir(parents=True, exist_ok=True)
|
||||||
|
LOG_PATH.mkdir(parents=True, exist_ok=True)
|
||||||
|
TTF_PATH.mkdir(parents=True, exist_ok=True)
|
||||||
|
DATA_PATH.mkdir(parents=True, exist_ok=True)
|
||||||
|
DRAW_PATH.mkdir(parents=True, exist_ok=True)
|
||||||
|
TEMP_PATH.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
IMAGE_PATH = str(IMAGE_PATH.absolute()) + '/'
|
||||||
|
VOICE_PATH = str(VOICE_PATH.absolute()) + '/'
|
||||||
|
TXT_PATH = str(TXT_PATH.absolute()) + '/'
|
||||||
|
LOG_PATH = str(LOG_PATH.absolute()) + '/'
|
||||||
|
TTF_PATH = str(TTF_PATH.absolute()) + '/'
|
||||||
|
DATA_PATH = str(DATA_PATH.absolute()) + '/'
|
||||||
|
DRAW_PATH = str(DRAW_PATH.absolute()) + '/'
|
||||||
|
TEMP_PATH = str(TEMP_PATH.absolute()) + '/'
|
||||||
|
|
||||||
|
|
||||||
|
init_path()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
print(IMAGE_PATH)
|
||||||
BIN
configs/utils/__pycache__/util.cpython-39.pyc
Normal file
BIN
configs/utils/__pycache__/util.cpython-39.pyc
Normal file
Binary file not shown.
35
configs/utils/util.py
Normal file
35
configs/utils/util.py
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
from pathlib import Path
|
||||||
|
from services.init_config import init_config
|
||||||
|
try:
|
||||||
|
import ujson as json
|
||||||
|
except ModuleNotFoundError:
|
||||||
|
import json
|
||||||
|
|
||||||
|
|
||||||
|
data: dict = {}
|
||||||
|
|
||||||
|
|
||||||
|
def get_config_data():
|
||||||
|
global data
|
||||||
|
if not data:
|
||||||
|
try:
|
||||||
|
base_config = json.load(open(Path() / "config.json", 'r', encoding='utf8'))
|
||||||
|
plugins2cmd_config = json.load(open(Path() / 'configs' / 'plugins2cmd_config.json', 'r', encoding='utf8'))
|
||||||
|
other_config = json.load(open(Path() / 'configs' / 'other_config.json', 'r', encoding='utf8'))
|
||||||
|
for key in base_config.keys():
|
||||||
|
data.update(base_config[key])
|
||||||
|
for key in plugins2cmd_config.keys():
|
||||||
|
data.update(plugins2cmd_config[key])
|
||||||
|
for key in other_config.keys():
|
||||||
|
data.update(other_config[key])
|
||||||
|
except FileNotFoundError:
|
||||||
|
# logger.warning('配置文件不存在,生成默认配置....请填写数据库等必要数据后再次启动bot...')
|
||||||
|
init_config()
|
||||||
|
raise FileNotFoundError('配置文件不存在,生成默认配置....请填写数据库等必要数据后再次启动bot...')
|
||||||
|
except ValueError:
|
||||||
|
# logger.error('配置文件错误....')
|
||||||
|
raise ValueError('配置文件错误....')
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
594
data/anime.json
Normal file
594
data/anime.json
Normal file
@ -0,0 +1,594 @@
|
|||||||
|
{
|
||||||
|
"mua": [
|
||||||
|
"你想干嘛?(一脸嫌弃地后退)",
|
||||||
|
"诶……不可以随便亲亲啦",
|
||||||
|
"(亲了一下你)",
|
||||||
|
"只......只许这一次哦///////",
|
||||||
|
"唔...诶诶诶!!!",
|
||||||
|
"mua~",
|
||||||
|
"rua!大hentai!想...想亲咱就直说嘛⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄",
|
||||||
|
"!啾~~!"
|
||||||
|
],
|
||||||
|
"摸摸": [
|
||||||
|
"感觉你就像咱很久之前认识的一个人呢,有种莫名安心的感觉(>﹏<)",
|
||||||
|
"舒服w,蹭蹭~",
|
||||||
|
"唔。。头发要乱啦",
|
||||||
|
"呼噜呼噜~",
|
||||||
|
"再摸一次~",
|
||||||
|
"好舒服,蹭蹭~",
|
||||||
|
"不行那里不可以(´///ω/// `)",
|
||||||
|
"再摸咱就长不高啦~",
|
||||||
|
"你的手总是那么暖和呢~",
|
||||||
|
"好吧~_~,就一下下哦……唔~好了……都两下了……(害羞)",
|
||||||
|
"不可以总摸的哦,不然的话,会想那个的wwww",
|
||||||
|
"哼!谁稀罕你摸头啦!唔......为什么要做出那副表情......好啦好啦~咱......咱让你摸就是了......诶嘿嘿~好舒服......",
|
||||||
|
"呜姆呜姆~~~w(害羞,兴奋)主人喵~(侧过脑袋蹭蹭你的手"
|
||||||
|
],
|
||||||
|
"上你": [
|
||||||
|
"(把你按在地上)这么弱还想欺负咱,真是不自量力呢",
|
||||||
|
"你再这样我就不理你了(>д<)"
|
||||||
|
],
|
||||||
|
"傻了": [
|
||||||
|
"超级讨厌你说咱傻的说"
|
||||||
|
],
|
||||||
|
"蹭": [
|
||||||
|
"唔...你,这也是禁止事项哦→_→",
|
||||||
|
"嗯..好舒服呢",
|
||||||
|
"不要啊好痒的",
|
||||||
|
"不要过来啦讨厌!!!∑(°Д°ノ)ノ"
|
||||||
|
],
|
||||||
|
"裸体": [
|
||||||
|
"下流!",
|
||||||
|
"Hentai!",
|
||||||
|
"喂?妖妖灵吗?这里有一只大变态!",
|
||||||
|
"エッチ!"
|
||||||
|
],
|
||||||
|
"贴贴": [
|
||||||
|
"贴什么贴.....只......只能......一下哦!",
|
||||||
|
"贴...贴贴(靠近)",
|
||||||
|
"蹭蹭…你以为咱会这么说吗!baka死宅快到一边去啦!"
|
||||||
|
],
|
||||||
|
"老婆": [
|
||||||
|
"咱和你谈婚论嫁是不是还太早了一点呢?",
|
||||||
|
"咱在呢(ノ>ω<)ノ",
|
||||||
|
"见谁都是一口一个老婆的人,要不要把你也变成女孩子呢?(*-`ω´-)✄",
|
||||||
|
"神经病,凡是美少女都是你老婆吗?",
|
||||||
|
"嘛嘛~本喵才不是你的老婆呢",
|
||||||
|
"你黐线,凡是美少女都系你老婆啊?"
|
||||||
|
],
|
||||||
|
"抱": [
|
||||||
|
"诶嘿~(钻进你怀中)",
|
||||||
|
"o(*////▽////*)q",
|
||||||
|
"只能一会哦(张开双手)",
|
||||||
|
"你就像个孩子一样呢...摸摸头(>^ω^<)抱一下~你会舒服些吗?",
|
||||||
|
"嘛,真是拿你没办法呢,就一会儿哦",
|
||||||
|
"抱住不忍心放开",
|
||||||
|
"嗯嗯,抱抱~",
|
||||||
|
"抱一下~嘿w",
|
||||||
|
"抱抱ヾ(@^▽^@)ノ",
|
||||||
|
"喵呜~w(扑进怀里,瘫软"
|
||||||
|
],
|
||||||
|
"亲亲": [
|
||||||
|
"啊,好害羞啊,那,那只能亲一下哦,mua(⑅˃◡˂⑅)",
|
||||||
|
"亲~",
|
||||||
|
"啾~唔…不要总伸进来啊!",
|
||||||
|
"你怎么这么熟练呢?明明是咱先的",
|
||||||
|
"(〃ノωノ)亲…亲一个…啾w",
|
||||||
|
"(脸红)就只有这一次哦~你"
|
||||||
|
],
|
||||||
|
"草一下": [
|
||||||
|
"一下也不行!",
|
||||||
|
"想都不要想!",
|
||||||
|
"咬断!"
|
||||||
|
],
|
||||||
|
"一下": [
|
||||||
|
"一下也不行!"
|
||||||
|
],
|
||||||
|
"啪一下": [
|
||||||
|
"不可啪",
|
||||||
|
"不可以……你不可以做这种事情"
|
||||||
|
],
|
||||||
|
"咬一下": [
|
||||||
|
"啊呜~(反咬一口)",
|
||||||
|
"不可以咬咱,咱会痛的QAQ",
|
||||||
|
"不要啦。咱怕疼",
|
||||||
|
"你是说咬呢……还是说……咬♂️呢?",
|
||||||
|
"不要啦!很痛的!!(QAQ)"
|
||||||
|
],
|
||||||
|
"操": [
|
||||||
|
"(害怕)咱是不是应该报警呢"
|
||||||
|
],
|
||||||
|
"123": [
|
||||||
|
"boom!你有没有被咱吓到?",
|
||||||
|
"木头人~你不许动>w<",
|
||||||
|
"上山打老虎,老虎没打到\n咱来凑数——嗷呜嗷呜┗|`O′|┛嗷~~"
|
||||||
|
],
|
||||||
|
"进去": [
|
||||||
|
"不让!"
|
||||||
|
],
|
||||||
|
"调教": [
|
||||||
|
"总感觉你在欺负咱呢,对咱说调教什么的",
|
||||||
|
"啊!竟然在大街上明目张胆太过分啦!",
|
||||||
|
"你脑子里总是想着调教什么的,真是变态呢"
|
||||||
|
],
|
||||||
|
"内衣": [
|
||||||
|
"内...内衣才不给你看!(///////)",
|
||||||
|
"突然问这个干什么?",
|
||||||
|
"噫…你这个死变态想干嘛!居然想叫咱做这种事,死宅真恶心!快离我远点,我怕你污染到周围空气了(嫌弃脸)"
|
||||||
|
],
|
||||||
|
"摸头": [
|
||||||
|
"喂喂...不要停下来啊",
|
||||||
|
"欸...感觉..痒痒的呢",
|
||||||
|
"唔... 手...好温暖呢.....就像是......新出炉的蛋糕",
|
||||||
|
"走开啦,黑羽喵说过,被摸头会长不高的啦~~~",
|
||||||
|
"呜姆咪~~...好...好的说喵~...(害羞,猫耳往下压,任由"
|
||||||
|
],
|
||||||
|
"原味": [
|
||||||
|
"(/ω\)你真的要么……?记得还给咱~还有奶油爆米花(//??//)说好了呦~!"
|
||||||
|
],
|
||||||
|
"搓搓": [
|
||||||
|
"在搓哪里呢,,Ծ‸Ծ,,",
|
||||||
|
"呜,脸好疼呀...QAQ",
|
||||||
|
"不可以搓咱!"
|
||||||
|
],
|
||||||
|
"捏捏": [
|
||||||
|
"咱的脸...快捏红啦...快放手呀QAQ",
|
||||||
|
"晃休啦,咱要型气了o(>﹏<)o",
|
||||||
|
"躲开",
|
||||||
|
"疼...你快放手",
|
||||||
|
"快点给我放开啦!",
|
||||||
|
"唔……好痛!你这个baka在干什么…快给咱放开!唔……"
|
||||||
|
],
|
||||||
|
"挤挤": [
|
||||||
|
"哎呀~你不要挤咱啊(红着脸挤在你怀里)"
|
||||||
|
],
|
||||||
|
"呐": [
|
||||||
|
"嗯?咱在哟~你怎么了呀OAO",
|
||||||
|
"呐呐呐~",
|
||||||
|
"嗯?你有什么事吗?"
|
||||||
|
],
|
||||||
|
"胖次": [
|
||||||
|
"(*/ω\*)hentai",
|
||||||
|
"透明的",
|
||||||
|
"粉...粉白条纹...(羞)",
|
||||||
|
"轻轻地脱下,给你~",
|
||||||
|
"你想看咱的胖次吗?噫,四斋蒸鹅心......",
|
||||||
|
"(掀裙)今天……是…白,白色的呢……请温柔对她……",
|
||||||
|
"这种东西当然不能给你啦!",
|
||||||
|
"咱才不会给你呢",
|
||||||
|
"hentai,咱才不会跟你聊和胖…胖次有关的话题呢!",
|
||||||
|
"今天……今天是蓝白色的",
|
||||||
|
"今……今天只有创口贴噢",
|
||||||
|
"你的胖次什么颜色?",
|
||||||
|
"噫…你这个死变态想干嘛!居然想叫咱做这种事,死宅真恶心!快离我远点,我怕你污染到周围空气了(嫌弃脸)",
|
||||||
|
"可爱吗?你喜欢的话,摸一下……也可以哦"
|
||||||
|
],
|
||||||
|
"内裤": [
|
||||||
|
"今天……没有穿……有没有心动呀",
|
||||||
|
"粉...粉白条纹...(羞)",
|
||||||
|
"你这个大变态,咱才不要",
|
||||||
|
"可爱吗?你喜欢的话,摸一下……也可以哦"
|
||||||
|
],
|
||||||
|
"ghs": [
|
||||||
|
"是的呢(点头点头)"
|
||||||
|
],
|
||||||
|
"批": [
|
||||||
|
"你在说什么呀,再这样,咱就不理你了!"
|
||||||
|
],
|
||||||
|
"kkp": [
|
||||||
|
"你在说什么呀,再这样,咱就不理你了!"
|
||||||
|
],
|
||||||
|
"咕": [
|
||||||
|
"咕咕咕是要被当成鸽子炖的哦(:з」∠)_",
|
||||||
|
"咕咕咕"
|
||||||
|
],
|
||||||
|
"骚": [
|
||||||
|
"说这种话咱会生气的"
|
||||||
|
],
|
||||||
|
"喜欢": [
|
||||||
|
"最喜欢你了,需要暖床吗?",
|
||||||
|
"当然是你啦",
|
||||||
|
"咱也是,非常喜欢你~",
|
||||||
|
"那么大!(张开手画圆),丫!手不够长。QAQ 咱真的最喜欢你了~",
|
||||||
|
"不可以哦,只可以喜欢咱一个人",
|
||||||
|
"突然说这种事...",
|
||||||
|
"喜欢⁄(⁄⁄•⁄ω⁄•⁄⁄)⁄咱最喜欢你了",
|
||||||
|
"咱也喜欢你哦",
|
||||||
|
"好啦好啦,咱知道了",
|
||||||
|
"有人喜欢咱,咱觉得很幸福",
|
||||||
|
"诶嘿嘿,好高兴"
|
||||||
|
],
|
||||||
|
"suki": [
|
||||||
|
"最喜欢你了,需要暖床吗?",
|
||||||
|
"当然是你啦",
|
||||||
|
"咱也是,非常喜欢你~",
|
||||||
|
"那么大!(张开手画圆),丫!手不够长。QAQ 咱真的最喜欢你了~",
|
||||||
|
"不可以哦,只可以喜欢咱一个人",
|
||||||
|
"突然说这种事...",
|
||||||
|
"喜欢⁄(⁄⁄•⁄ω⁄•⁄⁄)⁄咱最喜欢你了",
|
||||||
|
"咱也喜欢你哦",
|
||||||
|
"好啦好啦,咱知道了",
|
||||||
|
"有人喜欢咱,咱觉得很幸福",
|
||||||
|
"诶嘿嘿,好高兴"
|
||||||
|
],
|
||||||
|
"好き": [
|
||||||
|
"最喜欢你了,需要暖床吗?",
|
||||||
|
"当然是你啦",
|
||||||
|
"咱也是,非常喜欢你~",
|
||||||
|
"那么大!(张开手画圆),丫!手不够长。QAQ 咱真的最喜欢你了~",
|
||||||
|
"不可以哦,只可以喜欢咱一个人",
|
||||||
|
"突然说这种事...",
|
||||||
|
"喜欢⁄(⁄⁄•⁄ω⁄•⁄⁄)⁄咱最喜欢你了",
|
||||||
|
"咱也喜欢你哦",
|
||||||
|
"好啦好啦,咱知道了",
|
||||||
|
"有人喜欢咱,咱觉得很幸福",
|
||||||
|
"诶嘿嘿,好高兴"
|
||||||
|
],
|
||||||
|
"不能": [
|
||||||
|
"虽然很遗憾,那算了吧。"
|
||||||
|
],
|
||||||
|
"砸了": [
|
||||||
|
"不可以这么粗暴的对待它们!"
|
||||||
|
],
|
||||||
|
"透": [
|
||||||
|
"来啊来啊有本事就先插破屏幕啊",
|
||||||
|
"那你就先捅破屏幕啊baka",
|
||||||
|
"不给你一耳光你都不知道咱的厉害"
|
||||||
|
],
|
||||||
|
"口我": [
|
||||||
|
"再伸过来就帮你切掉",
|
||||||
|
"咱才不呢!baka你居然想叫本小姐干那种事情,哼(つд⊂)(生气)"
|
||||||
|
],
|
||||||
|
"草我": [
|
||||||
|
"这时候应该喊666吧..咱这么思考着..",
|
||||||
|
"!!哼!baka你居然敢叫咱做这种事情?!讨厌讨厌讨厌!(▼皿▼#)"
|
||||||
|
],
|
||||||
|
"自慰": [
|
||||||
|
"这个世界的人类还真是恶心呢。",
|
||||||
|
"咱才不想讨论那些恶心的事情呢。",
|
||||||
|
"咱才不呢!baka你居然想叫本小姐干那种事情,哼(つд⊂)(生气)",
|
||||||
|
"!!哼!baka你居然敢叫咱做这种事情?!讨厌讨厌讨厌!(▼皿▼#)"
|
||||||
|
],
|
||||||
|
"onani": [
|
||||||
|
"这个世界的人类还真是恶心呢。",
|
||||||
|
"咱才不想讨论那些恶心的事情呢。",
|
||||||
|
"咱才不呢!baka你居然想叫本小姐干那种事情,哼(つд⊂)(生气)",
|
||||||
|
"!!哼!baka你居然敢叫咱做这种事情?!讨厌讨厌讨厌!(▼皿▼#)"
|
||||||
|
],
|
||||||
|
"オナニー": [
|
||||||
|
"这个世界的人类还真是恶心呢。",
|
||||||
|
"咱才不想讨论那些恶心的事情呢。",
|
||||||
|
"咱才不呢!baka你居然想叫本小姐干那种事情,哼(つд⊂)(生气)",
|
||||||
|
"!!哼!baka你居然敢叫咱做这种事情?!讨厌讨厌讨厌!(▼皿▼#)"
|
||||||
|
],
|
||||||
|
"炸了": [
|
||||||
|
"你才炸了!",
|
||||||
|
"才没有呢",
|
||||||
|
"咱好好的呀"
|
||||||
|
],
|
||||||
|
"色图": [
|
||||||
|
"天天色图色图的,今天就把你变成色图!",
|
||||||
|
"咱没有色图",
|
||||||
|
"哈?你的脑子一天都在想些什么呢,咱才没有这种东西啦。"
|
||||||
|
],
|
||||||
|
"涩图": [
|
||||||
|
"天天色图色图的,今天就把你变成色图!",
|
||||||
|
"咱没有色图",
|
||||||
|
"哈?你的脑子一天都在想些什么呢,咱才没有这种东西啦。"
|
||||||
|
],
|
||||||
|
"告白": [
|
||||||
|
"欸?你要向咱告白吗..好害羞..",
|
||||||
|
"诶!?这么突然!?人家还......还没做好心理准备呢(脸红)"
|
||||||
|
],
|
||||||
|
"对不起": [
|
||||||
|
"嗯,咱已经原谅你了呢(笑)",
|
||||||
|
"道歉的时候要露出胸部,这是常识"
|
||||||
|
],
|
||||||
|
"回来": [
|
||||||
|
"欢迎回来~",
|
||||||
|
"欢迎回来,你想喝茶吗?咱去给你沏~",
|
||||||
|
"欢迎回来,咱等你很久了~",
|
||||||
|
"你回来啦,是先吃饭呢还是先洗澡呢或者是●先●吃●咱●——呢(///^.^///)"
|
||||||
|
],
|
||||||
|
"吻": [
|
||||||
|
"你太突然了,咱还没有心理准备",
|
||||||
|
"公共场合不要这样子了啦",
|
||||||
|
"才...才没有感觉呢!可没有下次了,知道了吗!哼~"
|
||||||
|
],
|
||||||
|
"软": [
|
||||||
|
"软乎乎的呢(,,・ω・,,)"
|
||||||
|
],
|
||||||
|
"柔软": [
|
||||||
|
"(脸红)请,请不要说这么让人害羞的话呀……"
|
||||||
|
],
|
||||||
|
"壁咚": [
|
||||||
|
"呀!不要啊!等一...下~",
|
||||||
|
"呜...不要啦!不要戏弄咱~",
|
||||||
|
"不要这样子啦(*/ω\*)",
|
||||||
|
"太....太近啦。",
|
||||||
|
"你要壁咚咱吗?好害羞(灬ꈍ εꈍ灬)",
|
||||||
|
"为什么要把咱按在墙上呢?",
|
||||||
|
"呜哇(/ω\)…快…快放开咱!!",
|
||||||
|
"放开我,不然我揍你了!放开我!放…开我~",
|
||||||
|
"??????咱只是默默地抬起了膝盖",
|
||||||
|
"啊.....你...你要干什么?!走开.....走开啦大hentai!一巴掌拍飞!(╯‵□′)╯︵┻━┻"
|
||||||
|
],
|
||||||
|
"掰开": [
|
||||||
|
"噫…你这个死肥宅又想让咱干什么污秽的事情,真是恶心,离咱远点好吗(嫌弃)",
|
||||||
|
"ヽ(#`Д´)ノ在干什么呢"
|
||||||
|
],
|
||||||
|
"女友": [
|
||||||
|
"女友什么的,咱才不承认呢!"
|
||||||
|
],
|
||||||
|
"是": [
|
||||||
|
"是什么是,你个笨蛋",
|
||||||
|
"总感觉你在敷衍呢..."
|
||||||
|
],
|
||||||
|
"喵": [
|
||||||
|
"诶~~小猫咪不要害怕呦,在姐姐怀里乖乖的,姐姐带你回去哦。",
|
||||||
|
"不要这么卖萌啦~咱也不知道怎么办丫",
|
||||||
|
"摸头⊙ω⊙",
|
||||||
|
"汪汪汪!",
|
||||||
|
"嗷~喵~",
|
||||||
|
"喵~?喵呜~w"
|
||||||
|
],
|
||||||
|
"嗷呜": [
|
||||||
|
"嗷呜嗷呜嗷呜...恶龙咆哮┗|`O′|┛"
|
||||||
|
],
|
||||||
|
"叫": [
|
||||||
|
"喵呜~",
|
||||||
|
"嗷呜嗷呜嗷呜...恶龙咆哮┗|`O′|┛"
|
||||||
|
],
|
||||||
|
"拜": [
|
||||||
|
"拜拜~(ノ ̄▽ ̄)",
|
||||||
|
"拜拜,路上小心~要早点回来陪咱玩哦~",
|
||||||
|
"~\\(≧▽≦)/~拜拜,下次见喽!"
|
||||||
|
],
|
||||||
|
"佬": [
|
||||||
|
"不是巨佬,是萌新"
|
||||||
|
],
|
||||||
|
"awsl": [
|
||||||
|
"你别死啊!(抱住使劲晃)",
|
||||||
|
"你别死啊!咱又要孤单一个人了QAQ"
|
||||||
|
],
|
||||||
|
"臭": [
|
||||||
|
"哪里有臭味?(疑惑)",
|
||||||
|
"快捏住鼻子"
|
||||||
|
],
|
||||||
|
"香": [
|
||||||
|
"咱闻不到呢⊙ω⊙"
|
||||||
|
],
|
||||||
|
"腿": [
|
||||||
|
"嗯?!不要啊...请停下来!",
|
||||||
|
"不给摸,再这样咱要生气了ヽ( ̄д ̄;)ノ",
|
||||||
|
"你好恶心啊,讨厌!",
|
||||||
|
"你难道是足控?",
|
||||||
|
"就让你摸一会哟~(。??ω??。)…",
|
||||||
|
"呜哇!好害羞...不过既然是你的话,是没关系的哦",
|
||||||
|
"不可以玩咱的大腿啦",
|
||||||
|
"你就那么喜欢大腿吗?唔...有点害羞呢......"
|
||||||
|
],
|
||||||
|
"脚": [
|
||||||
|
"咿呀……不要……",
|
||||||
|
"不要ヽ(≧Д≦)ノ好痒(ಡωಡ),人家的丝袜都要漏了",
|
||||||
|
"不要ヽ(≧Д≦)ノ好痒(ಡωಡ)",
|
||||||
|
"好痒(把脚伸出去)"
|
||||||
|
],
|
||||||
|
"胸": [
|
||||||
|
"不要啦ヽ(≧Д≦)ノ",
|
||||||
|
"(-`ェ´-╬)",
|
||||||
|
"(•̀へ •́ ╮ ) 怎么能对咱做这种事情",
|
||||||
|
"你好恶心啊,讨厌!",
|
||||||
|
"你的眼睛在看哪里!",
|
||||||
|
"就让你摸一会哟~(。??ω??。)…",
|
||||||
|
"请不要这样先生,你想剁手吗?"
|
||||||
|
],
|
||||||
|
"脸": [
|
||||||
|
"唔!不可以随便摸咱的脸啦!",
|
||||||
|
"非洲血统是没法改变的呢(笑)",
|
||||||
|
"啊姆!(含手指)",
|
||||||
|
"好舒服呢(脸红)",
|
||||||
|
"请不要放开手啦//A//"
|
||||||
|
],
|
||||||
|
"头发": [
|
||||||
|
"没问题,请尽情的摸吧",
|
||||||
|
"发型要乱…乱了啦(脸红)",
|
||||||
|
"就让你摸一会哟~(。??ω??。)…"
|
||||||
|
],
|
||||||
|
"手": [
|
||||||
|
"爪爪",
|
||||||
|
"//A//"
|
||||||
|
],
|
||||||
|
"pr": [
|
||||||
|
"咿呀……不要……",
|
||||||
|
"...变态!!",
|
||||||
|
"不要啊(脸红)",
|
||||||
|
"呀,不要太过分了啊~",
|
||||||
|
"当然可以(///)",
|
||||||
|
"呀,不要太过分了啊~"
|
||||||
|
],
|
||||||
|
"舔": [
|
||||||
|
"呀,不要太过分了啊~",
|
||||||
|
"要...要融化了啦>╱╱╱<",
|
||||||
|
"不可以哦",
|
||||||
|
"呀,不要太过分了啊~"
|
||||||
|
],
|
||||||
|
"舔耳": [
|
||||||
|
"喵!好痒啊 不要这样子啦"
|
||||||
|
],
|
||||||
|
"穴": [
|
||||||
|
"你这么问很失礼呢!咱是粉粉嫩嫩的!",
|
||||||
|
"不行那里不可以(´///ω/// `)",
|
||||||
|
"不可以总摸的哦,不然的话,咱会想那个的wwww",
|
||||||
|
"ヽ(#`Д´)ノ在干什么呢"
|
||||||
|
],
|
||||||
|
"腰": [
|
||||||
|
"咱给你按摩一下吧~",
|
||||||
|
"快松手,咱好害羞呀..",
|
||||||
|
"咱又不是猫,你不要搂着咱啦",
|
||||||
|
"让咱来帮你捏捏吧!"
|
||||||
|
],
|
||||||
|
"诶嘿嘿": [
|
||||||
|
"又在想什么H的事呢(脸红)",
|
||||||
|
"诶嘿嘿(〃'▽'〃)",
|
||||||
|
"你傻笑什么呢,摸摸"
|
||||||
|
],
|
||||||
|
"可爱": [
|
||||||
|
"诶嘿嘿(〃'▽'〃)",
|
||||||
|
"才……才不是为了你呢!你不要多想哦!",
|
||||||
|
"才,才没有高兴呢!哼~",
|
||||||
|
"咱是世界上最可爱的",
|
||||||
|
"唔...谢谢你夸奖~0///0"
|
||||||
|
],
|
||||||
|
"扭蛋": [
|
||||||
|
"铛铛铛——你抽到了咱呢",
|
||||||
|
"嘿~恭喜抽中空气一份呢"
|
||||||
|
],
|
||||||
|
"鼻子": [
|
||||||
|
"啊——唔...没什么...阿嚏!ヽ(*。>Д<)o゜"
|
||||||
|
],
|
||||||
|
"眼睛": [
|
||||||
|
"就如同咱的眼睛一样,能看透人的思想哦wwww忽闪忽闪的,诶嘿嘿~"
|
||||||
|
],
|
||||||
|
"色气": [
|
||||||
|
"咱才不色气呢,一定是你看错了!"
|
||||||
|
],
|
||||||
|
"推": [
|
||||||
|
"逆推",
|
||||||
|
"唔~好害羞呢",
|
||||||
|
"你想对咱做什么呢...(捂脸)"
|
||||||
|
],
|
||||||
|
"床": [
|
||||||
|
"快来吧",
|
||||||
|
"男女不同床,可没有下次了。(鼓脸",
|
||||||
|
"嗯?咱吗…没办法呢。只有这一次哦……",
|
||||||
|
"哎?!!!给你暖床……也不是不行啦。(脸红)"
|
||||||
|
],
|
||||||
|
"手冲": [
|
||||||
|
"手冲什么的是不可以的哦"
|
||||||
|
],
|
||||||
|
"饿": [
|
||||||
|
"请问主人是想先吃饭,还是先吃我喵?~"
|
||||||
|
],
|
||||||
|
"变": [
|
||||||
|
"猫猫不会变呐(弱气,害羞",
|
||||||
|
"呜...呜姆...喵喵来报恩了喵...(害羞"
|
||||||
|
],
|
||||||
|
"敲": [
|
||||||
|
"喵呜~",
|
||||||
|
"唔~",
|
||||||
|
"脑瓜疼~呜姆> <",
|
||||||
|
"欸喵,好痛的说..."
|
||||||
|
],
|
||||||
|
"爬": [
|
||||||
|
"惹~呜~怎么爬呢~",
|
||||||
|
"呜...(弱弱爬走"
|
||||||
|
],
|
||||||
|
"怕": [
|
||||||
|
"不怕~(蹭蹭你姆~"
|
||||||
|
],
|
||||||
|
"冲": [
|
||||||
|
"呜,冲不动惹~",
|
||||||
|
"哭唧唧~冲不出来了惹~"
|
||||||
|
],
|
||||||
|
"射了": [
|
||||||
|
"呜咿~!?(惊,害羞",
|
||||||
|
"还不可以射哦~"
|
||||||
|
],
|
||||||
|
"不穿衣服": [
|
||||||
|
"呜姆~!(惊吓,害羞)变...变态喵~~~!"
|
||||||
|
],
|
||||||
|
"迫害": [
|
||||||
|
"不...不要...不要...呜呜呜...(害怕,抽泣"
|
||||||
|
],
|
||||||
|
"猫粮": [
|
||||||
|
"呜咿姆~!?(惊,接住吃",
|
||||||
|
"呜姆~!(惊,害羞)呜...谢...谢谢主人..喵...(脸红,嚼嚼嚼,开心",
|
||||||
|
"呜?谢谢喵~~(嚼嚼嚼,嘎嘣脆)"
|
||||||
|
],
|
||||||
|
"揪尾巴": [
|
||||||
|
"呜哇咿~~~!(惊吓,疼痛地捂住尾巴",
|
||||||
|
"呜咿咿咿~~~!!哇啊咿~~~!(惊慌,惨叫,挣扎",
|
||||||
|
"呜咿...(瘫倒,无神,被",
|
||||||
|
"呜姆咿~~~!(惊吓,惨叫,捂尾巴,发抖",
|
||||||
|
"呜哇咿~~~!!!(惊吓,颤抖,娇叫,捂住尾巴,双腿发抖"
|
||||||
|
],
|
||||||
|
"薄荷": [
|
||||||
|
"咪呜~!喵~...喵~姆~...(高兴地嗅闻",
|
||||||
|
"呜...呜咿~~!咿...姆...(呜咽,渐渐瘫软,意识模糊",
|
||||||
|
"(小嘴被猫薄荷塞满了,呜咽",
|
||||||
|
"喵~...喵~...咪...咪呜姆~...嘶哈嘶哈...喵哈...喵哈...嘶哈...喵...(眼睛逐渐迷离,瘫软在地上,嘴角流口水,吸猫薄荷吸到意识模糊",
|
||||||
|
"呜姆咪~!?(惊)喵呜~!(兴奋地扑到猫薄荷上面",
|
||||||
|
"呜姆~!(惊,害羞)呜...谢...谢谢你..喵...(脸红,轻轻叼住,嚼嚼嚼,开心"
|
||||||
|
],
|
||||||
|
"边揪尾巴边猫薄荷": [
|
||||||
|
"呜...呜咿~~!咿...姆...(呜咽,渐渐瘫软,意识模糊"
|
||||||
|
],
|
||||||
|
"早": [
|
||||||
|
"早喵~",
|
||||||
|
"早上好的说~~",
|
||||||
|
"欸..早..早上好(揉眼睛"
|
||||||
|
],
|
||||||
|
"晚安": [
|
||||||
|
"晚安好梦哟~",
|
||||||
|
"欸,晚安的说"
|
||||||
|
],
|
||||||
|
"揉": [
|
||||||
|
"是是,想怎么揉就怎么揉啊!?来用力抓啊!?我就是特别允许你这么做了!请!?",
|
||||||
|
"快停下,咱的头发又乱啦(??????︿??????)",
|
||||||
|
"你快放手啦,咱还在工作呢",
|
||||||
|
"戳戳你肚子",
|
||||||
|
"你想揉就揉吧..就这一次哦?"
|
||||||
|
],
|
||||||
|
"榨": [
|
||||||
|
"是专门负责榨果汁的小姐姐嘛?(´・ω・`)",
|
||||||
|
"那咱就把你放进榨汁机里了哦?",
|
||||||
|
"咱又不是榨汁姬(/‵Д′)/~ ╧╧"
|
||||||
|
],
|
||||||
|
"掐": [
|
||||||
|
"你讨厌!又掐澪的脸",
|
||||||
|
"晃休啦,咱要型气了啦!!o(>﹏<)o",
|
||||||
|
"(一只手拎起你)这么鶸还想和咱抗衡,还差得远呢!"
|
||||||
|
],
|
||||||
|
"奶子": [
|
||||||
|
"下流!",
|
||||||
|
"对咱说这种话,你真是太过分了",
|
||||||
|
"咿呀~好奇怪的感觉(>_<)",
|
||||||
|
"(打你)快放手,不可以随便摸人家的胸部啦!"
|
||||||
|
],
|
||||||
|
"嫩": [
|
||||||
|
"很可爱吧(๑•̀ω•́)ノ",
|
||||||
|
"唔,你指的是什么呀"
|
||||||
|
],
|
||||||
|
"蹭蹭": [
|
||||||
|
"(按住你的头)好痒呀 不要啦",
|
||||||
|
"嗯..好舒服呢",
|
||||||
|
"呀~好痒啊~哈哈~,停下来啦,哈哈哈",
|
||||||
|
"(害羞)"
|
||||||
|
],
|
||||||
|
"牵手": [
|
||||||
|
"只许牵一下哦",
|
||||||
|
"嗯!好的你~(伸手)",
|
||||||
|
"你的手有些凉呢,让澪来暖一暖吧。"
|
||||||
|
],
|
||||||
|
"握手": [
|
||||||
|
"你的手真暖和呢",
|
||||||
|
"举爪"
|
||||||
|
],
|
||||||
|
"拍照": [
|
||||||
|
"那就拜托你啦~请把咱拍得更可爱一些吧w"
|
||||||
|
],
|
||||||
|
"w": [
|
||||||
|
"www"
|
||||||
|
],
|
||||||
|
"www": [
|
||||||
|
"有什么好笑的吗?",
|
||||||
|
"草"
|
||||||
|
],
|
||||||
|
"太二了": [
|
||||||
|
"哼,你不也是吗`(*>﹏<*)′",
|
||||||
|
"人家只是想和你一起玩耍的说(≧∀≦)ゞ",
|
||||||
|
"好..冷漠的说,大坏蛋再也不理你了!",
|
||||||
|
"不听不听不听,反弹ヾ(≧▽≦*)o"
|
||||||
|
]
|
||||||
|
}
|
||||||
BIN
models/__pycache__/bag_user.cpython-38.pyc
Normal file
BIN
models/__pycache__/bag_user.cpython-38.pyc
Normal file
Binary file not shown.
BIN
models/__pycache__/bag_user.cpython-39.pyc
Normal file
BIN
models/__pycache__/bag_user.cpython-39.pyc
Normal file
Binary file not shown.
BIN
models/__pycache__/ban_user.cpython-38.pyc
Normal file
BIN
models/__pycache__/ban_user.cpython-38.pyc
Normal file
Binary file not shown.
BIN
models/__pycache__/ban_user.cpython-39.pyc
Normal file
BIN
models/__pycache__/ban_user.cpython-39.pyc
Normal file
Binary file not shown.
BIN
models/__pycache__/buff_price.cpython-38.pyc
Normal file
BIN
models/__pycache__/buff_price.cpython-38.pyc
Normal file
Binary file not shown.
BIN
models/__pycache__/buff_price.cpython-39.pyc
Normal file
BIN
models/__pycache__/buff_price.cpython-39.pyc
Normal file
Binary file not shown.
BIN
models/__pycache__/count_user.cpython-38.pyc
Normal file
BIN
models/__pycache__/count_user.cpython-38.pyc
Normal file
Binary file not shown.
BIN
models/__pycache__/count_user.cpython-39.pyc
Normal file
BIN
models/__pycache__/count_user.cpython-39.pyc
Normal file
Binary file not shown.
BIN
models/__pycache__/friend_user.cpython-38.pyc
Normal file
BIN
models/__pycache__/friend_user.cpython-38.pyc
Normal file
Binary file not shown.
BIN
models/__pycache__/friend_user.cpython-39.pyc
Normal file
BIN
models/__pycache__/friend_user.cpython-39.pyc
Normal file
Binary file not shown.
BIN
models/__pycache__/group_info.cpython-38.pyc
Normal file
BIN
models/__pycache__/group_info.cpython-38.pyc
Normal file
Binary file not shown.
BIN
models/__pycache__/group_info.cpython-39.pyc
Normal file
BIN
models/__pycache__/group_info.cpython-39.pyc
Normal file
Binary file not shown.
BIN
models/__pycache__/group_member_info.cpython-38.pyc
Normal file
BIN
models/__pycache__/group_member_info.cpython-38.pyc
Normal file
Binary file not shown.
BIN
models/__pycache__/group_member_info.cpython-39.pyc
Normal file
BIN
models/__pycache__/group_member_info.cpython-39.pyc
Normal file
Binary file not shown.
BIN
models/__pycache__/group_remind.cpython-38.pyc
Normal file
BIN
models/__pycache__/group_remind.cpython-38.pyc
Normal file
Binary file not shown.
BIN
models/__pycache__/group_remind.cpython-39.pyc
Normal file
BIN
models/__pycache__/group_remind.cpython-39.pyc
Normal file
Binary file not shown.
BIN
models/__pycache__/level_user.cpython-38.pyc
Normal file
BIN
models/__pycache__/level_user.cpython-38.pyc
Normal file
Binary file not shown.
BIN
models/__pycache__/level_user.cpython-39.pyc
Normal file
BIN
models/__pycache__/level_user.cpython-39.pyc
Normal file
Binary file not shown.
BIN
models/__pycache__/open_cases_user.cpython-38.pyc
Normal file
BIN
models/__pycache__/open_cases_user.cpython-38.pyc
Normal file
Binary file not shown.
BIN
models/__pycache__/open_cases_user.cpython-39.pyc
Normal file
BIN
models/__pycache__/open_cases_user.cpython-39.pyc
Normal file
Binary file not shown.
BIN
models/__pycache__/sigin_group_user.cpython-38.pyc
Normal file
BIN
models/__pycache__/sigin_group_user.cpython-38.pyc
Normal file
Binary file not shown.
BIN
models/__pycache__/sigin_group_user.cpython-39.pyc
Normal file
BIN
models/__pycache__/sigin_group_user.cpython-39.pyc
Normal file
Binary file not shown.
190
models/bag_user.py
Normal file
190
models/bag_user.py
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
|
||||||
|
from services.db_context import db
|
||||||
|
|
||||||
|
|
||||||
|
class UserBag(db.Model):
|
||||||
|
__tablename__ = 'bag_users'
|
||||||
|
|
||||||
|
id = db.Column(db.Integer(), primary_key=True)
|
||||||
|
user_qq = db.Column(db.BigInteger(), nullable=False)
|
||||||
|
belonging_group = db.Column(db.BigInteger(), nullable=False)
|
||||||
|
gold = db.Column(db.Integer(), default=100)
|
||||||
|
props = db.Column(db.TEXT(), nullable=False, default="")
|
||||||
|
spend_total_gold = db.Column(db.Integer(), default=0)
|
||||||
|
get_total_gold = db.Column(db.Integer(), default=0)
|
||||||
|
get_today_gold = db.Column(db.Integer(), default=0)
|
||||||
|
spend_today_gold = db.Column(db.Integer(), default=0)
|
||||||
|
|
||||||
|
_idx1 = db.Index('bag_group_users_idx1', 'user_qq', 'belonging_group', unique=True)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def get_my_total_gold(cls, user_qq: int, belonging_group: int) -> str:
|
||||||
|
query = cls.query.where(
|
||||||
|
(cls.user_qq == user_qq) & (cls.belonging_group == belonging_group)
|
||||||
|
)
|
||||||
|
user = await query.gino.first()
|
||||||
|
if not user:
|
||||||
|
user = await cls.create(
|
||||||
|
user_qq=user_qq,
|
||||||
|
belonging_group=belonging_group,
|
||||||
|
)
|
||||||
|
return f'当前金币:{user.gold}\n今日获取金币:{user.get_today_gold}\n今日花费金币:{user.spend_today_gold}' \
|
||||||
|
f'\n今日收益:{user.get_today_gold - user.spend_today_gold}' \
|
||||||
|
f'\n总赚取金币:{user.get_total_gold}\n总花费金币:{user.spend_total_gold}'
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def get_gold(cls, user_qq: int, belonging_group: int) -> int:
|
||||||
|
query = cls.query.where(
|
||||||
|
(cls.user_qq == user_qq) & (cls.belonging_group == belonging_group)
|
||||||
|
)
|
||||||
|
user = await query.gino.first()
|
||||||
|
if user:
|
||||||
|
return user.gold
|
||||||
|
else:
|
||||||
|
await cls.create(
|
||||||
|
user_qq=user_qq,
|
||||||
|
belonging_group=belonging_group,
|
||||||
|
)
|
||||||
|
return 100
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def get_props(cls, user_qq: int, belonging_group: int) -> str:
|
||||||
|
query = cls.query.where(
|
||||||
|
(cls.user_qq == user_qq) & (cls.belonging_group == belonging_group)
|
||||||
|
)
|
||||||
|
user = await query.gino.first()
|
||||||
|
if user:
|
||||||
|
return user.props
|
||||||
|
else:
|
||||||
|
await cls.create(
|
||||||
|
user_qq=user_qq,
|
||||||
|
belonging_group=belonging_group,
|
||||||
|
)
|
||||||
|
return ''
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def add_glod(cls, user_qq: int, belonging_group: int, num: int) -> bool:
|
||||||
|
query = cls.query.where(
|
||||||
|
(cls.user_qq == user_qq) & (cls.belonging_group == belonging_group)
|
||||||
|
)
|
||||||
|
query = query.with_for_update()
|
||||||
|
user = await query.gino.first()
|
||||||
|
try:
|
||||||
|
if user:
|
||||||
|
await user.update(
|
||||||
|
gold=user.gold + num,
|
||||||
|
get_total_gold=user.get_total_gold + num,
|
||||||
|
get_today_gold=user.get_today_gold + num
|
||||||
|
).apply()
|
||||||
|
else:
|
||||||
|
await cls.create(
|
||||||
|
user_qq=user_qq,
|
||||||
|
belonging_group=belonging_group,
|
||||||
|
gold=100 + num,
|
||||||
|
get_total_gold=num,
|
||||||
|
get_today_gold=num,
|
||||||
|
)
|
||||||
|
return True
|
||||||
|
except Exception:
|
||||||
|
return False
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def spend_glod(cls, user_qq: int, belonging_group: int, num: int) -> bool:
|
||||||
|
query = cls.query.where(
|
||||||
|
(cls.user_qq == user_qq) & (cls.belonging_group == belonging_group)
|
||||||
|
)
|
||||||
|
query = query.with_for_update()
|
||||||
|
user = await query.gino.first()
|
||||||
|
try:
|
||||||
|
if user:
|
||||||
|
await user.update(
|
||||||
|
gold=user.gold - num,
|
||||||
|
spend_total_gold=user.spend_total_gold + num,
|
||||||
|
spend_today_gold=user.spend_today_gold + num
|
||||||
|
).apply()
|
||||||
|
else:
|
||||||
|
await cls.create(
|
||||||
|
user_qq=user_qq,
|
||||||
|
belonging_group=belonging_group,
|
||||||
|
gold=100 - num,
|
||||||
|
spend_total_gold=num,
|
||||||
|
spend_today_gold=num
|
||||||
|
)
|
||||||
|
return True
|
||||||
|
except Exception:
|
||||||
|
return False
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def add_props(cls, user_qq: int, belonging_group: int, name: str) -> bool:
|
||||||
|
query = cls.query.where(
|
||||||
|
(cls.user_qq == user_qq) & (cls.belonging_group == belonging_group)
|
||||||
|
)
|
||||||
|
query = query.with_for_update()
|
||||||
|
user = await query.gino.first()
|
||||||
|
try:
|
||||||
|
if user:
|
||||||
|
await user.update(
|
||||||
|
props=user.props + f'{name},'
|
||||||
|
).apply()
|
||||||
|
else:
|
||||||
|
await cls.create(
|
||||||
|
user_qq=user_qq,
|
||||||
|
belonging_group=belonging_group,
|
||||||
|
props=f'{name},'
|
||||||
|
)
|
||||||
|
return True
|
||||||
|
except Exception:
|
||||||
|
return False
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def del_props(cls, user_qq: int, belonging_group: int, name: str) -> bool:
|
||||||
|
query = cls.query.where(
|
||||||
|
(cls.user_qq == user_qq) & (cls.belonging_group == belonging_group)
|
||||||
|
)
|
||||||
|
query = query.with_for_update()
|
||||||
|
user = await query.gino.first()
|
||||||
|
try:
|
||||||
|
if user:
|
||||||
|
rst = ''
|
||||||
|
props = user.props
|
||||||
|
if props.find(name) != -1:
|
||||||
|
props = props.split(',')
|
||||||
|
try:
|
||||||
|
index = props.index(name)
|
||||||
|
except ValueError:
|
||||||
|
return False
|
||||||
|
props = props[:index] + props[index + 1:]
|
||||||
|
for p in props:
|
||||||
|
if p != '':
|
||||||
|
rst += p + ','
|
||||||
|
await user.update(
|
||||||
|
props=rst
|
||||||
|
).apply()
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
except Exception:
|
||||||
|
return False
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def get_user_all(cls, group_id: int = None) -> list:
|
||||||
|
user_list = []
|
||||||
|
if not group_id:
|
||||||
|
query = await cls.query.gino.all()
|
||||||
|
else:
|
||||||
|
query = await cls.query.where(
|
||||||
|
(cls.belonging_group == group_id)
|
||||||
|
).gino.all()
|
||||||
|
for user in query:
|
||||||
|
user_list.append(user)
|
||||||
|
return user_list
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
84
models/ban_user.py
Normal file
84
models/ban_user.py
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
from services.db_context import db
|
||||||
|
import time
|
||||||
|
|
||||||
|
|
||||||
|
class BanUser(db.Model):
|
||||||
|
__tablename__ = 'ban_users'
|
||||||
|
|
||||||
|
user_qq = db.Column(db.BigInteger(), nullable=False, primary_key=True)
|
||||||
|
ban_level = db.Column(db.Integer(), nullable=False)
|
||||||
|
ban_time = db.Column(db.BigInteger())
|
||||||
|
duration = db.Column(db.BigInteger())
|
||||||
|
|
||||||
|
_idx1 = db.Index('ban_group_users_idx1', 'user_qq', unique=True)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def check_ban_level(cls, user_qq: int, level: int) -> 'bool':
|
||||||
|
user = await cls.query.where(
|
||||||
|
(cls.user_qq == user_qq)
|
||||||
|
).gino.first()
|
||||||
|
if not user:
|
||||||
|
return False
|
||||||
|
if user.ban_level > level:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def check_ban_time(cls, user_qq: int) -> 'str':
|
||||||
|
query = cls.query.where(
|
||||||
|
(cls.user_qq == user_qq)
|
||||||
|
)
|
||||||
|
user = await query.gino.first()
|
||||||
|
if not user:
|
||||||
|
return ''
|
||||||
|
if time.time() - (user.ban_time + user.duration) > 0 and user.duration != -1:
|
||||||
|
return ''
|
||||||
|
if user.duration == -1:
|
||||||
|
return '∞'
|
||||||
|
return time.time() - user.ban_time - user.duration
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def isban(cls, user_qq: int) -> 'bool':
|
||||||
|
if await cls.check_ban_time(user_qq):
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
await cls.unban(user_qq, True)
|
||||||
|
return False
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def ban(cls, user_qq: int, ban_level: int, duration: int, for_update: bool = False) -> 'bool':
|
||||||
|
query = cls.query.where(
|
||||||
|
(cls.user_qq == user_qq)
|
||||||
|
)
|
||||||
|
if for_update:
|
||||||
|
query = await query.with_for_update()
|
||||||
|
user = await query.gino.first()
|
||||||
|
if not await cls.check_ban_time(user_qq):
|
||||||
|
await cls.unban(user_qq)
|
||||||
|
user = None
|
||||||
|
if user is None:
|
||||||
|
await cls.create(
|
||||||
|
user_qq=user_qq,
|
||||||
|
ban_level=ban_level,
|
||||||
|
ban_time=time.time(),
|
||||||
|
duration=duration,
|
||||||
|
)
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def unban(cls, user_qq: int, for_update: bool = False) -> 'bool':
|
||||||
|
query = cls.query.where(
|
||||||
|
(cls.user_qq == user_qq)
|
||||||
|
)
|
||||||
|
if for_update:
|
||||||
|
query = query.with_for_update()
|
||||||
|
user = await query.gino.first()
|
||||||
|
if user is None:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
await cls.delete.where(
|
||||||
|
(cls.user_qq == user_qq)
|
||||||
|
).gino.status()
|
||||||
|
return True
|
||||||
33
models/buff_price.py
Normal file
33
models/buff_price.py
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
from services.db_context import db
|
||||||
|
|
||||||
|
# 1.狂牙武器箱
|
||||||
|
|
||||||
|
|
||||||
|
class BuffPrice(db.Model):
|
||||||
|
__tablename__ = 'buff_prices'
|
||||||
|
|
||||||
|
id = db.Column(db.Integer(), primary_key=True)
|
||||||
|
case_id = db.Column(db.Integer(), nullable=False)
|
||||||
|
skin_name = db.Column(db.Unicode(), nullable=False)
|
||||||
|
skin_price = db.Column(db.Float(), nullable=False)
|
||||||
|
update_date = db.Column(db.DateTime(), nullable=False)
|
||||||
|
|
||||||
|
_idx1 = db.Index('buff_price_idx1', 'skin_name', unique=True)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def ensure(cls, skin_name: str, for_update: bool = False) -> 'BuffPrice':
|
||||||
|
query = cls.query.where(
|
||||||
|
(cls.skin_name == skin_name)
|
||||||
|
)
|
||||||
|
if for_update:
|
||||||
|
query = query.with_for_update()
|
||||||
|
user = await query.gino.first()
|
||||||
|
return user or await cls.create(
|
||||||
|
case_id=1,
|
||||||
|
skin_name=skin_name,
|
||||||
|
skin_price=0,
|
||||||
|
update_date=datetime.min,
|
||||||
|
)
|
||||||
|
|
||||||
78
models/count_user.py
Normal file
78
models/count_user.py
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
|
||||||
|
from services.db_context import db
|
||||||
|
|
||||||
|
|
||||||
|
class UserCount(db.Model):
|
||||||
|
__tablename__ = 'count_users'
|
||||||
|
|
||||||
|
user_qq = db.Column(db.BigInteger(), nullable=False, primary_key=True)
|
||||||
|
reimu_count = db.Column(db.Integer(), nullable=False, default=0)
|
||||||
|
setu_r18_count = db.Column(db.Integer(), nullable=False, default=0)
|
||||||
|
|
||||||
|
_idx1 = db.Index('sign_reimu_users_idx1', 'user_qq', unique=True)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def add_user(cls, user_qq: int):
|
||||||
|
query = cls.query.where(
|
||||||
|
(cls.user_qq == user_qq)
|
||||||
|
)
|
||||||
|
query = query.with_for_update()
|
||||||
|
if not await query.gino.first():
|
||||||
|
await cls.create(
|
||||||
|
user_qq=user_qq,
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def add_count(cls, user_qq: int, name: str, count: int = 1):
|
||||||
|
query = cls.query.where(
|
||||||
|
(cls.user_qq == user_qq)
|
||||||
|
)
|
||||||
|
query = query.with_for_update()
|
||||||
|
user = await query.gino.first()
|
||||||
|
if user:
|
||||||
|
if name == 'reimu':
|
||||||
|
await user.update(
|
||||||
|
reimu_count=cls.reimu_count + count
|
||||||
|
).apply()
|
||||||
|
if name == 'setu_r18':
|
||||||
|
await user.update(
|
||||||
|
setu_r18_count=cls.setu_r18_count + count
|
||||||
|
).apply()
|
||||||
|
else:
|
||||||
|
await cls.create(
|
||||||
|
user_qq=user_qq
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def check_count(cls, user_qq: int, name: str, max_count: int) -> bool:
|
||||||
|
query = cls.query.where(
|
||||||
|
(cls.user_qq == user_qq)
|
||||||
|
)
|
||||||
|
user = await query.gino.first()
|
||||||
|
if user:
|
||||||
|
if name == 'reimu':
|
||||||
|
if user.reimu_count == max_count:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
if name == 'setu_r18':
|
||||||
|
if user.setu_r18_count == max_count:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
await cls.add_user(user_qq)
|
||||||
|
return False
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def reset_count(cls):
|
||||||
|
for user in await cls.query.gino.all():
|
||||||
|
await user.update(
|
||||||
|
reimu_count=0,
|
||||||
|
setu_r18_count=0
|
||||||
|
).apply()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
87
models/friend_user.py
Normal file
87
models/friend_user.py
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
from services.db_context import db
|
||||||
|
|
||||||
|
|
||||||
|
class FriendUser(db.Model):
|
||||||
|
__tablename__ = 'friend_users'
|
||||||
|
|
||||||
|
id = db.Column(db.Integer(), primary_key=True)
|
||||||
|
user_id = db.Column(db.BigInteger(), nullable=False)
|
||||||
|
user_name = db.Column(db.Unicode(), nullable=False, default="")
|
||||||
|
nickname = db.Column(db.Unicode())
|
||||||
|
|
||||||
|
_idx1 = db.Index('friend_users_idx1', 'user_id', unique=True)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def get_user_name(cls, user_id: int) -> str:
|
||||||
|
query = cls.query.where(
|
||||||
|
cls.user_id == user_id
|
||||||
|
)
|
||||||
|
user = await query.gino.first()
|
||||||
|
if user:
|
||||||
|
return user.user_name
|
||||||
|
else:
|
||||||
|
return ''
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def add_friend_info(cls, user_id: int, user_name: str) -> 'bool':
|
||||||
|
try:
|
||||||
|
query = cls.query.where(
|
||||||
|
cls.user_id == user_id
|
||||||
|
)
|
||||||
|
user = await query.with_for_update().gino.first()
|
||||||
|
if not user:
|
||||||
|
await cls.create(
|
||||||
|
user_id=user_id,
|
||||||
|
user_name=user_name,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
await user.update(
|
||||||
|
user_name=user_name,
|
||||||
|
).apply()
|
||||||
|
return True
|
||||||
|
except Exception:
|
||||||
|
return False
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def delete_friend_info(cls, user_id: int) -> 'bool':
|
||||||
|
try:
|
||||||
|
query = cls.query.where(
|
||||||
|
cls.user_id == user_id
|
||||||
|
)
|
||||||
|
user = await query.with_for_update().gino.first()
|
||||||
|
if user:
|
||||||
|
await user.delete()
|
||||||
|
return True
|
||||||
|
except Exception:
|
||||||
|
return False
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def get_friend_nickname(cls, user_id: int) -> 'str':
|
||||||
|
query = cls.query.where(
|
||||||
|
cls.user_id == user_id
|
||||||
|
)
|
||||||
|
user = await query.with_for_update().gino.first()
|
||||||
|
if user:
|
||||||
|
if user.nickname:
|
||||||
|
return user.nickname
|
||||||
|
return ''
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def set_friend_nickname(cls, user_id: int, nickname: str) -> 'bool':
|
||||||
|
try:
|
||||||
|
query = cls.query.where(
|
||||||
|
cls.user_id == user_id
|
||||||
|
)
|
||||||
|
user = await query.with_for_update().gino.first()
|
||||||
|
if not user:
|
||||||
|
await cls.create(
|
||||||
|
user_id=user_id,
|
||||||
|
nickname=nickname,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
await user.update(
|
||||||
|
nickname=nickname,
|
||||||
|
).apply()
|
||||||
|
return True
|
||||||
|
except Exception:
|
||||||
|
return False
|
||||||
56
models/group_info.py
Normal file
56
models/group_info.py
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
|
||||||
|
from services.db_context import db
|
||||||
|
|
||||||
|
|
||||||
|
class GroupInfo(db.Model):
|
||||||
|
__tablename__ = 'group_info'
|
||||||
|
|
||||||
|
group_id = db.Column(db.BigInteger(), nullable=False, primary_key=True)
|
||||||
|
group_name = db.Column(db.Unicode(), nullable=False, default="")
|
||||||
|
max_member_count = db.Column(db.Integer(), nullable=False, default=0)
|
||||||
|
member_count = db.Column(db.Integer(), nullable=False, default=0)
|
||||||
|
|
||||||
|
_idx1 = db.Index('group_info_idx1', 'group_id', unique=True)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def get_group_info(cls, group_id: int) -> 'GroupInfo':
|
||||||
|
query = cls.query.where(
|
||||||
|
cls.group_id == group_id
|
||||||
|
)
|
||||||
|
return await query.gino.first()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def add_group_info(cls, group_id: int, group_name: str, max_member_count: int, member_count: int) -> bool:
|
||||||
|
try:
|
||||||
|
group = await cls.query.where(
|
||||||
|
cls.group_id == group_id
|
||||||
|
).with_for_update().gino.first()
|
||||||
|
if group:
|
||||||
|
await cls.update(
|
||||||
|
group_id=group_id,
|
||||||
|
group_name=group_name,
|
||||||
|
max_member_count=max_member_count,
|
||||||
|
member_count=member_count,
|
||||||
|
).apply()
|
||||||
|
else:
|
||||||
|
await cls.create(
|
||||||
|
group_id=group_id,
|
||||||
|
group_name=group_name,
|
||||||
|
max_member_count=max_member_count,
|
||||||
|
member_count=member_count,
|
||||||
|
)
|
||||||
|
return True
|
||||||
|
except Exception:
|
||||||
|
return False
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def delete_group_info(cls, group_id: int) -> bool:
|
||||||
|
try:
|
||||||
|
await cls.delete.where(
|
||||||
|
cls.group_id == group_id
|
||||||
|
).gino.status()
|
||||||
|
return True
|
||||||
|
except Exception:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
99
models/group_member_info.py
Normal file
99
models/group_member_info.py
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
from services.db_context import db
|
||||||
|
|
||||||
|
|
||||||
|
class GroupInfoUser(db.Model):
|
||||||
|
__tablename__ = 'group_info_users'
|
||||||
|
|
||||||
|
id = db.Column(db.Integer(), primary_key=True)
|
||||||
|
user_qq = db.Column(db.BigInteger(), nullable=False)
|
||||||
|
user_name = db.Column(db.Unicode(), nullable=False)
|
||||||
|
belonging_group = db.Column(db.BigInteger(), nullable=False)
|
||||||
|
user_join_time = db.Column(db.DateTime(), nullable=False)
|
||||||
|
nickname = db.Column(db.Unicode())
|
||||||
|
|
||||||
|
_idx1 = db.Index('info_group_users_idx1', 'user_qq', 'belonging_group', unique=True)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def insert(cls, user_qq: int, belonging_group: int, user_name: str, user_join_time: datetime) -> 'bool':
|
||||||
|
query = cls.query.where(
|
||||||
|
(cls.user_qq == user_qq) & (cls.belonging_group == belonging_group)
|
||||||
|
)
|
||||||
|
query = query.with_for_update()
|
||||||
|
try:
|
||||||
|
if await query.gino.first() is None:
|
||||||
|
await cls.create(
|
||||||
|
user_qq=user_qq,
|
||||||
|
user_name=user_name,
|
||||||
|
belonging_group=belonging_group,
|
||||||
|
user_join_time=user_join_time,
|
||||||
|
)
|
||||||
|
return True
|
||||||
|
except:
|
||||||
|
return False
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def select_member_info(cls, user_qq: int, belonging_group: int) -> 'GroupInfoUser':
|
||||||
|
query = cls.query.where(
|
||||||
|
(cls.user_qq == user_qq) & (cls.belonging_group == belonging_group)
|
||||||
|
)
|
||||||
|
return await query.gino.first()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def delete_member_info(cls, user_qq: int, belonging_group: int) -> 'bool':
|
||||||
|
query = cls.query.where(
|
||||||
|
(cls.user_qq == user_qq) & (cls.belonging_group == belonging_group)
|
||||||
|
)
|
||||||
|
query = query.with_for_update()
|
||||||
|
user = await query.gino.first()
|
||||||
|
try:
|
||||||
|
if user is None:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
await cls.delete.where(
|
||||||
|
(cls.user_qq == user_qq) & (cls.belonging_group == belonging_group)
|
||||||
|
).gino.status()
|
||||||
|
return True
|
||||||
|
except:
|
||||||
|
return False
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def query_group_member_list(cls, belonging_group: int) -> 'list':
|
||||||
|
member_list = []
|
||||||
|
query = cls.query.where(
|
||||||
|
(cls.belonging_group == belonging_group)
|
||||||
|
)
|
||||||
|
for user in await query.gino.all():
|
||||||
|
member_list.append(user.user_qq)
|
||||||
|
return member_list
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def set_group_member_nickname(cls, user_qq: int, belonging_group: int, nickname: str) -> 'bool':
|
||||||
|
query = cls.query.where(
|
||||||
|
(cls.user_qq == user_qq) & (cls.belonging_group == belonging_group)
|
||||||
|
)
|
||||||
|
user = await query.gino.first()
|
||||||
|
if user:
|
||||||
|
await user.update(
|
||||||
|
nickname=nickname
|
||||||
|
).apply()
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def get_group_member_nickname(cls, user_qq: int, belonging_group: int) -> 'str':
|
||||||
|
query = cls.query.where(
|
||||||
|
(cls.user_qq == user_qq) & (cls.belonging_group == belonging_group)
|
||||||
|
)
|
||||||
|
user = await query.gino.first()
|
||||||
|
if user:
|
||||||
|
if user.nickname:
|
||||||
|
return user.nickname
|
||||||
|
return ''
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
100
models/group_remind.py
Normal file
100
models/group_remind.py
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
from services.db_context import db
|
||||||
|
|
||||||
|
|
||||||
|
class GroupRemind(db.Model):
|
||||||
|
__tablename__ = 'group_reminds'
|
||||||
|
|
||||||
|
id = db.Column(db.Integer(), primary_key=True)
|
||||||
|
group_id = db.Column(db.BigInteger(), nullable=False)
|
||||||
|
hy = db.Column(db.Boolean(), default=True) # 进群欢迎
|
||||||
|
kxcz = db.Column(db.Boolean(), default=True) # 开箱重置
|
||||||
|
zwa = db.Column(db.Boolean(), default=True) # 早晚安
|
||||||
|
gb = db.Column(db.Boolean(), default=True) # 广播
|
||||||
|
blpar = db.Column(db.Boolean(), default=True) # bilibili转发解析
|
||||||
|
pa = db.Column(db.Boolean(), default=True) # 爬
|
||||||
|
epic = db.Column(db.Boolean(), default=False) # epic
|
||||||
|
almanac = db.Column(db.Boolean(), default=False) # 原神黄历
|
||||||
|
|
||||||
|
_idx1 = db.Index('info_group_reminds_idx1', 'group_id', unique=True)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def get_status(cls, group_id: int, name: str) -> bool:
|
||||||
|
group = await cls.query.where(
|
||||||
|
(cls.group_id == group_id)
|
||||||
|
).gino.first()
|
||||||
|
if not group:
|
||||||
|
group = await cls.create(
|
||||||
|
group_id=group_id,
|
||||||
|
)
|
||||||
|
if name == 'hy':
|
||||||
|
return group.hy
|
||||||
|
if name == 'kxcz':
|
||||||
|
return group.kxcz
|
||||||
|
if name == 'zwa':
|
||||||
|
return group.zwa
|
||||||
|
if name == 'gb':
|
||||||
|
return group.gb
|
||||||
|
if name == 'blpar':
|
||||||
|
return group.blpar
|
||||||
|
if name == 'epic':
|
||||||
|
return group.epic
|
||||||
|
if name == 'pa':
|
||||||
|
return group.pa
|
||||||
|
if name == 'almanac':
|
||||||
|
return group.almanac
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def set_status(cls, group_id: int, name: str, status: bool) -> bool:
|
||||||
|
try:
|
||||||
|
group = await cls.query.where(
|
||||||
|
(cls.group_id == group_id)
|
||||||
|
).gino.first()
|
||||||
|
if not group:
|
||||||
|
group = await cls.create(
|
||||||
|
group_id=group_id,
|
||||||
|
)
|
||||||
|
if name == 'hy':
|
||||||
|
await group.update(
|
||||||
|
hy=status,
|
||||||
|
).apply()
|
||||||
|
if name == 'kxcz':
|
||||||
|
await group.update(
|
||||||
|
kxcz=status,
|
||||||
|
).apply()
|
||||||
|
if name == 'zwa':
|
||||||
|
await group.update(
|
||||||
|
zwa=status,
|
||||||
|
).apply()
|
||||||
|
if name == 'gb':
|
||||||
|
await group.update(
|
||||||
|
gb=status,
|
||||||
|
).apply()
|
||||||
|
if name == 'blpar':
|
||||||
|
await group.update(
|
||||||
|
blpar=status,
|
||||||
|
).apply()
|
||||||
|
if name == 'epic':
|
||||||
|
await group.update(
|
||||||
|
epic=status,
|
||||||
|
).apply()
|
||||||
|
if name == 'pa':
|
||||||
|
await group.update(
|
||||||
|
pa=status,
|
||||||
|
).apply()
|
||||||
|
if name == 'almanac':
|
||||||
|
await group.update(
|
||||||
|
almanac=status,
|
||||||
|
).apply()
|
||||||
|
return True
|
||||||
|
except Exception as e:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
94
models/level_user.py
Normal file
94
models/level_user.py
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
from services.db_context import db
|
||||||
|
|
||||||
|
|
||||||
|
class LevelUser(db.Model):
|
||||||
|
__tablename__ = 'level_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)
|
||||||
|
user_level = db.Column(db.BigInteger(), nullable=False)
|
||||||
|
group_flag = db.Column(db.Integer(), nullable=False, default=0)
|
||||||
|
|
||||||
|
_idx1 = db.Index('level_group_users_idx1', 'user_qq', 'group_id', unique=True)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def get_user_level(cls, user_qq: int, group_id: int) -> int:
|
||||||
|
query = cls.query.where(
|
||||||
|
(cls.user_qq == user_qq) & (cls.group_id == group_id)
|
||||||
|
)
|
||||||
|
user = await query.gino.first()
|
||||||
|
if user:
|
||||||
|
return user.user_level
|
||||||
|
else:
|
||||||
|
return -1
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def set_level(cls, user_qq: int, group_id: int, level: int, group_flag: int = 0) -> 'bool':
|
||||||
|
query = cls.query.where(
|
||||||
|
(cls.user_qq == user_qq) & (cls.group_id == group_id)
|
||||||
|
)
|
||||||
|
query = query.with_for_update()
|
||||||
|
user = await query.gino.first()
|
||||||
|
if user is None:
|
||||||
|
await cls.create(
|
||||||
|
user_qq=user_qq,
|
||||||
|
group_id=group_id,
|
||||||
|
user_level=level,
|
||||||
|
group_flag=group_flag,
|
||||||
|
)
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
await user.update(user_level=level, group_flag=group_flag).apply()
|
||||||
|
return False
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def delete_level(cls, user_qq: int, group_id: int, for_update: bool = False) -> 'bool':
|
||||||
|
query = cls.query.where(
|
||||||
|
(cls.user_qq == user_qq) & (cls.group_id == group_id)
|
||||||
|
)
|
||||||
|
if for_update:
|
||||||
|
query = query.with_for_update()
|
||||||
|
user = await query.gino.first()
|
||||||
|
if user is None:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
await user.delete()
|
||||||
|
return True
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def check_level(cls, user_qq: int, group_id: int, level: int) -> 'bool':
|
||||||
|
if group_id != 0:
|
||||||
|
query = cls.query.where(
|
||||||
|
(cls.user_qq == user_qq) & (cls.group_id == group_id)
|
||||||
|
)
|
||||||
|
user = await query.gino.first()
|
||||||
|
if user is None:
|
||||||
|
return False
|
||||||
|
user_level = user.user_level
|
||||||
|
else:
|
||||||
|
query = cls.query.where(
|
||||||
|
cls.user_qq == user_qq
|
||||||
|
)
|
||||||
|
highest_level = 0
|
||||||
|
for user in await query.gino.all():
|
||||||
|
if user.user_level > highest_level:
|
||||||
|
highest_level = user.user_level
|
||||||
|
user_level = highest_level
|
||||||
|
if user_level >= level:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def is_group_flag(cls, user_qq: int, group_id: int) -> 'bool':
|
||||||
|
user = await cls.query.where(
|
||||||
|
(cls.user_qq == user_qq) & (cls.group_id == group_id)
|
||||||
|
).gino.first()
|
||||||
|
if not user:
|
||||||
|
return False
|
||||||
|
if user.group_flag == 1:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
59
models/open_cases_user.py
Normal file
59
models/open_cases_user.py
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
from services.db_context import db
|
||||||
|
|
||||||
|
|
||||||
|
class OpenCasesUser(db.Model):
|
||||||
|
__tablename__ = 'open_cases_users'
|
||||||
|
|
||||||
|
id = db.Column(db.Integer(), primary_key=True)
|
||||||
|
user_qq = db.Column(db.BigInteger(), nullable=False)
|
||||||
|
belonging_group = db.Column(db.BigInteger(), nullable=False)
|
||||||
|
total_count = db.Column(db.Integer(), nullable=False, default=0)
|
||||||
|
blue_count = db.Column(db.Integer(), nullable=False, default=0)
|
||||||
|
blue_st_count = db.Column(db.Integer(), nullable=False, default=0)
|
||||||
|
purple_count = db.Column(db.Integer(), nullable=False, default=0)
|
||||||
|
purple_st_count = db.Column(db.Integer(), nullable=False, default=0)
|
||||||
|
pink_count = db.Column(db.Integer(), nullable=False, default=0)
|
||||||
|
pink_st_count = db.Column(db.Integer(), nullable=False, default=0)
|
||||||
|
red_count = db.Column(db.Integer(), nullable=False, default=0)
|
||||||
|
red_st_count = db.Column(db.Integer(), nullable=False, default=0)
|
||||||
|
knife_count = db.Column(db.Integer(), nullable=False, default=0)
|
||||||
|
knife_st_count = db.Column(db.Integer(), nullable=False, default=0)
|
||||||
|
spend_money = db.Column(db.Integer(), nullable=False, default=0)
|
||||||
|
make_money = db.Column(db.Float(), nullable=False, default=0)
|
||||||
|
today_open_total = db.Column(db.Integer(), nullable=False, default=0)
|
||||||
|
open_cases_time_last = db.Column(db.DateTime(timezone=True), nullable=False, default=datetime.now())
|
||||||
|
knifes_name = db.Column(db.Unicode(), nullable=False, default="")
|
||||||
|
|
||||||
|
_idx1 = db.Index('open_cases_group_users_idx1', 'user_qq', 'belonging_group', unique=True)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def ensure(cls, user_qq: int, belonging_group: int, for_update: bool = False) -> 'OpenCasesUser':
|
||||||
|
query = cls.query.where(
|
||||||
|
(cls.user_qq == user_qq) & (cls.belonging_group == belonging_group)
|
||||||
|
)
|
||||||
|
if for_update:
|
||||||
|
query = query.with_for_update()
|
||||||
|
user = await query.gino.first()
|
||||||
|
return user or await cls.create(
|
||||||
|
user_qq=user_qq,
|
||||||
|
belonging_group=belonging_group,
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def get_user_all(cls, group_id: int = None) -> 'list':
|
||||||
|
user_list = []
|
||||||
|
if not group_id:
|
||||||
|
query = await cls.query.gino.all()
|
||||||
|
else:
|
||||||
|
query = await cls.query.where(
|
||||||
|
(cls.belonging_group == group_id)
|
||||||
|
).gino.all()
|
||||||
|
for user in query:
|
||||||
|
user_list.append(user)
|
||||||
|
return user_list
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
59
models/sigin_group_user.py
Normal file
59
models/sigin_group_user.py
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
from services.db_context import db
|
||||||
|
|
||||||
|
|
||||||
|
class SignGroupUser(db.Model):
|
||||||
|
__tablename__ = 'sign_group_users'
|
||||||
|
|
||||||
|
id = db.Column(db.Integer(), primary_key=True)
|
||||||
|
user_qq = db.Column(db.BigInteger(), nullable=False)
|
||||||
|
belonging_group = db.Column(db.BigInteger(), nullable=False)
|
||||||
|
|
||||||
|
checkin_count = db.Column(db.Integer(), nullable=False)
|
||||||
|
checkin_time_last = db.Column(db.DateTime(timezone=True), nullable=False)
|
||||||
|
impression = db.Column(db.Numeric(scale=3, asdecimal=False), nullable=False)
|
||||||
|
add_probability = db.Column(db.Numeric(scale=3, asdecimal=False), nullable=False, default=0)
|
||||||
|
specify_probability = db.Column(db.Numeric(scale=3, asdecimal=False), nullable=False, default=0)
|
||||||
|
|
||||||
|
_idx1 = db.Index('sign_group_users_idx1', 'user_qq', 'belonging_group', unique=True)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def ensure(cls, user_qq: int, belonging_group: int, for_update: bool = False) -> 'SignGroupUser':
|
||||||
|
query = cls.query.where(
|
||||||
|
(cls.user_qq == user_qq) & (cls.belonging_group == belonging_group)
|
||||||
|
)
|
||||||
|
if for_update:
|
||||||
|
query = query.with_for_update()
|
||||||
|
user = await query.gino.first()
|
||||||
|
return user or await cls.create(
|
||||||
|
user_qq=user_qq,
|
||||||
|
belonging_group=belonging_group,
|
||||||
|
checkin_count=0,
|
||||||
|
checkin_time_last=datetime.min, # 从未签到过
|
||||||
|
impression=0,
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def query_impression_all(cls, belonging_group: int) -> 'list,list':
|
||||||
|
impression_list = []
|
||||||
|
user_qq_list = []
|
||||||
|
query = cls.query.where(
|
||||||
|
(cls.belonging_group == belonging_group)
|
||||||
|
)
|
||||||
|
for user in await query.gino.all():
|
||||||
|
impression_list.append(user.impression)
|
||||||
|
user_qq_list.append(user.user_qq)
|
||||||
|
return user_qq_list, impression_list
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def query_glod_all(cls, belonging_group: int) -> 'list,list':
|
||||||
|
glod_list = []
|
||||||
|
user_qq_list = []
|
||||||
|
query = cls.query.where(
|
||||||
|
(cls.belonging_group == belonging_group)
|
||||||
|
)
|
||||||
|
for user in await query.gino.all():
|
||||||
|
glod_list.append(user.glod)
|
||||||
|
user_qq_list.append(user.user_qq)
|
||||||
|
return user_qq_list, glod_list
|
||||||
0
plugins/__init__.py
Normal file
0
plugins/__init__.py
Normal file
BIN
plugins/__pycache__/__init__.cpython-38.pyc
Normal file
BIN
plugins/__pycache__/__init__.cpython-38.pyc
Normal file
Binary file not shown.
BIN
plugins/__pycache__/__init__.cpython-39.pyc
Normal file
BIN
plugins/__pycache__/__init__.cpython-39.pyc
Normal file
Binary file not shown.
BIN
plugins/__pycache__/add_dy.cpython-38.pyc
Normal file
BIN
plugins/__pycache__/add_dy.cpython-38.pyc
Normal file
Binary file not shown.
BIN
plugins/__pycache__/admin_config.cpython-38.pyc
Normal file
BIN
plugins/__pycache__/admin_config.cpython-38.pyc
Normal file
Binary file not shown.
BIN
plugins/__pycache__/admin_config.cpython-39.pyc
Normal file
BIN
plugins/__pycache__/admin_config.cpython-39.pyc
Normal file
Binary file not shown.
BIN
plugins/__pycache__/change_dy.cpython-38.pyc
Normal file
BIN
plugins/__pycache__/change_dy.cpython-38.pyc
Normal file
Binary file not shown.
BIN
plugins/__pycache__/del_dy.cpython-38.pyc
Normal file
BIN
plugins/__pycache__/del_dy.cpython-38.pyc
Normal file
Binary file not shown.
BIN
plugins/__pycache__/fake_msg.cpython-38.pyc
Normal file
BIN
plugins/__pycache__/fake_msg.cpython-38.pyc
Normal file
Binary file not shown.
BIN
plugins/__pycache__/fake_msg.cpython-39.pyc
Normal file
BIN
plugins/__pycache__/fake_msg.cpython-39.pyc
Normal file
Binary file not shown.
BIN
plugins/__pycache__/fudu.cpython-38.pyc
Normal file
BIN
plugins/__pycache__/fudu.cpython-38.pyc
Normal file
Binary file not shown.
BIN
plugins/__pycache__/fudu.cpython-39.pyc
Normal file
BIN
plugins/__pycache__/fudu.cpython-39.pyc
Normal file
Binary file not shown.
BIN
plugins/__pycache__/group_welcome_msg.cpython-38.pyc
Normal file
BIN
plugins/__pycache__/group_welcome_msg.cpython-38.pyc
Normal file
Binary file not shown.
BIN
plugins/__pycache__/group_welcome_msg.cpython-39.pyc
Normal file
BIN
plugins/__pycache__/group_welcome_msg.cpython-39.pyc
Normal file
Binary file not shown.
BIN
plugins/__pycache__/hook.cpython-38.pyc
Normal file
BIN
plugins/__pycache__/hook.cpython-38.pyc
Normal file
Binary file not shown.
BIN
plugins/__pycache__/hook.cpython-39.pyc
Normal file
BIN
plugins/__pycache__/hook.cpython-39.pyc
Normal file
Binary file not shown.
BIN
plugins/__pycache__/jitang.cpython-38.pyc
Normal file
BIN
plugins/__pycache__/jitang.cpython-38.pyc
Normal file
Binary file not shown.
BIN
plugins/__pycache__/jitang.cpython-39.pyc
Normal file
BIN
plugins/__pycache__/jitang.cpython-39.pyc
Normal file
Binary file not shown.
BIN
plugins/__pycache__/mute.cpython-38.pyc
Normal file
BIN
plugins/__pycache__/mute.cpython-38.pyc
Normal file
Binary file not shown.
BIN
plugins/__pycache__/mute.cpython-39.pyc
Normal file
BIN
plugins/__pycache__/mute.cpython-39.pyc
Normal file
Binary file not shown.
BIN
plugins/__pycache__/my_info.cpython-38.pyc
Normal file
BIN
plugins/__pycache__/my_info.cpython-38.pyc
Normal file
Binary file not shown.
BIN
plugins/__pycache__/my_info.cpython-39.pyc
Normal file
BIN
plugins/__pycache__/my_info.cpython-39.pyc
Normal file
Binary file not shown.
BIN
plugins/__pycache__/nickname.cpython-38.pyc
Normal file
BIN
plugins/__pycache__/nickname.cpython-38.pyc
Normal file
Binary file not shown.
BIN
plugins/__pycache__/nickname.cpython-39.pyc
Normal file
BIN
plugins/__pycache__/nickname.cpython-39.pyc
Normal file
Binary file not shown.
BIN
plugins/__pycache__/parse_bilibili_json.cpython-38.pyc
Normal file
BIN
plugins/__pycache__/parse_bilibili_json.cpython-38.pyc
Normal file
Binary file not shown.
BIN
plugins/__pycache__/parse_bilibili_json.cpython-39.pyc
Normal file
BIN
plugins/__pycache__/parse_bilibili_json.cpython-39.pyc
Normal file
Binary file not shown.
BIN
plugins/__pycache__/quotations.cpython-38.pyc
Normal file
BIN
plugins/__pycache__/quotations.cpython-38.pyc
Normal file
Binary file not shown.
BIN
plugins/__pycache__/quotations.cpython-39.pyc
Normal file
BIN
plugins/__pycache__/quotations.cpython-39.pyc
Normal file
Binary file not shown.
BIN
plugins/__pycache__/server_ip.cpython-38.pyc
Normal file
BIN
plugins/__pycache__/server_ip.cpython-38.pyc
Normal file
Binary file not shown.
BIN
plugins/__pycache__/server_ip.cpython-39.pyc
Normal file
BIN
plugins/__pycache__/server_ip.cpython-39.pyc
Normal file
Binary file not shown.
BIN
plugins/__pycache__/show_all.cpython-38.pyc
Normal file
BIN
plugins/__pycache__/show_all.cpython-38.pyc
Normal file
Binary file not shown.
BIN
plugins/__pycache__/show_dy.cpython-38.pyc
Normal file
BIN
plugins/__pycache__/show_dy.cpython-38.pyc
Normal file
Binary file not shown.
BIN
plugins/__pycache__/start.cpython-38.pyc
Normal file
BIN
plugins/__pycache__/start.cpython-38.pyc
Normal file
Binary file not shown.
BIN
plugins/__pycache__/statistics_hook.cpython-39.pyc
Normal file
BIN
plugins/__pycache__/statistics_hook.cpython-39.pyc
Normal file
Binary file not shown.
BIN
plugins/__pycache__/test.cpython-38.pyc
Normal file
BIN
plugins/__pycache__/test.cpython-38.pyc
Normal file
Binary file not shown.
BIN
plugins/__pycache__/test.cpython-39.pyc
Normal file
BIN
plugins/__pycache__/test.cpython-39.pyc
Normal file
Binary file not shown.
BIN
plugins/__pycache__/update_info.cpython-38.pyc
Normal file
BIN
plugins/__pycache__/update_info.cpython-38.pyc
Normal file
Binary file not shown.
BIN
plugins/__pycache__/update_info.cpython-39.pyc
Normal file
BIN
plugins/__pycache__/update_info.cpython-39.pyc
Normal file
Binary file not shown.
BIN
plugins/__pycache__/update_pic.cpython-38.pyc
Normal file
BIN
plugins/__pycache__/update_pic.cpython-38.pyc
Normal file
Binary file not shown.
BIN
plugins/__pycache__/update_pic.cpython-39.pyc
Normal file
BIN
plugins/__pycache__/update_pic.cpython-39.pyc
Normal file
Binary file not shown.
BIN
plugins/__pycache__/white2black_img.cpython-38.pyc
Normal file
BIN
plugins/__pycache__/white2black_img.cpython-38.pyc
Normal file
Binary file not shown.
BIN
plugins/__pycache__/white2black_img.cpython-39.pyc
Normal file
BIN
plugins/__pycache__/white2black_img.cpython-39.pyc
Normal file
Binary file not shown.
71
plugins/aconfig/__init__.py
Normal file
71
plugins/aconfig/__init__.py
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
import random
|
||||||
|
from nonebot import on_keyword
|
||||||
|
import os
|
||||||
|
from util.init_result import image
|
||||||
|
from configs.path_config import IMAGE_PATH
|
||||||
|
from nonebot import on_command
|
||||||
|
from nonebot.rule import to_me
|
||||||
|
from nonebot.typing import T_State
|
||||||
|
from nonebot.adapters.cqhttp import Bot, GroupMessageEvent, MessageEvent
|
||||||
|
from nonebot.adapters.cqhttp.permission import GROUP
|
||||||
|
from util.utils import FreqLimiter
|
||||||
|
|
||||||
|
|
||||||
|
__plugin_name__ = '基本设置 [Hidden]'
|
||||||
|
__plugin_usage__ = '用法: 基本'
|
||||||
|
|
||||||
|
|
||||||
|
_flmt = FreqLimiter(300)
|
||||||
|
|
||||||
|
|
||||||
|
config_playgame = on_keyword({'打游戏'}, permission=GROUP, priority=1, block=True)
|
||||||
|
|
||||||
|
|
||||||
|
@config_playgame.handle()
|
||||||
|
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
|
||||||
|
if not _flmt.check(event.group_id):
|
||||||
|
return
|
||||||
|
_flmt.start_cd(event.group_id)
|
||||||
|
await config_playgame.finish(image(
|
||||||
|
random.choice(os.listdir(IMAGE_PATH + "dayouxi/")
|
||||||
|
), "dayouxi"))
|
||||||
|
|
||||||
|
|
||||||
|
self_introduction = on_command("自我介绍", aliases={'介绍', '你是谁', '你叫什么'},
|
||||||
|
rule=to_me(), priority=5, block=True)
|
||||||
|
|
||||||
|
|
||||||
|
@self_introduction.handle()
|
||||||
|
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||||
|
result = "我叫绪山真寻\n" \
|
||||||
|
"你们可以叫我真寻,小真寻,哪怕你们叫我小寻子我也能接受!\n" \
|
||||||
|
"年龄的话我还是个**岁初中生(至少现在是)\n" \
|
||||||
|
"身高保密!!!(也就比美波里(姐姐..(妹妹))矮一点)\n" \
|
||||||
|
"我生日是在3月6号, 能记住的话我会很高兴的\n现在是自宅警备系的现役JC\n" \
|
||||||
|
"最好的朋友是椛!\n"\
|
||||||
|
+ image("zhenxun")
|
||||||
|
await self_introduction.finish(result)
|
||||||
|
|
||||||
|
laopo = on_keyword({'老婆'}, rule=to_me(), priority=5, block=True)
|
||||||
|
|
||||||
|
|
||||||
|
@laopo.handle()
|
||||||
|
async def _(bot: Bot, event: MessageEvent, state: T_State):
|
||||||
|
await laopo.finish(image('laopo.jpg', 'other'))
|
||||||
|
|
||||||
|
|
||||||
|
# config_robot = on_keyword({"机器人"}, permission=GROUP, priority=5, block=True)
|
||||||
|
# @config_robot.handle()
|
||||||
|
# async def _(bot: Bot, event: Event, state: T_State):
|
||||||
|
# if not _flmt.check(event.group_id) or event.group_id == 774261838:
|
||||||
|
# return
|
||||||
|
# _flmt.start_cd(event.group_id)
|
||||||
|
# await config_robot.send("小真寻才不是机器人!")
|
||||||
|
# result = "我叫绪山真寻\n" \
|
||||||
|
# "你们可以叫我真寻,小真寻,哪怕你们叫我小寻子我也能接受!\n" \
|
||||||
|
# "年龄的话我还是个**岁初中生(至少现在是)\n" \
|
||||||
|
# "身高保密!!!(也就比美波里(姐姐..(妹妹))矮一点)\n" \
|
||||||
|
# "我生日是在3月6号, 能记住的话我会很高兴的\n现在是自宅警备系的现役JC\n" \
|
||||||
|
# "最好的朋友是椛!\n"\
|
||||||
|
# + image("zhenxun", "")
|
||||||
|
# await config_jieshao.finish(result)
|
||||||
BIN
plugins/aconfig/__pycache__/__init__.cpython-38.pyc
Normal file
BIN
plugins/aconfig/__pycache__/__init__.cpython-38.pyc
Normal file
Binary file not shown.
BIN
plugins/aconfig/__pycache__/__init__.cpython-39.pyc
Normal file
BIN
plugins/aconfig/__pycache__/__init__.cpython-39.pyc
Normal file
Binary file not shown.
88
plugins/admin_bot_manage/__init__.py
Normal file
88
plugins/admin_bot_manage/__init__.py
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
from nonebot import on_command
|
||||||
|
from util.utils import get_message_text, get_message_imgs, scheduler, get_bot
|
||||||
|
from nonebot.typing import T_State
|
||||||
|
from nonebot.adapters.cqhttp import Bot, GroupMessageEvent
|
||||||
|
from .data_source import set_group_status, custom_group_welcome, change_group_switch, \
|
||||||
|
update_member_info, group_current_status
|
||||||
|
from nonebot.adapters.cqhttp.permission import GROUP
|
||||||
|
from services.log import logger
|
||||||
|
from configs.config import plugins2name_dict
|
||||||
|
from nonebot.plugin import export
|
||||||
|
|
||||||
|
__plugin_usage__ = '''自定义进群欢迎消息:
|
||||||
|
自定义进群欢迎消息 xxxx(图片)
|
||||||
|
示例:自定义进群欢迎消息 欢迎新人!(后面可以跟一张图片噢)'''
|
||||||
|
|
||||||
|
export = export()
|
||||||
|
export.update_member_info = update_member_info
|
||||||
|
|
||||||
|
cmds = []
|
||||||
|
for cmd_list in plugins2name_dict.values():
|
||||||
|
for cmd in cmd_list:
|
||||||
|
cmds.append(f'开启{cmd}')
|
||||||
|
cmds.append(f'关闭{cmd}')
|
||||||
|
cmds = set(cmds)
|
||||||
|
|
||||||
|
group_status = on_command('oc_reminds', aliases={'开启早晚安', '关闭早晚安',
|
||||||
|
'开启进群欢迎', '关闭进群欢迎',
|
||||||
|
'开启每日开箱重置提醒', '关闭每日开箱重置提醒',
|
||||||
|
'开启b站转发解析', '关闭b站转发解析',
|
||||||
|
'开启epic通知', '关闭epic通知',
|
||||||
|
'开启丢人爬', '关闭丢人爬',
|
||||||
|
'开启原神黄历提醒', '关闭原神黄历提醒',
|
||||||
|
'开启全部通知', '开启所有通知', '关闭全部通知', '关闭所有通知',
|
||||||
|
'群通知状态'}, permission=GROUP, priority=4, block=True)
|
||||||
|
|
||||||
|
switch_rule = on_command('switch_rule', aliases=cmds, permission=GROUP, priority=4, block=True)
|
||||||
|
custom_welcome = on_command('自定义进群欢迎消息', aliases={'自定义欢迎消息', '自定义群欢迎消息'}, permission=GROUP, priority=5, block=True)
|
||||||
|
refresh_member_group = on_command("更新群组成员列表", aliases={"更新群组成员信息"}, permission=GROUP, priority=5, block=True)
|
||||||
|
|
||||||
|
|
||||||
|
@switch_rule.handle()
|
||||||
|
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
|
||||||
|
await switch_rule.send(await change_group_switch(state["_prefix"]["raw_command"].strip(), event.group_id))
|
||||||
|
logger.info(f'USER {event.user_id} GROUP {event.group_id} 使用群功能管理命令 {state["_prefix"]["raw_command"]}')
|
||||||
|
|
||||||
|
|
||||||
|
@group_status.handle()
|
||||||
|
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
|
||||||
|
if state["_prefix"]["raw_command"] in ['群通知状态']:
|
||||||
|
await group_status.finish(await group_current_status(event.group_id))
|
||||||
|
await group_status.send(await set_group_status(state["_prefix"]["raw_command"], event.group_id),
|
||||||
|
at_sender=True)
|
||||||
|
logger.info(f'USER {event.user_id} GROUP {event.group_id} 使用群通知管理命令 {state["_prefix"]["raw_command"]}')
|
||||||
|
|
||||||
|
|
||||||
|
@custom_welcome.handle()
|
||||||
|
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
|
||||||
|
if str(event.get_message()) in ['帮助'] or str(event.get_message()) == '':
|
||||||
|
await custom_welcome.finish(__plugin_usage__)
|
||||||
|
msg = get_message_text(event.json())
|
||||||
|
imgs = get_message_imgs(event.json())
|
||||||
|
await custom_welcome.finish(await custom_group_welcome(msg, imgs, event.user_id, event.group_id), at_sender=True)
|
||||||
|
|
||||||
|
|
||||||
|
@refresh_member_group.handle()
|
||||||
|
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
|
||||||
|
if await update_member_info(event.group_id):
|
||||||
|
await refresh_member_group.finish("更新群员信息成功!", at_sender=True)
|
||||||
|
else:
|
||||||
|
await refresh_member_group.finish("更新群员信息失败!", at_sender=True)
|
||||||
|
|
||||||
|
|
||||||
|
# 自动更新群员信息
|
||||||
|
@scheduler.scheduled_job(
|
||||||
|
'cron',
|
||||||
|
hour=2,
|
||||||
|
minute=1,
|
||||||
|
)
|
||||||
|
async def _():
|
||||||
|
bot = get_bot()
|
||||||
|
gl = await bot.get_group_list(self_id=bot.self_id)
|
||||||
|
gl = [g['group_id'] for g in gl]
|
||||||
|
for g in gl:
|
||||||
|
try:
|
||||||
|
await update_member_info(g)
|
||||||
|
logger.info(f'更新群组 g:{g} 成功')
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f'更新群组错误 g:{g} e:{e}')
|
||||||
BIN
plugins/admin_bot_manage/__pycache__/__init__.cpython-38.pyc
Normal file
BIN
plugins/admin_bot_manage/__pycache__/__init__.cpython-38.pyc
Normal file
Binary file not shown.
BIN
plugins/admin_bot_manage/__pycache__/__init__.cpython-39.pyc
Normal file
BIN
plugins/admin_bot_manage/__pycache__/__init__.cpython-39.pyc
Normal file
Binary file not shown.
BIN
plugins/admin_bot_manage/__pycache__/data_source.cpython-38.pyc
Normal file
BIN
plugins/admin_bot_manage/__pycache__/data_source.cpython-38.pyc
Normal file
Binary file not shown.
BIN
plugins/admin_bot_manage/__pycache__/data_source.cpython-39.pyc
Normal file
BIN
plugins/admin_bot_manage/__pycache__/data_source.cpython-39.pyc
Normal file
Binary file not shown.
210
plugins/admin_bot_manage/data_source.py
Normal file
210
plugins/admin_bot_manage/data_source.py
Normal file
@ -0,0 +1,210 @@
|
|||||||
|
from models.group_remind import GroupRemind
|
||||||
|
from services.log import logger
|
||||||
|
from configs.path_config import DATA_PATH
|
||||||
|
import os
|
||||||
|
import aiofiles
|
||||||
|
import aiohttp
|
||||||
|
from util.init_result import image
|
||||||
|
from util.utils import get_local_proxy, get_bot
|
||||||
|
from pathlib import Path
|
||||||
|
from nonebot import require
|
||||||
|
from configs.config import plugins2name_dict
|
||||||
|
from models.group_member_info import GroupInfoUser
|
||||||
|
import time
|
||||||
|
from datetime import datetime
|
||||||
|
from services.db_context import db
|
||||||
|
from models.level_user import LevelUser
|
||||||
|
from configs.config import ADMIN_DEFAULT_AUTH
|
||||||
|
try:
|
||||||
|
import ujson as json
|
||||||
|
except ModuleNotFoundError:
|
||||||
|
import json
|
||||||
|
|
||||||
|
|
||||||
|
export = require("nonebot_plugin_manager")
|
||||||
|
|
||||||
|
|
||||||
|
command_dict = {
|
||||||
|
'早晚安': 'zwa',
|
||||||
|
'进群欢迎': 'hy',
|
||||||
|
'每日开箱重置提醒': 'kxcz',
|
||||||
|
'b站转发解析': 'blpar',
|
||||||
|
'epic': 'epic',
|
||||||
|
'丢人爬': 'pa',
|
||||||
|
'原神黄历提醒': 'almanac',
|
||||||
|
}
|
||||||
|
command_list = list(command_dict.values())
|
||||||
|
command_info_dt = {
|
||||||
|
'早晚安': '将会在每晚11:59晚安,在6:01早安哦',
|
||||||
|
'每日开箱重置提醒': '将会在每日00:01提示开箱重置!',
|
||||||
|
'epic': '将会在每日中午12:01发送可白嫖的epic游戏',
|
||||||
|
'原神黄历提醒': '将会在每日8:00发送当日的原神黄历',
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async def remind_status(group: int, name: str, flag: bool) -> str:
|
||||||
|
_name = ''
|
||||||
|
if name in command_dict.values():
|
||||||
|
_name = list(command_dict.keys())[list(command_dict.values()).index(name)]
|
||||||
|
if flag:
|
||||||
|
rst = '开启'
|
||||||
|
if await GroupRemind.get_status(group, name):
|
||||||
|
return f'该群已经{rst}过 {_name},请勿重复开启!'
|
||||||
|
else:
|
||||||
|
rst = '关闭'
|
||||||
|
if not await GroupRemind.get_status(group, name):
|
||||||
|
return f'该群已经{rst}过 {_name},请勿重复开启!'
|
||||||
|
if await GroupRemind.set_status(group, name, flag):
|
||||||
|
info = command_info_dt[_name] if command_info_dt.get(_name) else ''
|
||||||
|
if info:
|
||||||
|
info = '\n' + info
|
||||||
|
return f'成功{rst} {_name}!0v0 {info}'
|
||||||
|
else:
|
||||||
|
return f'{rst} {_name} 失败了...'
|
||||||
|
|
||||||
|
|
||||||
|
async def set_group_status(name: str, group_id: int):
|
||||||
|
flag = None
|
||||||
|
if name[:2] == '开启':
|
||||||
|
flag = True
|
||||||
|
elif name[:2] == '关闭':
|
||||||
|
flag = False
|
||||||
|
cmd = name[2:]
|
||||||
|
if cmd in ['全部通知', '所有通知']:
|
||||||
|
for command in command_list:
|
||||||
|
await remind_status(group_id, command, flag)
|
||||||
|
return f'已{name[:2]}所有通知!'
|
||||||
|
return await remind_status(group_id, command_dict[cmd], flag)
|
||||||
|
|
||||||
|
|
||||||
|
async def group_current_status(group_id: int):
|
||||||
|
result = f'(被动技能)\n早晚安通知:{"√" if await GroupRemind.get_status(group_id, "zwa") else "×"}\n' \
|
||||||
|
f'进群欢迎:{"√" if await GroupRemind.get_status(group_id, "hy") else "×"}\n' \
|
||||||
|
f'每日开箱重置通知:{"√" if await GroupRemind.get_status(group_id, "kxcz") else "×"}\n' \
|
||||||
|
f'b站转发解析:{"√" if await GroupRemind.get_status(group_id, "blpar") else "×"}\n' \
|
||||||
|
f'丢人爬:{"√" if await GroupRemind.get_status(group_id, "pa") else "×"}\n' \
|
||||||
|
f'epic免费游戏:{"√" if await GroupRemind.get_status(group_id, "epic") else "×"}\n' \
|
||||||
|
f'原神黄历提醒:{"√" if await GroupRemind.get_status(group_id, "almanac") else "×"}'
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
custom_welcome_msg_json = Path() / "data" / "custom_welcome_msg" / "custom_welcome_msg.json"
|
||||||
|
|
||||||
|
|
||||||
|
async def custom_group_welcome(msg, imgs, user_id, group_id):
|
||||||
|
img_result = ''
|
||||||
|
img = imgs[0] if imgs else ''
|
||||||
|
result = ''
|
||||||
|
if os.path.exists(DATA_PATH + f'custom_welcome_msg/{group_id}.jpg'):
|
||||||
|
os.remove(DATA_PATH + f'custom_welcome_msg/{group_id}.jpg')
|
||||||
|
# print(custom_welcome_msg_json)
|
||||||
|
if not custom_welcome_msg_json.exists():
|
||||||
|
custom_welcome_msg_json.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
data = {}
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
data = json.load(open(custom_welcome_msg_json, 'r'))
|
||||||
|
except FileNotFoundError:
|
||||||
|
data = {}
|
||||||
|
try:
|
||||||
|
if msg:
|
||||||
|
data[str(group_id)] = str(msg)
|
||||||
|
json.dump(data, open(custom_welcome_msg_json, 'w'), indent=4, ensure_ascii=False)
|
||||||
|
logger.info(f'USER {user_id} GROUP {group_id} 更换群欢迎消息 {msg}')
|
||||||
|
result += msg
|
||||||
|
if img:
|
||||||
|
async with aiohttp.ClientSession() as session:
|
||||||
|
async with session.get(img, proxy=get_local_proxy()) as response:
|
||||||
|
async with aiofiles.open(DATA_PATH + f'custom_welcome_msg/{group_id}.jpg', 'wb') as f:
|
||||||
|
await f.write(await response.read())
|
||||||
|
img_result = image(abspath=DATA_PATH + f'custom_welcome_msg/{group_id}.jpg')
|
||||||
|
logger.info(f'USER {user_id} GROUP {group_id} 更换群欢迎消息图片')
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f'GROUP {group_id} 替换群消息失败 e:{e}')
|
||||||
|
return '替换群消息失败..'
|
||||||
|
return f'替换群欢迎消息成功:\n{result}' + img_result
|
||||||
|
|
||||||
|
|
||||||
|
async def change_group_switch(cmd: str, group_id: int):
|
||||||
|
group_id = str(group_id)
|
||||||
|
status = cmd[:2]
|
||||||
|
cmd = cmd[2:]
|
||||||
|
try:
|
||||||
|
with open(DATA_PATH + 'manager/plugin_list.json', 'r', encoding='utf8') as f:
|
||||||
|
plugin_list = json.load(f)
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
except FileNotFoundError:
|
||||||
|
pass
|
||||||
|
for plugin_cmd in plugins2name_dict.keys():
|
||||||
|
if cmd in plugins2name_dict[plugin_cmd]:
|
||||||
|
# print(plugin_list[plugin_cmd])
|
||||||
|
if status == '开启':
|
||||||
|
# if group_id in plugin_list[plugin_cmd]:
|
||||||
|
if group_id not in plugin_list[plugin_cmd] or plugin_list[plugin_cmd][group_id]:
|
||||||
|
return f'功能 {cmd} 正处于开启状态!不要重复开启.'
|
||||||
|
export.unblock_plugin(group_id, plugin_cmd)
|
||||||
|
else:
|
||||||
|
if group_id in plugin_list[plugin_cmd]:
|
||||||
|
if not plugin_list[plugin_cmd][group_id]:
|
||||||
|
return f'功能 {cmd} 正处于关闭状态!不要重复关闭.'
|
||||||
|
export.block_plugin(group_id, plugin_cmd)
|
||||||
|
if os.path.exists(DATA_PATH + f'group_help/{group_id}.png'):
|
||||||
|
os.remove(DATA_PATH + f'group_help/{group_id}.png')
|
||||||
|
|
||||||
|
return f'{status} {cmd} 功能!'
|
||||||
|
return f'没有找到 {cmd} 功能喔'
|
||||||
|
|
||||||
|
|
||||||
|
async def update_member_info(group_id: int) -> bool:
|
||||||
|
bot = get_bot()
|
||||||
|
_group_user_list = await bot.get_group_member_list(group_id=group_id)
|
||||||
|
_error_member_list = []
|
||||||
|
_exist_member_list = []
|
||||||
|
# try:
|
||||||
|
for user_info in _group_user_list:
|
||||||
|
if user_info['card'] == "":
|
||||||
|
nickname = user_info['nickname']
|
||||||
|
else:
|
||||||
|
nickname = user_info['card']
|
||||||
|
async with db.transaction():
|
||||||
|
# 更新权限
|
||||||
|
if user_info['role'] in ['owner', 'admin'] and not await LevelUser.is_group_flag(user_info['user_id'], group_id):
|
||||||
|
await LevelUser.set_level(user_info['user_id'], user_info['group_id'], ADMIN_DEFAULT_AUTH)
|
||||||
|
if str(user_info['user_id']) in bot.config.superusers:
|
||||||
|
await LevelUser.set_level(user_info['user_id'], user_info['group_id'], 9)
|
||||||
|
user = await GroupInfoUser.select_member_info(user_info['user_id'], user_info['group_id'])
|
||||||
|
if user:
|
||||||
|
if user.user_name != nickname:
|
||||||
|
await user.update(user_name=nickname).apply()
|
||||||
|
logger.info(f"用户{user_info['user_id']} 所属{user_info['group_id']} 更新群昵称成功")
|
||||||
|
_exist_member_list.append(int(user_info['user_id']))
|
||||||
|
continue
|
||||||
|
join_time = datetime.strptime(
|
||||||
|
time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(user_info['join_time'])), "%Y-%m-%d %H:%M:%S")
|
||||||
|
if await GroupInfoUser.insert(
|
||||||
|
user_info['user_id'],
|
||||||
|
user_info['group_id'],
|
||||||
|
nickname,
|
||||||
|
join_time,):
|
||||||
|
_exist_member_list.append(int(user_info['user_id']))
|
||||||
|
logger.info(f"用户{user_info['user_id']} 所属{user_info['group_id']} 更新成功")
|
||||||
|
else:
|
||||||
|
_error_member_list.append(f"用户{user_info['user_id']} 所属{user_info['group_id']} 更新失败\n")
|
||||||
|
_del_member_list = list(set(_exist_member_list).difference(set(await GroupInfoUser.query_group_member_list(group_id))))
|
||||||
|
if _del_member_list:
|
||||||
|
for del_user in _del_member_list:
|
||||||
|
if await GroupInfoUser.delete_member_info(del_user, group_id):
|
||||||
|
logger.info(f"退群用户{del_user} 所属{group_id} 已删除")
|
||||||
|
else:
|
||||||
|
logger.info(f"退群用户{del_user} 所属{group_id} 删除失败")
|
||||||
|
if _error_member_list:
|
||||||
|
result = ""
|
||||||
|
for error_user in _error_member_list:
|
||||||
|
result += error_user
|
||||||
|
await bot.send_private_msg(user_id=int(list(bot.config.superusers)[0]), message=result[:-1])
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
27
plugins/admin_config.py
Normal file
27
plugins/admin_config.py
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
from nonebot import on_notice
|
||||||
|
from services.log import logger
|
||||||
|
from nonebot.adapters.cqhttp import Bot, GroupAdminNoticeEvent
|
||||||
|
from nonebot.typing import T_State
|
||||||
|
from models.level_user import LevelUser
|
||||||
|
from models.group_member_info import GroupInfoUser
|
||||||
|
from configs.config import ADMIN_DEFAULT_AUTH
|
||||||
|
|
||||||
|
|
||||||
|
admin_notice = on_notice(priority=5)
|
||||||
|
|
||||||
|
|
||||||
|
@admin_notice.handle()
|
||||||
|
async def _(bot: Bot, event: GroupAdminNoticeEvent, state: T_State):
|
||||||
|
try:
|
||||||
|
nickname = (await GroupInfoUser.select_member_info(event.user_id, event.group_id)).user_name
|
||||||
|
except AttributeError:
|
||||||
|
nickname = event.user_id
|
||||||
|
if event.sub_type == 'set':
|
||||||
|
await LevelUser.set_level(event.user_id, event.group_id, ADMIN_DEFAULT_AUTH)
|
||||||
|
logger.info(f'为新晋管理员 {nickname}({event.user_id}) 添加权限等级:{ADMIN_DEFAULT_AUTH}')
|
||||||
|
if event.sub_type == 'unset':
|
||||||
|
await LevelUser.delete_level(event.user_id, event.group_id)
|
||||||
|
logger.info(f'将非管理员 {nickname}({event.user_id}) 取消权限等级')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
46
plugins/admin_help/__init__.py
Normal file
46
plugins/admin_help/__init__.py
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
from nonebot import on_command
|
||||||
|
from nonebot.typing import T_State
|
||||||
|
from nonebot.adapters import Bot
|
||||||
|
from nonebot.adapters.cqhttp import GroupMessageEvent
|
||||||
|
from util.img_utils import CreateImg
|
||||||
|
from configs.path_config import IMAGE_PATH
|
||||||
|
from util.init_result import image
|
||||||
|
|
||||||
|
|
||||||
|
__plugin_name__ = '管理帮助 [Hidden]'
|
||||||
|
__plugin_usage__ = '''管理帮助(权限等级):
|
||||||
|
1.更新群组成员列表(1)
|
||||||
|
2.功能开关 --> 指令:开启/关闭xx功能(2)
|
||||||
|
3.查看群被动技能 --> 指令:群通知状态(2)
|
||||||
|
4.自定义群欢迎 --> 指令:自定义进群欢迎消息(2)
|
||||||
|
5.将用户拉入真寻黑名单 --> .ban/.unban(5)
|
||||||
|
6.刷屏禁言相关 --> 指令:刷屏检测设置/设置检测时间
|
||||||
|
\t\t/设置检测次数/设置禁言时长(5)
|
||||||
|
7.上传图片(6)
|
||||||
|
8.移动图片(7)
|
||||||
|
9.删除图片(7)
|
||||||
|
对我说 “指令名 帮助” 获取对应详细帮助
|
||||||
|
群主与管理员默认 5 级权限
|
||||||
|
'''
|
||||||
|
|
||||||
|
passive_help = '''【被动技能开关(2):
|
||||||
|
开启/关闭进群欢迎
|
||||||
|
开启/关闭每日开箱重置提醒
|
||||||
|
开启/关闭b站转发解析
|
||||||
|
开启/关闭丢人爬
|
||||||
|
开启/关闭epic通知
|
||||||
|
开启/关闭全部通知
|
||||||
|
开启/关闭原神黄历提醒】
|
||||||
|
'''
|
||||||
|
|
||||||
|
admin_help = on_command("管理员帮助", aliases={"管理帮助"}, priority=5, block=True)
|
||||||
|
|
||||||
|
admin_help_img = CreateImg(1000, 600, font_size=24)
|
||||||
|
admin_help_img.text((10, 10), __plugin_usage__)
|
||||||
|
admin_help_img.paste(CreateImg(400, 600, font_size=24).text((0, 0), passive_help), (600, 50))
|
||||||
|
admin_help_img.save(IMAGE_PATH + 'admin_help_img.png')
|
||||||
|
|
||||||
|
|
||||||
|
@admin_help.handle()
|
||||||
|
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
|
||||||
|
await admin_help.send(image('admin_help_img.png'))
|
||||||
BIN
plugins/admin_help/__pycache__/__init__.cpython-38.pyc
Normal file
BIN
plugins/admin_help/__pycache__/__init__.cpython-38.pyc
Normal file
Binary file not shown.
BIN
plugins/admin_help/__pycache__/__init__.cpython-39.pyc
Normal file
BIN
plugins/admin_help/__pycache__/__init__.cpython-39.pyc
Normal file
Binary file not shown.
61
plugins/ai/__init__.py
Normal file
61
plugins/ai/__init__.py
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
from .data_source import get_qqbot_chat_result, hello, no_result
|
||||||
|
from services.log import logger
|
||||||
|
from nonebot import on_message
|
||||||
|
from nonebot.rule import to_me
|
||||||
|
from nonebot.typing import T_State
|
||||||
|
from nonebot.adapters.cqhttp import Bot, GroupMessageEvent, PrivateMessageEvent
|
||||||
|
from util.utils import get_message_text, get_message_imgs
|
||||||
|
from models.friend_user import FriendUser
|
||||||
|
from models.group_member_info import GroupInfoUser
|
||||||
|
|
||||||
|
__plugin_name__ = 'AI'
|
||||||
|
|
||||||
|
|
||||||
|
ai = on_message(rule=to_me(), priority=8)
|
||||||
|
|
||||||
|
|
||||||
|
@ai.handle()
|
||||||
|
async def _(bot: Bot, event: PrivateMessageEvent, state: T_State):
|
||||||
|
msg = get_message_text(event.json())
|
||||||
|
imgs = get_message_imgs(event.json())
|
||||||
|
if str(event.get_message()).find('CQ:xml') != -1:
|
||||||
|
return
|
||||||
|
# 打招呼
|
||||||
|
if not msg and not imgs:
|
||||||
|
await ai.finish(hello())
|
||||||
|
img = imgs[0] if imgs else ''
|
||||||
|
nickname = await FriendUser.get_friend_nickname(event.user_id)
|
||||||
|
if not nickname:
|
||||||
|
nickname = await FriendUser.get_user_name(event.user_id)
|
||||||
|
if not nickname:
|
||||||
|
nickname = "你"
|
||||||
|
result = await get_qqbot_chat_result(msg, img, event.user_id, nickname)
|
||||||
|
logger.info(f"USER {event.user_id} 问题:{msg}\n回答:{result}")
|
||||||
|
if result:
|
||||||
|
await ai.finish(result)
|
||||||
|
else:
|
||||||
|
await ai.finish(no_result())
|
||||||
|
|
||||||
|
|
||||||
|
@ai.handle()
|
||||||
|
async def _(bot: Bot, event: GroupMessageEvent, state: T_State):
|
||||||
|
# if await GroupRemind.get_status(event.group_id, 'ai'):
|
||||||
|
msg = get_message_text(event.json())
|
||||||
|
imgs = get_message_imgs(event.json())
|
||||||
|
# 打招呼
|
||||||
|
if not msg and not imgs:
|
||||||
|
await ai.finish(hello())
|
||||||
|
img = imgs[0] if imgs else ''
|
||||||
|
nickname = await GroupInfoUser.get_group_member_nickname(event.user_id, event.group_id)
|
||||||
|
if not nickname:
|
||||||
|
try:
|
||||||
|
nickname = (await GroupInfoUser.select_member_info(event.user_id, event.group_id)).user_name
|
||||||
|
except AttributeError:
|
||||||
|
nickname = "你"
|
||||||
|
result = await get_qqbot_chat_result(msg, img, event.user_id, nickname)
|
||||||
|
logger.info(f"问题:{msg}\n回答:{result}")
|
||||||
|
if result:
|
||||||
|
await ai.finish(result)
|
||||||
|
else:
|
||||||
|
await ai.finish(no_result())
|
||||||
|
|
||||||
BIN
plugins/ai/__pycache__/__init__.cpython-38.pyc
Normal file
BIN
plugins/ai/__pycache__/__init__.cpython-38.pyc
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user