diff --git a/.env b/.env new file mode 100644 index 00000000..17cba72e --- /dev/null +++ b/.env @@ -0,0 +1 @@ +ENVIRONMENT=dev \ No newline at end of file diff --git a/.env.dev b/.env.dev new file mode 100644 index 00000000..4bb3adfc --- /dev/null +++ b/.env.dev @@ -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 diff --git a/bot.py b/bot.py new file mode 100644 index 00000000..2244a30a --- /dev/null +++ b/bot.py @@ -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'} + + + diff --git a/configs/__pycache__/config.cpython-39.pyc b/configs/__pycache__/config.cpython-39.pyc new file mode 100644 index 00000000..f19513ba Binary files /dev/null and b/configs/__pycache__/config.cpython-39.pyc differ diff --git a/configs/__pycache__/path_config.cpython-39.pyc b/configs/__pycache__/path_config.cpython-39.pyc new file mode 100644 index 00000000..e1325544 Binary files /dev/null and b/configs/__pycache__/path_config.cpython-39.pyc differ diff --git a/configs/config.py b/configs/config.py new file mode 100644 index 00000000..509b0151 --- /dev/null +++ b/configs/config.py @@ -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) + + + + + diff --git a/configs/path_config.py b/configs/path_config.py new file mode 100644 index 00000000..0fffc5ed --- /dev/null +++ b/configs/path_config.py @@ -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) diff --git a/configs/utils/__pycache__/util.cpython-39.pyc b/configs/utils/__pycache__/util.cpython-39.pyc new file mode 100644 index 00000000..3ec6590c Binary files /dev/null and b/configs/utils/__pycache__/util.cpython-39.pyc differ diff --git a/configs/utils/util.py b/configs/utils/util.py new file mode 100644 index 00000000..c8118a8b --- /dev/null +++ b/configs/utils/util.py @@ -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 + + + diff --git a/data/anime.json b/data/anime.json new file mode 100644 index 00000000..d2a0aef1 --- /dev/null +++ b/data/anime.json @@ -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" + ] +} diff --git a/models/__pycache__/bag_user.cpython-38.pyc b/models/__pycache__/bag_user.cpython-38.pyc new file mode 100644 index 00000000..8d6fa903 Binary files /dev/null and b/models/__pycache__/bag_user.cpython-38.pyc differ diff --git a/models/__pycache__/bag_user.cpython-39.pyc b/models/__pycache__/bag_user.cpython-39.pyc new file mode 100644 index 00000000..006382c6 Binary files /dev/null and b/models/__pycache__/bag_user.cpython-39.pyc differ diff --git a/models/__pycache__/ban_user.cpython-38.pyc b/models/__pycache__/ban_user.cpython-38.pyc new file mode 100644 index 00000000..ed4e7bdb Binary files /dev/null and b/models/__pycache__/ban_user.cpython-38.pyc differ diff --git a/models/__pycache__/ban_user.cpython-39.pyc b/models/__pycache__/ban_user.cpython-39.pyc new file mode 100644 index 00000000..5153464e Binary files /dev/null and b/models/__pycache__/ban_user.cpython-39.pyc differ diff --git a/models/__pycache__/buff_price.cpython-38.pyc b/models/__pycache__/buff_price.cpython-38.pyc new file mode 100644 index 00000000..76edac6a Binary files /dev/null and b/models/__pycache__/buff_price.cpython-38.pyc differ diff --git a/models/__pycache__/buff_price.cpython-39.pyc b/models/__pycache__/buff_price.cpython-39.pyc new file mode 100644 index 00000000..fec50cc4 Binary files /dev/null and b/models/__pycache__/buff_price.cpython-39.pyc differ diff --git a/models/__pycache__/count_user.cpython-38.pyc b/models/__pycache__/count_user.cpython-38.pyc new file mode 100644 index 00000000..5dfdcdd4 Binary files /dev/null and b/models/__pycache__/count_user.cpython-38.pyc differ diff --git a/models/__pycache__/count_user.cpython-39.pyc b/models/__pycache__/count_user.cpython-39.pyc new file mode 100644 index 00000000..45be2eed Binary files /dev/null and b/models/__pycache__/count_user.cpython-39.pyc differ diff --git a/models/__pycache__/friend_user.cpython-38.pyc b/models/__pycache__/friend_user.cpython-38.pyc new file mode 100644 index 00000000..c5d76c39 Binary files /dev/null and b/models/__pycache__/friend_user.cpython-38.pyc differ diff --git a/models/__pycache__/friend_user.cpython-39.pyc b/models/__pycache__/friend_user.cpython-39.pyc new file mode 100644 index 00000000..0e627b4c Binary files /dev/null and b/models/__pycache__/friend_user.cpython-39.pyc differ diff --git a/models/__pycache__/group_info.cpython-38.pyc b/models/__pycache__/group_info.cpython-38.pyc new file mode 100644 index 00000000..1b0b8e46 Binary files /dev/null and b/models/__pycache__/group_info.cpython-38.pyc differ diff --git a/models/__pycache__/group_info.cpython-39.pyc b/models/__pycache__/group_info.cpython-39.pyc new file mode 100644 index 00000000..5ea59da3 Binary files /dev/null and b/models/__pycache__/group_info.cpython-39.pyc differ diff --git a/models/__pycache__/group_member_info.cpython-38.pyc b/models/__pycache__/group_member_info.cpython-38.pyc new file mode 100644 index 00000000..cd427a7c Binary files /dev/null and b/models/__pycache__/group_member_info.cpython-38.pyc differ diff --git a/models/__pycache__/group_member_info.cpython-39.pyc b/models/__pycache__/group_member_info.cpython-39.pyc new file mode 100644 index 00000000..a8bfda9d Binary files /dev/null and b/models/__pycache__/group_member_info.cpython-39.pyc differ diff --git a/models/__pycache__/group_remind.cpython-38.pyc b/models/__pycache__/group_remind.cpython-38.pyc new file mode 100644 index 00000000..9b96bd72 Binary files /dev/null and b/models/__pycache__/group_remind.cpython-38.pyc differ diff --git a/models/__pycache__/group_remind.cpython-39.pyc b/models/__pycache__/group_remind.cpython-39.pyc new file mode 100644 index 00000000..88eca93f Binary files /dev/null and b/models/__pycache__/group_remind.cpython-39.pyc differ diff --git a/models/__pycache__/level_user.cpython-38.pyc b/models/__pycache__/level_user.cpython-38.pyc new file mode 100644 index 00000000..5dcb3809 Binary files /dev/null and b/models/__pycache__/level_user.cpython-38.pyc differ diff --git a/models/__pycache__/level_user.cpython-39.pyc b/models/__pycache__/level_user.cpython-39.pyc new file mode 100644 index 00000000..61b4cc83 Binary files /dev/null and b/models/__pycache__/level_user.cpython-39.pyc differ diff --git a/models/__pycache__/open_cases_user.cpython-38.pyc b/models/__pycache__/open_cases_user.cpython-38.pyc new file mode 100644 index 00000000..00d3ebba Binary files /dev/null and b/models/__pycache__/open_cases_user.cpython-38.pyc differ diff --git a/models/__pycache__/open_cases_user.cpython-39.pyc b/models/__pycache__/open_cases_user.cpython-39.pyc new file mode 100644 index 00000000..13941238 Binary files /dev/null and b/models/__pycache__/open_cases_user.cpython-39.pyc differ diff --git a/models/__pycache__/sigin_group_user.cpython-38.pyc b/models/__pycache__/sigin_group_user.cpython-38.pyc new file mode 100644 index 00000000..67abd98e Binary files /dev/null and b/models/__pycache__/sigin_group_user.cpython-38.pyc differ diff --git a/models/__pycache__/sigin_group_user.cpython-39.pyc b/models/__pycache__/sigin_group_user.cpython-39.pyc new file mode 100644 index 00000000..7a2c5918 Binary files /dev/null and b/models/__pycache__/sigin_group_user.cpython-39.pyc differ diff --git a/models/bag_user.py b/models/bag_user.py new file mode 100644 index 00000000..9952e156 --- /dev/null +++ b/models/bag_user.py @@ -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 + + + + + + + + diff --git a/models/ban_user.py b/models/ban_user.py new file mode 100644 index 00000000..3172b6df --- /dev/null +++ b/models/ban_user.py @@ -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 diff --git a/models/buff_price.py b/models/buff_price.py new file mode 100644 index 00000000..510743ca --- /dev/null +++ b/models/buff_price.py @@ -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, + ) + diff --git a/models/count_user.py b/models/count_user.py new file mode 100644 index 00000000..81a8a72e --- /dev/null +++ b/models/count_user.py @@ -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() + + + + diff --git a/models/friend_user.py b/models/friend_user.py new file mode 100644 index 00000000..d32801a0 --- /dev/null +++ b/models/friend_user.py @@ -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 diff --git a/models/group_info.py b/models/group_info.py new file mode 100644 index 00000000..63beb498 --- /dev/null +++ b/models/group_info.py @@ -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 + + diff --git a/models/group_member_info.py b/models/group_member_info.py new file mode 100644 index 00000000..5dbc4879 --- /dev/null +++ b/models/group_member_info.py @@ -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 '' + + + + + + diff --git a/models/group_remind.py b/models/group_remind.py new file mode 100644 index 00000000..8437ab8a --- /dev/null +++ b/models/group_remind.py @@ -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 + + + + + + + + + + diff --git a/models/level_user.py b/models/level_user.py new file mode 100644 index 00000000..2093f116 --- /dev/null +++ b/models/level_user.py @@ -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 + diff --git a/models/open_cases_user.py b/models/open_cases_user.py new file mode 100644 index 00000000..85c8c60e --- /dev/null +++ b/models/open_cases_user.py @@ -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 + + + + diff --git a/models/sigin_group_user.py b/models/sigin_group_user.py new file mode 100644 index 00000000..4b659182 --- /dev/null +++ b/models/sigin_group_user.py @@ -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 diff --git a/plugins/__init__.py b/plugins/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/plugins/__pycache__/__init__.cpython-38.pyc b/plugins/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..61e31c0d Binary files /dev/null and b/plugins/__pycache__/__init__.cpython-38.pyc differ diff --git a/plugins/__pycache__/__init__.cpython-39.pyc b/plugins/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 00000000..020e7d6d Binary files /dev/null and b/plugins/__pycache__/__init__.cpython-39.pyc differ diff --git a/plugins/__pycache__/add_dy.cpython-38.pyc b/plugins/__pycache__/add_dy.cpython-38.pyc new file mode 100644 index 00000000..7ce2a3b5 Binary files /dev/null and b/plugins/__pycache__/add_dy.cpython-38.pyc differ diff --git a/plugins/__pycache__/admin_config.cpython-38.pyc b/plugins/__pycache__/admin_config.cpython-38.pyc new file mode 100644 index 00000000..8a9208c5 Binary files /dev/null and b/plugins/__pycache__/admin_config.cpython-38.pyc differ diff --git a/plugins/__pycache__/admin_config.cpython-39.pyc b/plugins/__pycache__/admin_config.cpython-39.pyc new file mode 100644 index 00000000..916fc828 Binary files /dev/null and b/plugins/__pycache__/admin_config.cpython-39.pyc differ diff --git a/plugins/__pycache__/change_dy.cpython-38.pyc b/plugins/__pycache__/change_dy.cpython-38.pyc new file mode 100644 index 00000000..e5774a10 Binary files /dev/null and b/plugins/__pycache__/change_dy.cpython-38.pyc differ diff --git a/plugins/__pycache__/del_dy.cpython-38.pyc b/plugins/__pycache__/del_dy.cpython-38.pyc new file mode 100644 index 00000000..13f9d385 Binary files /dev/null and b/plugins/__pycache__/del_dy.cpython-38.pyc differ diff --git a/plugins/__pycache__/fake_msg.cpython-38.pyc b/plugins/__pycache__/fake_msg.cpython-38.pyc new file mode 100644 index 00000000..ea2ce00c Binary files /dev/null and b/plugins/__pycache__/fake_msg.cpython-38.pyc differ diff --git a/plugins/__pycache__/fake_msg.cpython-39.pyc b/plugins/__pycache__/fake_msg.cpython-39.pyc new file mode 100644 index 00000000..08a1dbf6 Binary files /dev/null and b/plugins/__pycache__/fake_msg.cpython-39.pyc differ diff --git a/plugins/__pycache__/fudu.cpython-38.pyc b/plugins/__pycache__/fudu.cpython-38.pyc new file mode 100644 index 00000000..55536dca Binary files /dev/null and b/plugins/__pycache__/fudu.cpython-38.pyc differ diff --git a/plugins/__pycache__/fudu.cpython-39.pyc b/plugins/__pycache__/fudu.cpython-39.pyc new file mode 100644 index 00000000..d21c499f Binary files /dev/null and b/plugins/__pycache__/fudu.cpython-39.pyc differ diff --git a/plugins/__pycache__/group_welcome_msg.cpython-38.pyc b/plugins/__pycache__/group_welcome_msg.cpython-38.pyc new file mode 100644 index 00000000..a6bfdf99 Binary files /dev/null and b/plugins/__pycache__/group_welcome_msg.cpython-38.pyc differ diff --git a/plugins/__pycache__/group_welcome_msg.cpython-39.pyc b/plugins/__pycache__/group_welcome_msg.cpython-39.pyc new file mode 100644 index 00000000..e73285b9 Binary files /dev/null and b/plugins/__pycache__/group_welcome_msg.cpython-39.pyc differ diff --git a/plugins/__pycache__/hook.cpython-38.pyc b/plugins/__pycache__/hook.cpython-38.pyc new file mode 100644 index 00000000..504dc298 Binary files /dev/null and b/plugins/__pycache__/hook.cpython-38.pyc differ diff --git a/plugins/__pycache__/hook.cpython-39.pyc b/plugins/__pycache__/hook.cpython-39.pyc new file mode 100644 index 00000000..4429fd30 Binary files /dev/null and b/plugins/__pycache__/hook.cpython-39.pyc differ diff --git a/plugins/__pycache__/jitang.cpython-38.pyc b/plugins/__pycache__/jitang.cpython-38.pyc new file mode 100644 index 00000000..d6dbb4bc Binary files /dev/null and b/plugins/__pycache__/jitang.cpython-38.pyc differ diff --git a/plugins/__pycache__/jitang.cpython-39.pyc b/plugins/__pycache__/jitang.cpython-39.pyc new file mode 100644 index 00000000..9e6c1051 Binary files /dev/null and b/plugins/__pycache__/jitang.cpython-39.pyc differ diff --git a/plugins/__pycache__/mute.cpython-38.pyc b/plugins/__pycache__/mute.cpython-38.pyc new file mode 100644 index 00000000..3931683d Binary files /dev/null and b/plugins/__pycache__/mute.cpython-38.pyc differ diff --git a/plugins/__pycache__/mute.cpython-39.pyc b/plugins/__pycache__/mute.cpython-39.pyc new file mode 100644 index 00000000..d33d11db Binary files /dev/null and b/plugins/__pycache__/mute.cpython-39.pyc differ diff --git a/plugins/__pycache__/my_info.cpython-38.pyc b/plugins/__pycache__/my_info.cpython-38.pyc new file mode 100644 index 00000000..6ee37bb7 Binary files /dev/null and b/plugins/__pycache__/my_info.cpython-38.pyc differ diff --git a/plugins/__pycache__/my_info.cpython-39.pyc b/plugins/__pycache__/my_info.cpython-39.pyc new file mode 100644 index 00000000..14304782 Binary files /dev/null and b/plugins/__pycache__/my_info.cpython-39.pyc differ diff --git a/plugins/__pycache__/nickname.cpython-38.pyc b/plugins/__pycache__/nickname.cpython-38.pyc new file mode 100644 index 00000000..9c59ba11 Binary files /dev/null and b/plugins/__pycache__/nickname.cpython-38.pyc differ diff --git a/plugins/__pycache__/nickname.cpython-39.pyc b/plugins/__pycache__/nickname.cpython-39.pyc new file mode 100644 index 00000000..29823fee Binary files /dev/null and b/plugins/__pycache__/nickname.cpython-39.pyc differ diff --git a/plugins/__pycache__/parse_bilibili_json.cpython-38.pyc b/plugins/__pycache__/parse_bilibili_json.cpython-38.pyc new file mode 100644 index 00000000..9c27968d Binary files /dev/null and b/plugins/__pycache__/parse_bilibili_json.cpython-38.pyc differ diff --git a/plugins/__pycache__/parse_bilibili_json.cpython-39.pyc b/plugins/__pycache__/parse_bilibili_json.cpython-39.pyc new file mode 100644 index 00000000..f648969e Binary files /dev/null and b/plugins/__pycache__/parse_bilibili_json.cpython-39.pyc differ diff --git a/plugins/__pycache__/quotations.cpython-38.pyc b/plugins/__pycache__/quotations.cpython-38.pyc new file mode 100644 index 00000000..1da2b002 Binary files /dev/null and b/plugins/__pycache__/quotations.cpython-38.pyc differ diff --git a/plugins/__pycache__/quotations.cpython-39.pyc b/plugins/__pycache__/quotations.cpython-39.pyc new file mode 100644 index 00000000..cece1c3d Binary files /dev/null and b/plugins/__pycache__/quotations.cpython-39.pyc differ diff --git a/plugins/__pycache__/server_ip.cpython-38.pyc b/plugins/__pycache__/server_ip.cpython-38.pyc new file mode 100644 index 00000000..4bc3755a Binary files /dev/null and b/plugins/__pycache__/server_ip.cpython-38.pyc differ diff --git a/plugins/__pycache__/server_ip.cpython-39.pyc b/plugins/__pycache__/server_ip.cpython-39.pyc new file mode 100644 index 00000000..ad404eb2 Binary files /dev/null and b/plugins/__pycache__/server_ip.cpython-39.pyc differ diff --git a/plugins/__pycache__/show_all.cpython-38.pyc b/plugins/__pycache__/show_all.cpython-38.pyc new file mode 100644 index 00000000..aff9e8ef Binary files /dev/null and b/plugins/__pycache__/show_all.cpython-38.pyc differ diff --git a/plugins/__pycache__/show_dy.cpython-38.pyc b/plugins/__pycache__/show_dy.cpython-38.pyc new file mode 100644 index 00000000..d0ad36b5 Binary files /dev/null and b/plugins/__pycache__/show_dy.cpython-38.pyc differ diff --git a/plugins/__pycache__/start.cpython-38.pyc b/plugins/__pycache__/start.cpython-38.pyc new file mode 100644 index 00000000..74da3032 Binary files /dev/null and b/plugins/__pycache__/start.cpython-38.pyc differ diff --git a/plugins/__pycache__/statistics_hook.cpython-39.pyc b/plugins/__pycache__/statistics_hook.cpython-39.pyc new file mode 100644 index 00000000..197e3151 Binary files /dev/null and b/plugins/__pycache__/statistics_hook.cpython-39.pyc differ diff --git a/plugins/__pycache__/test.cpython-38.pyc b/plugins/__pycache__/test.cpython-38.pyc new file mode 100644 index 00000000..8d400c85 Binary files /dev/null and b/plugins/__pycache__/test.cpython-38.pyc differ diff --git a/plugins/__pycache__/test.cpython-39.pyc b/plugins/__pycache__/test.cpython-39.pyc new file mode 100644 index 00000000..49b11867 Binary files /dev/null and b/plugins/__pycache__/test.cpython-39.pyc differ diff --git a/plugins/__pycache__/update_info.cpython-38.pyc b/plugins/__pycache__/update_info.cpython-38.pyc new file mode 100644 index 00000000..ece25f1f Binary files /dev/null and b/plugins/__pycache__/update_info.cpython-38.pyc differ diff --git a/plugins/__pycache__/update_info.cpython-39.pyc b/plugins/__pycache__/update_info.cpython-39.pyc new file mode 100644 index 00000000..4105d524 Binary files /dev/null and b/plugins/__pycache__/update_info.cpython-39.pyc differ diff --git a/plugins/__pycache__/update_pic.cpython-38.pyc b/plugins/__pycache__/update_pic.cpython-38.pyc new file mode 100644 index 00000000..d32b3c56 Binary files /dev/null and b/plugins/__pycache__/update_pic.cpython-38.pyc differ diff --git a/plugins/__pycache__/update_pic.cpython-39.pyc b/plugins/__pycache__/update_pic.cpython-39.pyc new file mode 100644 index 00000000..558c39e4 Binary files /dev/null and b/plugins/__pycache__/update_pic.cpython-39.pyc differ diff --git a/plugins/__pycache__/white2black_img.cpython-38.pyc b/plugins/__pycache__/white2black_img.cpython-38.pyc new file mode 100644 index 00000000..1d7a8d3e Binary files /dev/null and b/plugins/__pycache__/white2black_img.cpython-38.pyc differ diff --git a/plugins/__pycache__/white2black_img.cpython-39.pyc b/plugins/__pycache__/white2black_img.cpython-39.pyc new file mode 100644 index 00000000..1b5d8c59 Binary files /dev/null and b/plugins/__pycache__/white2black_img.cpython-39.pyc differ diff --git a/plugins/aconfig/__init__.py b/plugins/aconfig/__init__.py new file mode 100644 index 00000000..90221aec --- /dev/null +++ b/plugins/aconfig/__init__.py @@ -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) diff --git a/plugins/aconfig/__pycache__/__init__.cpython-38.pyc b/plugins/aconfig/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..42dacef3 Binary files /dev/null and b/plugins/aconfig/__pycache__/__init__.cpython-38.pyc differ diff --git a/plugins/aconfig/__pycache__/__init__.cpython-39.pyc b/plugins/aconfig/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 00000000..11dcfb37 Binary files /dev/null and b/plugins/aconfig/__pycache__/__init__.cpython-39.pyc differ diff --git a/plugins/admin_bot_manage/__init__.py b/plugins/admin_bot_manage/__init__.py new file mode 100644 index 00000000..891b1f82 --- /dev/null +++ b/plugins/admin_bot_manage/__init__.py @@ -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}') diff --git a/plugins/admin_bot_manage/__pycache__/__init__.cpython-38.pyc b/plugins/admin_bot_manage/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..5a1526bb Binary files /dev/null and b/plugins/admin_bot_manage/__pycache__/__init__.cpython-38.pyc differ diff --git a/plugins/admin_bot_manage/__pycache__/__init__.cpython-39.pyc b/plugins/admin_bot_manage/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 00000000..098a4cde Binary files /dev/null and b/plugins/admin_bot_manage/__pycache__/__init__.cpython-39.pyc differ diff --git a/plugins/admin_bot_manage/__pycache__/data_source.cpython-38.pyc b/plugins/admin_bot_manage/__pycache__/data_source.cpython-38.pyc new file mode 100644 index 00000000..6f9fd211 Binary files /dev/null and b/plugins/admin_bot_manage/__pycache__/data_source.cpython-38.pyc differ diff --git a/plugins/admin_bot_manage/__pycache__/data_source.cpython-39.pyc b/plugins/admin_bot_manage/__pycache__/data_source.cpython-39.pyc new file mode 100644 index 00000000..5437c578 Binary files /dev/null and b/plugins/admin_bot_manage/__pycache__/data_source.cpython-39.pyc differ diff --git a/plugins/admin_bot_manage/data_source.py b/plugins/admin_bot_manage/data_source.py new file mode 100644 index 00000000..48f312fd --- /dev/null +++ b/plugins/admin_bot_manage/data_source.py @@ -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 + + + + diff --git a/plugins/admin_config.py b/plugins/admin_config.py new file mode 100644 index 00000000..a2b7b4a6 --- /dev/null +++ b/plugins/admin_config.py @@ -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}) 取消权限等级') + + + diff --git a/plugins/admin_help/__init__.py b/plugins/admin_help/__init__.py new file mode 100644 index 00000000..2b1e8afc --- /dev/null +++ b/plugins/admin_help/__init__.py @@ -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')) diff --git a/plugins/admin_help/__pycache__/__init__.cpython-38.pyc b/plugins/admin_help/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..2a943938 Binary files /dev/null and b/plugins/admin_help/__pycache__/__init__.cpython-38.pyc differ diff --git a/plugins/admin_help/__pycache__/__init__.cpython-39.pyc b/plugins/admin_help/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 00000000..569123fd Binary files /dev/null and b/plugins/admin_help/__pycache__/__init__.cpython-39.pyc differ diff --git a/plugins/ai/__init__.py b/plugins/ai/__init__.py new file mode 100644 index 00000000..64a84913 --- /dev/null +++ b/plugins/ai/__init__.py @@ -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()) + diff --git a/plugins/ai/__pycache__/__init__.cpython-38.pyc b/plugins/ai/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..c8ad1e1f Binary files /dev/null and b/plugins/ai/__pycache__/__init__.cpython-38.pyc differ diff --git a/plugins/ai/__pycache__/__init__.cpython-39.pyc b/plugins/ai/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 00000000..f3e1b82b Binary files /dev/null and b/plugins/ai/__pycache__/__init__.cpython-39.pyc differ diff --git a/plugins/ai/__pycache__/data_source.cpython-38.pyc b/plugins/ai/__pycache__/data_source.cpython-38.pyc new file mode 100644 index 00000000..43b03ebe Binary files /dev/null and b/plugins/ai/__pycache__/data_source.cpython-38.pyc differ diff --git a/plugins/ai/__pycache__/data_source.cpython-39.pyc b/plugins/ai/__pycache__/data_source.cpython-39.pyc new file mode 100644 index 00000000..4eaa7fd0 Binary files /dev/null and b/plugins/ai/__pycache__/data_source.cpython-39.pyc differ diff --git a/plugins/ai/data_source.py b/plugins/ai/data_source.py new file mode 100644 index 00000000..bfc333bc --- /dev/null +++ b/plugins/ai/data_source.py @@ -0,0 +1,142 @@ +from configs.config import TL_KEY +import aiohttp +import random +import os +from configs.path_config import IMAGE_PATH, DATA_PATH +from util.init_result import image +from util.utils import get_bot + +try: + import ujson as json +except ModuleNotFoundError: + import json + +url = "http://openapi.tuling123.com/openapi/api/v2" + +index = 0 + +anime_data = json.load(open(DATA_PATH + 'anime.json', 'r', encoding='utf8')) + + +# 图灵AI +async def get_qqbot_chat_result(text: str, img_url: str, user_id: int, user_name: str) -> str: + global index + if index == 5: + index = 0 + if len(text) < 6 and random.random() < 0.6: + keys = anime_data.keys() + for key in keys: + if text.find(key) != -1: + return random.choice(anime_data[key]).replace('你', user_name) + if text: + req = { + "perception": + { + "inputText": + { + "text": text + }, + "selfInfo": + { + "location": + { + "city": "陨石坑", + "province": "火星", + "street": "第5坑位" + } + } + }, + "userInfo": + { + "apiKey": TL_KEY[index], + "userId": str(user_id) + } + } + elif img_url: + req = { + "reqType": 1, + "perception": + { + "inputImage": { + "url": img_url + }, + "selfInfo": + { + "location": + { + "city": "陨石坑", + "province": "火星", + "street": "第5坑位" + } + } + }, + "userInfo": + { + "apiKey": TL_KEY[index], + "userId": str(user_id) + } + } + async with aiohttp.ClientSession() as sess: + async with sess.post(url, json=req) as response: + if response.status != 200: + return '' + resp_payload = json.loads(await response.text()) + if resp_payload['intent']: + if resp_payload['intent']['code'] == 4003: + index += 1 + # 该AI很屑!!!!!!!!!!!! + async with sess.get(f'http://api.qingyunke.com/api.php?key=free&appid=0&msg={text}') as res: + data = json.loads(await res.text()) + if data['result'] == 0: + content = data['content'] + if content.find('菲菲') != -1: + content = content.replace('菲菲', list(get_bot().config.nickname)[0]) + if content.find('公众号') != -1: + content = '' + if content.find('{br}') != -1: + content = content.replace('{br}', '\n') + if content.find('提示') != -1: + content = content[:content.find('提示')] + return content + if resp_payload['results']: + for result in resp_payload['results']: + if result['resultType'] == 'text': + text = result['values']['text'] + if user_name: + text = text.replace('小朋友', user_name) + if len(user_name) < 5: + if random.random() < 0.5: + user_name = "~".join(user_name) + '~' + if random.random() < 0.5: + if user_name.find('大人') == -1: + user_name += '大~人~' + text = text.replace('小主人', user_name) + return text + + +def hello() -> str: + result = random.choice(( + "哦豁?!", + "你好!Ov<", + f"库库库,呼唤{list(get_bot().config.nickname)[0]}做什么呢", + "我在呢!", + "呼呼,叫俺干嘛" + )) + img = random.choice(os.listdir(IMAGE_PATH + "zai/")) + if img[-4:] == ".gif": + result += image(img, "zai") + else: + result += image(img, "zai") + return result + + +def no_result() -> str: + return random.choice([ + '你在说啥子?', + f'纯洁的{list(get_bot().config.nickname)[0]}没听懂', + '下次再告诉你(下次一定)', + '你觉得我听懂了吗?嗯?', + '我!不!知!道!' + ]) + image( + random.choice(os.listdir(IMAGE_PATH + "noresult/") + ), "noresult") diff --git a/plugins/auto_invite/__init__.py b/plugins/auto_invite/__init__.py new file mode 100644 index 00000000..6e971406 --- /dev/null +++ b/plugins/auto_invite/__init__.py @@ -0,0 +1,44 @@ +from nonebot import on_request +from nonebot.adapters.cqhttp import Bot, FriendRequestEvent, GroupRequestEvent +from models.friend_user import FriendUser +from datetime import datetime +from configs.config import AUTO_ADD_FRIEND +from nonebot.adapters.cqhttp.exception import ActionFailed + +__plugin_name__ = '处理请求' + +friend_req = on_request(priority=5) + + +@friend_req.handle() +async def _(bot: Bot, event: FriendRequestEvent, state: dict): + if AUTO_ADD_FRIEND: + nickname = '' + for user in await bot.get_friend_list(): + if user['user_id'] == event.user_id: + nickname = user['nickname'] + await FriendUser.add_friend_info(user['user_id'], user['nickname']) + break + await bot.send_private_msg(user_id=int(list(bot.config.superusers)[0]), message=f"{nickname}({event.user_id})" + f" 添加小真寻好友(已自动同意)") + await bot.set_friend_add_request(flag=event.flag, approve=True) + + +group_req = on_request(priority=5, block=True) + + +@group_req.handle() +async def _(bot: Bot, event: GroupRequestEvent, state: dict): + if event.sub_type == 'invite': + nickname = await FriendUser.get_user_name(event.user_id) + if str(event.user_id) in bot.config.superusers: + try: + await bot.set_group_add_request(flag=event.flag, sub_type='invite', approve=True) + except ActionFailed: + pass + else: + await bot.send_private_msg(user_id=int(list(bot.config.superusers)[0]), + message=f"报告..\n{nickname}({event.user_id})" + f" 希望邀请我加入 {event.group_id}\n邀请日期:{str(datetime.now()).split('.')[0]}") + await bot.send_private_msg(user_id=event.user_id, + message="想要邀请我偷偷入群嘛~~已经提醒管理员了\n等待管理员处理吧~") diff --git a/plugins/auto_invite/__pycache__/__init__.cpython-38.pyc b/plugins/auto_invite/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..bc01b25a Binary files /dev/null and b/plugins/auto_invite/__pycache__/__init__.cpython-38.pyc differ diff --git a/plugins/auto_invite/__pycache__/__init__.cpython-39.pyc b/plugins/auto_invite/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 00000000..9a9a1a90 Binary files /dev/null and b/plugins/auto_invite/__pycache__/__init__.cpython-39.pyc differ diff --git a/plugins/ban/__init__.py b/plugins/ban/__init__.py new file mode 100644 index 00000000..543ede34 --- /dev/null +++ b/plugins/ban/__init__.py @@ -0,0 +1,82 @@ +from nonebot import on_command +from models.ban_user import BanUser +from models.level_user import LevelUser +from nonebot.typing import T_State +from nonebot.adapters import Bot +from nonebot.adapters.cqhttp import GroupMessageEvent +from nonebot.adapters.cqhttp.permission import GROUP +from util.utils import get_message_at, get_message_text, is_number +from services.log import logger +from models.group_member_info import GroupInfoUser + + +__plugin_name__ = 'Ban/unBan' +__plugin_usage__ = f'用法: 封禁/解封用户(不是禁言!是针对bot是否处理封禁用户消息)\n' \ + '示例:.ban @djdsk\n' \ + '示例:.ban @djdsk 0(小时) 30(分钟)\n' \ + '示例:.ban @sdasf 4(小时)\n' \ + '示例:.unban @sdasf' + + +ban = on_command(".ban", aliases={'.unban', '/ban', '/unban'}, priority=5, permission=GROUP, block=True) + + +@ban.handle() +async def _(bot: Bot, event: GroupMessageEvent, state: T_State): + if get_message_text(event.json()) in ['帮助'] or str(event.get_message()) == '': + await ban.finish(__plugin_usage__) + # try: + result = '' + qq = int(get_message_at(event.json())[0]) + if qq: + nickname = await GroupInfoUser.get_group_member_nickname(qq, event.group_id) + if not nickname: + nickname = '用户' + msg = get_message_text(event.json()) + if msg: + msg = msg.split(" ") + if len(msg) == 2: + if not is_number(msg[0].strip()) or not is_number(msg[1].strip()): + await ban.finish('参数必须是数字!', at_sender=True) + time = int(msg[0]) * 60 * 60 + int(msg[1]) * 60 + else: + if not is_number(msg[0].strip()): + await ban.finish('参数必须是数字!', at_sender=True) + time = int(msg[0]) * 60 * 60 + else: + time = -1 + if state["_prefix"]["raw_command"] in [".ban", '/ban']: + if await LevelUser.get_user_level(event.user_id, event.group_id) <= await \ + LevelUser.get_user_level(qq, event.group_id) and str(event.user_id) not in bot.config.superusers: + await ban.finish(f"您的权限等级比对方低或相等, {list(bot.config.nickname)[0]}不能为您使用此功能!", at_sender=True) + if await BanUser.ban(qq, await LevelUser.get_user_level(event.user_id, event.group_id), time): + logger.info(f"USER {event.user_id} GROUP {event.group_id} 将 USER {qq} 封禁 时长 {time/60} 分钟") + result = f"已经将 {nickname} 加入{list(bot.config.nickname)[0]}的黑名单了!" + if time != -1: + result += f"将在 {time/60} 分钟后解封" + else: + time = await BanUser.check_ban_time(qq) + if is_number(time): + time = abs(time) + if time < 60: + time = str(int(time)) + ' 秒' + else: + time = str(int(time / 60)) + ' 分钟' + else: + time += ' 分钟' + result = f"{nickname} 已在黑名单!预计 {time}后解封" + else: + if await BanUser.check_ban_level(qq, await LevelUser.get_user_level(event.user_id, event.group_id)) and\ + str(event.user_id) not in bot.config.superusers: + await ban.finish(f"ban掉 {nickname} 的管理员权限比您高,无法进行unban", at_sender=True) + if await BanUser.unban(qq): + logger.info(f"USER {event.user_id} GROUP {event.group_id} 将 USER {qq} 解禁") + result = f"已经把 {nickname} 从黑名单中删除了!" + else: + result = f"{nickname} 不在黑名单!" + else: + await ban.finish('艾特人了吗??', at_sender=True) + # except Exception as e: + # result = 'ban/unban执行出错,确定艾特人了吗?' + # logger.error(f'ban/unban执行出错 e:{e}') + await ban.finish(result, at_sender=True) diff --git a/plugins/ban/__pycache__/__init__.cpython-38.pyc b/plugins/ban/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..e38a327f Binary files /dev/null and b/plugins/ban/__pycache__/__init__.cpython-38.pyc differ diff --git a/plugins/ban/__pycache__/__init__.cpython-39.pyc b/plugins/ban/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 00000000..3bb7d493 Binary files /dev/null and b/plugins/ban/__pycache__/__init__.cpython-39.pyc differ diff --git a/plugins/broadcast/__init__.py b/plugins/broadcast/__init__.py new file mode 100644 index 00000000..cf40fcd3 --- /dev/null +++ b/plugins/broadcast/__init__.py @@ -0,0 +1,44 @@ +from nonebot import on_command +from nonebot.typing import T_State +from nonebot.adapters import Bot, Event +from nonebot.permission import SUPERUSER +import asyncio +from util.utils import get_message_text, get_message_imgs +from services.log import logger +from models.group_remind import GroupRemind +from util.init_result import image + +broadcast = on_command("广播-", priority=1, permission=SUPERUSER, block=True) + + +@broadcast.handle() +async def _(bot: Bot, event: Event, state: T_State): + msg = get_message_text(event.json()) + imgs = get_message_imgs(event.json()) + rst = '' + for img in imgs: + rst += image(img) + sid = bot.self_id + gl = await bot.get_group_list(self_id=sid) + gl = [g['group_id'] for g in gl] + for g in gl: + if await GroupRemind.get_status(g, 'gb'): + await asyncio.sleep(0.5) + try: + await bot.send_group_msg(self_id=sid, group_id=g, message=msg+rst) + logger.info(f'群{g} 投递广播成功') + except Exception as e: + logger.error(f'群{g} 投递广播失败:{type(e)}') + try: + await broadcast.send(f'群{g} 投递广播失败:{type(e)}') + except Exception as e: + logger.critical(f'向广播发起者进行错误回报时发生错误:{type(e)}') + await broadcast.send(f'广播完成!') + + + + + + + + diff --git a/plugins/broadcast/__pycache__/__init__.cpython-38.pyc b/plugins/broadcast/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..4afd8a50 Binary files /dev/null and b/plugins/broadcast/__pycache__/__init__.cpython-38.pyc differ diff --git a/plugins/broadcast/__pycache__/__init__.cpython-39.pyc b/plugins/broadcast/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 00000000..b196d44e Binary files /dev/null and b/plugins/broadcast/__pycache__/__init__.cpython-39.pyc differ diff --git a/plugins/bt/__init__.py b/plugins/bt/__init__.py new file mode 100644 index 00000000..7e2e79a8 --- /dev/null +++ b/plugins/bt/__init__.py @@ -0,0 +1,95 @@ +from nonebot import on_command +from .data_source import get_bt_info +from services.log import logger +from nonebot.typing import T_State +from nonebot.adapters import Bot +from nonebot.adapters.cqhttp import PrivateMessageEvent +from util.utils import get_message_text +from nonebot.adapters.cqhttp.permission import PRIVATE +from util.utils import UserExistLimiter + +__plugin_name__ = '磁力搜索' +__plugin_usage__ = r""" +* 请各位使用后不要转发 * +* 有时可能搜不到,再试一次就行了 * +参数: -U(时间) -H(热度) -S(大小) + -V(仅视频) -P(仅图片) -A(仅压缩包) + -R (R18懂的都懂) + num(页数, 如果不知道页数请不要填,并且是倒叙,比如页数总数是29,你想查看第一页的内容, 就使用 bt 29 xxx) +-按相关度检索(默认) +bt [关键词] +-按更新时间检索(参数不区分大小写,但要注意空格) +bt -U [关键词] +-搜索第10页数 +bt 10(倒着) [关键词] +""".strip() + +_ulmt = UserExistLimiter() + +bt = on_command('bt', permission=PRIVATE, priority=5, block=True) + + +@bt.args_parser +async def _(bot: Bot, event: PrivateMessageEvent, state: T_State): + if str(event.get_message()) in ['取消', '算了']: + await bt.finish("已取消操作..", at_sender=True) + msg = get_message_text(event.json()) + if not msg: + await bt.reject('你想搜索什么呢?', at_sender=True) + mp = msg.split(" ") + if len(mp) > 1: + args = '' + for i in range(len(mp) - 1): + args += mp[i] + ' ' + state['args'] = args + state['bt'] = mp[1] + else: + state['bt'] = get_message_text(event.json()) + state['args'] = '' + + +@bt.handle() +async def _(bot: Bot, event: PrivateMessageEvent, state: T_State): + if get_message_text(event.json()) in ['帮助'] or str(event.get_message()) == '': + await bt.finish(__plugin_usage__) + if _ulmt.check(event.user_id): + await bt.finish('您有bt任务正在进行,请等待结束.', at_sender=True) + mp = get_message_text(event.json()).split(" ") + if len(mp) > 1: + args = '' + for i in range(len(mp) - 1): + args += mp[i] + ' ' + state['args'] = args.strip() + state['bt'] = mp[-1] + else: + state['bt'] = get_message_text(event.json()) + state['args'] = '' + + +@bt.got('bt', prompt='虚空磁力?查什么GKD') +async def _(bot: Bot, event: PrivateMessageEvent, state: T_State): + _ulmt.set_True(event.user_id) + keyword = state['bt'] + args = state['args'] + await bt.send('开始搜索....', at_sender=True) + try: + if args.find('-R') == -1 and args.find('-r') == -1: + bt_report = await get_bt_info(keyword, args) + else: + bt_report = await get_bt_info(keyword, args, '0') + if bt_report: + if len(bt_report.split("\n")) < 2: + await bt.finish(bt_report + '搜索失败了,再试一次也许能成', at_sender=True) + else: + await bt.send("如果有页数没资源请再试一次\n" + bt_report) + logger.info( + f"(USER {event.user_id}, GROUP {event.group_id if event.message_type != 'private' else 'private'})" + f" 搜索bt {args} {keyword}") + else: + logger.error("没查询到资源") + await bt.send("没有查询到资源(也有可能是超时,再试一次?)", at_sender=True) + _ulmt.set_False(event.user_id) + except Exception as e: + _ulmt.set_False(event.user_id) + await bt.send("bt出错啦,再试一次?", at_sender=True) + logger.info(f'bt {keyword} 出错 e:{e}') diff --git a/plugins/bt/__pycache__/__init__.cpython-38.pyc b/plugins/bt/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..01bdabee Binary files /dev/null and b/plugins/bt/__pycache__/__init__.cpython-38.pyc differ diff --git a/plugins/bt/__pycache__/__init__.cpython-39.pyc b/plugins/bt/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 00000000..58d50e12 Binary files /dev/null and b/plugins/bt/__pycache__/__init__.cpython-39.pyc differ diff --git a/plugins/bt/__pycache__/data_source.cpython-38.pyc b/plugins/bt/__pycache__/data_source.cpython-38.pyc new file mode 100644 index 00000000..0d4af9b7 Binary files /dev/null and b/plugins/bt/__pycache__/data_source.cpython-38.pyc differ diff --git a/plugins/bt/__pycache__/data_source.cpython-39.pyc b/plugins/bt/__pycache__/data_source.cpython-39.pyc new file mode 100644 index 00000000..f7c47d95 Binary files /dev/null and b/plugins/bt/__pycache__/data_source.cpython-39.pyc differ diff --git a/plugins/bt/data_source.py b/plugins/bt/data_source.py new file mode 100644 index 00000000..b00ee71c --- /dev/null +++ b/plugins/bt/data_source.py @@ -0,0 +1,96 @@ +from util.user_agent import get_user_agent +import aiohttp +from lxml import etree +from lxml.etree import Element +from configs.config import MAXINFO_BT +from urllib import parse +from html import unescape +from util.utils import get_local_proxy, is_number +import time +import platform +if platform.system() == 'Windows': + import asyncio + asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy()) + + +url = 'https://www.btmet.com/search.php' + + +async def get_bt_info(keyword: str, args: str, r18: str = '1') -> str: + cookiesDit = { + 'r18': r18 + } + s_time = time.time() + params = get_params(keyword, args) + async with aiohttp.ClientSession(headers=get_user_agent(), cookies=cookiesDit) as session: + async with session.get(url, proxy=get_local_proxy(), params=params, timeout=30) as response: + html = etree.HTML(await response.text()) + print(response.url) + num = html.xpath('//div[@id="wall"]//span/b/text()')[0] + print(num) + if num.find(",") != -1: + num = num.split(',')[0] + if num == '0': + return "没有找到记录" + + div_all = html.xpath('//div[@class="search-item"]')[1:] + div_all = div_all[:MAXINFO_BT] if len(div_all) > MAXINFO_BT else div_all + line_list = [await get_item_line(div) for div in div_all] + clist = [] + for line in line_list: + if line.strip() != '': + clist.append(line) + + return f"搜索 {keyword} 结果(共 {int(int(num.text) / 10) if int(num) % 10 == 0 else int(int(num) / 10) + 1} " \ + f"页)(耗时 {int(time.time() - s_time)} 秒):\n" + "\n\n".join(clist) + + +async def get_item_line(div: Element) -> str: + try: + magent = div.xpath('./div[2]/a/@href')[0] + size = div.xpath('./div[@class="f_left"]/div[@class="item-bar"]/span/b/font/text()')[0] + type = div.xpath('./div[@class="f_left"]/div[@class="item-bar"]/span[@class="cpill blue-pill"]/text()')[0].strip() + + title_doc = div.xpath('.//a[@class="smashTitle"]//text()')[0] + title_code = title_doc[title_doc.find('("') + 2: title_doc.find('")')] + title_xml_code = parse.unquote(title_code) + title_xml = etree.HTML(unescape(title_xml_code)) + title = title_xml.xpath('string(.)') + except Exception: + return '' + return "【{}】| {}\n【{}】| {}".format(type, title, size, magent) + + +# https://www.btmet.com/search.php?q=%E9%92%A2%E9%93%81%E4%BE%A0&c=5&o=0&l=&p=2 +def get_params(keyword: str, args: str) -> dict: + params = { + 'q': keyword, + 'c': '', + 'l': '', + 'o': 0, + 'p': '' + } + if not args: + return params + args = args.split(" ") + for arg in args: + if '-U' == arg.upper(): + params['o'] = 1 + if '-S' == arg.upper(): + params['o'] = 2 + if '-H' == arg.upper(): + params['o'] = 3 + if '-V' == arg.upper(): + params['c'] = 1 + if '-P' == arg.upper(): + params['c'] = 2 + if '-A' == arg.upper(): + params['c'] = 5 + if is_number(arg): + params['p'] = arg + return params + + +# print(asyncio.get_event_loop().run_until_complete(get_bt_info('钢铁侠', ''))) + + diff --git a/plugins/check/__init__.py b/plugins/check/__init__.py new file mode 100644 index 00000000..78c96318 --- /dev/null +++ b/plugins/check/__init__.py @@ -0,0 +1,20 @@ + +from nonebot import on_command +from .data_source import Check +from nonebot.adapters.cqhttp import Bot, Event +from nonebot.typing import T_State +from nonebot.rule import to_me +from nonebot.permission import SUPERUSER + + +__plugin_name__ = '自我检查' + +check = Check() + + +check_ = on_command('自检', aliases={'check'}, rule=to_me(), permission=SUPERUSER, block=True, priority=1) + + +@check_.handle() +async def _(bot: Bot, event: Event, state: T_State): + await check_.send(await check.show()) diff --git a/plugins/check/__pycache__/__init__.cpython-38.pyc b/plugins/check/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..0735d60d Binary files /dev/null and b/plugins/check/__pycache__/__init__.cpython-38.pyc differ diff --git a/plugins/check/__pycache__/__init__.cpython-39.pyc b/plugins/check/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 00000000..5bfd5f68 Binary files /dev/null and b/plugins/check/__pycache__/__init__.cpython-39.pyc differ diff --git a/plugins/check/__pycache__/data_source.cpython-38.pyc b/plugins/check/__pycache__/data_source.cpython-38.pyc new file mode 100644 index 00000000..279d1374 Binary files /dev/null and b/plugins/check/__pycache__/data_source.cpython-38.pyc differ diff --git a/plugins/check/__pycache__/data_source.cpython-39.pyc b/plugins/check/__pycache__/data_source.cpython-39.pyc new file mode 100644 index 00000000..dcfa2938 Binary files /dev/null and b/plugins/check/__pycache__/data_source.cpython-39.pyc differ diff --git a/plugins/check/data_source.py b/plugins/check/data_source.py new file mode 100644 index 00000000..865769fe --- /dev/null +++ b/plugins/check/data_source.py @@ -0,0 +1,67 @@ +import psutil +import aiohttp +import time +from datetime import datetime +from util.user_agent import get_user_agent +from asyncio.exceptions import TimeoutError +from aiohttp.client_exceptions import ClientConnectorError +from util.utils import get_local_proxy +import asyncio +from services.log import logger + + +class Check: + def __init__(self): + self.cpu = None + self.memory = None + self.disk = None + self.user = None + self.baidu = 200 + self.google = 200 + + async def check_all(self): + await self.check_network() + await asyncio.sleep(0.1) + self.check_system() + self.check_user() + + def check_system(self): + self.cpu = psutil.cpu_percent() + self.memory = psutil.virtual_memory().percent + self.disk = psutil.disk_usage("/").percent + + async def check_network(self): + async with aiohttp.ClientSession(headers=get_user_agent()) as session: + try: + async with session.get('https://www.baidu.com/', proxy=get_local_proxy(), timeout=3) as response: + pass + except (TimeoutError, ClientConnectorError) as e: + logger.warning(f'访问BaiDu失败... e: {e}') + self.baidu = 404 + try: + async with session.get('https://www.google.com/', proxy=get_local_proxy(), timeout=3) as response: + pass + except (TimeoutError, ClientConnectorError) as e: + logger.warning(f'访问Google失败... e: {e}') + self.google = 404 + + def check_user(self): + rst = '' + for user in psutil.users(): + rst += f'[{user.name}] {time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(user.started))}\n' + self.user = rst[:-1] + + async def show(self): + await self.check_all() + rst = f'[Time] {str(datetime.now()).split(".")[0]}\n' \ + f'-----System-----\n' \ + f'[CPU] {self.cpu}%\n' \ + f'[Memory] {self.memory}%\n' \ + f'[Disk] {self.disk}%\n' \ + f'-----Network-----\n' \ + f'[BaiDu] {self.baidu}\n' \ + f'[Google] {self.google}\n' + if self.user: + rst += '-----User-----\n' + self.user + return rst + diff --git a/plugins/coser/__init__.py b/plugins/coser/__init__.py new file mode 100644 index 00000000..2e8ec9bf --- /dev/null +++ b/plugins/coser/__init__.py @@ -0,0 +1,39 @@ +from nonebot import on_command +from util.utils import get_message_text +from nonebot.typing import T_State +from nonebot.adapters import Bot, Event +from services.log import logger +from util.init_result import image +import requests + +__plugin_usage_coser__ = '不得看看可爱的coser?发送‘coser’' + + +coser = on_command('cos', aliases={'coser', '括丝'}, priority=5, block=True) + + +url_2 = 'http://api.rosysun.cn/cos' + + +@coser.handle() +async def _(bot: Bot, event: Event, state: T_State): + if get_message_text(event.json()) in ['帮助']: + await coser.finish(__plugin_usage_coser__) + img_url = requests.get(url_2).text + await coser.send(image(img_url)) + logger.info( + f"(USER {event.user_id}, GROUP {event.group_id if event.message_type != 'private' else 'private'}) 发送COSER") + + + + + + + + + + + + + + diff --git a/plugins/coser/__pycache__/__init__.cpython-38.pyc b/plugins/coser/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..45df0634 Binary files /dev/null and b/plugins/coser/__pycache__/__init__.cpython-38.pyc differ diff --git a/plugins/coser/__pycache__/__init__.cpython-39.pyc b/plugins/coser/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 00000000..fd08ed41 Binary files /dev/null and b/plugins/coser/__pycache__/__init__.cpython-39.pyc differ diff --git a/plugins/delete_img/__init__.py b/plugins/delete_img/__init__.py new file mode 100644 index 00000000..9c20ee64 --- /dev/null +++ b/plugins/delete_img/__init__.py @@ -0,0 +1,79 @@ +from configs.path_config import IMAGE_PATH, TEMP_PATH +import os +from util.init_result import image +from services.log import logger +from nonebot import on_command +from nonebot.rule import to_me +from nonebot.typing import T_State +from nonebot.adapters import Bot, Event +from configs.config import IMAGE_DIR_LIST +from util.utils import is_number, cn2py + +__plugin_name__ = '删除图片' +__plugin_usage__ = '删除图片帮助:\n\t' \ + '1.查看列表 --> 指令: 删除图片 列表/目录\n\t' \ + '2.删除图片 图库 id, 即在相应目录下删除图片\n\t\t示例: 删除图片 色图 1 ' + + +delete_img = on_command("删除图片", priority=5, rule=to_me(), block=True) + + +@delete_img.args_parser +async def parse(bot: Bot, event: Event, state: T_State): + if str(event.get_message()) in ['取消', '算了']: + await delete_img.finish("已取消操作..", at_sender=True) + if state["_current_key"] in ['path']: + if str(event.get_message()) not in IMAGE_DIR_LIST: + await delete_img.reject("此目录不正确,请重新输入目录!") + state[state["_current_key"]] = str(event.get_message()) + if state["_current_key"] == 'id': + if not is_number(str(event.get_message())): + await delete_img.reject("id不正确!请重新输入数字...") + state[state["_current_key"]] = str(event.get_message()) + + +@delete_img.handle() +async def _(bot: Bot, event: Event, state: T_State): + raw_arg = str(event.get_message()).strip() + if raw_arg: + args = raw_arg.split(" ") + if args[0] in ['帮助']: + await delete_img.finish(__plugin_usage__) + if len(args) >= 2 and args[0] in IMAGE_DIR_LIST and is_number(args[1]): + state['path'] = args[0] + state['id'] = args[1] + + +@delete_img.got("path", prompt="请输入要删除的目标图库?") +@delete_img.got("id", prompt="请输入要删除的图片id?") +async def arg_handle(bot: Bot, event: Event, state: T_State): + path = cn2py(state['path']) + img_id = state['id'] + path = IMAGE_PATH + path + max_id = len(os.listdir(path)) - 1 + if int(img_id) > max_id or int(img_id) < 0: + await delete_img.finish(f"Id超过上下限,上限:{max_id}", at_sender=True) + try: + if os.path.exists(IMAGE_PATH + TEMP_PATH + "delete.jpg"): + os.remove(IMAGE_PATH + TEMP_PATH + "delete.jpg") + logger.info("删除图片 delete.jpg 成功") + except Exception as e: + logger.warning(f"删除图片 delete.jpg 失败 e{e}") + try: + os.rename(path + img_id + ".jpg", IMAGE_PATH + TEMP_PATH + "delete.jpg") + logger.info(f"移动 {path}{img_id}.jpg 移动成功") + except Exception as e: + logger.warning(f"{path}{img_id}.jpg --> 移动失败 e:{e}") + if not os.path.exists(path + img_id + ".jpg"): + try: + if int(img_id) != max_id: + os.rename(path + str(max_id) + ".jpg", path + img_id + ".jpg") + except FileExistsError: + logger.error(f"{path}{max_id}.jpg 替换 {path}{img_id}.jpg 失败 e:{e}") + logger.info(f"{path}{max_id}.jpg 替换 {path}{img_id}.jpg 成功") + logger.info(f"USER {event.user_id} GROUP {event.group_id if event.message_type != 'private' else 'private'}" + f" -> id: {img_id} 删除成功") + await delete_img.finish(f"id: {img_id} 删除成功" + image("delete.jpg", TEMP_PATH), at_sender=True) + await delete_img.finish(f"id: {img_id} 删除失败!") + + diff --git a/plugins/delete_img/__pycache__/__init__.cpython-38.pyc b/plugins/delete_img/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..bf87c76e Binary files /dev/null and b/plugins/delete_img/__pycache__/__init__.cpython-38.pyc differ diff --git a/plugins/delete_img/__pycache__/__init__.cpython-39.pyc b/plugins/delete_img/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 00000000..e6418283 Binary files /dev/null and b/plugins/delete_img/__pycache__/__init__.cpython-39.pyc differ diff --git a/plugins/dialogue/__init__.py b/plugins/dialogue/__init__.py new file mode 100644 index 00000000..40d0ccd7 --- /dev/null +++ b/plugins/dialogue/__init__.py @@ -0,0 +1,54 @@ +from nonebot import on_command +from nonebot.typing import T_State +from nonebot.adapters import Bot, Event +from nonebot.permission import SUPERUSER +from util.utils import get_message_text, is_number +from services.log import logger +from util.init_result import at + + +__plugin_name__ = '联系管理员' +__plugin_usage__ = '滴滴滴- 后接内容 联系管理员' + + +dialogue = on_command("[滴滴滴]", aliases={"滴滴滴-"}, priority=1, block=True) +reply = on_command("/t", priority=1, permission=SUPERUSER, block=True) + + +@dialogue.handle() +async def _(bot: Bot, event: Event, state: T_State): + uid = event.user_id + coffee = int(list(bot.config.superusers)[0]) + text = get_message_text(event.json()) + if not text or text in ['帮助']: + await dialogue.send("请发送[滴滴滴]+您要说的内容~", at_sender=True) + else: + if event.get_event_name() == "message.private.friend": + group_id = "" + else: + group_id = event.group_id + await bot.send_private_msg(user_id=coffee, message=f'Q{uid}@群{group_id}\n{text}') + await dialogue.send(f'您的话已发送至管理员!\n======\n{text}', at_sender=True) + logger.info(f"Q{uid}@群{group_id} 联系管理员:{coffee} text:{text}") + + +@reply.handle() +async def _(bot: Bot, event: Event, state: T_State): + if get_message_text(event.json()) in ['帮助']: + await reply.finish(f'/t qq group text') + msg = get_message_text(event.json()).split(" ") + user_id = int(msg[0]) + if is_number(msg[1]) and len(msg[1]) > 5: + group_id = int(msg[1]) + text = msg[2] + else: + group_id = "" + text = msg[1] + if group_id: + await bot.send_group_msg(group_id=group_id, message=at(user_id) + "\n管理员回复\n=======\n" + text) + else: + if user_id in [qq['user_id'] for qq in await bot.get_friend_list()]: + await bot.send_private_msg(user_id=user_id, message="管理员回复\n=======\n" + text) + await reply.finish("发送成功", at_sender=True) + else: + await reply.send(f"对象不是{list(bot.config.nickname)[0]}的好友...", at_sender=True) diff --git a/plugins/dialogue/__pycache__/__init__.cpython-38.pyc b/plugins/dialogue/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..07fc0cb6 Binary files /dev/null and b/plugins/dialogue/__pycache__/__init__.cpython-38.pyc differ diff --git a/plugins/dialogue/__pycache__/__init__.cpython-39.pyc b/plugins/dialogue/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 00000000..8ee41a1a Binary files /dev/null and b/plugins/dialogue/__pycache__/__init__.cpython-39.pyc differ diff --git a/plugins/draw_card/__init__.py b/plugins/draw_card/__init__.py new file mode 100644 index 00000000..a5383798 --- /dev/null +++ b/plugins/draw_card/__init__.py @@ -0,0 +1,174 @@ +from nonebot import on_regex, on_keyword +from nonebot.adapters.cqhttp import Bot, MessageEvent +from nonebot.permission import SUPERUSER +from nonebot.typing import T_State +from .genshin_handle import genshin_draw, update_genshin_info, reset_count +from .prts_handle import update_prts_info, prts_draw, reload_pool +from .pretty_handle import update_pretty_info, pretty_draw +from .update_game_info import update_info +from util.utils import is_number, scheduler +from services.log import logger +import re + + +prts = on_regex(r'.*?方舟[1-9|一][0-9]{0,2}[抽|井]', priority=5, block=True) +prts_update = on_keyword({'更新方舟信息', '更新明日方舟信息'}, permission=SUPERUSER, priority=1, block=True) +prts_reload = on_keyword({'重载方舟卡池'}, priority=1, block=True) + +genshin = on_regex('.*?原神[1-9|一][0-9]{0,2}[抽|井]', priority=5, block=True) +genshin_reset = on_keyword({'重置原神抽卡'}, priority=1, block=True) +genshin_update = on_keyword({'更新原神信息'}, permission=SUPERUSER, priority=1, block=True) + +pretty = on_regex('.*?马娘卡?[1-9|一][0-9]{0,2}[抽|井]', priority=5, block=True) +pretty_update = on_keyword({'更新马娘信息', '更新赛马娘信息'}, permission=SUPERUSER, priority=1, block=True) + + +@prts.handle() +async def _(bot: Bot, event: MessageEvent, state: T_State): + msg = str(event.get_message()).strip() + if msg in ['方舟一井', '方舟1井']: + num = 300 + else: + rmsg = re.search(r'.*?方舟(.*)抽', msg) + if rmsg and is_number(rmsg.group(1)): + try: + num = int(rmsg.group(1)) + except ValueError: + await prts.finish('必!须!是!数!字!', at_sender=True) + if num > 300: + await prts.finish('一井都满不足不了你嘛!快爬开!', at_sender=True) + if num < 1: + await prts.finish('虚空抽卡???', at_sender=True) + else: + return + # print(num) + await prts.send(await prts_draw(num), at_sender=True) + logger.info( + f"(USER {event.user_id}, GROUP {event.group_id if event.message_type != 'private' else 'private'})" + f" 方舟{num}抽") + + +@prts_reload.handle() +async def _(bot: Bot, event: MessageEvent, state: T_State): + await reload_pool() + await prts_reload.finish('重载完成!') + + +@genshin.handle() +async def _(bot: Bot, event: MessageEvent, state: T_State): + msg = str(event.get_message()).strip() + if msg in ['原神一井', '原神1井']: + num = 180 + else: + rmsg = re.search(r'.*?原神(.*)抽', msg) + if rmsg and is_number(rmsg.group(1)): + try: + num = int(rmsg.group(1)) + except ValueError: + await genshin.finish('必!须!是!数!字!', at_sender=True) + if num > 300: + await genshin.finish('一井都满不足不了你嘛!快爬开!', at_sender=True) + if num < 1: + await genshin.finish('虚空抽卡???', at_sender=True) + else: + return + await genshin.send(await genshin_draw(event.user_id, num), at_sender=True) + logger.info( + f"(USER {event.user_id}, GROUP {event.group_id if event.message_type != 'private' else 'private'})" + f" 原神{num}抽") + + +@genshin_reset.handle() +async def _(bot: Bot, event: MessageEvent, state: T_State): + reset_count(event.user_id) + await genshin_reset.send('重置了原神抽卡次数', at_sender=True) + + +@pretty.handle() +async def _(bot: Bot, event: MessageEvent, state: T_State): + msg = str(event.get_message()).strip() + if msg in ['赛马娘一井', '赛马娘1井', '马娘一井', '马娘1井', '赛马娘卡一井', '赛马娘卡1井', '马娘卡一井', '马娘卡1井']: + num = 200 + if msg.find("卡") == -1: + pool_name = 'horse' + else: + pool_name = 'card' + else: + rmsg = re.search(r'.*?马娘(.*)抽', msg) + if rmsg: + num = rmsg.group(1) + if num[0] == '卡': + num = num[1:] + pool_name = 'card' + else: + pool_name = 'horse' + if is_number(num): + try: + num = int(num) + except ValueError: + await genshin.finish('必!须!是!数!字!', at_sender=True) + if num > 200: + await genshin.finish('一井都满不足不了你嘛!快爬开!', at_sender=True) + if num < 1: + await genshin.finish('虚空抽卡???', at_sender=True) + else: + return + await pretty.send(await pretty_draw(num, pool_name), at_sender=True) + logger.info( + f"(USER {event.user_id}, GROUP {event.group_id if event.message_type != 'private' else 'private'})" + f" 赛马娘{num}抽") + + +@prts_update.handle() +async def _(bot: Bot, event: MessageEvent, state: T_State): + await update_prts_info() + await reload_pool() + await prts_update.finish('更新完成!') + + +@genshin_update.handle() +async def _(bot: Bot, event: MessageEvent, state: T_State): + await update_genshin_info() + await genshin_update.finish('更新完成!') + + +@pretty_update.handle() +async def _(bot: Bot, event: MessageEvent, state: T_State): + await update_pretty_info() + await genshin_update.finish('更新完成!') + + +# 更新资源 +@scheduler.scheduled_job( + 'cron', + hour=4, + minute=1, +) +async def _(): + try: + await update_prts_info() + logger.info('自动更新明日方舟信息') + except Exception as e: + logger.error(f'自动更新明日方舟信息出错 e:{e}') + try: + await update_genshin_info() + logger.info('自动更新原神信息') + except Exception as e: + logger.error(f'自动更新原神信息出错 e:{e}') + try: + await update_pretty_info() + logger.info('自动更新赛马娘信息') + except Exception as e: + logger.error(f'自动更新赛马娘信息出错 e:{e}') + + +# 每天四点重载up卡池 +@scheduler.scheduled_job( + 'cron', + hour=4, + minute=1, +) +async def _(): + await reload_pool() + + diff --git a/plugins/draw_card/__pycache__/__init__.cpython-38.pyc b/plugins/draw_card/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..228a0662 Binary files /dev/null and b/plugins/draw_card/__pycache__/__init__.cpython-38.pyc differ diff --git a/plugins/draw_card/__pycache__/__init__.cpython-39.pyc b/plugins/draw_card/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 00000000..c8e3c911 Binary files /dev/null and b/plugins/draw_card/__pycache__/__init__.cpython-39.pyc differ diff --git a/plugins/draw_card/__pycache__/announcement.cpython-39.pyc b/plugins/draw_card/__pycache__/announcement.cpython-39.pyc new file mode 100644 index 00000000..f8f5af29 Binary files /dev/null and b/plugins/draw_card/__pycache__/announcement.cpython-39.pyc differ diff --git a/plugins/draw_card/__pycache__/config.cpython-38.pyc b/plugins/draw_card/__pycache__/config.cpython-38.pyc new file mode 100644 index 00000000..a1980fc3 Binary files /dev/null and b/plugins/draw_card/__pycache__/config.cpython-38.pyc differ diff --git a/plugins/draw_card/__pycache__/config.cpython-39.pyc b/plugins/draw_card/__pycache__/config.cpython-39.pyc new file mode 100644 index 00000000..4dd03ded Binary files /dev/null and b/plugins/draw_card/__pycache__/config.cpython-39.pyc differ diff --git a/plugins/draw_card/__pycache__/genshin_handle.cpython-38.pyc b/plugins/draw_card/__pycache__/genshin_handle.cpython-38.pyc new file mode 100644 index 00000000..fbc3ba8d Binary files /dev/null and b/plugins/draw_card/__pycache__/genshin_handle.cpython-38.pyc differ diff --git a/plugins/draw_card/__pycache__/genshin_handle.cpython-39.pyc b/plugins/draw_card/__pycache__/genshin_handle.cpython-39.pyc new file mode 100644 index 00000000..eec4add5 Binary files /dev/null and b/plugins/draw_card/__pycache__/genshin_handle.cpython-39.pyc differ diff --git a/plugins/draw_card/__pycache__/init_card_pool.cpython-39.pyc b/plugins/draw_card/__pycache__/init_card_pool.cpython-39.pyc new file mode 100644 index 00000000..02d57fa4 Binary files /dev/null and b/plugins/draw_card/__pycache__/init_card_pool.cpython-39.pyc differ diff --git a/plugins/draw_card/__pycache__/pretty_handle.cpython-39.pyc b/plugins/draw_card/__pycache__/pretty_handle.cpython-39.pyc new file mode 100644 index 00000000..8774e41b Binary files /dev/null and b/plugins/draw_card/__pycache__/pretty_handle.cpython-39.pyc differ diff --git a/plugins/draw_card/__pycache__/prts_handle.cpython-38.pyc b/plugins/draw_card/__pycache__/prts_handle.cpython-38.pyc new file mode 100644 index 00000000..8e4f77e7 Binary files /dev/null and b/plugins/draw_card/__pycache__/prts_handle.cpython-38.pyc differ diff --git a/plugins/draw_card/__pycache__/prts_handle.cpython-39.pyc b/plugins/draw_card/__pycache__/prts_handle.cpython-39.pyc new file mode 100644 index 00000000..db3503ce Binary files /dev/null and b/plugins/draw_card/__pycache__/prts_handle.cpython-39.pyc differ diff --git a/plugins/draw_card/__pycache__/update_game_info.cpython-38.pyc b/plugins/draw_card/__pycache__/update_game_info.cpython-38.pyc new file mode 100644 index 00000000..429d5438 Binary files /dev/null and b/plugins/draw_card/__pycache__/update_game_info.cpython-38.pyc differ diff --git a/plugins/draw_card/__pycache__/update_game_info.cpython-39.pyc b/plugins/draw_card/__pycache__/update_game_info.cpython-39.pyc new file mode 100644 index 00000000..95e4b678 Binary files /dev/null and b/plugins/draw_card/__pycache__/update_game_info.cpython-39.pyc differ diff --git a/plugins/draw_card/__pycache__/util.cpython-38.pyc b/plugins/draw_card/__pycache__/util.cpython-38.pyc new file mode 100644 index 00000000..9345c928 Binary files /dev/null and b/plugins/draw_card/__pycache__/util.cpython-38.pyc differ diff --git a/plugins/draw_card/__pycache__/util.cpython-39.pyc b/plugins/draw_card/__pycache__/util.cpython-39.pyc new file mode 100644 index 00000000..4f102f4c Binary files /dev/null and b/plugins/draw_card/__pycache__/util.cpython-39.pyc differ diff --git a/plugins/draw_card/announcement.py b/plugins/draw_card/announcement.py new file mode 100644 index 00000000..2c3e78c8 --- /dev/null +++ b/plugins/draw_card/announcement.py @@ -0,0 +1,119 @@ +import aiohttp +from bs4 import BeautifulSoup +import re +from datetime import datetime +from pathlib import Path +from configs.path_config import DRAW_PATH +from util.user_agent import get_user_agent + +try: + import ujson as json +except ModuleNotFoundError: + import json + +up_char_file = Path(DRAW_PATH) / "draw_card_up" / "prts_up_char.json" + +prts_url = "https://wiki.biligame.com/arknights/%E6%96%B0%E9%97%BB%E5%85%AC%E5%91%8A" + + +def _get_up_char(r: str, text: str): + pr = re.search(r, text) + chars = pr.group(1) + probability = pr.group(2) + chars = chars.replace('[限定]', '').replace('[', '').replace(']', '') + probability = probability.replace('【', '') + return chars, probability + + +class PrtsAnnouncement: + + @staticmethod + async def get_announcement_text(): + async with aiohttp.ClientSession(headers=get_user_agent()) as session: + async with session.get(prts_url, timeout=7) as res: + soup = BeautifulSoup(await res.text(), 'lxml') + trs = soup.find('table').find('tbody').find_all('tr') + for tr in trs: + a = tr.find_all('td')[-1].find('a') + if a.text.find('寻访') != -1: + url = a.get('href') + break + async with session.get(f'https://wiki.biligame.com/{url}', timeout=7) as res: + return await res.text(), a.text[:-4] + + @staticmethod + async def update_up_char(): + up_char_file.parent.mkdir(parents=True, exist_ok=True) + data = {'up_char': {'6': {}, '5': {}, '4': {}}, 'title': '', 'time': ''} + text, title = await PrtsAnnouncement.get_announcement_text() + soup = BeautifulSoup(text, 'lxml') + data['title'] = title + context = soup.find('div', {'id': 'mw-content-text'}).find('div') + data['pool_img'] = str(context.find('div', {'class': 'center'}).find('div').find('a'). + find('img').get('srcset')).split(' ')[-2] + # print(context.find_all('p')) + for p in context.find_all('p')[1:]: + if p.text.find('活动时间') != -1: + pr = re.search(r'.*?活动时间:(.*)', p.text) + data['time'] = pr.group(1) + elif p.text.find('★★★★★★') != -1: + chars, probability = _get_up_char(r'.*?★★★★★★:(.*?)(.*?出率的?(.*?)%.*?).*?', p.text) + slt = '/' + if chars.find('\\') != -1: + slt = '\\' + for char in chars.split(slt): + data['up_char']['6'][char.strip()] = probability.strip() + elif p.text.find('★★★★★') != -1: + chars, probability = _get_up_char(r'.*?★★★★★:(.*?)(.*?出率的?(.*?)%.*?).*?', p.text) + slt = '/' + if chars.find('\\') != -1: + slt = '\\' + for char in chars.split(slt): + data['up_char']['5'][char.strip()] = probability.strip() + elif p.text.find('★★★★') != -1: + chars, probability = _get_up_char(r'.*?★★★★:(.*?)(.*?出率的?(.*?)%.*?).*?', p.text) + slt = '/' + if chars.find('\\') != -1: + slt = '\\' + for char in chars.split(slt): + data['up_char']['4'][char.strip()] = probability.strip() + break + pr = re.search(r'.*?★:(.*?)(在(.*?)★.*?以(.*?)倍权值.*?).*?', p.text) + if pr: + char = pr.group(1) + star = pr.group(2) + weight = pr.group(3) + char = char.replace('[限定]', '').replace('[', '').replace(']', '') + data['up_char'][star][char.strip()] = f'权{weight}' + # data['time'] = '03月09日16:00 - 05月23日03:59' + if not is_expired(data): + data['title'] = '' + else: + with open(up_char_file, 'w', encoding='utf8') as f: + json.dump(data, f, indent=4, ensure_ascii=False) + if not up_char_file.exists(): + with open(up_char_file, 'w', encoding='utf8') as f: + json.dump(data, f, indent=4, ensure_ascii=False) + else: + with open(up_char_file, 'r', encoding='utf8') as f: + old_data = json.load(f) + if is_expired(old_data): + return old_data + else: + with open(up_char_file, 'w', encoding='utf8') as f: + json.dump(data, f, indent=4, ensure_ascii=False) + return data + + +# 是否过时 +def is_expired(data: dict): + times = data['time'].split('-') + for i in range(len(times)): + times[i] = str(datetime.now().year) + '-' + times[i].split('日')[0].strip().replace('月', '-') + start_date = datetime.strptime(times[0], '%Y-%m-%d').date() + end_date = datetime.strptime(times[1], '%Y-%m-%d').date() + now = datetime.now().date() + return start_date < now < end_date + +# ad = Announcement('https://wiki.biligame.com/arknights/%E6%96%B0%E9%97%BB%E5%85%AC%E5%91%8A') +# asyncio.get_event_loop().run_until_complete(check_up_char('prts')) diff --git a/plugins/draw_card/config.py b/plugins/draw_card/config.py new file mode 100644 index 00000000..eba09697 --- /dev/null +++ b/plugins/draw_card/config.py @@ -0,0 +1,104 @@ +import nonebot +from pathlib import Path +try: + import ujson as json +except ModuleNotFoundError: + import json + +# 方舟概率 +PRTS_SIX_P = 0.02 +PRTS_FIVE_P = 0.08 +PRTS_FOUR_P = 0.48 +PRTS_THREE_P = 0.42 + +# 原神概率 +GENSHIN_FIVE_P = 0.006 +GENSHIN_FOUR_P = 0.051 +GENSHIN_THREE_P = 0.43 +GENSHIN_G_FOUR_P = 0.13 +GENSHIN_G_FIVE_P = 0.016 +I72_ADD = 0.0585 + +# 赛马娘概率 +PRETTY_THREE = 0.03 +PRETTY_TWO = 0.18 +PRETTY_ONE = 0.79 + +path_dict = { + 'genshin': '原神', + 'prts': '明日方舟', + 'pretty': '赛马娘', +} + + +_draw_config = Path() / "data" / "draw_card" / "draw_card_config" / "draw_card_config.json" + + +driver: nonebot.Driver = nonebot.get_driver() + + +@driver.on_startup +def check_config(): + global PRTS_SIX_P, PRTS_FOUR_P, PRTS_FIVE_P, PRTS_THREE_P, GENSHIN_G_FIVE_P, \ + GENSHIN_G_FOUR_P, GENSHIN_FOUR_P, GENSHIN_FIVE_P, I72_ADD, path_dict, PRETTY_THREE, \ + PRETTY_ONE, PRETTY_TWO, GENSHIN_THREE_P + if _draw_config.exists(): + data = json.load(open(_draw_config, 'r', encoding='utf8')) + PRTS_SIX_P = float(data['prts']['six']) + PRTS_FIVE_P = float(data['prts']['five']) + PRTS_FOUR_P = float(data['prts']['four']) + PRTS_THREE_P = float(data['prts']['three']) + + GENSHIN_FIVE_P = float(data['genshin']['five_char']) + GENSHIN_FOUR_P = float(data['genshin']['four_char']) + GENSHIN_THREE_P = float(data['genshin']['three_char']) + GENSHIN_G_FIVE_P = float(data['genshin']['five_weapon']) + GENSHIN_G_FOUR_P = float(data['genshin']['four_weapon']) + I72_ADD = float(data['genshin']['72_add']) + + PRETTY_THREE = float(data['pretty']['three']) + PRETTY_TWO = float(data['pretty']['two']) + PRETTY_ONE = float(data['pretty']['one']) + + path_dict = data['path_dict'] + else: + _draw_config.parent.mkdir(parents=True, exist_ok=True) + config_dict = { + 'path_dict': { + 'genshin': '原神', + 'prts': '明日方舟', + 'pretty': '赛马娘', + }, + + 'prts': { + 'six': 0.02, + 'five': 0.08, + 'four': 0.48, + 'three': 0.42, + }, + + 'genshin': { + 'five_char': 0.006, + 'four_char': 0.051, + 'three_char': 0.43, + 'five_weapon': 0.13, + 'four_weapon': 0.016, + '72_add': 0.0585, + }, + + 'pretty': { + 'three': 0.03, + 'two': 0.18, + 'one': 0.79, + } + } + json.dump(config_dict, open(_draw_config, 'w', encoding='utf8'), indent=4, ensure_ascii=False) + + + + + + + + + diff --git a/plugins/draw_card/genshin_handle.py b/plugins/draw_card/genshin_handle.py new file mode 100644 index 00000000..923ae50f --- /dev/null +++ b/plugins/draw_card/genshin_handle.py @@ -0,0 +1,149 @@ + +import os +import nonebot +import random +from .update_game_info import update_info +from .util import generate_img, init_star_rst, BaseData, set_list +from .config import GENSHIN_FIVE_P, GENSHIN_FOUR_P, GENSHIN_G_FIVE_P, GENSHIN_THREE_P, I72_ADD +from dataclasses import dataclass +from .init_card_pool import init_game_pool +from configs.path_config import DRAW_PATH +from util.init_result import image +try: + import ujson as json +except ModuleNotFoundError: + import json + +driver: nonebot.Driver = nonebot.get_driver() + +genshin_five = {} +genshin_count = {} +genshin_pl_count = {} + +ALL_CHAR = [] +ALL_ARM = [] + + +@dataclass +class GenshinChar(BaseData): + pass + + +async def genshin_draw(user_id: int, count: int): + # 0 1 2 + cnlist = ['★★★★★', '★★★★', '★★★'] + genshin_list, five_list, five_olist, five_dict, star_list = _format_card_information(count, user_id) + rst = init_star_rst(star_list, cnlist, five_list, five_olist) + print(five_list) + temp = '' + if count > 90: + genshin_list = set_list(genshin_list) + return image(b64=await generate_img(genshin_list, 'genshin', star_list)) + '\n' + rst[:-1] + \ + temp[:-1] + f'\n距离保底发还剩 {90 - genshin_count[user_id] if genshin_count.get(user_id) else "^"} 抽' \ + + "\n【五星:0.6%,四星:5.1%\n第72抽开始五星概率每抽加0.585%】" + + +async def update_genshin_info(): + global ALL_CHAR, ALL_ARM + url = 'https://wiki.biligame.com/ys/角色筛选' + data, code = await update_info(url, 'genshin') + if code == 200: + ALL_CHAR = init_game_pool('genshin', data, GenshinChar) + url = 'https://wiki.biligame.com/ys/武器图鉴' + data, code = await update_info(url, 'genshin_arm', ['头像', '名称', '类型', '稀有度.alt', '初始基础属性1', + '初始基础属性2', '攻击力(MAX)', '副属性(MAX)', '技能']) + if code == 200: + ALL_ARM = init_game_pool('genshin', data, GenshinChar) + + +# asyncio.get_event_loop().run_until_complete(update_genshin_info()) + + +@driver.on_startup +async def init_data(): + global ALL_CHAR, ALL_ARM + if not os.path.exists(DRAW_PATH + '/draw_card_config/genshin.json') or \ + not os.path.exists(DRAW_PATH + '/draw_card_config/genshin_arm.json'): + await update_genshin_info() + else: + with open(DRAW_PATH + '/draw_card_config/genshin.json', 'r', encoding='utf8') as f: + genshin_dict = json.load(f) + with open(DRAW_PATH + '/draw_card_config/genshin_arm.json', 'r', encoding='utf8') as f: + genshin_arm_dict = json.load(f) + ALL_CHAR = init_game_pool('genshin', genshin_dict, GenshinChar) + ALL_ARM = init_game_pool('genshin', genshin_arm_dict, GenshinChar) + + +# 抽取卡池 +def _get_genshin_card(mode: int = 1, add: float = 0.0): + global ALL_ARM, ALL_CHAR + if mode == 1: + star = random.sample([5, 4, 3], + counts=[int(GENSHIN_FIVE_P * 1000) + int(add * 1000), int(GENSHIN_FOUR_P * 1000), + int(GENSHIN_THREE_P * 1000)], + k=1)[0] + elif mode == 2: + star = random.sample([5, 4], + counts=[int(GENSHIN_G_FIVE_P * 1000) + int(add * 1000), int(GENSHIN_FOUR_P * 1000)], + k=1)[0] + else: + star = 5 + chars = [x for x in (ALL_ARM if random.random() < 0.5 or star == 3 else ALL_CHAR) if x.star == star] + return random.choice(chars), abs(star - 5) + + +def _format_card_information(_count: int, user_id): + genshin_list = [] + star_list = [0, 0, 0] + five_index_list = [] + five_list = [] + five_dict = {} + add = 0.0 + if genshin_count.get(user_id) and _count <= 90: + f_count = genshin_count[user_id] + else: + f_count = 0 + if genshin_pl_count.get(user_id) and _count <= 90: + count = genshin_pl_count[user_id] + else: + count = 0 + for i in range(_count): + count += 1 + f_count += 1 + # 十连保底 + if count == 10 and f_count != 90: + if f_count >= 72: + add += I72_ADD + char, code = _get_genshin_card(2, add) + count = 0 + # 大保底 + elif f_count == 90: + char, code = _get_genshin_card(3) + else: + if f_count >= 72: + add += I72_ADD + char, code = _get_genshin_card(add=add) + if code == 1: + count = 0 + star_list[code] += 1 + if code == 0: + if _count <= 90: + genshin_five[user_id] = f_count + add = 0.0 + f_count = 0 + five_list.append(char.name) + five_index_list.append(i) + try: + five_dict[char.name] += 1 + except KeyError: + five_dict[char.name] = 1 + genshin_list.append(char) + if _count <= 90: + genshin_count[user_id] = f_count + genshin_pl_count[user_id] = count + return genshin_list, five_list, five_index_list, five_dict, star_list + + +def reset_count(user_id: int): + genshin_count[user_id] = 0 + genshin_pl_count[user_id] = 0 diff --git a/plugins/draw_card/init_card_pool.py b/plugins/draw_card/init_card_pool.py new file mode 100644 index 00000000..46ec58be --- /dev/null +++ b/plugins/draw_card/init_card_pool.py @@ -0,0 +1,33 @@ +from typing import Any + + +def init_game_pool(game: str, data: dict, Operator: Any): + tmp_lst = [] + if game == 'prts': + for key in data.keys(): + limited = False + recruit_only = False + event_only = False + if '限定寻访' in data[key]['获取途径']: + limited = True + if len(data[key]['获取途径']) == 1 and data[key]['获取途径'][0] == '公开招募': + recruit_only = True + if '活动获取' in data[key]['获取途径']: + event_only = True + if key.find('阿米娅') != -1: + continue + tmp_lst.append(Operator(name=key, star=int(data[key]['星级']), + limited=limited, recruit_only=recruit_only, event_only=event_only)) + if game == 'genshin': + for key in data.keys(): + if key.find('旅行者') != -1: + continue + tmp_lst.append(Operator(name=key, star=int(data[key]['稀有度'][:1]), limited=False)) + if game == 'pretty': + for key in data.keys(): + tmp_lst.append(Operator(name=key, star=data[key]['初始星级'], limited=False)) + if game == 'pretty_card': + for key in data.keys(): + tmp_lst.append(Operator(name=data[key]['中文名'], star=len(data[key]['稀有度']), limited=False)) + return tmp_lst + diff --git a/plugins/draw_card/pretty_handle.py b/plugins/draw_card/pretty_handle.py new file mode 100644 index 00000000..dfee34fe --- /dev/null +++ b/plugins/draw_card/pretty_handle.py @@ -0,0 +1,105 @@ + +import os +import nonebot +from util.init_result import image +from configs.path_config import DRAW_PATH +from .update_game_info import update_info +from .util import download_img, init_star_rst, generate_img, max_card, BaseData, set_list +import random +from .config import PRETTY_THREE, PRETTY_TWO, PRETTY_ONE +from dataclasses import dataclass +from .init_card_pool import init_game_pool +try: + import ujson as json +except ModuleNotFoundError: + import json + +driver: nonebot.Driver = nonebot.get_driver() + +ALL_CHAR = [] +ALL_CARD = [] + + +@dataclass +class PrettyChar(BaseData): + pass + + +async def pretty_draw(count: int, pool_name): + if pool_name == 'card': + cnlist = ['SSR', 'SR', 'R'] + else: + cnlist = ['★★★', '★★', '★'] + obj_list, obj_dict, three_list, star_list, three_olist = _format_card_information(count, pool_name) + rst = init_star_rst(star_list, cnlist, three_list, three_olist) + if count > 90: + obj_list = set_list(obj_list) + return image(b64=await generate_img(obj_list, 'pretty', star_list)) \ + + '\n' + rst[:-1] + '\n' + max_card(obj_dict) + + +async def update_pretty_info(): + global ALL_CHAR, ALL_CARD + url = 'https://wiki.biligame.com/umamusume/赛马娘图鉴' + data, code = await update_info(url, 'pretty') + if code == 200: + ALL_CHAR = init_game_pool('pretty', data, PrettyChar) + url = 'https://wiki.biligame.com/umamusume/支援卡图鉴' + data, code = await update_info(url, 'pretty_card') + if code == 200: + ALL_CARD = init_game_pool('pretty_card', data, PrettyChar) + + +@driver.on_startup +async def init_data(): + global ALL_CHAR, ALL_CARD + if not os.path.exists(DRAW_PATH + '/draw_card_config/pretty.json') or\ + not os.path.exists(DRAW_PATH + '/draw_card_config/pretty_card.json'): + await update_pretty_info() + for icon_url in [ + 'https://patchwiki.biligame.com/images/umamusume/thumb/0/06/q23szwkbtd7pfkqrk3wcjlxxt9z595o.png' + '/40px-SSR.png', + 'https://patchwiki.biligame.com/images/umamusume/thumb/3/3b/d1jmpwrsk4irkes1gdvoos4ic6rmuht.png' + '/40px-SR.png', + 'https://patchwiki.biligame.com/images/umamusume/thumb/f/f7/afqs7h4snmvovsrlifq5ib8vlpu2wvk.png' + '/40px-R.png']: + await download_img(icon_url, 'pretty', icon_url.split('-')[-1][:-4]) + else: + with open(DRAW_PATH + '/draw_card_config/pretty.json', 'r', encoding='utf8') as f: + pretty_char_dict = json.load(f) + with open(DRAW_PATH + '/draw_card_config/pretty_card.json', 'r', encoding='utf8') as f: + pretty_card_dict = json.load(f) + ALL_CHAR = init_game_pool('pretty', pretty_char_dict, PrettyChar) + ALL_CARD = init_game_pool('pretty_card', pretty_card_dict, PrettyChar) + + +# 抽取卡池 +def _get_pretty_card(itype): + global ALL_CHAR, ALL_CARD + star = random.sample([3, 2, 1], + counts=[int(PRETTY_THREE * 100), int(PRETTY_TWO * 100), + int(PRETTY_ONE * 100)], + k=1)[0] + chars = [x for x in (ALL_CARD if itype == 'card' else ALL_CHAR) if x.star == star] + return random.choice(chars), abs(star - 3) + + +# 整理数据 +def _format_card_information(count: int, pool_name: str): + three_list = [] + three_olist = [] + obj_list = [] + obj_dict = {} + star_list = [0, 0, 0] + for i in range(count): + obj, code = _get_pretty_card(pool_name) + star_list[code] += 1 + if code == 0: + three_list.append(obj.name) + three_olist.append(i) + try: + obj_dict[obj.name] += 1 + except KeyError: + obj_dict[obj.name] = 1 + obj_list.append(obj) + return obj_list, obj_dict, three_list, star_list, three_olist diff --git a/plugins/draw_card/prts_handle.py b/plugins/draw_card/prts_handle.py new file mode 100644 index 00000000..2631cf96 --- /dev/null +++ b/plugins/draw_card/prts_handle.py @@ -0,0 +1,162 @@ + +import os +import nonebot +import random +from .config import PRTS_FIVE_P, PRTS_FOUR_P, PRTS_SIX_P, PRTS_THREE_P +from .update_game_info import update_info +from .util import generate_img, init_star_rst, max_card, BaseData, UpEvent, set_list +from .init_card_pool import init_game_pool +from pathlib import Path +from .announcement import PrtsAnnouncement +from dataclasses import dataclass +from util.init_result import image +from configs.path_config import DRAW_PATH +from services.log import logger +try: + import ujson as json +except ModuleNotFoundError: + import json + +driver: nonebot.Driver = nonebot.get_driver() + +up_char_file = Path() / "data" / "draw_card" / "draw_card_up" / "prts_up_char.json" + +prts_dict = {} +UP_OPERATOR = [] +ALL_OPERATOR = [] +_CURRENT_POOL_TITLE = '' + + +@dataclass +class Operator(BaseData): + recruit_only: bool # 公招限定 + event_only: bool # 活动获得干员 + # special_only: bool # 升变/异格干员 + + +async def prts_draw(count: int = 300): + cnlist = ['★★★★★★', '★★★★★', '★★★★', '★★★'] + operator_list, operator_dict, six_list, star_list, six_olist = _format_card_information(count) + up_list = [] + if _CURRENT_POOL_TITLE: + for x in UP_OPERATOR: + for operator in x.operators: + up_list.append(operator) + rst = init_star_rst(star_list, cnlist, six_list, six_olist, up_list) + if count > 90: + operator_list = set_list(operator_list) + pool_info = "当前up池: " if _CURRENT_POOL_TITLE else "" + return pool_info + _CURRENT_POOL_TITLE + image(b64=await generate_img(operator_list, 'prts', star_list)) \ + + '\n' + rst[:-1] + '\n' + max_card(operator_dict) + + +async def update_prts_info(): + global prts_dict, ALL_OPERATOR + url = 'https://wiki.biligame.com/arknights/干员数据表' + data, code = await update_info(url, 'prts', ['头像', '名称', '阵营', '星级', '性别', '是否感染', '初始生命', '初始防御', + '初始法抗', '再部署', '部署费用', '阻挡数', '攻击速度', '标签']) + if code == 200: + prts_dict = data + ALL_OPERATOR = init_game_pool('prts', prts_dict, Operator) + + +@driver.on_startup +async def init_data(): + global prts_dict, ALL_OPERATOR + if not os.path.exists(DRAW_PATH + '/draw_card_config/prts.json'): + await update_prts_info() + else: + with open(DRAW_PATH + '/draw_card_config/prts.json', 'r', encoding='utf8') as f: + prts_dict = json.load(f) + ALL_OPERATOR = init_game_pool('prts', prts_dict, Operator) + await _init_up_char() + # print([x.operators for x in UP_OPERATOR if x.star == 5 and x.zoom > 1]) + + +# 抽取干员 +def _get_operator_card(): + star = random.sample([6, 5, 4, 3], + counts=[int(PRTS_SIX_P * 100), int(PRTS_FIVE_P * 100), + int(PRTS_FOUR_P * 100), int(PRTS_THREE_P * 100)], + k=1)[0] + if _CURRENT_POOL_TITLE: + zooms = [x.zoom for x in UP_OPERATOR if x.star == star] + zoom = 0 + weight = 0 + # 分配概率和权重 + for z in zooms: + if z < 1: + zoom = z + else: + weight = z + # UP + if random.random() < zoom: + up_operators = [x.operators for x in UP_OPERATOR if x.star == star and x.zoom < 1][0] + up_operator_name = random.choice(up_operators) + # print(up_operator_name) + acquire_operator = [x for x in ALL_OPERATOR if x.name == up_operator_name][0] + else: + all_star_operators = [x for x in ALL_OPERATOR if x.star == star + and not any([x.limited, x.event_only, x.recruit_only])] + weight_up_operators = [x.operators for x in UP_OPERATOR if x.star == star and x.zoom > 1] + # 权重 + if weight_up_operators and random.random() < 1.0 / float(len(all_star_operators)) * weight: + up_operator_name = random.choice(weight_up_operators[0]) + acquire_operator = [x for x in ALL_OPERATOR if x.name == up_operator_name][0] + else: + acquire_operator = random.choice(all_star_operators) + else: + acquire_operator = random.choice([x for x in ALL_OPERATOR if x.star == star + and not any([x.limited, x.event_only, x.recruit_only])]) + # print(f'{acquire_operator}: {star}') + return acquire_operator, abs(star - 6) + + +# 整理抽卡数据 +def _format_card_information(count: int): + operator_list = [] # 抽取的干员列表 + operator_dict = {} # 抽取各干员次数 + star_list = [0, 0, 0, 0] # 各个星级次数 + six_list = [] # 六星干员列表 + six_index_list = [] # 六星干员获取位置 + for i in range(count): + operator, code = _get_operator_card() + star_list[code] += 1 + if code == 0: + six_list.append(operator.name) + six_index_list.append(i) + try: + operator_dict[operator.name] += 1 + except KeyError: + operator_dict[operator.name] = 1 + operator_list.append(operator) + return operator_list, operator_dict, six_list, star_list, six_index_list + + +# 获取up干员和概率 +async def _init_up_char(): + global up_char_dict, _CURRENT_POOL_TITLE + up_char_dict = await PrtsAnnouncement.update_up_char() + # print(up_char_dict) + _CURRENT_POOL_TITLE = up_char_dict['title'] + up_char_dict = up_char_dict['up_char'] + logger.info(f'成功获取明日方舟当前up信息...当前up池: {_CURRENT_POOL_TITLE}') + average_dict = {'6': {}, '5': {}, '4': {}} + for star in up_char_dict.keys(): + for key in up_char_dict[star].keys(): + if average_dict[star].get(up_char_dict[star][key]): + average_dict[star][up_char_dict[star][key]].append(key) + else: + average_dict[star][up_char_dict[star][key]] = [key] + up_char_dict = {'6': {}, '5': {}, '4': {}} + for star in average_dict.keys(): + for str_zoom in average_dict[star].keys(): + if str_zoom[0] == '权': + zoom = float(str_zoom[1:]) + else: + zoom = float(str_zoom) / 100 + UP_OPERATOR.append(UpEvent(star=int(star), operators=average_dict[star][str_zoom], zoom=zoom)) + + +async def reload_pool(): + await _init_up_char() diff --git a/plugins/draw_card/update_game_info.py b/plugins/draw_card/update_game_info.py new file mode 100644 index 00000000..c9b208b9 --- /dev/null +++ b/plugins/draw_card/update_game_info.py @@ -0,0 +1,162 @@ +#coding:utf-8 +import aiohttp +from configs.path_config import DRAW_PATH +from asyncio.exceptions import TimeoutError +from services.log import logger +from bs4 import BeautifulSoup +from .util import download_img +from urllib.parse import unquote +import bs4 +from util.user_agent import get_user_agent +import re +try: + import ujson as json +except ModuleNotFoundError: + import json + + +async def update_info(url: str, game_name: str, info_list: list = None) -> 'dict, int': + try: + with open(DRAW_PATH + f'/draw_card_config/{game_name}.json', 'r', encoding='utf8') as f: + data = json.load(f) + except (ValueError, FileNotFoundError): + data = {} + try: + async with aiohttp.ClientSession(headers=get_user_agent()) as session: + async with session.get(url, timeout=7) as response: + soup = BeautifulSoup(await response.text(), 'lxml') + max_count = 0 + _tbody = None + for tbody in soup.find_all('tbody'): + if len(tbody.find_all('tr')) > max_count: + _tbody = tbody + max_count = len(tbody.find_all('tr')) + trs = _tbody.find_all('tr') + att_dict = {'头像': 0, '名称': 1} + index = 2 + for th in trs[0].find_all('th')[2:]: + text = th.text + if text[-1] == '\n': + text = text[:-1] + att_dict[text] = index + index += 1 + for tr in trs[1:]: + member_dict = {} + k_name = '' + tds = tr.find_all('td') + if not info_list: + info_list = att_dict.keys() + for key in info_list: + attr = '' + if key.find('.') != -1: + key = key.split('.') + attr = key[-1] + key = key[0] + td = tds[att_dict[key]] + last_tag = unquote(_find_last_tag(td, attr), 'utf-8') + if game_name.find('pretty') == -1 and last_tag.find('http') == -1: + last_tag = last_tag.split('.')[0] + if key == '名称': + k_name = last_tag + member_dict[key] = last_tag + if game_name == 'pretty' and key == '初始星级': + member_dict['初始星级'] = len(td.find_all('img')) + avatar_img = await _modify_avatar_url(session, game_name, member_dict["名称"]) + if avatar_img: + member_dict['头像'] = avatar_img + name = member_dict['名称'] + if game_name == 'pretty_card': + name = member_dict['中文名'] + await download_img(member_dict['头像'], game_name, name) + if k_name: + data[k_name] = member_dict + logger.info(f'{k_name} is update...') + data = await _last_check(data, game_name, session) + except TimeoutError: + return {}, 999 + with open(DRAW_PATH + f'/draw_card_config/{game_name}.json', 'w', encoding='utf8') as wf: + wf.write(json.dumps(data, ensure_ascii=False, indent=4)) + return data, 200 + + +def _find_last_tag(element: bs4.element.Tag, attr: str) -> str: + last_tag = [] + for des in element.descendants: + last_tag.append(des) + if len(last_tag) == 1 and last_tag[0] == '\n': + last_tag = '' + elif last_tag[-1] == '\n': + last_tag = last_tag[-2] + else: + last_tag = last_tag[-1] + if attr and str(last_tag): + last_tag = last_tag[attr] + elif str(last_tag).find('([\s\S]*)'): + obtain = obtain.split('
') + elif obtain.find('
'): + obtain = obtain.split('
') + data[key]['获取途径'] = obtain + # if game_name == 'genshin': + # for key in data.keys(): + # async with session.get(f'https://wiki.biligame.com/ys/{key}', timeout=7) as res: + # soup = BeautifulSoup(await res.text(), 'lxml') + # trs = soup.find('div', {'class': 'poke-bg'}).find('table').find('tbody').find_all('tr') + # for tr in trs: + # if tr.find('th').text.find('常驻/限定') != -1: + # data[key]['常驻/限定'] = tr.find('td').text + # break + if game_name == 'pretty': + for keys in data.keys(): + for key in data[keys].keys(): + # print(f'key --> {data[keys][key]}') + r = re.search(r'.*?40px-(.*)图标.png', str(data[keys][key])) + if r: + data[keys][key] = r.group(1) + return data + + + + +# ul = soup.find('div', {'class': 'savelist_bot'}).find('ul') + + diff --git a/plugins/draw_card/util.py b/plugins/draw_card/util.py new file mode 100644 index 00000000..edd57e94 --- /dev/null +++ b/plugins/draw_card/util.py @@ -0,0 +1,161 @@ +import os +import aiohttp +import aiofiles +from asyncio.exceptions import TimeoutError +from aiohttp.client_exceptions import InvalidURL +from typing import List, Union, Set +import asyncio +from pathlib import Path +from .config import path_dict +import nonebot +from util.utils import cn2py +from util.img_utils import CreateImg +from util.user_agent import get_user_agent +from configs.path_config import IMAGE_PATH +from dataclasses import dataclass +from services.log import logger +try: + import ujson as json +except ModuleNotFoundError: + import json + + +driver: nonebot.Driver = nonebot.get_driver() + + +@dataclass +class BaseData: + name: str + star: int + limited: bool # 限定 + + +@dataclass +class UpEvent: + star: int # 对应up星级 + operators: List[BaseData] # 干员列表 + zoom: float # up提升倍率 + + +async def download_img(url: str, path: str, name: str) -> bool: + path = path.split('_')[0] + codename = cn2py(name) + # if not _p.exists(): + # _p.mkdir(parents=True, exist_ok=True) + if not os.path.exists(IMAGE_PATH + f'/draw_card/{path}/{codename}.png'): + try: + async with aiohttp.ClientSession(headers=get_user_agent()) as session: + async with session.get(url, timeout=7) as response: + async with aiofiles.open(IMAGE_PATH + f'/draw_card/{path}/{codename}.png', 'wb') as f: + await f.write(await response.read()) + logger.info(f'下载 {path_dict[path]} 图片成功,名称:{name},url:{url}') + return True + except TimeoutError: + logger.info(f'下载 {path_dict[path]} 图片超时,名称:{name},url:{url}') + return False + except InvalidURL: + logger.info(f'下载 {path_dict[path]} 链接错误,名称:{name},url:{url}') + return False + else: + # logger.info(f'{path_dict[path]} 图片 {name} 已存在') + return False + + +@driver.on_startup +def _check_dir(): + for dir_name in path_dict.keys(): + _p = Path(IMAGE_PATH + f'/draw_card/' + dir_name) + if not _p.exists(): + _p.mkdir(parents=True, exist_ok=True) + + +async def generate_img(card_set: Union[Set[BaseData], List[BaseData]], game_name: str, star_list: list) -> str: + # try: + img_list = [] + color_list = [] + for x in card_set: + if game_name == 'prts': + if x.star == 6: + color_list.append('#FFD700') + elif x.star == 5: + color_list.append('#DAA520') + elif x.star == 4: + color_list.append('#9370D8') + else: + color_list.append('white') + pyname = cn2py(x.name) + img_list.append(IMAGE_PATH + f'/draw_card/{game_name}/{pyname}.png') + img_len = len(img_list) + w = 100 * 10 + if img_len <= 10: + w = 100 * img_len + h = 100 + elif img_len % 10 == 0: + h = 100 * int(img_len / 10) + else: + h = 100 * int(img_len / 10) + 100 + card_img = await asyncio.get_event_loop().run_in_executor(None, _pst, h, img_list, game_name, color_list) + num = 0 + for n in star_list: + num += n + A = CreateImg(w, h) + A.paste(card_img) + return A.pic2bs4() + + +def _pst(h: int, img_list: list, game_name: str, color_list: list): + card_img = CreateImg(100 * 10, h, 100, 100) + idx = 0 + for img in img_list: + try: + if game_name == 'prts': + bk = CreateImg(100, 100, color=color_list[idx]) + b = CreateImg(94, 94, background=img) + bk.paste(b, (3, 3)) + b = bk + idx += 1 + else: + b = CreateImg(100, 100, background=img) + except FileNotFoundError: + print(f'{img} not exists') + b = CreateImg(100, 100, color='black') + card_img.paste(b) + return card_img + + +def init_star_rst(star_list: list, cnlist: list, max_star_list: list, max_star_olist: list, up_list: list = None) -> str: + if not up_list: + up_list = [] + rst = '' + for i in range(len(star_list)): + if star_list[i]: + rst += f'[{cnlist[i]}×{star_list[i]}] ' + rst += '\n' + for i in range(len(max_star_list)): + if max_star_list[i] in up_list: + rst += f'第 {max_star_olist[i]+1} 抽获取UP {max_star_list[i]}\n' + else: + rst += f'第 {max_star_olist[i]+1} 抽获取 {max_star_list[i]}\n' + return rst + + +def max_card(_dict: dict): + _max_value = max(_dict.values()) + _max_user = list(_dict.keys())[list(_dict.values()).index(_max_value)] + return f'抽取到最多的是{_max_user},共抽取了{_max_value}次' + # ThreeHighest = nlargest(3, operator_dict, key=operator_dict.get) + # rst = '最喜欢你的前三位是干员是:\n' + # for name in ThreeHighest: + # rst += f'{name} 共投了 {operator_dict[name]} 份简历\n' + # return rst[:-1] + + +def set_list(lst: List[BaseData]) -> list: + tmp = [] + name_lst = [] + for x in lst: + if x.name not in name_lst: + tmp.append(x) + name_lst.append(x.name) + return tmp + diff --git a/plugins/epic/__init__.py b/plugins/epic/__init__.py new file mode 100644 index 00000000..b96e3013 --- /dev/null +++ b/plugins/epic/__init__.py @@ -0,0 +1,60 @@ +from nonebot import on_command +from services.log import logger +from nonebot.adapters.cqhttp import Bot, MessageEvent +from nonebot.typing import T_State +from util.utils import scheduler, get_bot +from .data_source import get_epic_game +from models.group_remind import GroupRemind +from nonebot.adapters.cqhttp.exception import ActionFailed + +__plugin_usage__ = 'epic免费游戏提醒' + + +epic = on_command("epic", priority=5, block=True) + + +@epic.handle() +async def _(bot: Bot, event: MessageEvent, state: T_State): + # try: + if str(event.get_message()) in ['帮助']: + await epic.finish(__plugin_usage__) + try: + result = await get_epic_game() + except: + result = '网络出错了!' + await epic.send(result) + logger.info( + f"(USER {event.user_id}, GROUP {event.group_id if event.message_type != 'private' else 'private'})" + f" 获取epic免费游戏") + # except Exception as e: + # logger.error(f'epic 出错 e:{e}') + # await epic.finish('网络好像炸了,再试一次?', at_sender=True) + + +# epic免费游戏 +@scheduler.scheduled_job( + 'cron', + hour=12, + minute=1, +) +async def _(): + # try: + 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: + if await GroupRemind.get_status(g, 'epic'): + result = await get_epic_game() + if result == '今天没有游戏可以白嫖了!': + return + try: + await bot.send_group_msg(group_id=g, + message=result) + except ActionFailed: + logger.error(f'{g}群 epic免费游戏推送错误') + # except Exception as e: + # logger.error(f'epic免费游戏推送错误 e:{e}') + + + + diff --git a/plugins/epic/__pycache__/__init__.cpython-38.pyc b/plugins/epic/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..d34d9136 Binary files /dev/null and b/plugins/epic/__pycache__/__init__.cpython-38.pyc differ diff --git a/plugins/epic/__pycache__/__init__.cpython-39.pyc b/plugins/epic/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 00000000..08ef01d7 Binary files /dev/null and b/plugins/epic/__pycache__/__init__.cpython-39.pyc differ diff --git a/plugins/epic/__pycache__/data_source.cpython-38.pyc b/plugins/epic/__pycache__/data_source.cpython-38.pyc new file mode 100644 index 00000000..825f6e02 Binary files /dev/null and b/plugins/epic/__pycache__/data_source.cpython-38.pyc differ diff --git a/plugins/epic/__pycache__/data_source.cpython-39.pyc b/plugins/epic/__pycache__/data_source.cpython-39.pyc new file mode 100644 index 00000000..4c17f0c8 Binary files /dev/null and b/plugins/epic/__pycache__/data_source.cpython-39.pyc differ diff --git a/plugins/epic/data_source.py b/plugins/epic/data_source.py new file mode 100644 index 00000000..8f40f32f --- /dev/null +++ b/plugins/epic/data_source.py @@ -0,0 +1,46 @@ +import aiohttp +import aiofiles +from util.utils import get_local_proxy +import feedparser +import platform +from util.init_result import image +from configs.path_config import IMAGE_PATH +from util.user_agent import get_user_agent +if platform.system() == 'Windows': + import asyncio + asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy()) + + +url = 'https://rsshub.app/epicgames/freegames' + + +async def get_epic_game() -> str: + result = '' + async with aiohttp.ClientSession(headers=get_user_agent()) as session: + async with session.get(url, proxy=get_local_proxy(), timeout=7) as response: + data = feedparser.parse(await response.text())['entries'] + if len(data) == 0: + return result + index = 0 + for item in data: + title = item['title'] + img_url = item['summary'][item['summary'].find('src="')+5: item['summary'].rfind('"')] + async with session.get(img_url, proxy=get_local_proxy(), timeout=7) as res: + async with aiofiles.open(IMAGE_PATH + f'temp/epic_{index}.jpg', 'wb') as f: + await f.write(await res.read()) + link = item['link'] + result += image(f'epic_{index}.jpg', 'temp') + f'\n【游戏】| {title}\n【链接】 | {link}\n' + index += 1 + if result != '': + result = 'epic限免游戏(速速白嫖):\n' + result + else: + result = '今天没有游戏可以白嫖了!' + print(result) + return result + + + + +# print(asyncio.get_event_loop().run_until_complete(get_epic_game())) + + diff --git a/plugins/fake_msg.py b/plugins/fake_msg.py new file mode 100644 index 00000000..ab4e794a --- /dev/null +++ b/plugins/fake_msg.py @@ -0,0 +1,55 @@ +from nonebot.typing import T_State +from nonebot.adapters.cqhttp import Bot, MessageEvent +from nonebot import on_command +from util.utils import get_message_imgs, get_message_text +from util.init_result import share +from services.log import logger + + +__plugin_usage__ = '用法:\n格式:网址 标题 内容(可省略) 图片(可省略)\n示例:假消息 www.4399.com 我喜欢萝莉 为什么我喜欢... (图片)' + + +fake_msg = on_command('假消息', priority=5, block=True) + + +@fake_msg.handle() +async def _(bot: Bot, event: MessageEvent, state: T_State): + msg = get_message_text(event.json()).split(' ') + img = get_message_imgs(event.json()) + if not msg or msg in ['帮助']: + await fake_msg.finish(__plugin_usage__) + if len(msg) > 1: + if len(msg) == 2: + url = msg[0] + title = msg[1] + content = '' + else: + url = msg[0] + title = msg[1] + content = msg[2] + if img: + img = img[0] + else: + img = '' + if url.find('http://') == -1: + url = 'http://' + url + await fake_msg.send(share(url, title, content, img)) + logger.info( + f"(USER {event.user_id}, GROUP {event.group_id if event.message_type != 'private' else 'private'})" + f" 构造假消息 url {url}, title {title}, content {content}") + else: + await fake_msg.finish('消息格式错误:\n网址 标题 内容(可省略) 图片(可省略)') + + + + + + + + + + + + + + diff --git a/plugins/fudu.py b/plugins/fudu.py new file mode 100644 index 00000000..22ee19e8 --- /dev/null +++ b/plugins/fudu.py @@ -0,0 +1,88 @@ +from nonebot.adapters.cqhttp.permission import GROUP +from configs.path_config import IMAGE_PATH +from util.img_utils import get_img_hash +import random +from util.init_result import image +from nonebot import on_message +from util.utils import get_message_text, get_message_imgs, get_local_proxy +from nonebot.typing import T_State +from nonebot.adapters.cqhttp import Bot, GroupMessageEvent +import aiohttp +import aiofiles +from collections import defaultdict +from configs.config import FUDU_PROBABILITY + + +class Fudu: + def __init__(self): + self.mlist = defaultdict(list) + + def append(self, key, content): + self.mlist[key].append(content) + + def clear(self, key): + self.mlist[key] = [] + + def size(self, key) -> int: + return len(self.mlist[key]) + + def check(self, key, content) -> bool: + return self.mlist[key][0] == content + + def get(self, key): + return self.mlist[key][0] + + +_fudulist = Fudu() + + +fudu = on_message(permission=GROUP, priority=9) + + +@fudu.handle() +async def _(bot: Bot, event: GroupMessageEvent, state: T_State): + if event.is_tome() or state["_prefix"]["raw_command"]: + return + if get_message_text(event.json()): + if get_message_text(event.json()).find('@可爱的小真寻') != -1: + await fudu.finish('复制粘贴的虚空艾特?', at_sender=True) + imgs = get_message_imgs(event.json()) + msg = get_message_text(event.json()) + if not imgs and not msg: + return + if imgs: + img_hash = await get_fudu_img_hash(imgs[0], event.group_id) + else: + img_hash = '' + add_msg = msg + '|-|' + img_hash + if _fudulist.size(event.group_id) == 0: + _fudulist.append(event.group_id, add_msg) + elif _fudulist.check(event.group_id, add_msg): + _fudulist.append(event.group_id, add_msg) + else: + _fudulist.clear(event.group_id) + _fudulist.append(event.group_id, add_msg) + if _fudulist.size(event.group_id) > 2: + if random.random() < FUDU_PROBABILITY: + if random.random() < 0.2: + await fudu.finish("打断施法!") + if imgs and msg: + rst = msg + image(f'compare_{event.group_id}_img.jpg', 'temp') + elif imgs: + rst = image(f'compare_{event.group_id}_img.jpg', 'temp') + elif msg: + rst = msg + else: + rst = '' + if rst: + await fudu.send(rst) + _fudulist.clear(event.group_id) + + +async def get_fudu_img_hash(url, group_id): + async with aiohttp.ClientSession() as session: + async with session.get(url, proxy=get_local_proxy(), timeout=5) as response: + async with aiofiles.open(IMAGE_PATH + f"temp/compare_{group_id}_img.jpg", 'wb') as f: + await f.write(await response.read()) + img_hash = get_img_hash(IMAGE_PATH + f"temp/compare_{group_id}_img.jpg") + return str(img_hash) diff --git a/plugins/genshin/almanac/__init__.py b/plugins/genshin/almanac/__init__.py new file mode 100644 index 00000000..36122e09 --- /dev/null +++ b/plugins/genshin/almanac/__init__.py @@ -0,0 +1,49 @@ +from .alc import get_almanac_base64_str, load_data +import os +from util.utils import get_bot, scheduler +from nonebot import on_command +from models.level_user import LevelUser +from nonebot.typing import T_State +from nonebot.adapters.cqhttp import Bot, GroupMessageEvent +from util.init_result import image +from services.log import logger +from models.group_remind import GroupRemind + +FILE_PATH = os.path.dirname(__file__) + +almanac = on_command('原神黄历', priority=5, block=True) +reload = on_command('重载原神黄历数据', priority=5, block=True) + + +@almanac.handle() +async def _(bot: Bot, event: GroupMessageEvent, state: T_State): + almanac_base64 = get_almanac_base64_str() + mes = image(b64=almanac_base64) + "\n ※ 黄历数据来源于 genshin.pub" + await almanac.send(mes) + logger.info( + f"(USER {event.user_id}, GROUP {event.group_id if event.message_type != 'private' else 'private'})" + f" 发送查看原神黄历") + + +@reload.handle() +async def _(bot: Bot, event: GroupMessageEvent, state: T_State): + if await LevelUser.check_level(event.user_id, event.group_id, 5): + load_data() + await reload.send("重载成功") + + +@scheduler.scheduled_job( + 'cron', + hour=10, + minute=25, +) +async def _(): + # 每日提醒 + bot = get_bot() + gl = await bot.get_group_list(self_id=bot.self_id) + gl = [g['group_id'] for g in gl] + almanac_base64 = get_almanac_base64_str() + mes = image(b64=almanac_base64) + "\n ※ 黄历数据来源于 genshin.pub" + for gid in gl: + if await GroupRemind.get_status(gid, 'almanac'): + await bot.send_group_msg(group_id=int(gid), message=mes) diff --git a/plugins/genshin/almanac/__pycache__/__init__.cpython-39.pyc b/plugins/genshin/almanac/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 00000000..45815d12 Binary files /dev/null and b/plugins/genshin/almanac/__pycache__/__init__.cpython-39.pyc differ diff --git a/plugins/genshin/almanac/__pycache__/alc.cpython-39.pyc b/plugins/genshin/almanac/__pycache__/alc.cpython-39.pyc new file mode 100644 index 00000000..00560e4b Binary files /dev/null and b/plugins/genshin/almanac/__pycache__/alc.cpython-39.pyc differ diff --git a/plugins/genshin/almanac/alc.py b/plugins/genshin/almanac/alc.py new file mode 100644 index 00000000..45b0205a --- /dev/null +++ b/plugins/genshin/almanac/alc.py @@ -0,0 +1,123 @@ +from PIL import Image, ImageDraw, ImageFont +from io import BytesIO + +import os +import json +import random +import base64 +import time + +FILE_PATH = os.path.dirname(__file__) +FONT_PATH = os.path.join(FILE_PATH, "汉仪文黑.ttf") + +data = {} # configs.json里的数据 + +almanac_data = { + # 生成的黄历base64字符串和黄历更新日期 + "date": "", + "almanac_base64_str": "" +} + +chinese = {"0": "", "1": "一", "2": "二", "3": "三", "4": "四", "5": "五", "6": "六", "7": "七", "8": "八", "9": "九"} + + +def month_to_chinese(month: str): + # 把日期数字转成中文数字 + m = int(month) + if m < 10: + return chinese[month[-1]] + elif m < 20: + return "十" + chinese[month[-1]] + else: + return chinese[month[0]] + "十" + chinese[month[-1]] + + +def load_data(): + # 载入config.json文件的数据 + global data + with open(os.path.join(FILE_PATH, 'config.json'), 'r', encoding='UTF-8') as f: + data = json.load(f) + + almanac_data["date"] = "" + almanac_data["almanac_base64_str"] = "" + + +load_data() + + +def seed_random_list(seed: str, l: list): + # 使用随机种子随机选择列表中的元素,相同的种子和列表将返回同样的输出 + seed = seed + str(l) + random.seed(seed) + index = random.random() * len(l) + return l[int(index)] + + +def generate_almanac(): + # 生成黄历图片,然后转换成base64保存到 almanac_data["almanac_base64_str"] + + seed = time.strftime("%Y-%m-%d") + offset = 1 + today_luck = [] + l = list(data.keys()) + + while len(today_luck) < 6: + # 随机6个不同的运势放到 today_luck + r = seed_random_list(str(offset) + seed, l) + if r in today_luck: + offset += 1 + else: + today_luck.append(r) + + back = Image.open(os.path.join(FILE_PATH, "back.png")) + + year = time.strftime("%Y") + month = month_to_chinese(time.strftime("%m")) + "月" + day = month_to_chinese(time.strftime("%d")) + "日" + + draw = ImageDraw.Draw(back) + draw.text((118, 165), year, fill="#8d7650ff", font=ImageFont.truetype(FONT_PATH, size=30), anchor="mm", + align="center") + draw.text((260, 165), day, fill="#f7f8f2ff", font=ImageFont.truetype(FONT_PATH, size=35), anchor="mm", + align="center") + draw.text((410, 165), month, fill="#8d7650ff", font=ImageFont.truetype(FONT_PATH, size=30), anchor="mm", + align="center") + + buff = Image.new("RGBA", (325, 160)) + debuff = Image.new("RGBA", (325, 160)) + + buff_draw = ImageDraw.Draw(buff) + debuff_draw = ImageDraw.Draw(debuff) + + for i in range(3): + buff_name = today_luck[i] + debuff_name = today_luck[(i + 3)] + + buff_effect = seed_random_list(seed, data[buff_name]["buff"]) + debuff_effect = seed_random_list(seed, data[debuff_name]["debuff"]) + + buff_draw.text((0, i * 53), buff_name, fill="#756141ff", font=ImageFont.truetype(FONT_PATH, size=25)) + debuff_draw.text((0, i * 53), debuff_name, fill="#756141ff", font=ImageFont.truetype(FONT_PATH, size=25)) + + buff_draw.text((0, i * 53 + 28), buff_effect, fill="#b5b3acff", font=ImageFont.truetype(FONT_PATH, size=19)) + debuff_draw.text((0, i * 53 + 28), debuff_effect, fill="#b5b3acff", font=ImageFont.truetype(FONT_PATH, size=19)) + + back.paste(buff, (150, 230), buff) + back.paste(debuff, (150, 400), debuff) + + bio = BytesIO() + back.save(bio, format='PNG') + base64_str = base64.b64encode(bio.getvalue()).decode() + + almanac_data["date"] = time.strftime("%Y-%m-%d") + almanac_data["almanac_base64_str"] = 'base64://' + base64_str + + +def get_almanac_base64_str(): + # if almanac_data["date"] == time.strftime("%Y-%m-%d"): + # return almanac_data["almanac_base64_str"] + # else: + # generate_almanac() + # return almanac_data["almanac_base64_str"] + generate_almanac() + return almanac_data["almanac_base64_str"] diff --git a/plugins/genshin/almanac/back.png b/plugins/genshin/almanac/back.png new file mode 100644 index 00000000..bce9428b Binary files /dev/null and b/plugins/genshin/almanac/back.png differ diff --git a/plugins/genshin/almanac/config.json b/plugins/genshin/almanac/config.json new file mode 100644 index 00000000..ebd1e35b --- /dev/null +++ b/plugins/genshin/almanac/config.json @@ -0,0 +1,70 @@ +{ + "抽卡":{ + "buff": ["欧气满满,十连出金","出金不歪"], + "debuff": ["武器大师","保底出金","金色会是痛苦大剑"] + }, + "刷世界boss":{ + "buff": ["双攻双爆角斗士"], + "debuff": ["只有保底材料","贪生怕死角斗士"] + }, + "刷风本":{ + "buff": ["会有极品猎人套","会掉真正的少女心","治疗加成少女头"], + "debuff": ["勇往直前少女心","少女飘摇的杀意","少女暴怒的容颜"] + }, + "刷火本":{ + "buff": ["魔女帽子火伤杯","暴伤魔女帽!","火伤魔女心!"], + "debuff": ["幡 然 醒 悟","这么阴间的地方真的会有魔女套吗?","不务正业火魔女","会匹配到3个卢姥爷"] + }, + "刷岩本":{ + "buff": ["悠久的磐岩伴你左右","岩神的庇护常在"], + "debuff": ["防御流星杯,你值得拥有"] + }, + "刷宗室":{ + "buff": ["物理伤害骑士道,元素精通宗室套"], + "debuff": ["贪生怕死骑士道,物理伤害宗室杯"] + }, + "刷冰本":{ + "buff": ["双暴词条概率up"], + "debuff": ["防御力船帽,无人可及"] + }, + "刷雷本":{ + "buff": ["愿雷鸟伴你左右"], + "debuff": ["来表演一个只掉平雷套的绝活","风神忽悠雷凶兆"] + }, + "锄大地":{ + "buff": ["会掉一大堆紫色材料"], + "debuff": ["深渊法师爱你哟","会被冰水法控到死"] + }, + "挖矿":{ + "buff": ["开矿出双材料"], + "debuff": ["去别人世界会被拒"] + }, + "刷天赋本":{ + "buff": ["金色!我看到了金色的书!"], + "debuff": ["2蓝2绿不会变"] + }, + "刷突破材料":{ + "buff": ["金色!我看到了金色的材料!"], + "debuff": ["2蓝2绿不会变"] + }, + "升级圣遗物":{ + "buff": ["稀有词条跳跳跳","会双爆拉满"], + "debuff": ["女 仆 狂 喜","无中生有防御力","生命拉满","完美避开双爆"] + }, + "打风魔龙":{ + "buff": ["看我一箭一个风魔鸡","今天特瓦林可以给想要的突破材料","5金加原胚!"], + "debuff": ["会不小心掉下平台","不小心被地板烫死了"] + }, + "打狼王":{ + "buff": ["今天安德琉斯的心情不错,可以py一下","5金加原胚!"], + "debuff": ["狼尾巴*1"] + }, + "打公子":{ + "buff": ["今天可以和公子py想要的突破材料","5金加原胚!"], + "debuff": ["要角没有!要命一条!"] + } +} + + + + diff --git a/plugins/genshin/almanac/汉仪文黑.ttf b/plugins/genshin/almanac/汉仪文黑.ttf new file mode 100644 index 00000000..891435dc Binary files /dev/null and b/plugins/genshin/almanac/汉仪文黑.ttf differ diff --git a/plugins/genshin/material_remind/__init__.py b/plugins/genshin/material_remind/__init__.py new file mode 100644 index 00000000..0abd8bd4 --- /dev/null +++ b/plugins/genshin/material_remind/__init__.py @@ -0,0 +1,72 @@ +from nonebot import on_command +from nonebot.typing import T_State +from nonebot.adapters.cqhttp import Bot, MessageEvent +from util.init_result import image + +import time + +material = on_command('今日素材', aliases={'今日材料', '今天素材', '今天材料'}, priority=5, block=True) +role_material = on_command('天赋材料', priority=5, block=True) + + +def get_today_material(name: str): + # 返回今天的材料图片CQ码 + if name == '天赋材料': + return image('天赋材料.png', "genshin/material/") + week = time.strftime("%w") + png_name = '' + if week == "0": + return "今天是周日,所有材料副本都开放了。" + elif week in ["1", "4"]: + png_name = f"{name}_周一周四.png" + elif week in ["2", "5"]: + png_name = f"{name}_周二周五.png" + elif week in ["3", "6"]: + png_name = f"{name}_周三周六.png" + + return image(png_name, "genshin/material/") + + +# @sv.on_fullmatch('开启原神每日素材提醒') +# async def open_remind(bot , ev): +# gid = str(ev.group_id) +# if not (gid in group_list): +# group_list.append(gid) +# save_group_list() +# await bot.send(ev, "每日提醒已开启,每天8点会发送今日素材") +# +# +# @sv.on_fullmatch('关闭原神每日素材提醒') +# async def off_remind(bot , ev): +# gid = str(ev.group_id) +# if gid in group_list: +# group_list.remove(gid) +# save_group_list() +# await bot.send(ev, "每日提醒已关闭") + +@material.handle() +async def _(bot: Bot, event: MessageEvent, state: T_State): + if time.strftime("%w") == "0": + await material.send("今天是周日,所有材料副本都开放了。") + return + arms_material_CQ = get_today_material("武器突破材料") + roles_material_CQ = get_today_material("角色天赋材料") + await material.send(arms_material_CQ + roles_material_CQ) + + +@role_material.handle() +async def _(bot: Bot, event: MessageEvent, state: T_State): + await material.send(get_today_material("天赋材料")) + +# @sv.scheduled_job('cron', hour='8') +# async def material_remind(): +# # 每日提醒 +# if time.strftime("%w") == "0": +# # 如果今天是周日就不发了 +# return +# bot = get_bot() +# arms_material_CQ = get_today_material("武器突破材料") +# roles_material_CQ = get_today_material("角色天赋材料") +# for gid in group_list: +# await bot.send_group_msg(group_id=int(gid), message=arms_material_CQ) +# await bot.send_group_msg(group_id=int(gid), message=roles_material_CQ) diff --git a/plugins/genshin/material_remind/__pycache__/__init__.cpython-39.pyc b/plugins/genshin/material_remind/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 00000000..75200979 Binary files /dev/null and b/plugins/genshin/material_remind/__pycache__/__init__.cpython-39.pyc differ diff --git a/plugins/genshin/qiu_qiu_translation/__init__.py b/plugins/genshin/qiu_qiu_translation/__init__.py new file mode 100644 index 00000000..6f10114e --- /dev/null +++ b/plugins/genshin/qiu_qiu_translation/__init__.py @@ -0,0 +1,37 @@ +from .qiu_translation import qiu_qiu_word_translation, qiu_qiu_phrase_translation +from nonebot.adapters.cqhttp import Bot, MessageEvent +from nonebot.typing import T_State +from nonebot import on_command +from util.utils import get_message_text +from services.log import logger + + +qiuqiu = on_command("丘丘语翻译", aliases={"丘丘一下", "丘丘翻译"}, priority=5, block=True) + +suffix = "\n※ 只能从丘丘语翻译为中文,不能反向翻译\n" \ + "※ 注意空格,不要加入任何标点符号\n" \ + "※ 翻译数据来源于 米游社论坛" + + +@qiuqiu.handle() +async def _(bot: Bot, event: MessageEvent, state: T_State): + txt = get_message_text(event.json()).lower() + if txt == "": + return + mes = qiu_qiu_phrase_translation(txt) + if not mes: + mes = qiu_qiu_word_translation(txt) + mes += suffix + # print(mes) + await qiuqiu.send(mes, at_sender=True) + logger.info( + f"(USER {event.user_id}, GROUP {event.group_id if event.message_type != 'private' else 'private'})" + f" 发送丘丘翻译:" + txt) + + + + + + + + diff --git a/plugins/genshin/qiu_qiu_translation/__pycache__/__init__.cpython-39.pyc b/plugins/genshin/qiu_qiu_translation/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 00000000..c9e8e5b0 Binary files /dev/null and b/plugins/genshin/qiu_qiu_translation/__pycache__/__init__.cpython-39.pyc differ diff --git a/plugins/genshin/qiu_qiu_translation/__pycache__/qiu_translation.cpython-39.pyc b/plugins/genshin/qiu_qiu_translation/__pycache__/qiu_translation.cpython-39.pyc new file mode 100644 index 00000000..45faf564 Binary files /dev/null and b/plugins/genshin/qiu_qiu_translation/__pycache__/qiu_translation.cpython-39.pyc differ diff --git a/plugins/genshin/qiu_qiu_translation/qiu_qiu_dictionary.json b/plugins/genshin/qiu_qiu_translation/qiu_qiu_dictionary.json new file mode 100644 index 00000000..08d0f329 --- /dev/null +++ b/plugins/genshin/qiu_qiu_translation/qiu_qiu_dictionary.json @@ -0,0 +1,127 @@ +{ + "word": { + + "a": "啊", + + "beru": "做", + "biadam": "找死啊", + "biat": "暴揍", + "buka": "肚子", + + "celi": "元素", + + "dada": "厉害", + "dala": "什么", + "domu": "跳舞", + + "eleka": "此时此刻", + + "guru": "咕", + "gusha": "草", + + "ika": "敌人", + + "kundela": "活着", + "kuzi": "强大", + "kucha": "吃草", + + "la": "啦~", + "lata": "水元素", + + "mani": "给予", + "mi": "我", + "mimi": "我们", + "mita": "肉类", + "mosi": "吃", + "movo": "带来", + "muhe": "胜利", + + "ni": "风", + "nini": "风暴", + "nunu": "睡觉", + "nye": "不", + + "odomu": "朋友", + "olah": "你好", + + "plata": "盾牌", + "pupu": "噗噗", + + "sada": "唱歌", + "shato": "伴随", + "si": "什么", + + "tomo": "感激", + "todo": "放心", + "tiga": "矿石", + + "upa": "聚集", + "unu": "乌努", + + "valo": "谢谢你", + "vin": "酒", + + "ya": "人", + "yaya": "人们", + "ye": "家伙", + "yeye": "这些家伙", + "yo": "你", + "yoyo": "你们", + + "zido": "杀死" + + }, + "phrase": { + "beru si": "做什么", + "biadam": "可恶啊,找死啊,愤怒语气", + "biat": "打爆,暴揍;可恶的", + + "dada": " 极好的,厉害的", + "dala": "表示疑问,不明白的集合,翻译为哪个,什么", + + "guru-guru": "拟声词,形容肚子咕咕叫的声音,饥饿", + "guru guru": "拟声词,形容肚子咕咕叫的声音,饥饿", + "gusha": "植物类食物,不怎么好的,难过的", + + "kucha pupu": "拟声词,吃草时候的拟声词,咯吱噗噗,形容吃草吃得香,贬义", + + "mita": "肉类,好的,好东西,有时代丘丘人,丘丘人部落,好肉族", + "mosi mita": "吃肉,表示开心", + "mosi gusha": "吃草,表示难过", + "movo": "带来,搬运;可引申为收获,丰收", + "muhe": "胜利,战胜;成功的", + + "nini": "大量风元素,风暴,狂风", + "nye": "表示否定,没有了,不是", + + "pupu":"拟声词,噗噗,表示嘲讽", + + "sada": "唱歌,歌颂", + "shato": "乘着,伴随着", + + "upa": "凝聚,聚集,集合;聚落,部落", + "unu": "乌努,丘丘人所崇拜的神灵", + + "valo": "谢谢你,不客气/再见", + "vin": "酒的,喝酒有关的,酒桶盖子", + + "ya": "特指人类,一个人类", + "yaya": "人类的复数 ,大群人类", + "ye": "你这个家伙,蔑称;或用于地位高者对地位低者的称呼", + "yeye": "你们这些家伙,蔑称,ye的复数", + "yo": "你,友善称呼", + "yoyo": "你们,yo的复数,友善称呼ye", + + + + "nye mita da ye mosi zido": "再见,一路平安", + "vin plata dada": "你的酒桶盾牌真不错", + "kucha pupu gucha ye": "你咯吱噗噗的吃草的样子真的好搞笑", + "mani nini biaodomu": "愿风暴给予你死亡", + "celi dada mimi nunu": "赞美元素,我们睡觉吧", + "muhe ye": "你们是不可战胜的", + "ye dada": "你们可真棒", + "ye yika": "你们是敌人", + "nini zido": "愿风暴杀死你" + } +} \ No newline at end of file diff --git a/plugins/genshin/qiu_qiu_translation/qiu_translation.py b/plugins/genshin/qiu_qiu_translation/qiu_translation.py new file mode 100644 index 00000000..f4e9ebc4 --- /dev/null +++ b/plugins/genshin/qiu_qiu_translation/qiu_translation.py @@ -0,0 +1,71 @@ +import json +import os + +FILE_PATH = os.path.dirname(__file__) + +QIU_QIU_WORD = {} +QIU_QIU_PHRASE = {} + +with open(os.path.join(FILE_PATH, 'qiu_qiu_dictionary.json'), 'r', encoding='UTF-8') as f: + data = json.load(f) + QIU_QIU_WORD = data["word"] + QIU_QIU_PHRASE = data["phrase"] + + +def compare_words(word): + # 比对word库是否有匹配的单词,有的话返回翻译,没有返回原词 + if word in QIU_QIU_WORD: + return QIU_QIU_WORD[word] + + return word + + +def compare_phrase(phrase): + # 比对phrase库是否有匹配的单词,有的话返回翻译,没有的话匹配word库,都没有返回原词 + if phrase in QIU_QIU_PHRASE: + return QIU_QIU_PHRASE[phrase] + if phrase in QIU_QIU_WORD: + return QIU_QIU_WORD[phrase] + + return phrase + + +def qiu_qiu_word_translation(txt: str): + # 对语句按空格分隔替换单词翻译 + txt_list = txt.split(" ") + mes = "你查询的的丘丘语意思为:\n" + + for word in txt_list: + tra_word = compare_words(word) + + if tra_word == word: + # 如果是原词表示没有翻译,前后加空格接回语句里 + if not mes[-1] == " ": + mes += " " + mes += tra_word + mes += " " + else: + mes += tra_word + mes += "\n" + return mes + + +def qiu_qiu_phrase_translation(phrase): + # 语句翻译,先看phrase库是不是有匹配的语句 + # 没有的话把单词拆开返回单词的意思 + tra_phrase = compare_phrase(phrase) + if tra_phrase != phrase: + return f"\n翻译丘丘语意思为:\n【{tra_phrase}】\n" + + txt_list = phrase.split(" ") + mes = "没有查到这句丘丘语,以下是单词的翻译\n" + for word in txt_list: + if word == " ": + continue + tra_word = compare_phrase(word) + if tra_word == word: + mes += f"{word} : 没有这个词的翻译\n" + else: + mes += f"{word} : {tra_word}\n" + + return mes diff --git a/plugins/genshin/query_resource_points/__init__.py b/plugins/genshin/query_resource_points/__init__.py new file mode 100644 index 00000000..8e170d54 --- /dev/null +++ b/plugins/genshin/query_resource_points/__init__.py @@ -0,0 +1,96 @@ +from nonebot import on_command, on_regex +from .query_resource import get_resource_map_mes, get_resource_list_mes, up_label_and_point_list +from util.utils import get_message_text, scheduler +from nonebot.adapters.cqhttp import Bot, MessageEvent +from nonebot.typing import T_State +import os +from services.log import logger +import re +try: + import ujson as json +except ModuleNotFoundError: + import json + +qr = on_command("原神资源查询", priority=5, block=True) +qr_lst = on_command("原神资源列表", priority=5, block=True) +rex_qr = on_regex('.*?(在哪|在哪里|哪有|哪里有).*?', priority=5, block=True) + + +with open(os.path.dirname(__file__) + '/resource_type_id.json', 'r', encoding='utf-8') as f: + in_list = [n['name'] for n in json.load(f).values()] + + +@qr.handle() +async def _(bot: Bot, event: MessageEvent, state: T_State): + resource_name = get_message_text(event.json()) + if resource_name == "" or resource_name not in in_list: + return + + await qr.send(get_resource_map_mes(resource_name), at_sender=True) + logger.info( + f"(USER {event.user_id}, GROUP {event.group_id if event.message_type != 'private' else 'private'})" + f" 查询原神材料:" + resource_name) + + +@rex_qr.handle() +async def _(bot: Bot, event: MessageEvent, state: T_State): + msg = get_message_text(event.json()) + if msg.find('在哪') != -1: + rs = re.search('(.*)在哪.*?', msg) + resource_name = rs.group(1) if rs else '' + else: + rs = re.search('.*?(哪有|哪里有)(.*)', msg) + resource_name = rs.group(2) if rs else '' + if resource_name: + msg = get_resource_map_mes(resource_name) + if msg == '发送 原神资源列表 查看所有资源名称': + return + await rex_qr.send(msg, at_sender=True) + logger.info( + f"(USER {event.user_id}, GROUP {event.group_id if event.message_type != 'private' else 'private'})" + f" 查询原神材料:" + resource_name) + + +@qr_lst.handle() +async def _(bot: Bot, event: MessageEvent, state: T_State): + # 长条消息经常发送失败,所以只能这样了 + mes_list = [] + txt = get_resource_list_mes() + txt_list = txt.split("\n") + if event.message_type == 'group': + for txt in txt_list: + data = { + "type": "node", + "data": { + "name": f"这里是{list(bot.config.nickname)[0]}酱", + "uin": f"{bot.self_id}", + "content": txt + } + } + mes_list.append(data) + # await bot.send(ev, get_resource_list_mes(), at_sender=True) + if event.message_type == 'group': + await bot.send_group_forward_msg(group_id=event.group_id, messages=mes_list) + else: + rst = '' + for i in range(len(txt_list)): + rst += txt_list[i] + '\n' + if i % 5 == 0: + if rst: + await qr_lst.send(rst) + rst = '' + + # await qr_lst.send(Message(mes_list)) + + +@scheduler.scheduled_job( + 'cron', + hour=5, + minute=1, +) +async def _(): + try: + up_label_and_point_list() + logger.info(f'每日更新原神材料信息成功!') + except Exception as e: + logger.error(f'每日更新原神材料信息错误:{e}') diff --git a/plugins/genshin/query_resource_points/__pycache__/__init__.cpython-39.pyc b/plugins/genshin/query_resource_points/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 00000000..67a99089 Binary files /dev/null and b/plugins/genshin/query_resource_points/__pycache__/__init__.cpython-39.pyc differ diff --git a/plugins/genshin/query_resource_points/__pycache__/query_resource.cpython-39.pyc b/plugins/genshin/query_resource_points/__pycache__/query_resource.cpython-39.pyc new file mode 100644 index 00000000..7515ff1f Binary files /dev/null and b/plugins/genshin/query_resource_points/__pycache__/query_resource.cpython-39.pyc differ diff --git a/plugins/genshin/query_resource_points/icon/0.png b/plugins/genshin/query_resource_points/icon/0.png new file mode 100644 index 00000000..bdf2090b Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/0.png differ diff --git a/plugins/genshin/query_resource_points/icon/111.png b/plugins/genshin/query_resource_points/icon/111.png new file mode 100644 index 00000000..f4d2cbf0 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/111.png differ diff --git a/plugins/genshin/query_resource_points/icon/112.png b/plugins/genshin/query_resource_points/icon/112.png new file mode 100644 index 00000000..9e65d4d1 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/112.png differ diff --git a/plugins/genshin/query_resource_points/icon/114.png b/plugins/genshin/query_resource_points/icon/114.png new file mode 100644 index 00000000..d40c7408 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/114.png differ diff --git a/plugins/genshin/query_resource_points/icon/115.png b/plugins/genshin/query_resource_points/icon/115.png new file mode 100644 index 00000000..170c7cbe Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/115.png differ diff --git a/plugins/genshin/query_resource_points/icon/116.png b/plugins/genshin/query_resource_points/icon/116.png new file mode 100644 index 00000000..c4ef99d3 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/116.png differ diff --git a/plugins/genshin/query_resource_points/icon/121.png b/plugins/genshin/query_resource_points/icon/121.png new file mode 100644 index 00000000..0688557d Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/121.png differ diff --git a/plugins/genshin/query_resource_points/icon/122.png b/plugins/genshin/query_resource_points/icon/122.png new file mode 100644 index 00000000..50daa97b Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/122.png differ diff --git a/plugins/genshin/query_resource_points/icon/123.png b/plugins/genshin/query_resource_points/icon/123.png new file mode 100644 index 00000000..a5292464 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/123.png differ diff --git a/plugins/genshin/query_resource_points/icon/124.png b/plugins/genshin/query_resource_points/icon/124.png new file mode 100644 index 00000000..5a2e1080 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/124.png differ diff --git a/plugins/genshin/query_resource_points/icon/125.png b/plugins/genshin/query_resource_points/icon/125.png new file mode 100644 index 00000000..8b2a2f3b Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/125.png differ diff --git a/plugins/genshin/query_resource_points/icon/126.png b/plugins/genshin/query_resource_points/icon/126.png new file mode 100644 index 00000000..69fb0e25 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/126.png differ diff --git a/plugins/genshin/query_resource_points/icon/127.png b/plugins/genshin/query_resource_points/icon/127.png new file mode 100644 index 00000000..96deca99 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/127.png differ diff --git a/plugins/genshin/query_resource_points/icon/128.png b/plugins/genshin/query_resource_points/icon/128.png new file mode 100644 index 00000000..2a9d7fe4 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/128.png differ diff --git a/plugins/genshin/query_resource_points/icon/129.png b/plugins/genshin/query_resource_points/icon/129.png new file mode 100644 index 00000000..18dbf5da Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/129.png differ diff --git a/plugins/genshin/query_resource_points/icon/130.png b/plugins/genshin/query_resource_points/icon/130.png new file mode 100644 index 00000000..819cfa94 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/130.png differ diff --git a/plugins/genshin/query_resource_points/icon/132.png b/plugins/genshin/query_resource_points/icon/132.png new file mode 100644 index 00000000..c5f6ccdc Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/132.png differ diff --git a/plugins/genshin/query_resource_points/icon/133.png b/plugins/genshin/query_resource_points/icon/133.png new file mode 100644 index 00000000..4580c898 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/133.png differ diff --git a/plugins/genshin/query_resource_points/icon/134.png b/plugins/genshin/query_resource_points/icon/134.png new file mode 100644 index 00000000..8fea3209 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/134.png differ diff --git a/plugins/genshin/query_resource_points/icon/135.png b/plugins/genshin/query_resource_points/icon/135.png new file mode 100644 index 00000000..03dafbce Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/135.png differ diff --git a/plugins/genshin/query_resource_points/icon/136.png b/plugins/genshin/query_resource_points/icon/136.png new file mode 100644 index 00000000..0b66d22e Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/136.png differ diff --git a/plugins/genshin/query_resource_points/icon/137.png b/plugins/genshin/query_resource_points/icon/137.png new file mode 100644 index 00000000..1d2d1aeb Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/137.png differ diff --git a/plugins/genshin/query_resource_points/icon/138.png b/plugins/genshin/query_resource_points/icon/138.png new file mode 100644 index 00000000..46c1aa8e Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/138.png differ diff --git a/plugins/genshin/query_resource_points/icon/139.png b/plugins/genshin/query_resource_points/icon/139.png new file mode 100644 index 00000000..77faf73a Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/139.png differ diff --git a/plugins/genshin/query_resource_points/icon/140.png b/plugins/genshin/query_resource_points/icon/140.png new file mode 100644 index 00000000..0f8c18d4 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/140.png differ diff --git a/plugins/genshin/query_resource_points/icon/141.png b/plugins/genshin/query_resource_points/icon/141.png new file mode 100644 index 00000000..1f08de30 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/141.png differ diff --git a/plugins/genshin/query_resource_points/icon/142.png b/plugins/genshin/query_resource_points/icon/142.png new file mode 100644 index 00000000..3e9fed51 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/142.png differ diff --git a/plugins/genshin/query_resource_points/icon/144.png b/plugins/genshin/query_resource_points/icon/144.png new file mode 100644 index 00000000..a2bd5345 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/144.png differ diff --git a/plugins/genshin/query_resource_points/icon/145.png b/plugins/genshin/query_resource_points/icon/145.png new file mode 100644 index 00000000..7dbb019e Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/145.png differ diff --git a/plugins/genshin/query_resource_points/icon/146.png b/plugins/genshin/query_resource_points/icon/146.png new file mode 100644 index 00000000..3e3eb1a7 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/146.png differ diff --git a/plugins/genshin/query_resource_points/icon/147.png b/plugins/genshin/query_resource_points/icon/147.png new file mode 100644 index 00000000..0b1f1d6d Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/147.png differ diff --git a/plugins/genshin/query_resource_points/icon/148.png b/plugins/genshin/query_resource_points/icon/148.png new file mode 100644 index 00000000..5af3c4d3 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/148.png differ diff --git a/plugins/genshin/query_resource_points/icon/149.png b/plugins/genshin/query_resource_points/icon/149.png new file mode 100644 index 00000000..15c7b527 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/149.png differ diff --git a/plugins/genshin/query_resource_points/icon/15.png b/plugins/genshin/query_resource_points/icon/15.png new file mode 100644 index 00000000..ff293295 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/15.png differ diff --git a/plugins/genshin/query_resource_points/icon/150.png b/plugins/genshin/query_resource_points/icon/150.png new file mode 100644 index 00000000..6505b52b Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/150.png differ diff --git a/plugins/genshin/query_resource_points/icon/151.png b/plugins/genshin/query_resource_points/icon/151.png new file mode 100644 index 00000000..7e5f375a Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/151.png differ diff --git a/plugins/genshin/query_resource_points/icon/152.png b/plugins/genshin/query_resource_points/icon/152.png new file mode 100644 index 00000000..13fa2bb2 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/152.png differ diff --git a/plugins/genshin/query_resource_points/icon/153.png b/plugins/genshin/query_resource_points/icon/153.png new file mode 100644 index 00000000..0f0cd81a Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/153.png differ diff --git a/plugins/genshin/query_resource_points/icon/154.png b/plugins/genshin/query_resource_points/icon/154.png new file mode 100644 index 00000000..c64dc1a6 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/154.png differ diff --git a/plugins/genshin/query_resource_points/icon/155.png b/plugins/genshin/query_resource_points/icon/155.png new file mode 100644 index 00000000..c727d9bd Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/155.png differ diff --git a/plugins/genshin/query_resource_points/icon/156.png b/plugins/genshin/query_resource_points/icon/156.png new file mode 100644 index 00000000..4bae16d4 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/156.png differ diff --git a/plugins/genshin/query_resource_points/icon/157.png b/plugins/genshin/query_resource_points/icon/157.png new file mode 100644 index 00000000..a2240d86 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/157.png differ diff --git a/plugins/genshin/query_resource_points/icon/158.png b/plugins/genshin/query_resource_points/icon/158.png new file mode 100644 index 00000000..5557590a Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/158.png differ diff --git a/plugins/genshin/query_resource_points/icon/159.png b/plugins/genshin/query_resource_points/icon/159.png new file mode 100644 index 00000000..65e7847d Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/159.png differ diff --git a/plugins/genshin/query_resource_points/icon/16.png b/plugins/genshin/query_resource_points/icon/16.png new file mode 100644 index 00000000..335c5620 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/16.png differ diff --git a/plugins/genshin/query_resource_points/icon/160.png b/plugins/genshin/query_resource_points/icon/160.png new file mode 100644 index 00000000..ce63151f Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/160.png differ diff --git a/plugins/genshin/query_resource_points/icon/161.png b/plugins/genshin/query_resource_points/icon/161.png new file mode 100644 index 00000000..529fb1ef Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/161.png differ diff --git a/plugins/genshin/query_resource_points/icon/162.png b/plugins/genshin/query_resource_points/icon/162.png new file mode 100644 index 00000000..584445bd Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/162.png differ diff --git a/plugins/genshin/query_resource_points/icon/163.png b/plugins/genshin/query_resource_points/icon/163.png new file mode 100644 index 00000000..fff75557 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/163.png differ diff --git a/plugins/genshin/query_resource_points/icon/164.png b/plugins/genshin/query_resource_points/icon/164.png new file mode 100644 index 00000000..ecb3bf75 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/164.png differ diff --git a/plugins/genshin/query_resource_points/icon/165.png b/plugins/genshin/query_resource_points/icon/165.png new file mode 100644 index 00000000..7d3f2cb2 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/165.png differ diff --git a/plugins/genshin/query_resource_points/icon/166.png b/plugins/genshin/query_resource_points/icon/166.png new file mode 100644 index 00000000..3f79f9fb Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/166.png differ diff --git a/plugins/genshin/query_resource_points/icon/167.png b/plugins/genshin/query_resource_points/icon/167.png new file mode 100644 index 00000000..2e4ee1b8 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/167.png differ diff --git a/plugins/genshin/query_resource_points/icon/168.png b/plugins/genshin/query_resource_points/icon/168.png new file mode 100644 index 00000000..9f0dfc7a Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/168.png differ diff --git a/plugins/genshin/query_resource_points/icon/169.png b/plugins/genshin/query_resource_points/icon/169.png new file mode 100644 index 00000000..78f77636 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/169.png differ diff --git a/plugins/genshin/query_resource_points/icon/17.png b/plugins/genshin/query_resource_points/icon/17.png new file mode 100644 index 00000000..40b32bc6 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/17.png differ diff --git a/plugins/genshin/query_resource_points/icon/171.png b/plugins/genshin/query_resource_points/icon/171.png new file mode 100644 index 00000000..589dc69c Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/171.png differ diff --git a/plugins/genshin/query_resource_points/icon/172.png b/plugins/genshin/query_resource_points/icon/172.png new file mode 100644 index 00000000..7bb0c770 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/172.png differ diff --git a/plugins/genshin/query_resource_points/icon/174.png b/plugins/genshin/query_resource_points/icon/174.png new file mode 100644 index 00000000..8b98f1f4 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/174.png differ diff --git a/plugins/genshin/query_resource_points/icon/175.png b/plugins/genshin/query_resource_points/icon/175.png new file mode 100644 index 00000000..f7b230b8 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/175.png differ diff --git a/plugins/genshin/query_resource_points/icon/176.png b/plugins/genshin/query_resource_points/icon/176.png new file mode 100644 index 00000000..8ed71d50 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/176.png differ diff --git a/plugins/genshin/query_resource_points/icon/177.png b/plugins/genshin/query_resource_points/icon/177.png new file mode 100644 index 00000000..6bba6626 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/177.png differ diff --git a/plugins/genshin/query_resource_points/icon/178.png b/plugins/genshin/query_resource_points/icon/178.png new file mode 100644 index 00000000..7068d7fe Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/178.png differ diff --git a/plugins/genshin/query_resource_points/icon/179.png b/plugins/genshin/query_resource_points/icon/179.png new file mode 100644 index 00000000..93ad62d1 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/179.png differ diff --git a/plugins/genshin/query_resource_points/icon/18.png b/plugins/genshin/query_resource_points/icon/18.png new file mode 100644 index 00000000..834a9892 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/18.png differ diff --git a/plugins/genshin/query_resource_points/icon/180.png b/plugins/genshin/query_resource_points/icon/180.png new file mode 100644 index 00000000..a4f2cd33 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/180.png differ diff --git a/plugins/genshin/query_resource_points/icon/181.png b/plugins/genshin/query_resource_points/icon/181.png new file mode 100644 index 00000000..35d88703 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/181.png differ diff --git a/plugins/genshin/query_resource_points/icon/19.png b/plugins/genshin/query_resource_points/icon/19.png new file mode 100644 index 00000000..15c7b527 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/19.png differ diff --git a/plugins/genshin/query_resource_points/icon/2.png b/plugins/genshin/query_resource_points/icon/2.png new file mode 100644 index 00000000..750b70ab Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/2.png differ diff --git a/plugins/genshin/query_resource_points/icon/20.png b/plugins/genshin/query_resource_points/icon/20.png new file mode 100644 index 00000000..15c7b527 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/20.png differ diff --git a/plugins/genshin/query_resource_points/icon/21.png b/plugins/genshin/query_resource_points/icon/21.png new file mode 100644 index 00000000..15c7b527 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/21.png differ diff --git a/plugins/genshin/query_resource_points/icon/22.png b/plugins/genshin/query_resource_points/icon/22.png new file mode 100644 index 00000000..6d3903c2 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/22.png differ diff --git a/plugins/genshin/query_resource_points/icon/23.png b/plugins/genshin/query_resource_points/icon/23.png new file mode 100644 index 00000000..c741955a Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/23.png differ diff --git a/plugins/genshin/query_resource_points/icon/24.png b/plugins/genshin/query_resource_points/icon/24.png new file mode 100644 index 00000000..552c8e0c Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/24.png differ diff --git a/plugins/genshin/query_resource_points/icon/25.png b/plugins/genshin/query_resource_points/icon/25.png new file mode 100644 index 00000000..f965ee0f Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/25.png differ diff --git a/plugins/genshin/query_resource_points/icon/26.png b/plugins/genshin/query_resource_points/icon/26.png new file mode 100644 index 00000000..d83e5d94 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/26.png differ diff --git a/plugins/genshin/query_resource_points/icon/27.png b/plugins/genshin/query_resource_points/icon/27.png new file mode 100644 index 00000000..6505b52b Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/27.png differ diff --git a/plugins/genshin/query_resource_points/icon/28.png b/plugins/genshin/query_resource_points/icon/28.png new file mode 100644 index 00000000..4a55f481 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/28.png differ diff --git a/plugins/genshin/query_resource_points/icon/29.png b/plugins/genshin/query_resource_points/icon/29.png new file mode 100644 index 00000000..ad5640d2 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/29.png differ diff --git a/plugins/genshin/query_resource_points/icon/3.png b/plugins/genshin/query_resource_points/icon/3.png new file mode 100644 index 00000000..e7acb4d1 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/3.png differ diff --git a/plugins/genshin/query_resource_points/icon/30.png b/plugins/genshin/query_resource_points/icon/30.png new file mode 100644 index 00000000..aee459ae Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/30.png differ diff --git a/plugins/genshin/query_resource_points/icon/31.png b/plugins/genshin/query_resource_points/icon/31.png new file mode 100644 index 00000000..e2011791 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/31.png differ diff --git a/plugins/genshin/query_resource_points/icon/32.png b/plugins/genshin/query_resource_points/icon/32.png new file mode 100644 index 00000000..6920a7a0 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/32.png differ diff --git a/plugins/genshin/query_resource_points/icon/33.png b/plugins/genshin/query_resource_points/icon/33.png new file mode 100644 index 00000000..29c9d4c7 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/33.png differ diff --git a/plugins/genshin/query_resource_points/icon/34.png b/plugins/genshin/query_resource_points/icon/34.png new file mode 100644 index 00000000..a95826fa Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/34.png differ diff --git a/plugins/genshin/query_resource_points/icon/35.png b/plugins/genshin/query_resource_points/icon/35.png new file mode 100644 index 00000000..2b4490d4 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/35.png differ diff --git a/plugins/genshin/query_resource_points/icon/36.png b/plugins/genshin/query_resource_points/icon/36.png new file mode 100644 index 00000000..16122c1c Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/36.png differ diff --git a/plugins/genshin/query_resource_points/icon/37.png b/plugins/genshin/query_resource_points/icon/37.png new file mode 100644 index 00000000..b7ee5e4b Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/37.png differ diff --git a/plugins/genshin/query_resource_points/icon/38.png b/plugins/genshin/query_resource_points/icon/38.png new file mode 100644 index 00000000..e2edc76e Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/38.png differ diff --git a/plugins/genshin/query_resource_points/icon/39.png b/plugins/genshin/query_resource_points/icon/39.png new file mode 100644 index 00000000..084a54b2 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/39.png differ diff --git a/plugins/genshin/query_resource_points/icon/40.png b/plugins/genshin/query_resource_points/icon/40.png new file mode 100644 index 00000000..7d19ceae Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/40.png differ diff --git a/plugins/genshin/query_resource_points/icon/41.png b/plugins/genshin/query_resource_points/icon/41.png new file mode 100644 index 00000000..3e3eb753 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/41.png differ diff --git a/plugins/genshin/query_resource_points/icon/42.png b/plugins/genshin/query_resource_points/icon/42.png new file mode 100644 index 00000000..65ffab67 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/42.png differ diff --git a/plugins/genshin/query_resource_points/icon/43.png b/plugins/genshin/query_resource_points/icon/43.png new file mode 100644 index 00000000..14f37021 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/43.png differ diff --git a/plugins/genshin/query_resource_points/icon/44.png b/plugins/genshin/query_resource_points/icon/44.png new file mode 100644 index 00000000..f6e3abbc Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/44.png differ diff --git a/plugins/genshin/query_resource_points/icon/45.png b/plugins/genshin/query_resource_points/icon/45.png new file mode 100644 index 00000000..09e54d44 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/45.png differ diff --git a/plugins/genshin/query_resource_points/icon/46.png b/plugins/genshin/query_resource_points/icon/46.png new file mode 100644 index 00000000..f3c0091d Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/46.png differ diff --git a/plugins/genshin/query_resource_points/icon/47.png b/plugins/genshin/query_resource_points/icon/47.png new file mode 100644 index 00000000..588addf8 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/47.png differ diff --git a/plugins/genshin/query_resource_points/icon/48.png b/plugins/genshin/query_resource_points/icon/48.png new file mode 100644 index 00000000..e3588f05 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/48.png differ diff --git a/plugins/genshin/query_resource_points/icon/49.png b/plugins/genshin/query_resource_points/icon/49.png new file mode 100644 index 00000000..9a8084d2 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/49.png differ diff --git a/plugins/genshin/query_resource_points/icon/5.png b/plugins/genshin/query_resource_points/icon/5.png new file mode 100644 index 00000000..9f34678a Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/5.png differ diff --git a/plugins/genshin/query_resource_points/icon/52.png b/plugins/genshin/query_resource_points/icon/52.png new file mode 100644 index 00000000..d7a86d29 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/52.png differ diff --git a/plugins/genshin/query_resource_points/icon/53.png b/plugins/genshin/query_resource_points/icon/53.png new file mode 100644 index 00000000..edc32b6c Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/53.png differ diff --git a/plugins/genshin/query_resource_points/icon/54.png b/plugins/genshin/query_resource_points/icon/54.png new file mode 100644 index 00000000..079fcd3a Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/54.png differ diff --git a/plugins/genshin/query_resource_points/icon/55.png b/plugins/genshin/query_resource_points/icon/55.png new file mode 100644 index 00000000..0ad0c375 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/55.png differ diff --git a/plugins/genshin/query_resource_points/icon/56.png b/plugins/genshin/query_resource_points/icon/56.png new file mode 100644 index 00000000..675b4b51 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/56.png differ diff --git a/plugins/genshin/query_resource_points/icon/57.png b/plugins/genshin/query_resource_points/icon/57.png new file mode 100644 index 00000000..42059d7d Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/57.png differ diff --git a/plugins/genshin/query_resource_points/icon/58.png b/plugins/genshin/query_resource_points/icon/58.png new file mode 100644 index 00000000..6d974f15 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/58.png differ diff --git a/plugins/genshin/query_resource_points/icon/59.png b/plugins/genshin/query_resource_points/icon/59.png new file mode 100644 index 00000000..ea647506 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/59.png differ diff --git a/plugins/genshin/query_resource_points/icon/6.png b/plugins/genshin/query_resource_points/icon/6.png new file mode 100644 index 00000000..46dd6248 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/6.png differ diff --git a/plugins/genshin/query_resource_points/icon/61.png b/plugins/genshin/query_resource_points/icon/61.png new file mode 100644 index 00000000..bdb41098 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/61.png differ diff --git a/plugins/genshin/query_resource_points/icon/62.png b/plugins/genshin/query_resource_points/icon/62.png new file mode 100644 index 00000000..e2756288 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/62.png differ diff --git a/plugins/genshin/query_resource_points/icon/63.png b/plugins/genshin/query_resource_points/icon/63.png new file mode 100644 index 00000000..8ab37ba9 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/63.png differ diff --git a/plugins/genshin/query_resource_points/icon/64.png b/plugins/genshin/query_resource_points/icon/64.png new file mode 100644 index 00000000..a071a2d2 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/64.png differ diff --git a/plugins/genshin/query_resource_points/icon/65.png b/plugins/genshin/query_resource_points/icon/65.png new file mode 100644 index 00000000..f0ad7543 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/65.png differ diff --git a/plugins/genshin/query_resource_points/icon/66.png b/plugins/genshin/query_resource_points/icon/66.png new file mode 100644 index 00000000..fba56f23 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/66.png differ diff --git a/plugins/genshin/query_resource_points/icon/67.png b/plugins/genshin/query_resource_points/icon/67.png new file mode 100644 index 00000000..6a7718bb Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/67.png differ diff --git a/plugins/genshin/query_resource_points/icon/68.png b/plugins/genshin/query_resource_points/icon/68.png new file mode 100644 index 00000000..2e1c8b45 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/68.png differ diff --git a/plugins/genshin/query_resource_points/icon/69.png b/plugins/genshin/query_resource_points/icon/69.png new file mode 100644 index 00000000..40b32bc6 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/69.png differ diff --git a/plugins/genshin/query_resource_points/icon/70.png b/plugins/genshin/query_resource_points/icon/70.png new file mode 100644 index 00000000..185edcbb Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/70.png differ diff --git a/plugins/genshin/query_resource_points/icon/71.png b/plugins/genshin/query_resource_points/icon/71.png new file mode 100644 index 00000000..338673ca Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/71.png differ diff --git a/plugins/genshin/query_resource_points/icon/72.png b/plugins/genshin/query_resource_points/icon/72.png new file mode 100644 index 00000000..bc594d88 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/72.png differ diff --git a/plugins/genshin/query_resource_points/icon/73.png b/plugins/genshin/query_resource_points/icon/73.png new file mode 100644 index 00000000..91bbb218 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/73.png differ diff --git a/plugins/genshin/query_resource_points/icon/74.png b/plugins/genshin/query_resource_points/icon/74.png new file mode 100644 index 00000000..52ba1db2 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/74.png differ diff --git a/plugins/genshin/query_resource_points/icon/75.png b/plugins/genshin/query_resource_points/icon/75.png new file mode 100644 index 00000000..8a1bcf7c Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/75.png differ diff --git a/plugins/genshin/query_resource_points/icon/76.png b/plugins/genshin/query_resource_points/icon/76.png new file mode 100644 index 00000000..0db7ac5f Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/76.png differ diff --git a/plugins/genshin/query_resource_points/icon/77.png b/plugins/genshin/query_resource_points/icon/77.png new file mode 100644 index 00000000..a18d10d4 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/77.png differ diff --git a/plugins/genshin/query_resource_points/icon/78.png b/plugins/genshin/query_resource_points/icon/78.png new file mode 100644 index 00000000..123bbab2 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/78.png differ diff --git a/plugins/genshin/query_resource_points/icon/79.png b/plugins/genshin/query_resource_points/icon/79.png new file mode 100644 index 00000000..0ad0c375 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/79.png differ diff --git a/plugins/genshin/query_resource_points/icon/8.png b/plugins/genshin/query_resource_points/icon/8.png new file mode 100644 index 00000000..e41899b9 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/8.png differ diff --git a/plugins/genshin/query_resource_points/icon/80.png b/plugins/genshin/query_resource_points/icon/80.png new file mode 100644 index 00000000..59b29e15 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/80.png differ diff --git a/plugins/genshin/query_resource_points/icon/81.png b/plugins/genshin/query_resource_points/icon/81.png new file mode 100644 index 00000000..63e1103c Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/81.png differ diff --git a/plugins/genshin/query_resource_points/icon/82.png b/plugins/genshin/query_resource_points/icon/82.png new file mode 100644 index 00000000..c4b08c12 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/82.png differ diff --git a/plugins/genshin/query_resource_points/icon/83.png b/plugins/genshin/query_resource_points/icon/83.png new file mode 100644 index 00000000..52ba1db2 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/83.png differ diff --git a/plugins/genshin/query_resource_points/icon/85.png b/plugins/genshin/query_resource_points/icon/85.png new file mode 100644 index 00000000..ba15fa7c Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/85.png differ diff --git a/plugins/genshin/query_resource_points/icon/87.png b/plugins/genshin/query_resource_points/icon/87.png new file mode 100644 index 00000000..42978116 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/87.png differ diff --git a/plugins/genshin/query_resource_points/icon/9.png b/plugins/genshin/query_resource_points/icon/9.png new file mode 100644 index 00000000..4765b4e0 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/9.png differ diff --git a/plugins/genshin/query_resource_points/icon/90.png b/plugins/genshin/query_resource_points/icon/90.png new file mode 100644 index 00000000..05f6f4c0 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/90.png differ diff --git a/plugins/genshin/query_resource_points/icon/91.png b/plugins/genshin/query_resource_points/icon/91.png new file mode 100644 index 00000000..cb391933 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/91.png differ diff --git a/plugins/genshin/query_resource_points/icon/92.png b/plugins/genshin/query_resource_points/icon/92.png new file mode 100644 index 00000000..9119776b Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/92.png differ diff --git a/plugins/genshin/query_resource_points/icon/93.png b/plugins/genshin/query_resource_points/icon/93.png new file mode 100644 index 00000000..bf8164cd Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/93.png differ diff --git a/plugins/genshin/query_resource_points/icon/94.png b/plugins/genshin/query_resource_points/icon/94.png new file mode 100644 index 00000000..8b51144b Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/94.png differ diff --git a/plugins/genshin/query_resource_points/icon/box.png b/plugins/genshin/query_resource_points/icon/box.png new file mode 100644 index 00000000..dadec344 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/box.png differ diff --git a/plugins/genshin/query_resource_points/icon/box_alpha.png b/plugins/genshin/query_resource_points/icon/box_alpha.png new file mode 100644 index 00000000..0c634fa2 Binary files /dev/null and b/plugins/genshin/query_resource_points/icon/box_alpha.png differ diff --git a/plugins/genshin/query_resource_points/query_resource.py b/plugins/genshin/query_resource_points/query_resource.py new file mode 100644 index 00000000..7637ffae --- /dev/null +++ b/plugins/genshin/query_resource_points/query_resource.py @@ -0,0 +1,283 @@ +from urllib import request +from PIL import Image, ImageMath +from io import BytesIO +import json +import os +import time +import base64 +from configs.path_config import IMAGE_PATH +from util.init_result import image + +LABEL_URL = 'https://api-static.mihoyo.com/common/blackboard/ys_obc/v1/map/label/tree?app_sn=ys_obc' +POINT_LIST_URL = 'https://api-static.mihoyo.com/common/blackboard/ys_obc/v1/map/point/list?map_id=2&app_sn=ys_obc' + +header = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) ' \ + 'Chrome/84.0.4147.105 Safari/537.36' + +FILE_PATH = os.path.dirname(__file__) + +MAP_PATH = os.path.join(IMAGE_PATH, "genshin", "seek_god_eye", "icon", "map_icon.jpg") +MAP_IMAGE = Image.open(MAP_PATH) +MAP_SIZE = MAP_IMAGE.size + +# resource_point里记录的坐标是相对坐标,是以蒙德城的大雕像为中心的,所以图片合成时需要转换坐标 +CENTER = (3505, 1907) + +zoom = 0.75 +resource_icon_offset = (-int(150 * 0.5 * zoom), -int(150 * zoom)) + +data = { + "all_resource_type": { + # 这个字典保存所有资源类型, + # "1": { + # "id": 1, + # "name": "传送点", + # "icon": "", + # "parent_id": 0, + # "depth": 1, + # "node_type": 1, + # "jump_type": 0, + # "jump_target_id": 0, + # "display_priority": 0, + # "children": [] + # }, + }, + "can_query_type_list": { + # 这个字典保存所有可以查询的资源类型名称和ID,这个字典只有名称和ID + # 上边字典里"depth": 2的类型才可以查询,"depth": 1的是1级目录,不能查询 + # "七天神像":"2" + # "风神瞳":"5" + + }, + "all_resource_point_list": [ + # 这个列表保存所有资源点的数据 + # { + # "id": 2740, + # "label_id": 68, + # "x_pos": -1789, + # "y_pos": 2628, + # "author_name": "✟紫灵心✟", + # "ctime": "2020-10-29 10:41:21", + # "display_state": 1 + # }, + ], + "date": "" # 记录上次更新"all_resource_point_list"的日期 +} + + +def up_icon_image(sublist): + # 检查是否有图标,没有图标下载保存到本地 + id = sublist["id"] + icon_url = sublist["icon"] + + icon_path = os.path.join(FILE_PATH, "icon", f"{id}.png") + + if not os.path.exists(icon_path): + schedule = request.Request(icon_url) + schedule.add_header('User-Agent', header) + with request.urlopen(schedule) as f: + icon = Image.open(f) + icon = icon.resize((150, 150)) + + box_alpha = Image.open(os.path.join(FILE_PATH, "icon", "box_alpha.png")).getchannel("A") + box = Image.open(os.path.join(FILE_PATH, "icon", "box.png")) + + try: + icon_alpha = icon.getchannel("A") + icon_alpha = ImageMath.eval("convert(a*b/256, 'L')", a=icon_alpha, b=box_alpha) + except ValueError: + # 米游社的图有时候会没有alpha导致报错,这时候直接使用box_alpha当做alpha就行 + icon_alpha = box_alpha + + icon2 = Image.new("RGBA", (150, 150), "#00000000") + icon2.paste(icon, (0, -10)) + + bg = Image.new("RGBA", (150, 150), "#00000000") + bg.paste(icon2, mask=icon_alpha) + bg.paste(box, mask=box) + + with open(icon_path, "wb") as icon_file: + bg.save(icon_file) + + +def up_label_and_point_list(): + # 更新label列表和资源点列表 + + schedule = request.Request(LABEL_URL) + schedule.add_header('User-Agent', header) + with request.urlopen(schedule, timeout=5) as f: + if f.code != 200: # 检查返回的状态码是否是200 + raise ValueError(f"资源标签列表初始化失败,错误代码{f.code}") + label_data = json.loads(f.read().decode('utf-8')) + + for label in label_data["data"]["tree"]: + data["all_resource_type"][str(label["id"])] = label + + for sublist in label["children"]: + data["all_resource_type"][str(sublist["id"])] = sublist + data["can_query_type_list"][sublist["name"]] = str(sublist["id"]) + up_icon_image(sublist) + + label["children"] = [] + + schedule = request.Request(POINT_LIST_URL) + schedule.add_header('User-Agent', header) + with request.urlopen(schedule) as f: + if f.code != 200: # 检查返回的状态码是否是200 + raise ValueError(f"资源点列表初始化失败,错误代码{f.code}") + test = json.loads(f.read().decode('utf-8')) + data["all_resource_point_list"] = test["data"]["point_list"] + + data["date"] = time.strftime("%d") + + +# def load_resource_type_id(): +# with open(os.path.join(FILE_PATH,'resource_type_id.json'), 'r', encoding='UTF-8') as f: +# json_data = json.load(f) +# for id in json_data.keys(): +# data["all_resource_type"][id] = json_data[id] +# if json_data[id]["depth"] != 1: +# data["can_query_type_list"][json_data[id]["name"]] = id + + +# 初始化 +# load_resource_type_id() +up_label_and_point_list() + + +class Resource_map(object): + + def __init__(self, resource_name): + self.resource_id = str(data["can_query_type_list"][resource_name]) + + # 地图要要裁切的左上角和右下角坐标 + # 这里初始化为地图的大小 + self.x_start = MAP_SIZE[0] + self.y_start = MAP_SIZE[1] + self.x_end = 0 + self.y_end = 0 + + self.map_image = MAP_IMAGE.copy() + + self.resource_icon = Image.open(self.get_icon_path()) + self.resource_icon = self.resource_icon.resize((int(150 * zoom), int(150 * zoom))) + + self.resource_xy_list = self.get_resource_point_list() + + def get_icon_path(self): + # 检查有没有图标,有返回正确图标,没有返回默认图标 + icon_path = os.path.join(FILE_PATH, "icon", f"{self.resource_id}.png") + + if os.path.exists(icon_path): + return icon_path + else: + return os.path.join(FILE_PATH, "icon", "0.png") + + def get_resource_point_list(self): + temp_list = [] + for resource_point in data["all_resource_point_list"]: + if str(resource_point["label_id"]) == self.resource_id: + # 获取xy坐标,然后加上中心点的坐标完成坐标转换 + x = resource_point["x_pos"] + CENTER[0] + y = resource_point["y_pos"] + CENTER[1] + temp_list.append((int(x), int(y))) + return temp_list + + def paste(self): + for x, y in self.resource_xy_list: + # 把资源图片贴到地图上 + self.map_image.paste(self.resource_icon, (x + resource_icon_offset[0], y + resource_icon_offset[1]), + self.resource_icon) + + # 找出4个方向最远的坐标,用于后边裁切 + self.x_start = min(x, self.x_start) + self.y_start = min(y, self.y_start) + self.x_end = max(x, self.x_end) + self.y_end = max(y, self.y_end) + + def crop(self): + + # 先把4个方向扩展150像素防止把资源图标裁掉 + self.x_start -= 150 + self.y_start -= 150 + self.x_end += 150 + self.y_end += 150 + + # 如果图片裁切的太小会看不出资源的位置在哪,检查图片裁切的长和宽看够不够1000,不到1000的按1000裁切 + if (self.x_end - self.x_start) < 1000: + center = int((self.x_end + self.x_start) / 2) + self.x_start = center - 500 + self.x_end = center + 500 + if (self.y_end - self.y_start) < 1000: + center = int((self.y_end + self.y_start) / 2) + self.y_start = center - 500 + self.y_end = center + 500 + + self.map_image = self.map_image.crop((self.x_start, self.y_start, self.x_end, self.y_end)) + + def get_cq_cod(self): + + if not self.resource_xy_list: + return "没有这个资源的信息" + + self.paste() + + self.crop() + + bio = BytesIO() + self.map_image.save(bio, format='JPEG') + base64_str = 'base64://' + base64.b64encode(bio.getvalue()).decode() + + return image(b64=base64_str) + + def get_resource_count(self): + return len(self.resource_xy_list) + + +def get_resource_map_mes(name): + if data["date"] != time.strftime("%d"): + up_label_and_point_list() + + if not (name in data["can_query_type_list"]): + return f"没有 {name} 这种资源。\n发送 原神资源列表 查看所有资源名称" + + map = Resource_map(name) + count = map.get_resource_count() + + if not count: + return f"没有找到 {name} 资源的位置,可能米游社wiki还没更新。" + + mes = f"资源 {name} 的位置如下\n" + mes += map.get_cq_cod() + + mes += f"\n\n※ {name} 一共找到 {count} 个位置点\n※ 数据来源于米游社wiki" + return mes + + +def get_resource_list_mes(): + temp = {} + + for id in data["all_resource_type"].keys(): + # 先找1级目录 + if data["all_resource_type"][id]["depth"] == 1: + temp[id] = [] + + for id in data["all_resource_type"].keys(): + # 再找2级目录 + if data["all_resource_type"][id]["depth"] == 2: + temp[str(data["all_resource_type"][id]["parent_id"])].append(id) + + mes = "当前资源列表如下:\n" + + for resource_type_id in temp.keys(): + + if resource_type_id in ["1", "12", "50", "51", "95", "131"]: + # 在游戏里能查到的数据这里就不列举了,不然消息太长了 + continue + + mes += f"{data['all_resource_type'][resource_type_id]['name']}:" + for resource_id in temp[resource_type_id]: + mes += f"{data['all_resource_type'][resource_id]['name']}," + mes += "\n" + + return mes diff --git a/plugins/genshin/query_resource_points/resource_type_id.json b/plugins/genshin/query_resource_points/resource_type_id.json new file mode 100644 index 00000000..9459f34b --- /dev/null +++ b/plugins/genshin/query_resource_points/resource_type_id.json @@ -0,0 +1,926 @@ +{ + "1": { + "id": 1, + "name": "传送点", + "icon": "", + "parent_id": 0, + "depth": 1, + "node_type": 1, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "2": { + "id": 2, + "name": "七天神像", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/08/75276545/c59585d1fabc9c22ad3fcf94e1622aa8_357413506633071859.png", + "parent_id": 1, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "3": { + "id": 3, + "name": "传送锚点", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/08/75276545/0cc42d15134cbb724304050fd0bbcaac_8799482478853097434.png", + "parent_id": 1, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "4": { + "id": 4, + "name": "神瞳", + "icon": "", + "parent_id": 0, + "depth": 1, + "node_type": 1, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "5": { + "id": 5, + "name": "风神瞳", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/08/75276545/4b568dcdea1c699456464c611ce87e4f_3484482126589511603.png", + "parent_id": 4, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "6": { + "id": 6, + "name": "岩神瞳", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/08/75276545/f4409292be83f81d0c41c350a91ebac1_355618004292502793.png", + "parent_id": 4, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "7": { + "id": 7, + "name": "地灵龛", + "icon": "", + "parent_id": 0, + "depth": 1, + "node_type": 1, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "8": { + "id": 8, + "name": "蒙德地灵龛", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/08/75276545/a9f458cf7ba149ec659aabb581050a0b_3339433578214432669.png", + "parent_id": 7, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "9": { + "id": 9, + "name": "璃月地灵龛", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/08/75276545/a9f458cf7ba149ec659aabb581050a0b_3479171218459475297.png", + "parent_id": 7, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "10": { + "id": 10, + "name": "区域特产", + "icon": "", + "parent_id": 0, + "depth": 1, + "node_type": 1, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "29": { + "id": 29, + "name": "落落莓", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/08/75276545/11e1861e2b94d1b1e132d61c0f7c3948_5882174105995719914.png", + "parent_id": 10, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "30": { + "id": 30, + "name": "绝云椒椒", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/08/75276545/3184e356629e8b071a878063d1c0df94_5172487424247849295.png", + "parent_id": 10, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "31": { + "id": 31, + "name": "嘟嘟莲", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/08/75276545/07a2252a60301893294ef377e563f0e7_7014418407781853378.png", + "parent_id": 10, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "32": { + "id": 32, + "name": "清心", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/08/75276545/0de9385a957ef0cb981a5ed6a6984f57_7797138076139828289.png", + "parent_id": 10, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "33": { + "id": 33, + "name": "小灯草", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/08/75276545/348fe1164e9330226b225c011aea4d5a_2068903308538485227.png", + "parent_id": 10, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "34": { + "id": 34, + "name": "琉璃袋", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/08/75276545/77dc4532fe938a24c4cc714d77d48b0d_6612669651078791213.png", + "parent_id": 10, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "35": { + "id": 35, + "name": "塞西莉亚花", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/08/75276545/e55cfc43f5e483362e9ddf433653d326_9031812646608361297.png", + "parent_id": 10, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "36": { + "id": 36, + "name": "霓裳花", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/08/75276545/e22d205c11b39b9b6984a4ec8adefeb2_2210397206297609865.png", + "parent_id": 10, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "37": { + "id": 37, + "name": "蒲公英籽", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/08/75276545/a348a4302f58f499bdf89025d2cb2cdb_2244957478004520779.png", + "parent_id": 10, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "38": { + "id": 38, + "name": "琉璃百合", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/08/75276545/dfe6d92e18060cd724ebadd73ba084c6_7141991283452930467.png", + "parent_id": 10, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "39": { + "id": 39, + "name": "慕风蘑菇", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/08/75276545/d0f4c83add3dc326ffc92b5fedb6f82c_3118392491847470850.png", + "parent_id": 10, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "40": { + "id": 40, + "name": "石珀", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/08/75276545/5789d9dc9c8840f21f9afc2437e9026e_8487232206600716291.png", + "parent_id": 10, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "41": { + "id": 41, + "name": "钩钩果", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/08/75276545/7dedeee543b94525f0812a18eb09b7d7_4938366361261655916.png", + "parent_id": 10, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "42": { + "id": 42, + "name": "夜泊石", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/08/75276545/51adcbda83a2f2b4422db9ad4908245b_7898256673375056193.png", + "parent_id": 10, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "43": { + "id": 43, + "name": "风车菊", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/08/75276545/387684f5c9a891135e05f95192b6dc21_2171784899125537458.png", + "parent_id": 10, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "11": { + "id": 11, + "name": "矿物", + "icon": "", + "parent_id": 0, + "depth": 1, + "node_type": 1, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "15": { + "id": 15, + "name": "白铁块", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/08/75276545/4d0e329b0458a918d376bbbabd4415cd_9079005216548585535.png", + "parent_id": 11, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "16": { + "id": 16, + "name": "水晶块", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/08/75276545/ceede1f6fa9a3e53986b5ac63e2aacb9_3251440935681461856.png", + "parent_id": 11, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "12": { + "id": 12, + "name": "怪物(精英)", + "icon": "", + "parent_id": 0, + "depth": 1, + "node_type": 1, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "19": { + "id": 19, + "name": "火斧丘丘暴徒", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/08/75276545/cef1444b97c8f49cd8cd8aa10e5448ae_1229715974301029440.png", + "parent_id": 12, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "20": { + "id": 20, + "name": "木盾丘丘暴徒", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/08/75276545/cef1444b97c8f49cd8cd8aa10e5448ae_2049522587981126653.png", + "parent_id": 12, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "21": { + "id": 21, + "name": "岩盾丘丘暴徒", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/08/75276545/cef1444b97c8f49cd8cd8aa10e5448ae_4383986804076887911.png", + "parent_id": 12, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "22": { + "id": 22, + "name": "火深渊法师", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/08/75276545/3c287ea61919d856723ba802fd91677f_2936850964636137610.png", + "parent_id": 12, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "23": { + "id": 23, + "name": "水深渊法师", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/08/75276545/5d59b593551bb62506096c76bd55ab2a_5561999899365928315.png", + "parent_id": 12, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "24": { + "id": 24, + "name": "冰深渊法师", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/08/75276545/4b9b07114f30df8715f41835d3215add_6327856690043584281.png", + "parent_id": 12, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "25": { + "id": 25, + "name": "愚人众 债务处理人", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/08/75276545/359e5697e4609a7f34714bfa65cce97e_7545179401283346969.png", + "parent_id": 12, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "26": { + "id": 26, + "name": "愚人众 雷萤术士", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/08/75276545/a73112218e1329ae4728a096554258d7_4082505538504798279.png", + "parent_id": 12, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "27": { + "id": 27, + "name": "遗迹守卫", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/08/75276545/86ddf140b786c6a2a73b038e341403a7_6217455819326456307.png", + "parent_id": 12, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "28": { + "id": 28, + "name": "遗迹猎者", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/08/75276545/99ce18638304f8169918c85436d0585c_5415189466598569723.png", + "parent_id": 12, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "47": { + "id": 47, + "name": "冰霜骗骗花", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/14/75276545/54904a37ab2165e5b8ad91c7ee805061_2703681786862158841.png", + "parent_id": 12, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "48": { + "id": 48, + "name": "炽热骗骗花", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/14/75276545/1848c68a09d54637721529abb35b22a1_7882961499456527312.png", + "parent_id": 12, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "49": { + "id": 49, + "name": "幼岩龙蜥", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/14/75276545/83d1ef1dbb3b6d489c0b150886597cbc_5647365818975751099.png", + "parent_id": 12, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "53": { + "id": 53, + "name": "丘丘岩盔王", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/17/75276545/a6e1a33b8f4bd4c8a091f69ead200948_2480904266424771100.png", + "parent_id": 12, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "54": { + "id": 54, + "name": "愚人众先遣队", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/17/75276545/8dd741d0f58dc6abef2f9ee6d278a062_7759801496426769012.png", + "parent_id": 12, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "13": { + "id": 13, + "name": "宝箱", + "icon": "", + "parent_id": 0, + "depth": 1, + "node_type": 1, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "17": { + "id": 17, + "name": "普通的宝箱", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/08/75276545/35cf41aad7620ce6d5dc516defb967f7_7806440070871726330.png", + "parent_id": 13, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "44": { + "id": 44, + "name": "精致的宝箱", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/14/75276545/35cf41aad7620ce6d5dc516defb967f7_6214340810257945197.png", + "parent_id": 13, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "45": { + "id": 45, + "name": "珍贵的宝箱", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/14/75276545/44a7de58782f36f15bec044c1069da76_7523256410581248233.png", + "parent_id": 13, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "46": { + "id": 46, + "name": "华丽的宝箱", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/14/75276545/35cf41aad7620ce6d5dc516defb967f7_3987566332689612662.png", + "parent_id": 13, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "14": { + "id": 14, + "name": "解谜", + "icon": "", + "parent_id": 0, + "depth": 1, + "node_type": 1, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "18": { + "id": 18, + "name": "指引仙灵", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/08/75276545/8de3558f991ac422463712dd095278b3_109842752079072307.png", + "parent_id": 14, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "64": { + "id": 64, + "name": "限时挑战", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/21/75795471/a6978cb8965e81de4a25accbf6c236ce_6189233402996409228.png", + "parent_id": 14, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "65": { + "id": 65, + "name": "风车机关", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/10/21/75795471/de87958fa1e78efcc84da49aad61dede_7547151797455251961.jpg", + "parent_id": 14, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "66": { + "id": 66, + "name": "漂浮的风史莱姆", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/10/21/75795471/de87958fa1e78efcc84da49aad61dede_6780166156178323412.jpg", + "parent_id": 14, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "67": { + "id": 67, + "name": "压力机关", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/10/21/75795471/de87958fa1e78efcc84da49aad61dede_5932273944571249310.jpg", + "parent_id": 14, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "68": { + "id": 68, + "name": "蓬蓬果", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/10/21/75795471/de87958fa1e78efcc84da49aad61dede_7627546850715675857.jpg", + "parent_id": 14, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "69": { + "id": 69, + "name": "挖掘宝箱", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/10/21/75795471/de87958fa1e78efcc84da49aad61dede_200949033774003499.jpg", + "parent_id": 14, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "70": { + "id": 70, + "name": "元素方碑", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/10/21/75795471/de87958fa1e78efcc84da49aad61dede_8520221369291334139.jpg", + "parent_id": 14, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "71": { + "id": 71, + "name": "火炬机关", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/10/21/75795471/de87958fa1e78efcc84da49aad61dede_1061118532437351431.jpg", + "parent_id": 14, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "72": { + "id": 72, + "name": "巨型碎石", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/10/21/75795471/de87958fa1e78efcc84da49aad61dede_6449674692302465374.jpg", + "parent_id": 14, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "73": { + "id": 73, + "name": "小石堆", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/10/21/75795471/de87958fa1e78efcc84da49aad61dede_7798666829547657712.jpg", + "parent_id": 14, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "74": { + "id": 74, + "name": "拔植物", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/10/21/75795471/de87958fa1e78efcc84da49aad61dede_3891992353724563278.jpg", + "parent_id": 14, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "75": { + "id": 75, + "name": "被束缚的宝箱", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/10/21/75795471/de87958fa1e78efcc84da49aad61dede_7069442788377617628.jpg", + "parent_id": 14, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "76": { + "id": 76, + "name": "岩种子", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/10/21/75795471/de87958fa1e78efcc84da49aad61dede_6714446188416963945.jpg", + "parent_id": 14, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "77": { + "id": 77, + "name": "微解谜", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/10/21/75795471/de87958fa1e78efcc84da49aad61dede_3053004782269703586.jpg", + "parent_id": 14, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "50": { + "id": 50, + "name": "怪物(普通)", + "icon": "", + "parent_id": 0, + "depth": 1, + "node_type": 1, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "55": { + "id": 55, + "name": "丘丘人", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/17/75276545/74c2350936386d12f84e4244b8bd9750_8061221501486024583.png", + "parent_id": 50, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "56": { + "id": 56, + "name": "射手丘丘人", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/17/75276545/74c2350936386d12f84e4244b8bd9750_8668908145618002848.png", + "parent_id": 50, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "57": { + "id": 57, + "name": "丘丘萨满", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/17/75276545/fbd2f8a868f6c3a6f587d57d655f40c9_1156685569894627424.png", + "parent_id": 50, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "58": { + "id": 58, + "name": "盗宝团", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/17/75276545/a9ecb7952e877dfd7c1dfae5132c7181_242314377398779361.png", + "parent_id": 50, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "59": { + "id": 59, + "name": "史莱姆", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/17/75276545/de444c63df86b407045c0cca2d9c24b2_761844897909742071.png", + "parent_id": 50, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "51": { + "id": 51, + "name": "世界任务", + "icon": "", + "parent_id": 0, + "depth": 1, + "node_type": 1, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "52": { + "id": 52, + "name": "世界任务", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/16/75795471/c7263000d1f1ec150eddd27fca4d8630_2386396225561541114.png", + "parent_id": 51, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "60": { + "id": 60, + "name": "材料", + "icon": "", + "parent_id": 0, + "depth": 1, + "node_type": 1, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "61": { + "id": 61, + "name": "冰雾花花朵", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/17/75276545/cca41572bb14d20c094ce9af77eefda9_2844359998862121652.png", + "parent_id": 60, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "62": { + "id": 62, + "name": "烈焰花花蕊", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/17/75276545/82a7a8327bfa630eb5e52695a2b456e9_4760074611076337816.png", + "parent_id": 60, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + }, + "63": { + "id": 63, + "name": "电气水晶", + "icon": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/17/75276545/aab9020763a7bee1fb532b7117b21fd1_5874466862813696108.png", + "parent_id": 60, + "depth": 2, + "node_type": 2, + "jump_type": 0, + "jump_target_id": 0, + "display_priority": 0, + "children": [] + } +} \ No newline at end of file diff --git a/plugins/group_handle/__init__.py b/plugins/group_handle/__init__.py new file mode 100644 index 00000000..52ca7f4a --- /dev/null +++ b/plugins/group_handle/__init__.py @@ -0,0 +1,125 @@ +from nonebot import on_notice, on_request +from configs.path_config import IMAGE_PATH, DATA_PATH +from util.init_result import image +import os +import random +from models.group_member_info import GroupInfoUser +from datetime import datetime +from services.log import logger +from models.group_remind import GroupRemind +from nonebot.adapters.cqhttp import Bot, GroupIncreaseNoticeEvent, GroupDecreaseNoticeEvent, GroupRequestEvent +from nonebot.adapters.cqhttp.exception import ActionFailed +from pathlib import Path +from nonebot import require +try: + import ujson as json +except ModuleNotFoundError: + import json + + +export = require("admin_bot_manage") + +# 群员增加处理 +group_increase_handle = on_notice(priority=5) +# 群员减少处理 +group_decrease_handle = on_notice(priority=5) +# (群管理)加群同意请求 +add_group = on_request(priority=5) + + +@group_increase_handle.handle() +async def _(bot: Bot, event: GroupIncreaseNoticeEvent, state: dict): + if event.user_id == int(bot.self_id): + await export.update_member_info(event.group_id) + else: + join_time = datetime.now() + user_info = await bot.get_group_member_info(group_id=event.group_id, user_id=event.user_id) + if await GroupInfoUser.insert( + user_info['user_id'], + user_info['group_id'], + user_info['nickname'], + join_time, + ): + logger.info(f"用户{user_info['user_id']} 所属{user_info['group_id']} 更新成功") + else: + logger.info(f"用户{user_info['user_id']} 所属{user_info['group_id']} 更新失败") + if await GroupRemind.get_status(event.group_id, 'hy'): + msg = '' + img = '' + at_flag = False + custom_welcome_msg_json = Path() / "data" / "custom_welcome_msg" / "custom_welcome_msg.json" + if custom_welcome_msg_json.exists(): + data = json.load(open(custom_welcome_msg_json, 'r')) + if data.get(str(event.group_id)): + msg = data[str(event.group_id)] + if msg.find('[at]') != -1: + msg = msg.replace('[at]', '') + at_flag = True + if os.path.exists(DATA_PATH + f'custom_welcome_msg/{event.group_id}.jpg'): + img = image(abspath=DATA_PATH + f'custom_welcome_msg/{event.group_id}.jpg') + if msg or img: + await group_increase_handle.send("\n" + msg + img, at_sender=at_flag) + else: + await group_increase_handle.send( + '新人快跑啊!!本群现状↓(快使用自定义!)' + image(random.choice(os.listdir(IMAGE_PATH + "qxz/")), "qxz")) + + +@group_decrease_handle.handle() +async def _(bot: Bot, event: GroupDecreaseNoticeEvent, state: dict): + # 真寻被踢出群 + if event.sub_type == 'kick_me': + group_id = event.group_id + operator_id = event.operator_id + try: + operator_name = (await GroupInfoUser.select_member_info(event.operator_id, event.group_id)).user_name + except AttributeError: + operator_name = 'None' + coffee = int(list(bot.config.superusers)[0]) + await bot.send_private_msg( + user_id=coffee, + message=f'报告..\n' + f'我被 {operator_name}({operator_id})\n' + f'踢出了 {group_id}') + return + try: + user_name = (await GroupInfoUser.select_member_info(event.user_id, event.group_id)).user_name + except AttributeError: + user_name = str(event.user_id) + rst = '' + if event.sub_type == 'leave': + rst = f'{user_name}离开了我们...' + if event.sub_type == 'kick': + try: + operator_name = (await GroupInfoUser.select_member_info(event.operator_id, event.group_id)).user_name + except AttributeError: + operator_name = event.operator_id + rst = f'{user_name} 被 {operator_name} 送走了.' + try: + await group_decrease_handle.send(f"{rst}") + except ActionFailed: + return + if await GroupInfoUser.delete_member_info(event.user_id, event.group_id): + logger.info(f"用户{user_name}, qq={event.user_id} 所属{event.group_id} 删除成功") + else: + logger.info(f"用户{user_name}, qq={event.user_id} 所属{event.group_id} 删除失败") + + +@add_group.handle() +async def _(bot: Bot, event: GroupRequestEvent, state: dict): + pass + # user_info = await bot._get_vip_info(user_id=event.user_id) + # if user_info['level'] > 16: + # bot.set + + + + + + + + + + + + + diff --git a/plugins/group_handle/__pycache__/__init__.cpython-38.pyc b/plugins/group_handle/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..052dcad8 Binary files /dev/null and b/plugins/group_handle/__pycache__/__init__.cpython-38.pyc differ diff --git a/plugins/group_handle/__pycache__/__init__.cpython-39.pyc b/plugins/group_handle/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 00000000..18c53520 Binary files /dev/null and b/plugins/group_handle/__pycache__/__init__.cpython-39.pyc differ diff --git a/plugins/group_welcome_msg.py b/plugins/group_welcome_msg.py new file mode 100644 index 00000000..0b5bc0b9 --- /dev/null +++ b/plugins/group_welcome_msg.py @@ -0,0 +1,40 @@ +from nonebot import on_command +from nonebot.typing import T_State +from nonebot.adapters.cqhttp import Bot, GroupMessageEvent +from nonebot.adapters.cqhttp.permission import GROUP +from configs.path_config import DATA_PATH +from util.init_result import image +import os +from pathlib import Path +try: + import ujson as json +except ModuleNotFoundError: + import json + +view_custom_welcome = on_command('群欢迎消息', aliases={'查看群欢迎消息', '查看当前群欢迎消息'}, permission=GROUP, priority=5, block=True) + + +@view_custom_welcome.handle() +async def _(bot: Bot, event: GroupMessageEvent, state: T_State): + img = '' + msg = '' + if os.path.exists(DATA_PATH + f'custom_welcome_msg/{event.group_id}.jpg'): + img = image(abspath=DATA_PATH + f'custom_welcome_msg/{event.group_id}.jpg') + custom_welcome_msg_json = Path() / "data" / "custom_welcome_msg" / "custom_welcome_msg.json" + if custom_welcome_msg_json.exists(): + data = json.load(open(custom_welcome_msg_json, 'r')) + if data.get(str(event.group_id)): + msg = data[str(event.group_id)] + if msg.find('[at]') != -1: + msg = msg.replace('[at]', '') + if img or msg: + await view_custom_welcome.finish(msg + img, at_sender=True) + + + + + + + + + diff --git a/plugins/help/__init__.py b/plugins/help/__init__.py new file mode 100644 index 00000000..0c1e3ee8 --- /dev/null +++ b/plugins/help/__init__.py @@ -0,0 +1,35 @@ +from nonebot import on_command +from nonebot.adapters.cqhttp import Bot, GroupMessageEvent, PrivateMessageEvent +from nonebot.typing import T_State +from nonebot.rule import to_me +from configs.path_config import DATA_PATH +from util.init_result import image +import os +from .data_source import create_help_img, create_group_help_img +from nonebot import require + +export = require("nonebot_plugin_manager") + +__plugin_name__ = '帮助' + + +if not os.path.exists(DATA_PATH + 'group_help/'): + os.mkdir(DATA_PATH + 'group_help/') +create_help_img() +for file in os.listdir(DATA_PATH + 'group_help/'): + os.remove(DATA_PATH + 'group_help/' + file) + +_help = on_command("功能", rule=to_me(), aliases={"帮助", 'help'}, priority=1, block=True) + + +@_help.handle() +async def _(bot: Bot, event: GroupMessageEvent, state: T_State): + if not os.path.exists(DATA_PATH + f'group_help/{event.group_id}.png'): + create_group_help_img(event.group_id) + await _help.finish(image(abspath=DATA_PATH + f'group_help/{event.group_id}.png')) + + +@_help.handle() +async def _(bot: Bot, event: PrivateMessageEvent, state: T_State): + await _help.finish(image('help.png')) + diff --git a/plugins/help/__pycache__/__init__.cpython-38.pyc b/plugins/help/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..5799dfe6 Binary files /dev/null and b/plugins/help/__pycache__/__init__.cpython-38.pyc differ diff --git a/plugins/help/__pycache__/__init__.cpython-39.pyc b/plugins/help/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 00000000..960f0cb7 Binary files /dev/null and b/plugins/help/__pycache__/__init__.cpython-39.pyc differ diff --git a/plugins/help/__pycache__/config.cpython-38.pyc b/plugins/help/__pycache__/config.cpython-38.pyc new file mode 100644 index 00000000..8549f4cf Binary files /dev/null and b/plugins/help/__pycache__/config.cpython-38.pyc differ diff --git a/plugins/help/__pycache__/config.cpython-39.pyc b/plugins/help/__pycache__/config.cpython-39.pyc new file mode 100644 index 00000000..e6e147c1 Binary files /dev/null and b/plugins/help/__pycache__/config.cpython-39.pyc differ diff --git a/plugins/help/__pycache__/data_source.cpython-38.pyc b/plugins/help/__pycache__/data_source.cpython-38.pyc new file mode 100644 index 00000000..07934ed1 Binary files /dev/null and b/plugins/help/__pycache__/data_source.cpython-38.pyc differ diff --git a/plugins/help/__pycache__/data_source.cpython-39.pyc b/plugins/help/__pycache__/data_source.cpython-39.pyc new file mode 100644 index 00000000..31015e7c Binary files /dev/null and b/plugins/help/__pycache__/data_source.cpython-39.pyc differ diff --git a/plugins/help/config.py b/plugins/help/config.py new file mode 100644 index 00000000..5a57e26d --- /dev/null +++ b/plugins/help/config.py @@ -0,0 +1,52 @@ + +# 实用 +utility_help = { + 'update_pic': '一些对图片的操作 --> 指令:操作图片/图片/修改图片(包含 10 种图片操作)', + 'search_buff_skin_price': 'BUFF皮肤底价查询 --> 指令:查询皮肤(代理ip不得劲)', + 'weather': '天气查询 --> 指令:xx天气', + 'yiqing': '实时疫情数据 --> 指令:疫情查询/疫情/查询疫情', + 'bt': 'bt(磁力搜索){仅支持私聊,懂的都懂} --> 指令:bt', + 'reimu': '老司机必备!{仅支持私聊,懂的都懂}-> 指令:上车', + 'what_anime': '靠图识番 --> 指令:识番', + 'nonebot_plugin_picsearcher': '以图搜图 --> 指令:识图/这是什么/上一张图是什么', + 'search_anime': '找不到想看的动漫吗? --> 指令:搜番', + 'songpicker2': '来一首歌听听? --> 指令:点歌', + 'epic': 'epic速速白嫖 --> 指令:epic', + 'pixiv_r': 'P站排行榜直接冲 --> 指令:p站排行(可含参数)', + 'pixiv_s': 'P站的图随便搜搜 --> 指令:搜图(可含参数)', + 'translate': '出国旅游助手(狗头) --> 指令:英翻/翻英/日翻/翻日/韩翻/翻韩' +} +# 娱乐 +entertainment_help = { + 'sign_in': '签到(影响色图几率和开箱次数) --> 指令:签到/我的签到/好感度排行', + 'send_img': '发送图片 --> 指令:美图/萝莉/壁纸', + 'send_setu': '不要小看涩图啊混蛋! --> 指令:色图/n张色图/n张xx色图/查色图/...(请查看 色图 帮助)', + 'white2black_img': '黑白草图 --> 指令:黑白图/黑白草图', + 'coser': '三次元也不戳 --> 指令:coser', + 'jitang': '不喝点什么不舒服 --> 指令:鸡汤/语录', + 'send_dinggong_voice': '骂我(傲娇?) --> 指令:骂老子', + 'poke': '戳一戳发送语音美图萝莉图不美哉?', + 'open_cases': '模拟开箱(戒赌) --> 指令:开箱(N连开箱[N<=30])/我的开箱/群开箱统计/我的金色', + 'luxun': '鲁迅说过 --> 指令:鲁迅说', + 'fake_msg': '构造一个假消息 --> 指令:假消息', + 'shop': '商店系统(初始送100金币) --> 指令:商店/我的金币/购买道具/使用道具', + 'draw_card_p': '换个地方当非酋TvT... --> 指令:方舟一井/方舟N抽(0 指令:原神一井/原神N抽(0 指令:赛马娘一井/赛马娘N抽/赛马娘卡一井/赛马娘卡N抽(0 直接查看 骰子娘帮助!', + 'one_friend': '我有一个朋友想问问... --> 指令:我有一个朋友想问问xxx(内容)', + 'nickname': '区区昵称! --> 指令:以后叫我xx(昵称)/我是谁/取消昵称', + 'almanac': '这是一张正经的黄历 --> 指令:原神黄历', + 'material_remind': '看看原神今天要刷什么 --> 指令:今日素材/天赋材料', + 'qiu_qiu_translation': '这家伙到底在说什么? --> 指令:丘丘翻译/丘丘一下/丘丘语翻译', + 'query_resource_points': '地图资源速速查看 --> 指令:原神资源查询xx/原神资源列表/哪里有xx/xx在哪(xx=资源名称)', +} +# 其他 +other_help = [ + '群内csgo服务器(指定群) --> 指令:服务器/ip(其他群请私聊)', + '查看当前的群欢迎消息 --> 指令:群欢迎消息', + '这是一份正经的自我介绍 --> 指令:自我介绍', + '不得看看自己权力多大? --> 指令:我的权限', + '有人记得你是什么时候加入我们的 --> 指令:我的信息', + '让我看看更新了什么 --> 指令:更新信息' +] diff --git a/plugins/help/data_source.py b/plugins/help/data_source.py new file mode 100644 index 00000000..0d273f6f --- /dev/null +++ b/plugins/help/data_source.py @@ -0,0 +1,175 @@ +from util.img_utils import CreateImg +from configs.path_config import IMAGE_PATH, DATA_PATH +import ujson as json +import os +from .config import * +from nonebot import require + +export = require("nonebot_plugin_manager") + +width = 1200 +e_height = 0 +u_height = 700 +o_height = 1250 +# f_height = + + +def create_help_img(): + if os.path.exists(IMAGE_PATH + 'help.png'): + os.remove(IMAGE_PATH + 'help.png') + h = (100 + len(utility_help) * 24 + len(entertainment_help) * 24 + len(other_help) * 24) * 2 + A = CreateImg(width, h - 200, font_size=24) + e = CreateImg(width, len(entertainment_help) * 42, font_size=24) + rst = '' + i = 0 + for cmd in entertainment_help: + rst += f'{i + 1}.{entertainment_help[cmd]}\n' + i += 1 + e.text((10, 10), '娱乐功能:') + e.text((40, 40), rst) + u = CreateImg(width, len(utility_help) * 40 + 50, font_size=24, color='black') + rst = '' + i = 0 + for cmd in utility_help: + rst += f'{i + 1}.{utility_help[cmd]}\n' + i += 1 + u.text((10, 10), '实用功能:', fill=(255, 255, 255)) + u.text((40, 40), rst, fill=(255, 255, 255)) + o = CreateImg(width, len(other_help) * 40, font_size=24) + rst = '' + i = 0 + for i in range(len(other_help)): + rst += f'{i + 1}.{other_help[i]}\n' + i += 1 + o.text((10, 10), '其他功能:') + o.text((40, 40), rst) + A.paste(e, (0, 0)) + A.paste(u, (0, u_height)) + A.paste(o, (0, o_height)) + A.text((10, h * 0.72), '大部分交互功能可以通过输入‘取消’,‘算了’来取消当前交互\n对我说 “指令名 帮助” 获取对应详细帮助\n' + '可以通过 “滴滴滴- 后接内容” 联系管理员(有趣的想法尽管来吧!<还有Bug和建议>)\n[群管理员请看 管理员帮助(群主与管理员自带 5 级权限)]') + A.text((10, h * 0.79), f"【注】「色图概率:好感度 + 70%\n" + f"\t\t每 3 点好感度 + 1次开箱,初始 20 次\n" + f"\t\t开启/关闭功能只需输入‘开启/关闭 指令名’(每个功能的第一个指令)」\n" + f"\t\t示例:开启签到") + A.save(IMAGE_PATH + 'help.png') + + +def create_group_help_img(group_id: int): + group_id = str(group_id) + try: + with open(DATA_PATH + 'manager/plugin_list.json', 'r', encoding='utf8') as f: + plugin_list = json.load(f) + except (ValueError, FileNotFoundError): + pass + h = (100 + len(utility_help) * 24 + len(entertainment_help) * 24 + len(other_help) * 24) * 2 + A = CreateImg(1200, h - 200, font_size=24) + u = CreateImg(1200, len(utility_help) * 40, font_size=24, color='black') + o = CreateImg(1200, len(other_help) * 40, font_size=24) + e = CreateImg(width, len(entertainment_help) * 42, font_size=24) + rst = '' + i = 1 + # print(plugin_list) + for cmd in entertainment_help.keys(): + # dfg = '_' + # if cmd == 'draw_card_p': + # cmd = 'draw_card' + # dfg = 'p' + # elif cmd == 'draw_card_g': + # cmd = 'draw_card' + # dfg = 'g' + # flag = '√' + # if group_id in plugin_list[cmd]: + # if not plugin_list[cmd][group_id]: + # flag = '×' + # if cmd in ['nickname']: + # flag = '-' + flag, dfg = parse_cmd(cmd, group_id, plugin_list) + if dfg: + cmd = rcmd(dfg) + # if dfg == 'p': + # cmd = 'draw_card_p' + # elif dfg == 'g': + # cmd = 'draw_card_g' + rst += f'【{flag}】{i}.{entertainment_help[cmd]}\n' + i += 1 + e.text((10, 10), '娱乐功能:') + e.text((40, 40), rst) + + rst = '' + i = 1 + for cmd in utility_help.keys(): + # flag = '√' + # if group_id in plugin_list[cmd]: + # if not plugin_list[cmd][group_id]: + # flag = '×' + # if cmd in ['bt', 'reimu']: + # flag = '-' + flag, dfg = parse_cmd(cmd, group_id, plugin_list) + rst += f'【{flag}】{i}.{utility_help[cmd]}\n' + i += 1 + u.text((10, 10), '实用功能:', fill=(255, 255, 255)) + u.text((40, 40), rst, fill=(255, 255, 255)) + + rst = '' + for i in range(len(other_help)): + rst += f'{i + 1}.{other_help[i]}\n' + o.text((10, 10), '其他功能:') + o.text((40, 40), rst) + + A.paste(e, (0, 0)) + A.paste(u, (0, u_height)) + A.paste(o, (0, o_height)) + # A.text((width, 10), f'总开关【{"√" if data["总开关"] else "×"}】') + A.text((10, h * 0.72), '大部分交互功能可以通过输入‘取消’,‘算了’来取消当前交互\n对我说 “指令名 帮助” 获取对应详细帮助\n' + '可以通过 “滴滴滴- 后接内容” 联系管理员(有趣的想法尽管来吧!<还有Bug和建议>)' + '\n[群管理员请看 管理员帮助(群主与管理员自带 5 级权限)]') + A.text((10, h * 0.79), f"【注】「色图概率:好感度 + 70%\n" + f"\t\t每 3 点好感度 + 1次开箱,初始 20 次\n" + f"\t\t开启/关闭功能只需输入‘开启/关闭 指令名’(每个功能的第一个指令)」\n" + f"\t\t示例:开启签到\n" + f"\t\t可以通过管理员开关自动发送消息(早晚安等)\n" + f"\t\t^请查看管理员帮助^") + A.save(DATA_PATH + f'group_help/{group_id}.png') + + +def parse_cmd(cmd, group_id, plugin_list): + flag = '√' + dfg = None + if cmd == 'draw_card_p': + cmd = 'draw_card' + dfg = 'p' + elif cmd == 'draw_card_g': + cmd = 'draw_card' + dfg = 'g' + elif cmd == 'draw_card_h': + cmd = 'draw_card' + dfg = 'h' + elif cmd == 'pixiv_r': + cmd = 'pixiv' + dfg = 'r' + elif cmd == 'pixiv_s': + cmd = 'pixiv' + dfg = 's' + if group_id in plugin_list[cmd]: + if not plugin_list[cmd][group_id]: + flag = '×' + if cmd in ['bt', 'reimu', 'nickname']: + flag = '- ' + return flag, dfg + + +def rcmd(dfg): + if dfg == 'p': + return 'draw_card_p' + if dfg == 'g': + return 'draw_card_g' + if dfg == 'g': + return 'draw_card_h' + if dfg == 'r': + return 'pixiv_r' + if dfg == 's': + return 'pixiv_s' + + + diff --git a/plugins/hook.py b/plugins/hook.py new file mode 100644 index 00000000..6786284b --- /dev/null +++ b/plugins/hook.py @@ -0,0 +1,152 @@ +from nonebot.matcher import Matcher +from nonebot.message import run_preprocessor, IgnoredException +from nonebot.typing import T_State +from nonebot.adapters.cqhttp import Bot, MessageEvent, PrivateMessageEvent, GroupMessageEvent +from configs.config import BAN_RESULT, admin_plugins_auth, MALICIOUS_BAN_TIME, MALICIOUS_CHECK_TIME, MALICIOUS_BAN_COUNT +from models.ban_user import BanUser +from util.utils import is_number, static_flmt, BanCheckLimiter +from util.init_result import at +from services.log import logger +from models.level_user import LevelUser +try: + import ujson as json +except ModuleNotFoundError: + import json + + +# 检查是否被ban +@run_preprocessor +async def _(matcher: Matcher, bot: Bot, event: MessageEvent, state: T_State): + if matcher.type == 'message' and matcher.priority not in [1, 9]: + if await BanUser.isban(event.user_id) and str(event.user_id) not in bot.config.superusers: + time = await BanUser.check_ban_time(event.user_id) + if is_number(time): + time = abs(int(time)) + if time < 60: + time = str(time) + ' 秒' + else: + time = str(int(time / 60)) + ' 分' + else: + time = str(time) + ' 分' + if event.message_type == 'group': + if not static_flmt.check(event.user_id): + raise IgnoredException('用户处于黑名单中') + static_flmt.start_cd(event.user_id) + if matcher.priority != 9: + await bot.send_group_msg(group_id=event.group_id, + message=at(event.user_id) + BAN_RESULT + f' 在..在 {time}后才会理你喔') + else: + if not static_flmt.check(event.user_id): + raise IgnoredException('用户处于黑名单中') + static_flmt.start_cd(event.user_id) + if matcher.priority != 9: + await bot.send_private_msg(user_id=event.user_id, + message=at(event.user_id) + BAN_RESULT + f' 在..在 {time}后才会理你喔') + raise IgnoredException('用户处于黑名单中') + + +_blmt = BanCheckLimiter(MALICIOUS_BAN_TIME, MALICIOUS_BAN_COUNT) + + +# 恶意触发命令检测 +@run_preprocessor +async def _(matcher: Matcher, bot: Bot, event: GroupMessageEvent, state: T_State): + if matcher.type == 'message' and matcher.priority not in [1, 9]: + if state["_prefix"]["raw_command"]: + # print(state["_prefix"]["raw_command"]) + if _blmt.check(f'{event.user_id}{state["_prefix"]["raw_command"]}'): + if await BanUser.ban(event.user_id, 9, MALICIOUS_BAN_TIME * 60): + logger.info(f'USER {event.user_id} 触发了恶意触发检测') + # await update_img.finish('检测到恶意触发命令,您将被封禁 30 分钟', at_sender=True) + if event.message_type == 'group': + if not static_flmt.check(event.user_id): + return + static_flmt.start_cd(event.user_id) + await bot.send_group_msg(group_id=event.group_id, + message=at(event.user_id) + '检测到恶意触发命令,您将被封禁 30 分钟') + else: + if not static_flmt.check(event.user_id): + return + static_flmt.start_cd(event.user_id) + await bot.send_private_msg(user_id=event.user_id, + message=at(event.user_id) + '检测到恶意触发命令,您将被封禁 30 分钟') + raise IgnoredException('检测到恶意触发命令') + _blmt.add(f'{event.user_id}{state["_prefix"]["raw_command"]}') + + +# 权限检测 +@run_preprocessor +async def _(matcher: Matcher, bot: Bot, event: MessageEvent, state: T_State): + if await BanUser.isban(event.user_id): + return + if matcher.module in admin_plugins_auth.keys() and matcher.priority not in [1, 9]: + if event.message_type == 'group': + if not await LevelUser.check_level(event.user_id, event.group_id, admin_plugins_auth[matcher.module]): + await bot.send_group_msg(group_id=event.group_id, + message=f'{at(event.user_id)}你的权限不足喔,该功能需要的权限等级:' + f'{admin_plugins_auth[matcher.module]}') + raise IgnoredException('权限不足') + else: + if not await LevelUser.check_level(event.user_id, 0, admin_plugins_auth[matcher.module]): + await bot.send_private_msg(user_id=event.user_id, + message=f'你的权限不足喔,该功能需要的权限等级:{admin_plugins_auth[matcher.module]}') + raise IgnoredException('权限不足') + + +# 为什么AI会自己和自己聊天 +@run_preprocessor +async def _(matcher: Matcher, bot: Bot, event: PrivateMessageEvent, state: T_State): + if matcher.type == 'message' and event.user_id == int(bot.self_id): + raise IgnoredException('为什么AI会自己和自己聊天') + + +# 有命令就别说话了 +@run_preprocessor +async def _(matcher: Matcher, bot: Bot, event: MessageEvent, state: T_State): + if matcher.type == 'message': + if state["_prefix"]["raw_command"] and matcher.module == 'ai': + raise IgnoredException('有命令就别说话了') + + +# _ulmt = UserExistLimiter() +# +# +# # 是否有命令正在处理 +# @run_preprocessor +# async def _(matcher: Matcher, bot: Bot, event: Event, state: T_State): +# if matcher.module == 'admin_bot_manage': +# return +# if event.user_id == bot.self_id: +# raise IgnoredException('自己和自己聊天?') +# print(state["_prefix"]["raw_command"]) +# print(matcher.type) +# if (event.is_tome() and (state["_prefix"]["raw_command"] and matcher.type == 'message') +# and matcher.module == 'ai') or not static_group_dict[event.group_id]['总开关']: +# raise IgnoredException('Ai给爷爬?') +# # if matcher.module in ['ai']: +# # raise IgnoredException('Ai给爷爬?') +# if matcher.type == 'message' and matcher.priority not in [1, 8, 9]: +# if _ulmt.check(event.user_id): +# if event.message_type == 'group': +# await bot.send_group_msg(group_id=event.group_id, message=at(event.user_id) + '您有命令正在处理,等一哈!') +# else: +# await bot.send_private_msg(user_id=event.user_id, message='您有命令正在处理,等一哈!') +# raise IgnoredException('有命令正在处理') +# _ulmt.set_True(event.user_id) +# +# +# # 结束正在处理的命令 +# @run_postprocessor +# async def _(matcher: Matcher, bot: Bot, event: Event, state: T_State): +# _ulmt.set_False(event.user_id) +# +# +# # 结束正在处理的命令 +# @event_preprocessor +# async def _(bot: Bot, event: Event, state: T_State): +# try: +# _ulmt.set_False(event.user_id) +# except AttributeError: +# pass + + diff --git a/plugins/jitang.py b/plugins/jitang.py new file mode 100644 index 00000000..3ab1c011 --- /dev/null +++ b/plugins/jitang.py @@ -0,0 +1,35 @@ +from nonebot import on_command +from util.user_agent import get_user_agent +from bs4 import BeautifulSoup +from services.log import logger +from nonebot.adapters.cqhttp import Bot, Event +from nonebot.typing import T_State +import aiohttp + + +__plugin_name__ = '鸡汤' +__plugin_usage__ = '用法: 要喝一点鸡汤吗?' + + +url = "https://new.toodo.fun/funs/content?type=du" + + +jitang = on_command("鸡汤", aliases={"毒鸡汤"}, priority=5, block=True) + + +@jitang.handle() +async def _(bot: Bot, event: Event, state: T_State): + if str(event.get_message()) in ['帮助']: + await jitang.finish(__plugin_usage__) + try: + async with aiohttp.ClientSession(headers=get_user_agent()) as session: + async with session.get(url, timeout=7) as response: + soup = BeautifulSoup(await response.text(), 'lxml') + result = (soup.find_all('h3', {'class': 'text-center'}))[0].text + await jitang.send(result) + logger.info( + f"(USER {event.user_id}, GROUP {event.group_id if event.message_type != 'private' else 'private'})" + f" 发送鸡汤:" + result) + except Exception as e: + await jitang.send("出错啦!再试一次吧!", at_sender=True) + logger.info(f'鸡汤error e:{e}') diff --git a/plugins/last_chat/__init__.py b/plugins/last_chat/__init__.py new file mode 100644 index 00000000..a41f0166 --- /dev/null +++ b/plugins/last_chat/__init__.py @@ -0,0 +1,53 @@ +from nonebot import on_message +from nonebot.adapters.cqhttp.permission import GROUP +from nonebot.typing import T_State +from nonebot.adapters.cqhttp import Bot, GroupMessageEvent +import time +from .data_source import cancel_all_notice, save_data, get_data, set_data_value +from services.log import logger + + +__plugin_name__ = '查看群最后聊天时间 [Hidden]' + + +last_chat = on_message(priority=1, block=False, permission=GROUP) + + +@last_chat.handle() +async def _(bot: Bot, event: GroupMessageEvent, state: T_State): + time_data = await get_data() + set_data_value(event.group_id, time.time()) + if event.group_id in time_data['_group']: + time_data['_group'].remove(event.group_id) + set_data_value('_group', time_data['_group']) + for key in time_data.keys(): + if key not in ['check_time', '_group']: + if key not in time_data['_group']: + if time.time() - time_data[key] > 60 * 60 * 36: + await cancel_all_notice(key) + time_data["_group"].append(key) + set_data_value('_group', time_data['_group']) + logger.info(f'GROUP {event.group_id} 因群内发言时间大于36小时被取消全部通知') + if time.time() - time_data['check_time'] > 60 * 60 * 1: + set_data_value('check_time', time.time()) + save_data() + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/last_chat/__pycache__/__init__.cpython-38.pyc b/plugins/last_chat/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..ed75ce66 Binary files /dev/null and b/plugins/last_chat/__pycache__/__init__.cpython-38.pyc differ diff --git a/plugins/last_chat/__pycache__/__init__.cpython-39.pyc b/plugins/last_chat/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 00000000..57db412d Binary files /dev/null and b/plugins/last_chat/__pycache__/__init__.cpython-39.pyc differ diff --git a/plugins/last_chat/__pycache__/data_source.cpython-38.pyc b/plugins/last_chat/__pycache__/data_source.cpython-38.pyc new file mode 100644 index 00000000..64b24a31 Binary files /dev/null and b/plugins/last_chat/__pycache__/data_source.cpython-38.pyc differ diff --git a/plugins/last_chat/__pycache__/data_source.cpython-39.pyc b/plugins/last_chat/__pycache__/data_source.cpython-39.pyc new file mode 100644 index 00000000..b6d809c2 Binary files /dev/null and b/plugins/last_chat/__pycache__/data_source.cpython-39.pyc differ diff --git a/plugins/last_chat/data_source.py b/plugins/last_chat/data_source.py new file mode 100644 index 00000000..14e827a6 --- /dev/null +++ b/plugins/last_chat/data_source.py @@ -0,0 +1,74 @@ +from configs.path_config import DATA_PATH +from util.utils import get_bot +from models.group_remind import GroupRemind +from datetime import datetime +import time +from services.log import logger +try: + import ujson as json +except ModuleNotFoundError: + import json + + +time_data = {} + + +async def init(): + global time_data + bot = get_bot() + gl = await bot.get_group_list(self_id=bot.self_id) + gl = [g['group_id'] for g in gl] + data = read_data('group_last_chat_time.json') + for g in gl: + if not data.get(g): + time_data[g] = time.time() + if not time_data.get('check_time'): + time_data['check_time'] = time.time() + if not time_data.get('_group'): + time_data['_group'] = [] + save_data() + return time_data + + +def read_data(file_name: str): + try: + with open(DATA_PATH + file_name, 'r', encoding='utf8') as f: + return json.load(f) + except (ValueError, FileNotFoundError): + return {} + + +def save_data(): + with open(DATA_PATH + 'group_last_chat_time.json', 'w') as f: + json.dump(time_data, f, indent=4) + logger.info(f'自动存储 group_last_chat_time.json 时间:{str(datetime.now()).split(".")[0]}') + + +command_list = ['zwa', 'hy', 'kxcz', 'blpar', 'epic', 'pa'] + + +# 取消全部通知 +async def cancel_all_notice(group_id): + group_id = int(group_id) + for command in command_list: + if await GroupRemind.get_status(group_id, command): + await GroupRemind.set_status(group_id, command, False) + logger.info(f'关闭了 {group_id} 群的全部通知') + + +async def get_data(): + global time_data + if not time_data: + time_data = await init() + return time_data + + +def set_data_value(key, value): + global time_data + time_data[key] = value + + + + + + diff --git a/plugins/luxun/__init__.py b/plugins/luxun/__init__.py new file mode 100644 index 00000000..10ec89b8 --- /dev/null +++ b/plugins/luxun/__init__.py @@ -0,0 +1,64 @@ +from PIL import ImageFont, ImageDraw, Image +import textwrap +from configs.path_config import IMAGE_PATH, TTF_PATH +from nonebot import on_command +from nonebot.typing import T_State +from nonebot.adapters.cqhttp import Bot, MessageEvent +from util.init_result import image +from services.log import logger +from util.utils import UserExistLimiter, get_message_text +from util.img_utils import pic2b64 + +_ulmt = UserExistLimiter() + + +luxun = on_command("鲁迅说过", aliases={"鲁迅说"}) + + +@luxun.handle() +async def handle(bot: Bot, event: MessageEvent, state: T_State): + if _ulmt.check(event.user_id): + await luxun.finish('你的鲁迅正在说,等会', at_sender=True) + args = get_message_text(event.json()) + if args: + state["content"] = args if args else '烦了,不说了' + + +@luxun.got("content", prompt="你让鲁迅说点啥?") +async def handle_event(bot: Bot, event: MessageEvent, state: T_State): + filename = str(event.user_id) + "_.jpg" + content = state["content"].strip() + if content.startswith(',') or content.startswith(','): + content = content[1:] + _ulmt.set_True(event.user_id) + if len(content) > 20: + _ulmt.set_False(event.user_id) + await luxun.finish("太长了, 鲁迅说不完!", at_sender=True) + else: + if len(content) >= 12: + content = content[:12] + '\n' + content[12:] + img = image(b64=process_pic(content, filename)) + logger.info(f"USER {event.user_id} GROUP " + f"{event.group_id if event.message_type != 'private' else 'private'} 鲁迅说过 {content}") + await luxun.send(img) + _ulmt.set_False(event.user_id) + + +def process_pic(content, filename) -> str: + text = content + para = textwrap.wrap(text, width=15) + MAX_W, MAX_H = 480, 280 + bk_img = Image.open(IMAGE_PATH + "other/luxun.jpg") + font_path = TTF_PATH + "/msyh.ttf" + font = ImageFont.truetype(font_path, 37) + font2 = ImageFont.truetype(font_path, 30) + draw = ImageDraw.Draw(bk_img) + current_h, pad = 300, 10 + for line in para: + w, h = draw.textsize(line, font=font) + draw.text(((MAX_W - w) / 2, current_h), line, font=font) + current_h += h + pad + draw.text((320, 400), "——鲁迅", font=font2, fill=(255, 255, 255)) + return pic2b64(bk_img) + + diff --git a/plugins/luxun/__pycache__/__init__.cpython-38.pyc b/plugins/luxun/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..a35c3560 Binary files /dev/null and b/plugins/luxun/__pycache__/__init__.cpython-38.pyc differ diff --git a/plugins/luxun/__pycache__/__init__.cpython-39.pyc b/plugins/luxun/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 00000000..d808d7ad Binary files /dev/null and b/plugins/luxun/__pycache__/__init__.cpython-39.pyc differ diff --git a/plugins/move_img/__init__.py b/plugins/move_img/__init__.py new file mode 100644 index 00000000..fd2a9e80 --- /dev/null +++ b/plugins/move_img/__init__.py @@ -0,0 +1,84 @@ +import os +from services.log import logger +from nonebot import on_command +from nonebot.rule import to_me +from nonebot.typing import T_State +from nonebot.adapters.cqhttp import Bot, MessageEvent +from configs.config import IMAGE_DIR_LIST +from util.utils import is_number, cn2py +from configs.path_config import IMAGE_PATH + + +__plugin_name__ = '移动图片' +__plugin_usage__ = '移动图片帮助:\n\t' \ + '1.查看列表 --> 指令: 移动图片 列表/目录\n\t' \ + '2.移动图片 源 目的 id\n\t\t示例: 移动图片 色图 美图 1234' + + +move_img = on_command('移动图片', priority=5, rule=to_me(), block=True) + + +@move_img.args_parser +async def parse(bot: Bot, event: MessageEvent, state: T_State): + if str(event.get_message()) in ['取消', '算了']: + await move_img.finish("已取消操作..", at_sender=True) + if state["_current_key"] in ['source_path', 'destination_path']: + if str(event.get_message()) not in IMAGE_DIR_LIST: + await move_img.reject("此目录不正确,请重新输入目录!") + state[state["_current_key"]] = str(event.get_message()) + if state["_current_key"] == 'id': + if not is_number(str(event.get_message())): + await move_img.reject("id不正确!请重新输入数字...") + state[state["_current_key"]] = str(event.get_message()) + + +@move_img.handle() +async def _(bot: Bot, event: MessageEvent, state: T_State): + raw_arg = str(event.get_message()).strip() + if raw_arg: + args = raw_arg.split(" ") + if args[0] in ['帮助']: + await move_img.finish(__plugin_usage__) + if len(args) >= 3 and args[0] in IMAGE_DIR_LIST and args[1] in IMAGE_DIR_LIST and is_number(args[2]): + state['source_path'] = args[0] + state['destination_path'] = args[1] + state['id'] = args[2] + else: + await move_img.finish("参数错误,请重试", at_sender=True) + + +@move_img.got("source_path", prompt="要从哪个图库移出?") +@move_img.got("destination_path", prompt="要移动到哪个图库?") +@move_img.got("id", prompt="要移动的图片id是?") +async def _(bot: Bot, event: MessageEvent, state: T_State): + img_id = state['id'] + source_path = IMAGE_PATH + cn2py(state['source_path']) + destination_path = IMAGE_PATH + cn2py(state['destination_path']) + max_id = len(os.listdir(source_path)) - 1 + des_max_id = len(os.listdir(destination_path)) + if int(img_id) > max_id or int(img_id) < 0: + await move_img.finish(f"Id超过上下限,上限:{max_id}", at_sender=True) + try: + os.rename(source_path + img_id + ".jpg", destination_path + str(des_max_id) + ".jpg") + logger.info(f"移动 {source_path}{img_id}.jpg ---> {destination_path}{des_max_id} 移动成功") + except Exception as e: + logger.warning(f"移动 {source_path}{img_id}.jpg ---> {destination_path}{des_max_id} 移动失败 e:{e}") + await move_img.finish(f"移动图片id:{img_id} 失败了...", at_sender=True) + if max_id > 0: + try: + os.rename(source_path + str(max_id) + ".jpg", source_path + img_id + ".jpg") + logger.info(f"{source_path}{max_id}.jpg 替换 {source_path}{img_id}.jpg 成功") + except Exception as e: + logger.warning(f"{source_path}{max_id}.jpg 替换 {source_path}{img_id}.jpg 失败 e:{e}") + await move_img.finish(f"替换图片id:{max_id} -> {img_id} 失败了...", at_sender=True) + logger.info(f"USER {event.user_id} GROUP {event.group_id if event.message_type != 'private' else 'private'} ->" + f" {source_path} --> {destination_path} (id:{img_id}) 移动图片成功") + await move_img.finish(f"移动图片 id:{img_id} --> id:{des_max_id}成功", at_sender=True) + + + + + + + + diff --git a/plugins/move_img/__pycache__/__init__.cpython-38.pyc b/plugins/move_img/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..b3d09ef1 Binary files /dev/null and b/plugins/move_img/__pycache__/__init__.cpython-38.pyc differ diff --git a/plugins/move_img/__pycache__/__init__.cpython-39.pyc b/plugins/move_img/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 00000000..94716921 Binary files /dev/null and b/plugins/move_img/__pycache__/__init__.cpython-39.pyc differ diff --git a/plugins/mute.py b/plugins/mute.py new file mode 100644 index 00000000..17544058 --- /dev/null +++ b/plugins/mute.py @@ -0,0 +1,129 @@ +from nonebot import on_message, on_command +from nonebot.adapters.cqhttp import Bot, GroupMessageEvent +from nonebot.adapters.cqhttp.permission import GROUP +from util.utils import get_message_text, is_number, get_message_imgs, get_local_proxy +from nonebot.typing import T_State +import time +from nonebot.adapters.cqhttp.exception import ActionFailed +from configs.path_config import DATA_PATH, IMAGE_PATH +from util.img_utils import get_img_hash +from services.log import logger +import aiohttp +import aiofiles +from configs.config import MUTE_DEFAULT_COUNT, MUTE_DEFAULT_TIME, MUTE_DEFAULT_DURATION +try: + import ujson as json +except ModuleNotFoundError: + import json + +__plugin_name__ = '刷屏禁言' + + +mute = on_message(priority=1, block=False) +mute_setting = on_command('mute_setting', aliases={'设置检测时间', '设置检测次数', '设置禁言时长', '刷屏检测设置'}, permission=GROUP, block=True) + + +def get_data(): + try: + with open(DATA_PATH + 'group_mute_data.json', 'r', encoding='utf8') as f: + data = json.load(f) + except (ValueError, FileNotFoundError): + data = {} + return data + + +def save_data(): + global mute_data + with open(DATA_PATH + 'group_mute_data.json', 'w', encoding='utf8') as f: + json.dump(mute_data, f, indent=4) + + +async def download_img_and_hash(url, group_id): + async with aiohttp.ClientSession() as session: + async with session.get(url, proxy=get_local_proxy(), timeout=10) as response: + async with aiofiles.open(IMAGE_PATH + f'temp/mute_{group_id}_img.jpg', 'wb') as f: + await f.write(await response.read()) + return str(get_img_hash(IMAGE_PATH + f'temp/mute_{group_id}_img.jpg')) + + +mute_dict = {} +mute_data = get_data() + + +@mute.handle() +async def _(bot: Bot, event: GroupMessageEvent, state: T_State): + group_id = str(event.group_id) + msg = get_message_text(event.json()) + imgs = get_message_imgs(event.json()) + img_hash = '' + for img in imgs: + img_hash += await download_img_and_hash(img, event.group_id) + msg += img_hash + if not mute_data.get(group_id): + mute_data[group_id] = { + 'count': MUTE_DEFAULT_COUNT, + 'time': MUTE_DEFAULT_TIME, + 'duration': MUTE_DEFAULT_DURATION + } + if not mute_dict.get(event.user_id): + mute_dict[event.user_id] = { + 'time': time.time(), + 'count': 1, + 'msg': msg + } + else: + if state["_prefix"]["raw_command"] or not msg: + return + if msg and msg.find(mute_dict[event.user_id]['msg']) != -1: + mute_dict[event.user_id]['count'] += 1 + else: + mute_dict[event.user_id]['time'] = time.time() + mute_dict[event.user_id]['count'] = 1 + mute_dict[event.user_id]['msg'] = msg + if time.time() - mute_dict[event.user_id]['time'] > mute_data[group_id]['time']: + mute_dict[event.user_id]['time'] = time.time() + mute_dict[event.user_id]['count'] = 1 + if mute_dict[event.user_id]['count'] > mute_data[group_id]['count'] and\ + time.time() - mute_dict[event.user_id]['time'] < mute_data[group_id]['time']: + try: + if mute_data[group_id]['duration'] != 0: + await bot.set_group_ban(group_id=event.group_id, user_id=event.user_id, + duration=mute_data[group_id]['duration']) + await mute.send('检测到恶意刷屏,真寻要把你关进小黑屋!', at_sender=True) + mute_dict[event.user_id]['count'] = 0 + logger.info(f'USER {event.user_id} GROUP {event.group_id} ' + f'检测刷屏 被禁言 {mute_data[group_id]["duration"] / 60} 分钟') + except ActionFailed: + pass + + +@mute_setting.handle() +async def _(bot: Bot, event: GroupMessageEvent, state: T_State): + group_id = str(event.group_id) + if not mute_data.get(group_id): + mute_data[group_id] = { + 'count': 10, + 'time': 7, + 'duration': 0 + } + msg = get_message_text(event.json()) + if state["_prefix"]["raw_command"] == '刷屏检测设置': + await mute_setting.finish(f'最大次数:{mute_data[group_id]["count"]} 次\n' + f'规定时间:{mute_data[group_id]["time"]} 秒\n' + f'禁言时长:{mute_data[group_id]["duration"] / 60} 分钟\n' + f'【在规定时间内发送相同消息超过最大次数则禁言\n当禁言时长为0时关闭此功能】') + if not is_number(msg): + await mute.finish('设置的参数必须是数字啊!', at_sender=True) + if state["_prefix"]["raw_command"] == '设置检测时间': + mute_data[group_id]['time'] = int(msg) + msg += '秒' + if state["_prefix"]["raw_command"] == '设置检测次数': + mute_data[group_id]['count'] = int(msg) + msg += ' 次' + if state["_prefix"]["raw_command"] == '设置禁言时长': + mute_data[group_id]['duration'] = int(msg) * 60 + msg += ' 分钟' + await mute_setting.send(f'刷屏检测:{state["_prefix"]["raw_command"]}为 {msg}') + logger.info(f'USER {event.user_id} GROUP {group_id} {state["_prefix"]["raw_command"]}:{msg}') + save_data() + diff --git a/plugins/my_info.py b/plugins/my_info.py new file mode 100644 index 00000000..5e2fa712 --- /dev/null +++ b/plugins/my_info.py @@ -0,0 +1,40 @@ +from nonebot import on_command +from nonebot.adapters.cqhttp.permission import GROUP +from nonebot.typing import T_State +from nonebot.adapters.cqhttp import Bot, GroupMessageEvent +from models.group_member_info import GroupInfoUser +from datetime import timedelta +from models.level_user import LevelUser + +__plugin_name__ = '更新群组成员列表 [Hidden]' +__plugin_usage__ = ( + '用法:\n' + '更新群员的信息' +) + + +get_my_group_info = on_command("我的信息", permission=GROUP, priority=1, block=True) +my_level = on_command('我的权限', permission=GROUP, priority=5, block=True) + + +@get_my_group_info.handle() +async def _(bot: Bot, event: GroupMessageEvent, state: T_State): + result = await get_member_info(event.user_id, event.group_id) + await get_my_group_info.finish(result) + + +async def get_member_info(user_qq: int, group_id: int) -> str: + user = await GroupInfoUser.select_member_info(user_qq, group_id) + if user is None: + return "该群员不在列表中,请更新群成员信息" + result = "" + result += "昵称:" + user.user_name + "\n" + result += "加群时间:" + str(user.user_join_time.date() + timedelta(hours=8)) + return result + + +@my_level.handle() +async def _(bot: Bot, event: GroupMessageEvent, state: T_State): + if (level := await LevelUser.get_user_level(event.user_id, event.group_id)) == -1: + await my_level.finish('您目前没有任何权限了,硬要说的话就是0吧~', at_sender=True) + await my_level.finish(f'您目前的权限等级:{level}', at_sender=True) \ No newline at end of file diff --git a/plugins/nickname.py b/plugins/nickname.py new file mode 100644 index 00000000..844e9939 --- /dev/null +++ b/plugins/nickname.py @@ -0,0 +1,168 @@ +from nonebot import on_command +from nonebot.typing import T_State +from nonebot.adapters.cqhttp import Bot, GroupMessageEvent, PrivateMessageEvent +from nonebot.rule import to_me +from util.utils import get_message_text +from models.group_member_info import GroupInfoUser +from models.friend_user import FriendUser +import random +from models.ban_user import BanUser +from services.log import logger + +nickname = on_command('nickname', + aliases={'以后叫我', '以后请叫我', '称呼我', '以后请称呼我', '以后称呼我', '叫我', '请叫我'}, + rule=to_me(), priority=5, block=True) + +my_nickname = on_command('my_name', aliases={'我叫什么', '我是谁', '我的名字'}, rule=to_me(), priority=5, block=True) + + +cancel_nickname = on_command('取消昵称', rule=to_me(), priority=5, block=True) + + +@nickname.handle() +async def _(bot: Bot, event: GroupMessageEvent, state: T_State): + msg = get_message_text(event.json()) + if not msg: + await nickname.finish('叫你空白?叫你虚空?叫你无名??', at_sender=True) + if len(msg) > 10: + await nickname.finish('昵称可不能超过10个字!', at_sender=True) + if await GroupInfoUser.set_group_member_nickname(event.user_id, event.group_id, msg): + if len(msg) < 5: + if random.random() < 0.5: + msg = "~".join(msg) + await nickname.send(random.choice([ + '好啦好啦,我知道啦,{},以后就这么叫你吧', + '嗯嗯,小真寻记住你的昵称了哦,{}', + '好突然,突然要叫你昵称什么的...{}..', + '小真寻会好好记住的{}的,放心吧', + '好..好.,那窝以后就叫你{}了.' + ]).format(msg)) + logger.info(f'USER {event.user_id} GROUP {event.group_id} 设置群昵称 {msg}') + else: + await nickname.send('设置昵称失败,请更新群组成员信息!', at_sender=True) + logger.warning(f'USER {event.user_id} GROUP {event.group_id} 设置群昵称 {msg} 失败') + + +@nickname.handle() +async def _(bot: Bot, event: PrivateMessageEvent, state: T_State): + msg = get_message_text(event.json()) + if not msg: + await nickname.finish('叫你空白?叫你虚空?叫你无名??', at_sender=True) + if len(msg) > 10: + await nickname.finish('不要超过10个字!', at_sender=True) + if await FriendUser.set_friend_nickname(event.user_id, msg): + await nickname.send(random.choice([ + '好啦好啦,我知道啦,{},以后就这么叫你吧', + '嗯嗯,小真寻记住你的昵称了哦,{}', + '好突然,突然要叫你昵称什么的...{}..', + '小真寻会好好记住的{}的,放心吧', + '好..好.,那窝以后就叫你{}了.' + ]).format(msg)) + logger.info(f'USER {event.user_id} 设置昵称 {msg}') + else: + await nickname.send('设置昵称失败了,明天再来试一试!或联系管理员更新好友!', at_sender=True) + logger.warning(f'USER {event.user_id} 设置昵称 {msg} 失败') + + +@my_nickname.handle() +async def _(bot: Bot, event: GroupMessageEvent, state: T_State): + try: + nickname = await GroupInfoUser.get_group_member_nickname(event.user_id, event.group_id) + except AttributeError: + nickname = '' + if nickname: + await my_nickname.send(random.choice([ + '我肯定记得你啊,你是{}啊', + '我不会忘记你的,你也不要忘记我!{}', + '哼哼,真寻记忆力可是很好的,{}', + '嗯?你是失忆了嘛...{}..', + '不要小看真寻的记忆力啊!笨蛋{}!QAQ', + '哎?{}..怎么了吗..突然这样问..' + ]).format(nickname)) + else: + try: + nickname = (await GroupInfoUser.select_member_info(event.user_id, event.group_id)).user_name + except AttributeError: + nickname = event.user_id + await my_nickname.finish(random.choice([ + '对不起,我只记得一串神秘代码..{}\n【群管理快更新群组成员信息!】' + ]).format(nickname)) + await my_nickname.send(random.choice([ + '没..没有昵称嘛,{}', + '啊,你是{}啊,我想叫你的昵称!', + '是{}啊,有什么事吗?', + '你是{}?' + ]).format(nickname)) + + +@my_nickname.handle() +async def _(bot: Bot, event: PrivateMessageEvent, state: T_State): + nickname = await FriendUser.get_friend_nickname(event.user_id) + if nickname: + await my_nickname.send(random.choice([ + '我肯定记得你啊,你是{}啊', + '我不会忘记你的,你也不要忘记我!{}', + '哼哼,真寻记忆力可是很好的,{}', + '嗯?你是失忆了嘛...{}..', + '不要小看真寻的记忆力啊!笨蛋{}!QAQ', + '哎?{}..怎么了吗..突然这样问..' + ]).format(nickname)) + else: + nickname = await FriendUser.get_user_name(event.user_id) + if nickname: + await my_nickname.send(random.choice([ + '没..没有昵称嘛,{}', + '啊,你是{}啊,我想叫你的昵称!', + '是{}啊,有什么事吗?', + '你是{}?' + ]).format(nickname)) + else: + nickname = event.user_id + await my_nickname.finish(random.choice([ + '对不起,我只记得一串神秘代码..{}\n【火速联系管理员更新好友列表!】' + ]).format(nickname)) + + +@cancel_nickname.handle() +async def _(bot: Bot, event: GroupMessageEvent, state: T_State): + nickname = await GroupInfoUser.get_group_member_nickname(event.user_id, event.group_id) + if nickname: + await cancel_nickname.send(random.choice([ + '呜..真寻睡一觉就会忘记的..和梦一样..{}', + '窝知道了..{}..', + '是真寻哪里做的不好嘛..好吧..晚安{}', + '呃,{},下次我绝对绝对绝对不会再忘记你!', + '可..可恶!{}!太可恶了!呜' + ]).format(nickname)) + await GroupInfoUser.set_group_member_nickname(event.user_id, event.group_id, '') + await BanUser.ban(event.user_id, 9, 60) + else: + await cancel_nickname.send('你在做梦吗?你没有昵称啊', at_sender=True) + + +@cancel_nickname.handle() +async def _(bot: Bot, event: PrivateMessageEvent, state: T_State): + nickname = await FriendUser.get_user_name(event.user_id) + if nickname: + await cancel_nickname.send(random.choice([ + '呜..真寻睡一觉就会忘记的..和梦一样..{}', + '窝知道了..{}..', + '是真寻哪里做的不好嘛..好吧..晚安{}', + '呃,{},下次我绝对绝对绝对不会再忘记你!', + '可..可恶!{}!太可恶了!呜' + ]).format(nickname)) + await FriendUser.get_user_name(event.user_id) + await BanUser.ban(event.user_id, 9, 60) + else: + await cancel_nickname.send('你在做梦吗?你没有昵称啊', at_sender=True) + + + + + + + + + + + diff --git a/plugins/nonebot_plugin_cocdicer/__init__.py b/plugins/nonebot_plugin_cocdicer/__init__.py new file mode 100644 index 00000000..5dae4b6f --- /dev/null +++ b/plugins/nonebot_plugin_cocdicer/__init__.py @@ -0,0 +1,72 @@ +from .data_source import rd, help_message, st, en +from .madness import ti, li +from .create import Investigator +from .san_check import sc + +from nonebot.plugin import on_startswith +from nonebot.adapters.cqhttp import Bot, Event + +rdhelp = on_startswith("骰子娘帮助", priority=2) +stcommand = on_startswith(".st", priority=2) +encommand = on_startswith(".en", priority=2) +ticommand = on_startswith(".ti", priority=2) +licommand = on_startswith(".li", priority=2) +coc = on_startswith(".coc", priority=2) +sccommand = on_startswith(".sc", priority=2) +rdcommand = on_startswith(".r", priority=3) + + +@rdhelp.handle() +async def rdhelphandler(bot: Bot): + await rdhelp.finish(help_message()) + + +@stcommand.handle() +async def stcommandhandler(bot: Bot): + await rdhelp.finish(st()) + + +@encommand.handle() +async def enhandler(bot: Bot, event: Event): + args = str(event.get_message())[3:].strip() + await encommand.finish(en(args)) + + +@rdcommand.handle() +async def rdcommandhandler(bot: Bot, event: Event): + args = str(event.get_message())[2:].strip() + uid = event.get_session_id() + if args and not("." in args): + rrd = rd(args) + if type(rrd) == str: + await rdcommand.finish(rrd) + elif type(rrd) == list: + await bot.send_private_msg(user_id=uid, message=rrd[0]) + + +@coc.handle() +async def cochandler(bot: Bot, event: Event): + args = str(event.get_message())[4:].strip() + try: + args = int(args) + except: + args = 20 + inv = Investigator() + inv.age_change(args) + await coc.finish(inv.output()) + + +@ticommand.handle() +async def ticommandhandler(bot: Bot): + await ticommand.finish(ti()) + + +@licommand.handle() +async def licommandhandler(bot: Bot): + await licommand.finish(li()) + + +@sccommand.handle() +async def schandler(bot: Bot, event: Event): + args = str(event.get_message())[3:].strip() + await sccommand.finish(sc(args.lower())) diff --git a/plugins/nonebot_plugin_cocdicer/__pycache__/__init__.cpython-38.pyc b/plugins/nonebot_plugin_cocdicer/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..0bd616db Binary files /dev/null and b/plugins/nonebot_plugin_cocdicer/__pycache__/__init__.cpython-38.pyc differ diff --git a/plugins/nonebot_plugin_cocdicer/__pycache__/__init__.cpython-39.pyc b/plugins/nonebot_plugin_cocdicer/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 00000000..4c10f4a5 Binary files /dev/null and b/plugins/nonebot_plugin_cocdicer/__pycache__/__init__.cpython-39.pyc differ diff --git a/plugins/nonebot_plugin_cocdicer/__pycache__/create.cpython-38.pyc b/plugins/nonebot_plugin_cocdicer/__pycache__/create.cpython-38.pyc new file mode 100644 index 00000000..ecabf908 Binary files /dev/null and b/plugins/nonebot_plugin_cocdicer/__pycache__/create.cpython-38.pyc differ diff --git a/plugins/nonebot_plugin_cocdicer/__pycache__/create.cpython-39.pyc b/plugins/nonebot_plugin_cocdicer/__pycache__/create.cpython-39.pyc new file mode 100644 index 00000000..3a1b2aca Binary files /dev/null and b/plugins/nonebot_plugin_cocdicer/__pycache__/create.cpython-39.pyc differ diff --git a/plugins/nonebot_plugin_cocdicer/__pycache__/data_source.cpython-38.pyc b/plugins/nonebot_plugin_cocdicer/__pycache__/data_source.cpython-38.pyc new file mode 100644 index 00000000..cab8de52 Binary files /dev/null and b/plugins/nonebot_plugin_cocdicer/__pycache__/data_source.cpython-38.pyc differ diff --git a/plugins/nonebot_plugin_cocdicer/__pycache__/data_source.cpython-39.pyc b/plugins/nonebot_plugin_cocdicer/__pycache__/data_source.cpython-39.pyc new file mode 100644 index 00000000..5fde385e Binary files /dev/null and b/plugins/nonebot_plugin_cocdicer/__pycache__/data_source.cpython-39.pyc differ diff --git a/plugins/nonebot_plugin_cocdicer/__pycache__/madness.cpython-38.pyc b/plugins/nonebot_plugin_cocdicer/__pycache__/madness.cpython-38.pyc new file mode 100644 index 00000000..c657a445 Binary files /dev/null and b/plugins/nonebot_plugin_cocdicer/__pycache__/madness.cpython-38.pyc differ diff --git a/plugins/nonebot_plugin_cocdicer/__pycache__/madness.cpython-39.pyc b/plugins/nonebot_plugin_cocdicer/__pycache__/madness.cpython-39.pyc new file mode 100644 index 00000000..78cd6f2a Binary files /dev/null and b/plugins/nonebot_plugin_cocdicer/__pycache__/madness.cpython-39.pyc differ diff --git a/plugins/nonebot_plugin_cocdicer/__pycache__/messages.cpython-38.pyc b/plugins/nonebot_plugin_cocdicer/__pycache__/messages.cpython-38.pyc new file mode 100644 index 00000000..513aca28 Binary files /dev/null and b/plugins/nonebot_plugin_cocdicer/__pycache__/messages.cpython-38.pyc differ diff --git a/plugins/nonebot_plugin_cocdicer/__pycache__/messages.cpython-39.pyc b/plugins/nonebot_plugin_cocdicer/__pycache__/messages.cpython-39.pyc new file mode 100644 index 00000000..c024f9ff Binary files /dev/null and b/plugins/nonebot_plugin_cocdicer/__pycache__/messages.cpython-39.pyc differ diff --git a/plugins/nonebot_plugin_cocdicer/__pycache__/san_check.cpython-38.pyc b/plugins/nonebot_plugin_cocdicer/__pycache__/san_check.cpython-38.pyc new file mode 100644 index 00000000..9086d936 Binary files /dev/null and b/plugins/nonebot_plugin_cocdicer/__pycache__/san_check.cpython-38.pyc differ diff --git a/plugins/nonebot_plugin_cocdicer/__pycache__/san_check.cpython-39.pyc b/plugins/nonebot_plugin_cocdicer/__pycache__/san_check.cpython-39.pyc new file mode 100644 index 00000000..0538a8a1 Binary files /dev/null and b/plugins/nonebot_plugin_cocdicer/__pycache__/san_check.cpython-39.pyc differ diff --git a/plugins/nonebot_plugin_cocdicer/create.py b/plugins/nonebot_plugin_cocdicer/create.py new file mode 100644 index 00000000..30b66d78 --- /dev/null +++ b/plugins/nonebot_plugin_cocdicer/create.py @@ -0,0 +1,147 @@ +import random + + +build_dict = {64: -2, 84: -1, 124: 0, 164: 1, + 204: 2, 284: 3, 364: 4, 444: 5, 524: 6} +db_dict = {-2: "-2", -1: "-1", 0: "0", 1: "1d4", + 2: "1d6", 3: "2d6", 4: "3d6", 5: "4d6", 6: "5d6"} + + +def randattr(time: int = 3, ex: int = 0): + r = 0 + for _ in range(time): + r += random.randint(1, 6) + return (r+ex)*5 + + +class Investigator(object): + def __init__(self) -> None: + self.age = 20 + self.str = randattr() + self.con = randattr() + self.siz = randattr(2, 6) + self.dex = randattr() + self.app = randattr() + self.int = randattr(2, 6) + self.pow = randattr() + self.edu = randattr(2, 6) + self.luc = randattr() + + def body_build(self) -> int: + build = self.str + self.con + for i, j in build_dict.items(): + if build <= i: + return j + return + + def db(self) -> str: + return db_dict[self.body_build()] + + def lp_max(self) -> int: + return (self.con+self.siz)//10 + + def mov(self) -> int: + r = 8 + if self.age >= 80: + r -= 5 + elif self.age >= 70: + r -= 4 + elif self.age >= 60: + r -= 3 + elif self.age >= 50: + r -= 2 + elif self.age >= 40: + r -= 1 + if self.str < self.siz and self.dex < self.siz: + return r-1 + elif self.str > self.siz and self.dex > self.siz: + return r+1 + else: + return r + + def edu_up(self) -> str: + edu_check = random.randint(1, 100) + if edu_check > self.edu: + edu_en = random.randint(1, 10) + self.edu += edu_en + else: + return "教育成长检定D100=%d,小于%d,无增长。" % (edu_check, self.edu) + if self.edu > 99: + self.edu = 99 + return "教育成长检定D100=%d,成长1D10=%d,成长到了最高值99!" % (edu_check, edu_en) + else: + return "教育成长检定D100=%d,成长1D10=%d,成长到了%d" % (edu_check, edu_en, self.edu) + + def edu_ups(self, times) -> str: + r = "" + for _ in range(times): + r += self.edu_up() + return r + + def sum_down(self, sum) -> str: + if self.str + self.con + self.dex-45 < sum: + self.str = 15 + self.con = 15 + self.dex = 15 + else: + str_lost = random.randint(0, min(sum, self.str-15)) + while sum - str_lost > self.con + self.dex-30: + str_lost = random.randint(0, min(sum, self.str-15)) + self.str -= str_lost + sum -= str_lost + con_lost = random.randint(0, min(sum, self.con-15)) + while sum - con_lost > self.dex-15: + con_lost = random.randint(0, min(sum, self.con-15)) + self.con -= con_lost + sum -= con_lost + self.dex -= sum + return + + def age_change(self, age: int = 20) -> str: + if age < 15: + return "年龄过小,无法担当调查员" + elif age >= 90: + return "该调查员已经作古。" + self.age = age + if 15 <= age < 20: + self.str -= 5 + self.siz -= 5 + self.edu -= 5 + luc = randattr() + self.luc = luc if luc > self.luc else self.luc + return "力量、体型、教育值-5,幸运增强判定一次" + elif age < 40: + self.edu_up() + return "教育增强判定一次" + elif age < 50: + self.app -= 5 + self.sum_down(5) + self.edu_ups(2) + return "外貌-5,力量、体型、敏捷合计降低5,教育增强判定两次" + elif age < 60: + self.app -= 10 + self.sum_down(10) + self.edu_ups(3) + return "外貌-10,力量、体型、敏捷合计降低10,教育增强判定三次" + elif age < 70: + self.app -= 15 + self.sum_down(20) + self.edu_ups(4) + return "外貌-15,力量、体型、敏捷合计降低20,教育增强判定四次" + elif age < 80: + self.app -= 20 + self.sum_down(40) + self.edu_ups(4) + return "外貌-20,力量、体型、敏捷合计降低40,教育增强判定四次" + elif age < 90: + self.app -= 25 + self.sum_down(80) + self.edu_ups(4) + return "外貌-25,力量、体型、敏捷合计降低80,教育增强判定四次" + + def __repr__(self) -> str: + return "调查员 年龄:%d\n力量:%d 体质:%d 体型:%d\n敏捷:%d 外貌:%d 智力:%d\n意志:%d 教育:%d 幸运:%d\nDB:%s 生命值:%d 移动速度:%d" % ( + self.age, self.str, self.con, self.siz, self.dex, self.app, self.int, self.pow, self.edu, self.luc, self.db(), self.lp_max(), self.mov()) + + def output(self) -> str: + return self.__repr__() diff --git a/plugins/nonebot_plugin_cocdicer/data_source.py b/plugins/nonebot_plugin_cocdicer/data_source.py new file mode 100644 index 00000000..3e2bb074 --- /dev/null +++ b/plugins/nonebot_plugin_cocdicer/data_source.py @@ -0,0 +1,249 @@ +# 参考[OlivaDiceDocs](https://oliva.dicer.wiki/userdoc)实现的nonebot2骰娘插件 +import re +import random +from .messages import * + + +class Mylist(list): + def next(self, index: int): + if index < self.__len__()-1: + return self[index+1] + else: + return "" + + +def help_message(): + return main_help_message + + +def dhr(t, o): + if t == 0 and o == 0: + return 100 + else: + return t*10+o + + +def st(): + result = random.randint(1, 20) + if result < 4: + rstr = "右腿" + elif result < 7: + rstr = "左腿" + elif result < 11: + rstr = "腹部" + elif result < 16: + rstr = "胸部" + elif result < 18: + rstr = "右臂" + elif result < 20: + rstr = "左臂" + elif result < 21: + rstr = "头部" + return "D20=%d:命中了%s" % (result, rstr) + + +def en(arg: str) -> str: + try: + arg = int(arg) + except: + return en_help_message + check = random.randint(1, 100) + if check > arg or check > 95: + plus = random.randint(1, 10) + r = "判定值%d,判定成功,技能成长%d+%d=%d" % (check, arg, plus, arg+plus) + return r + "\n温馨提示:如果技能提高到90%或更高,增加2D6理智点数。" + else: + return "判定值%d,判定失败,技能无成长。" % check + + +class Dices(object): + def __init__(self): + self.dices = 1 + self.faces = 100 + self.a = False + self.anum = 0 + self.h = False + self.times = 1 + self.bp = 0 + self._bp_result = "" + self._tens_place = None + self._ones_place = None + self._head = "" + self._mid = "" + self._end = "" + self.result = 0 + self.a_check_mode = self.a_check + self._a_check_result = "" + self.ex_dice = None + self.ex_dice_type = 1 + self._ex_result = "" + + def real_dice(self): + if self.faces == 100: + self._tens_place = random.randint(0, 9) + self._ones_place = random.randint(0, 9) + self.result += dhr(self._tens_place, self._ones_place) + return dhr(self._tens_place, self._ones_place) + else: + rint = random.randint(1, self.faces) + self.result += rint + return rint + + def bp_dice(self): + if not self.bp or self.faces != 100 or self.dices != 1: + self._bp_result = "" + return self._bp_result + self._bp_result = " -> 十位:%d,个位:%d" % ( + self._tens_place, self._ones_place) + bp = self.bp + while bp > 0: + bd = random.randint(0, 9) + self._bp_result += ",奖励:%d" % bd + if dhr(bd, self._ones_place) < dhr(self._tens_place, self._ones_place): + self._tens_place = bd + self.result = dhr(self._tens_place, self._ones_place) + bp -= 1 + while bp < 0: + bd = random.randint(0, 9) + self._bp_result += ",惩罚:%d" % bd + if dhr(bd, self._ones_place) > dhr(self._tens_place, self._ones_place): + self._tens_place = bd + self.set_result() + bp += 1 + return self._bp_result + + def a_check(self): + if not (self.a and self.anum and self.faces == 100 and self.dices == 1): + self._a_check_result = "" + return self._a_check_result + if self.result == 100: + self._a_check_result = " 大失败!" + elif self.anum < 50 and self.result > 95: + self._a_check_result = "\n检定值%d %d>95 大失败!" % ( + self.anum, self.result) + elif self.result == 1: + self._a_check_result = " 大成功!" + elif self.result <= self.anum // 5: + self._a_check_result = "\n检定值%d %d≤%d 极难成功" % ( + self.anum, self.result, self.anum // 5) + elif self.result <= self.anum // 2: + self._a_check_result = "\n检定值%d %d≤%d 困难成功" % ( + self.anum, self.result, self.anum // 2) + elif self.result <= self.anum: + self._a_check_result = "\n检定值%d %d≤%d 成功" % ( + self.anum, self.result, self.anum) + else: + self._a_check_result = "\n检定值%d %d>%d 失败" % ( + self.anum, self.result, self.anum) + return self._a_check_result + + def xdy(self): + self.result = 0 + if self.dices == 1: + self.real_dice() + self.bp_dice() + self.a_check() + return "" + else: + dice_results = [] + for _ in range(self.dices): + dice_result = self.real_dice() + dice_results.append(str(dice_result)) + return "(%s)" % "+".join(dice_results) + + def _ex_handle(self): + if not self.ex_dice: + self._ex_result = "" + elif type(self.ex_dice) == int: + ex_result = self.ex_dice_type*self.ex_dice + self._ex_result = "%s%s%d" % (str( + self.result) if self.dices == 1 else "", "+" if self.ex_dice_type == 1 else "-", self.ex_dice) + self.result += ex_result + elif type(self.ex_dice) == Dices: + self.ex_dice.roll + ex_result = self.ex_dice_type*self.ex_dice.result + self._ex_result = "%s%s%d" % (str( + self.result) if self.dices == 1 else "", "+" if self.ex_dice_type == 1 else "-", self.ex_dice) + self.result += ex_result + return self._ex_result + + def roll(self): + r = "%d次投掷:" % self.times + if self.times != 1: + r += "\n" + for _ in range(self.times): + xdyr = self.xdy() + self._ex_handle() + self._head = "%sD%d%s=" % ( + "" if self.dices == 1 else str(self.dices), + self.faces, + "" if not self.ex_dice else ( + ("+" if self.ex_dice_type == 1 else "-") + str(self.ex_dice) if type(self.ex_dice) == int else (str(self.ex_dice.dices)+"D"+self.ex_dice.faces)) + ) + self._mid = "%s%s=" % (xdyr, self._ex_result) + self._end = "%d%s%s" % ( + self.result, self._bp_result, self._a_check_result) + r += "%s%s%s" % (self._head, self._mid if self.dices != + 1 or self.ex_dice else "", self._end) + self.times -= 1 + if self.times: + r += "\n" + return r + + +def prework(args: list, start=0): + for i in range(start, len(args), 1): + if not re.search("\\d+", args[i]) and len(args[i]) > 1: + p = args.pop(i) + for j in list(p): + args.insert(i, j) + i += 1 + if prework(args, i): + break + return True + + +def rd(arg: str): + try: + h = False + dices = Dices() + args = re.split("(\\d+)", arg.lower()) + prework(args) + args = Mylist(args) + for i in range(len(args)): + if args[i] == "a": + dices.a = True + elif args[i] == "#" and re.search("\\d+", args.next(i)): + dices.times = int(args[i+1]) + elif args[i] == "b": + dices.bp += 1 + elif args[i] == "p": + dices.bp -= 1 + elif args[i] == "d" and re.search("\\d+", args.next(i)): + dices.faces = int(args[i+1]) + elif args[i] == " " and re.search("\\d+", args.next(i)) and dices.a: + dices.anum = int(args[i+1]) + elif args[i] == "h": + h = True + elif re.search("\\d+", args[i]): + if args.next(i) == "d": + dices.dices = int(args[i]) + elif args[i-1] == " " and dices.a: + dices.anum = int(args[i]) + elif args[i] in ["-", "+"]: + dices.ex_dice_type = (-1 if args[i] == "-" else 1) + if args.next(i+1) == "d": + dices.ex_dice = Dices() + dices.ex_dice.dices = int(args.next(i)) + dices.ex_dice.faces = int(args.next(i+2)) + elif args.next(i): + dices.ex_dice = int(args.next(i)) + if h: + return [dices.roll()] + return dices.roll() + except: + return r_help_message + + +if __name__ == "__main__": + rd("2d100") diff --git a/plugins/nonebot_plugin_cocdicer/madness.py b/plugins/nonebot_plugin_cocdicer/madness.py new file mode 100644 index 00000000..6fd85bb2 --- /dev/null +++ b/plugins/nonebot_plugin_cocdicer/madness.py @@ -0,0 +1,36 @@ +import random + +from .messages import temporary_madness, madness_end, phobias, manias + + +def ti(): + i = random.randint(1, 10) + r = "临时疯狂判定1D10=%d\n" % i + r += temporary_madness[i-1] + if i == 9: + j = random.randint(1, 100) + r += "\n恐惧症状为:\n" + r += phobias[j-1] + elif i == 10: + j = random.randint(1, 100) + r += "\n狂躁症状为:\n" + r += manias[j-1] + r += "\n该症状将会持续1D10=%d" % random.randint(1, 10) + return r + + +def li(): + i = random.randint(1, 10) + r = "总结疯狂判定1D10=%d\n" % i + r += madness_end[i-1] + if i in [2, 3, 6, 9, 10]: + r += "\n调查员将在1D10=%d小时后醒来" % random.randint(1, 10) + if i == 9: + j = random.randint(1, 100) + r += "\n恐惧症状为:\n" + r += phobias[j-1] + elif i == 10: + j = random.randint(1, 100) + r += "\n狂躁症状为:\n" + r += manias[j-1] + return r diff --git a/plugins/nonebot_plugin_cocdicer/messages.py b/plugins/nonebot_plugin_cocdicer/messages.py new file mode 100644 index 00000000..20883424 --- /dev/null +++ b/plugins/nonebot_plugin_cocdicer/messages.py @@ -0,0 +1,258 @@ +main_help_message: str = "本骰娘由nonebot2强力驱动\n" \ + ".r 投掷指令 todo\n" \ + " d 制定骰子面数\n" \ + " a 检定\n" \ + " h 暗骰\n" \ + " # 多轮检定\n" \ + " bp 奖励骰&惩罚骰\n" \ + " +/- 附加计算 todo\n" \ + ".sc 疯狂检定\n" \ + ".st 射击命中判定\n" \ + ".ti 临时疯狂症状\n" \ + ".li 总结疯狂症状\n" \ + ".coc coc角色作成\n" \ + ".en 技能成长" +r_help_message: str = ".r[dah#bp] a_number [+/-]ex_number\n" \ + "d:骰子设定指令,标准格式为xdy,x为骰子数量y为骰子面数;\n" \ + "a:检定指令,根据后续a_number设定数值检定;\n" \ + "h:暗骰指令,骰子结构将会私聊发送给该指令者;\n" \ + "#:多轮投掷指令,#后接数字即可设定多轮投掷;\n" \ + "bp:奖励骰与惩罚骰;\n" \ + "+/-:附加计算指令,目前仅支持数字\n" \ + "示例:\n" \ + ".r#2bba 70:两次投掷 1D100 ,附加两个奖励骰,判定值为70\n" \ + ".rah:D100暗骰,由于没有 a_number 参数,判定将被忽略\n" \ + ".ra2d8+10 70:2D8+10,由于非D100,判定将被忽略" +sc_help_message: str = ".sc success/failure san_number\n" \ + "success:判定成功降低 san 值,支持 x 或 xdy 语法( x 与 y 为数字);\n" \ + "failure:判定失败降低 san 值,支持语法如上;\n" \ + "san_number:当前 san 值。" +en_help_message: str = ".en skill_level\nskill_level:需要成长的技能当前等级。" +temporary_madness = [ + "1) 失忆: 调查员会发现自己身处于一个安全的地点却没有任何来到这里的记忆。例如,调查员前一刻还在家中吃着早饭,下一刻就已经直面着不知名的怪物。这将会持续1D10轮。", + "2) 假性残疾:调查员陷入了心理性的失明,失聪以及躯体缺失感中,持续1D10轮。", + "3) 暴力倾向: 调查员陷入了六亲不认的暴力行为中,对周围的敌人与友方进行着无差别的攻击,持续1D10轮。", + "4) 偏执: 调查员陷入了严重的偏执妄想之中,持续1D10轮。有人在暗中窥视着他们,同伴中有人背叛了他们,没有人可以信任,万事皆虚。", + "5) 人际依赖: 守密人适当参考调查员的背景中重要之人的条目,调查员因为一些原因而降他人误认为了他重要的人并且努力的会与那个人保持那种关系,持续1D10轮。", + "6) 昏厥: 调查员当场昏倒,并需要1D10轮才能苏醒。", + "7) 逃避行为: 调查员会用任何的手段试图逃离现在所处的位置,即使这意味着开走唯一一辆交通工具并将其它人抛诸脑后,调查员会试图逃离1D10轮。", + "8) 竭嘶底里:调查员表现出大笑,哭泣,嘶吼,害怕等的极端情绪表现,持续1D10轮。", + "9) 恐惧: 调查员通过一次D100或者由守密人选择,来从恐惧症状表中选择一个恐惧源,就算这一恐惧的事物是并不存在的,调查员的症状会持续1D10轮。", + "10) 躁狂: 调查员通过一次D100或者由守密人选择,来从躁狂症状表中选择一个躁狂的诱因,这个症状将会持续1D10轮。" +] +madness_end = [ + "1) 失忆(Amnesia):回过神来,调查员们发现自己身处一个陌生的地方,并忘记了自己是谁。记忆会随时间恢复。", + "2) 被窃(Robbed):调查员在1D10小时后恢复清醒,发觉自己被盗,身体毫发无损。如果调查员携带着宝贵之物(见调查员背景),做幸运检定来决定其是否被盗。所有有价值的东西无需检定自动消失。", + "3) 遍体鳞伤(Battered):调查员在1D10小时后恢复清醒,发现自己身上满是拳痕和瘀伤。生命值减少到疯狂前的一半,但这不会造成重伤。调查员没有被窃。这种伤害如何持续到现在由守秘人决定。", + "4) 暴力倾向(Violence):调查员陷入强烈的暴力与破坏欲之中。调查员回过神来可能会理解自己做了什么也可能毫无印象。调查员对谁或何物施以暴力,他们是杀人还是仅仅造成了伤害,由守秘人决定。", + "5) 极端信念(Ideology/Beliefs):查看调查员背景中的思想信念,调查员会采取极端和疯狂的表现手段展示他们的思想信念之一。比如一个信教者会在地铁上高声布道。", + "6) 重要之人(Significant People):考虑调查员背景中的重要之人,及其重要的原因。在1D10小时或更久的时间中,调查员将不顾一切地接近那个人,并为他们之间的关系做出行动。", + "7) 被收容(Institutionalized):调查员在精神病院病房或警察局牢房中回过神来,他们可能会慢慢回想起导致自己被关在这里的事情。", + "8) 逃避行为(Flee in panic):调查员恢复清醒时发现自己在很远的地方,也许迷失在荒郊野岭,或是在驶向远方的列车或长途汽车上。", + "9) 恐惧(Phobia):调查员患上一个新的恐惧症状。在表Ⅸ:恐惧症状表上骰1个D100来决定症状,或由守秘人选择一个。调查员在1D10小时后回过神来,并开始为避开恐惧源而采取任何措施。", + "10) 狂躁(Mania):调查员患上一个新的狂躁症状。在表Ⅹ:狂躁症状表上骰1个D100来决定症状,或由守秘人选择一个。调查员会在1D10小时后恢复理智。在这次疯狂发作中,调查员将完全沉浸于其新的狂躁症状。这症状是否会表现给旁人则取决于守秘人和此调查员。" +] +phobias = [ + "1) 洗澡恐惧症(Ablutophobia):对于洗涤或洗澡的恐惧。", + "2) 恐高症(Acrophobia):对于身处高处的恐惧。", + "3) 飞行恐惧症(Aerophobia):对飞行的恐惧。", + "4) 广场恐惧症(Agoraphobia):对于开放的(拥挤)公共场所的恐惧。", + "5) 恐鸡症(Alektorophobia):对鸡的恐惧。", + "6) 大蒜恐惧症(Alliumphobia):对大蒜的恐惧。", + "7) 乘车恐惧症(Amaxophobia):对于乘坐地面载具的恐惧。", + "8) 恐风症(Ancraophobia):对风的恐惧。", + "9) 男性恐惧症(Androphobia):对于成年男性的恐惧。", + "10) 恐英症(Anglophobia):对英格兰或英格兰文化的恐惧。", + "11) 恐花症(Anthophobia):对花的恐惧。", + "12) 截肢者恐惧症(Apotemnophobia):对截肢者的恐惧。", + "13) 蜘蛛恐惧症(Arachnophobia):对蜘蛛的恐惧。", + "14) 闪电恐惧症(Astraphobia):对闪电的恐惧。", + "15) 废墟恐惧症(Atephobia):对遗迹或残址的恐惧。", + "16) 长笛恐惧症(Aulophobia):对长笛的恐惧。", + "17) 细菌恐惧症(Bacteriophobia):对细菌的恐惧。", + "18) 导弹/子弹恐惧症(Ballistophobia):对导弹或子弹的恐惧。", + "19) 跌落恐惧症(Basophobia):对于跌倒或摔落的恐惧。", + "20) 书籍恐惧症(Bibliophobia):对书籍的恐惧。", + "21) 植物恐惧症(Botanophobia):对植物的恐惧。", + "22) 美女恐惧症(Caligynephobia):对美貌女性的恐惧。", + "23) 寒冷恐惧症(Cheimaphobia):对寒冷的恐惧。", + "24) 恐钟表症(Chronomentrophobia):对于钟表的恐惧。", + "25) 幽闭恐惧症(Claustrophobia):对于处在封闭的空间中的恐惧。", + "26) 小丑恐惧症(Coulrophobia):对小丑的恐惧。", + "27) 恐犬症(Cynophobia):对狗的恐惧。", + "28) 恶魔恐惧症(Demonophobia):对邪灵或恶魔的恐惧。", + "29) 人群恐惧症(Demophobia):对人群的恐惧。", + "30) 牙科恐惧症①(Dentophobia):对牙医的恐惧。", + "31) 丢弃恐惧症(Disposophobia):对于丢弃物件的恐惧(贮藏癖)。", + "32) 皮毛恐惧症(Doraphobia):对动物皮毛的恐惧。", + "33) 过马路恐惧症(Dromophobia):对于过马路的恐惧。", + "34) 教堂恐惧症(Ecclesiophobia):对教堂的恐惧。", + "35) 镜子恐惧症(Eisoptrophobia):对镜子的恐惧。", + "36) 针尖恐惧症(Enetophobia):对针或大头针的恐惧。", + "37) 昆虫恐惧症(Entomophobia):对昆虫的恐惧。", + "38) 恐猫症(Felinophobia):对猫的恐惧。", + "39) 过桥恐惧症(Gephyrophobia):对于过桥的恐惧。", + "40) 恐老症(Gerontophobia):对于老年人或变老的恐惧。", + "41) 恐女症(Gynophobia):对女性的恐惧。", + "42) 恐血症(Haemaphobia):对血的恐惧。", + "43) 宗教罪行恐惧症(Hamartophobia):对宗教罪行的恐惧。", + "44) 触摸恐惧症(Haphophobia):对于被触摸的恐惧。", + "45) 爬虫恐惧症(Herpetophobia):对爬行动物的恐惧。", + "46) 迷雾恐惧症(Homichlophobia):对雾的恐惧。", + "47) 火器恐惧症(Hoplophobia):对火器的恐惧。", + "48) 恐水症(Hydrophobia):对水的恐惧。", + "49) 催眠恐惧症(Hypnophobia):对于睡眠或被催眠的恐惧。", + "50) 白袍恐惧症(Iatrophobia):对医生的恐惧。", + "51) 鱼类恐惧症(Ichthyophobia):对鱼的恐惧。", + "52) 蟑螂恐惧症(Katsaridaphobia):对蟑螂的恐惧。", + "53) 雷鸣恐惧症(Keraunophobia):对雷声的恐惧。", + "54) 蔬菜恐惧症(Lachanophobia):对蔬菜的恐惧。", + "55) 噪音恐惧症(Ligyrophobia):对刺耳噪音的恐惧。", + "56) 恐湖症(Limnophobia):对湖泊的恐惧。", + "57) 机械恐惧症(Mechanophobia):对机器或机械的恐惧。", + "58) 巨物恐惧症(Megalophobia):对于庞大物件的恐惧。", + "59) 捆绑恐惧症(Merinthophobia):对于被捆绑或紧缚的恐惧。", + "60) 流星恐惧症(Meteorophobia):对流星或陨石的恐惧。", + "61) 孤独恐惧症(Monophobia):对于一人独处的恐惧。", + "62) 不洁恐惧症(Mysophobia):对污垢或污染的恐惧。", + "63) 黏液恐惧症(Myxophobia):对黏液(史莱姆)的恐惧。", + "64) 尸体恐惧症(Necrophobia):对尸体的恐惧。", + "65) 数字8恐惧症(Octophobia):对数字8的恐惧。", + "66) 恐牙症(Odontophobia):对牙齿的恐惧。", + "67) 恐梦症(Oneirophobia):对梦境的恐惧。", + "68) 称呼恐惧症(Onomatophobia):对于特定词语的恐惧。", + "69) 恐蛇症(Ophidiophobia):对蛇的恐惧。", + "70) 恐鸟症(Ornithophobia):对鸟的恐惧。", + "71) 寄生虫恐惧症(Parasitophobia):对寄生虫的恐惧。", + "72) 人偶恐惧症(Pediophobia):对人偶的恐惧。", + "73) 吞咽恐惧症(Phagophobia):对于吞咽或被吞咽的恐惧。", + "74) 药物恐惧症(Pharmacophobia):对药物的恐惧。", + "75) 幽灵恐惧症(Phasmophobia):对鬼魂的恐惧。", + "76) 日光恐惧症(Phenogophobia):对日光的恐惧。", + "77) 胡须恐惧症(Pogonophobia):对胡须的恐惧。", + "78) 河流恐惧症(Potamophobia):对河流的恐惧。", + "79) 酒精恐惧症(Potophobia):对酒或酒精的恐惧。", + "80) 恐火症(Pyrophobia):对火的恐惧。", + "81) 魔法恐惧症(Rhabdophobia):对魔法的恐惧。", + "82) 黑暗恐惧症(Scotophobia):对黑暗或夜晚的恐惧。", + "83) 恐月症(Selenophobia):对月亮的恐惧。", + "84) 火车恐惧症(Siderodromophobia):对于乘坐火车出行的恐惧。", + "85) 恐星症(Siderophobia):对星星的恐惧。", + "86) 狭室恐惧症(Stenophobia):对狭小物件或地点的恐惧。", + "87) 对称恐惧症(Symmetrophobia):对对称的恐惧。", + "88) 活埋恐惧症(Taphephobia):对于被活埋或墓地的恐惧。", + "89) 公牛恐惧症(Taurophobia):对公牛的恐惧。", + "90) 电话恐惧症(Telephonophobia):对电话的恐惧。", + "91) 怪物恐惧症①(Teratophobia):对怪物的恐惧。", + "92) 深海恐惧症(Thalassophobia):对海洋的恐惧。", + "93) 手术恐惧症(Tomophobia):对外科手术的恐惧。", + "94) 十三恐惧症(Triskadekaphobia):对数字13的恐惧症。", + "95) 衣物恐惧症(Vestiphobia):对衣物的恐惧。", + "96) 女巫恐惧症(Wiccaphobia):对女巫与巫术的恐惧。", + "97) 黄色恐惧症(Xanthophobia):对黄色或“黄”字的恐惧。", + "98) 外语恐惧症(Xenoglossophobia):对外语的恐惧。", + "99) 异域恐惧症(Xenophobia):对陌生人或外国人的恐惧。", + "100) 动物恐惧症(Zoophobia):对动物的恐惧。" +] +manias = [ + "1) 沐浴癖(Ablutomania):执着于清洗自己。", + "2) 犹豫癖(Aboulomania):病态地犹豫不定。", + "3) 喜暗狂(Achluomania):对黑暗的过度热爱。", + "4) 喜高狂(Acromaniaheights):狂热迷恋高处。", + "5) 亲切癖(Agathomania):病态地对他人友好。", + "6) 喜旷症(Agromania):强烈地倾向于待在开阔空间中。", + "7) 喜尖狂(Aichmomania):痴迷于尖锐或锋利的物体。", + "8) 恋猫狂(Ailuromania):近乎病态地对猫友善。", + "9) 疼痛癖(Algomania):痴迷于疼痛。", + "10) 喜蒜狂(Alliomania):痴迷于大蒜。", + "11) 乘车癖(Amaxomania):痴迷于乘坐车辆。", + "12) 欣快癖(Amenomania):不正常地感到喜悦。", + "13) 喜花狂(Anthomania):痴迷于花朵。", + "14) 计算癖(Arithmomania):狂热地痴迷于数字。", + "15) 消费癖(Asoticamania):鲁莽冲动地消费。", + "16) 隐居癖(Automania):过度地热爱独自隐居(原文如此,存疑,Automania实际上是恋车癖)。", + "17) 芭蕾癖(Balletmania):痴迷于芭蕾舞。", + "18) 窃书癖(Biliokleptomania):无法克制偷窃书籍的冲动。", + "19) 恋书狂(Bibliomania):痴迷于书籍和/或阅读。", + "20) 磨牙癖(Bruxomania):无法克制磨牙的冲动。", + "21) 灵臆症(Cacodemomania):病态地坚信自己已被一个邪恶的灵体占据。", + "22) 美貌狂(Callomania):痴迷于自身的美貌。", + "23) 地图狂(Cartacoethes):在何时何处都无法控制查阅地图的冲动。", + "24) 跳跃狂(Catapedamania):痴迷于从高处跳下。", + "25) 喜冷症(Cheimatomania):对寒冷或寒冷的物体的反常喜爱。", + "26) 舞蹈狂(Choreomania):无法控制地起舞或发颤。", + "27) 恋床癖(Clinomania):过度地热爱待在床上。", + "28) 恋墓狂(Coimetormania):痴迷于墓地。", + "29) 色彩狂(Coloromania):痴迷于某种颜色。", + "30) 小丑狂(Coulromania):痴迷于小丑。", + "31) 恐惧狂(Countermania):执着于经历恐怖的场面。", + "32) 杀戮癖(Dacnomania):痴迷于杀戮。", + "33) 魔臆症(Demonomania):病态地坚信自己已被恶魔附身。", + "34) 抓挠癖(Dermatillomania):执着于抓挠自己的皮肤。", + "35) 正义狂(Dikemania):痴迷于目睹正义被伸张。", + "36) 嗜酒狂(Dipsomania):反常地渴求酒精。", + "37) 毛皮狂(Doramania):痴迷于拥有毛皮。(存疑)", + "38) 赠物癖(Doromania):痴迷于赠送礼物。", + "39) 漂泊症(Drapetomania):执着于逃离。", + "40) 漫游癖(Ecdemiomania):执着于四处漫游。", + "41) 自恋狂(Egomania):近乎病态地以自我为中心或自我崇拜。", + "42) 职业狂(Empleomania):对于工作的无尽病态渴求。", + "43) 臆罪症(Enosimania):病态地坚信自己带有罪孽。", + "44) 学识狂(Epistemomania):痴迷于获取学识。", + "45) 静止癖(Eremiomania):执着于保持安静。", + "46) 乙醚上瘾(Etheromania):渴求乙醚。", + "47) 求婚狂(Gamomania):痴迷于进行奇特的求婚。", + "48) 狂笑癖(Geliomania):无法自制地,强迫性的大笑。", + "49) 巫术狂(Goetomania):痴迷于女巫与巫术。", + "50) 写作癖(Graphomania):痴迷于将每一件事写下来。", + "51) 裸体狂(Gymnomania):执着于裸露身体。", + "52) 妄想狂(Habromania):近乎病态地充满愉快的妄想(而不顾现实状况如何)。", + "53) 蠕虫狂(Helminthomania):过度地喜爱蠕虫。", + "54) 枪械狂(Hoplomania):痴迷于火器。", + "55) 饮水狂(Hydromania):反常地渴求水分。", + "56) 喜鱼癖(Ichthyomania):痴迷于鱼类。", + "57) 图标狂(Iconomania):痴迷于图标与肖像。", + "58) 偶像狂(Idolomania):痴迷于甚至愿献身于某个偶像。", + "59) 信息狂(Infomania):痴迷于积累各种信息与资讯。", + "60) 射击狂(Klazomania):反常地执着于射击。", + "61) 偷窃癖(Kleptomania):反常地执着于偷窃。", + "62) 噪音癖(Ligyromania):无法自制地执着于制造响亮或刺耳的噪音。", + "63) 喜线癖(Linonomania):痴迷于线绳。", + "64) 彩票狂(Lotterymania):极端地执着于购买彩票。", + "65) 抑郁症(Lypemania):近乎病态的重度抑郁倾向。", + "66) 巨石狂(Megalithomania):当站在石环中或立起的巨石旁时,就会近乎病态地写出各种奇怪的创意。", + "67) 旋律狂(Melomania):痴迷于音乐或一段特定的旋律。", + "68) 作诗癖(Metromania):无法抑制地想要不停作诗。", + "69) 憎恨癖(Misomania):憎恨一切事物,痴迷于憎恨某个事物或团体。", + "70) 偏执狂(Monomania):近乎病态地痴迷与专注某个特定的想法或创意。", + "71) 夸大癖(Mythomania):以一种近乎病态的程度说谎或夸大事物。", + "72) 臆想症(Nosomania):妄想自己正在被某种臆想出的疾病折磨。", + "73) 记录癖(Notomania):执着于记录一切事物(例如摄影)。", + "74) 恋名狂(Onomamania):痴迷于名字(人物的、地点的、事物的)。", + "75) 称名癖(Onomatomania):无法抑制地不断重复某个词语的冲动。", + "76) 剔指癖(Onychotillomania):执着于剔指甲。", + "77) 恋食癖(Opsomania):对某种食物的病态热爱。", + "78) 抱怨癖(Paramania):一种在抱怨时产生的近乎病态的愉悦感。", + "79) 面具狂(Personamania):执着于佩戴面具。", + "80) 幽灵狂(Phasmomania):痴迷于幽灵。", + "81) 谋杀癖(Phonomania):病态的谋杀倾向。", + "82) 渴光癖(Photomania):对光的病态渴求。", + "83) 背德癖(Planomania):病态地渴求违背社会道德(原文如此,存疑,Planomania实际上是漂泊症)。", + "84) 求财癖(Plutomania):对财富的强迫性的渴望。", + "85) 欺骗狂(Pseudomania):无法抑制的执着于撒谎。", + "86) 纵火狂(Pyromania):执着于纵火。", + "87) 提问狂(Questiong-Asking Mania):执着于提问。", + "88) 挖鼻癖(Rhinotillexomania):执着于挖鼻子。", + "89) 涂鸦癖(Scribbleomania):沉迷于涂鸦。", + "90) 列车狂(Siderodromomania):认为火车或类似的依靠轨道交通的旅行方式充满魅力。", + "91) 臆智症(Sophomania):臆想自己拥有难以置信的智慧。", + "92) 科技狂(Technomania):痴迷于新的科技。", + "93) 臆咒狂(Thanatomania):坚信自己已被某种死亡魔法所诅咒。", + "94) 臆神狂(Theomania):坚信自己是一位神灵。", + "95) 抓挠癖(Titillomaniac):抓挠自己的强迫倾向。", + "96) 手术狂(Tomomania):对进行手术的不正常爱好。", + "97) 拔毛癖(Trichotillomania):执着于拔下自己的头发。", + "98) 臆盲症(Typhlomania):病理性的失明。", + "99) 嗜外狂(Xenomania):痴迷于异国的事物。", + "100) 喜兽癖(Zoomania):对待动物的态度近乎疯狂地友好。" +] diff --git a/plugins/nonebot_plugin_cocdicer/san_check.py b/plugins/nonebot_plugin_cocdicer/san_check.py new file mode 100644 index 00000000..1b8b2570 --- /dev/null +++ b/plugins/nonebot_plugin_cocdicer/san_check.py @@ -0,0 +1,38 @@ +from .data_source import Dices +from .messages import sc_help_message + +import re + + +def number_or_dice(arg: str): + if "d" in arg: + d = Dices() + if dices := re.search(r"\d+d", arg): + d.dices = int(dices.group()[:-1]) + if faces := re.search(r"d\d+", arg): + d.faces = int(faces.group()[1:]) + d.roll() + return d + else: + return int(arg) + + +def sc(arg: str) -> str: + a_num = re.search(r" \d+", arg) + success = re.search(r"\d*d\d+|\d+", arg) + failure = re.search(r"[\/]+(\d*d\d+|\d+)", arg) + if not (a_num and success and failure): + return sc_help_message + check_dice = Dices() + check_dice.a = True + check_dice.anum = int(a_num.group()[1:]) + success = number_or_dice(success.group()) + failure = number_or_dice(failure.group()[1:]) + r = "San Check" + check_dice.roll()[4:] + result = success if check_dice.result <= check_dice.anum else failure + r += "\n理智降低了" + if type(result) == int: + r += "%d点" % result + else: + r = r + result._head + str(result.result) + return r diff --git a/plugins/nonebot_plugin_manager/__init__.py b/plugins/nonebot_plugin_manager/__init__.py new file mode 100644 index 00000000..30a2c3f5 --- /dev/null +++ b/plugins/nonebot_plugin_manager/__init__.py @@ -0,0 +1,110 @@ +from nonebot.plugin import on_shell_command, get_loaded_plugins, export +from nonebot.matcher import Matcher +from nonebot.typing import T_State +from nonebot.exception import IgnoredException +from nonebot.message import run_preprocessor +from nonebot.adapters.cqhttp import Event, Bot, GroupMessageEvent, PrivateMessageEvent +from configs.config import plugins2name_dict +from models.ban_user import BanUser +from .data import ( + block_plugin, + unblock_plugin, + get_group_plugin_list, + auto_update_plugin_list, +) +from .parser import npm_parser + +# 导出给其他插件使用 +export = export() +export.block_plugin = block_plugin +export.unblock_plugin = unblock_plugin +export.unblock_plugin = unblock_plugin +export.get_group_plugin_list = get_group_plugin_list + +# 注册 shell_like 事件响应器 +plugin_manager = on_shell_command("npm", parser=npm_parser, priority=1) + + +# 在 Matcher 运行前检测其是否启用 +@run_preprocessor +async def _(matcher: Matcher, bot: Bot, event: Event, state: T_State): + plugin = matcher.module + group_id = _get_group_id(event) + loaded_plugin_list = _get_loaded_plugin_list() + plugin_list = auto_update_plugin_list(loaded_plugin_list) + + # 无视本插件的 Matcher + if plugin not in plugins2name_dict or matcher.priority in [1, 9] or await BanUser.isban(event.user_id): + return + try: + if isinstance(event, PrivateMessageEvent) and plugin_list[plugin]["default"]: + return + except: + pass + + # print(matcher.module) + # print(f'plugin_list[plugin]["default"] = {plugin_list[plugin]["default"]}') + # print(f'{matcher.module} -> this is hook') + if not plugin_list[plugin]["default"]: + if event.message_type == 'group': + await bot.send_group_msg(group_id=event.group_id, message='此功能正在维护...') + else: + await bot.send_private_msg(user_id=event.user_id, message='此功能正在维护...') + raise IgnoredException(f"Nonebot Plugin Manager has blocked {plugin} !") + # print(plugin_list[plugin]) + # print(group_id) + # print(plugin_list[plugin][group_id]) + # print(not plugin_list[plugin][group_id]) + if group_id in plugin_list[plugin]: + if not plugin_list[plugin][group_id]: + if plugin != 'ai' and matcher.type == 'message': + await bot.send_group_msg(group_id=event.group_id, message='该群未开启此功能..') + raise IgnoredException(f"Nonebot Plugin Manager has blocked {plugin} !") + + +@plugin_manager.handle() +async def _(bot: Bot, event: Event, state: T_State): + args = state["args"] + group_id = _get_group_id(event) + is_admin = _is_admin(event) + is_superuser = _is_superuser(bot, event) + if group_id == 0: + group_id = 'default' + + if hasattr(args, "handle"): + await plugin_manager.finish(args.handle(args, group_id, is_admin, is_superuser)) + + +# 获取插件列表,并自动排除本插件 +def _get_loaded_plugin_list() -> list: + return list( + filter( + lambda plugin: plugin != "nonebot_plugin_manager", + map(lambda plugin: plugin.name, get_loaded_plugins()), + ) + ) + + +def _get_group_id(event: Event) -> str: + try: + group_id = event.group_id + except AttributeError: + group_id = "default" + return str(group_id) if group_id else "default" + + +def _is_admin(event: Event) -> bool: + return ( + event.sender.role in ["admin", "owner"] + if isinstance(event, GroupMessageEvent) + else False + ) + + +def _is_superuser(bot: Bot, event: Event) -> bool: + return str(event.user_id) in bot.config.superusers + + +plugins_dict = { + +} diff --git a/plugins/nonebot_plugin_manager/__pycache__/__init__.cpython-38.pyc b/plugins/nonebot_plugin_manager/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..ce945162 Binary files /dev/null and b/plugins/nonebot_plugin_manager/__pycache__/__init__.cpython-38.pyc differ diff --git a/plugins/nonebot_plugin_manager/__pycache__/__init__.cpython-39.pyc b/plugins/nonebot_plugin_manager/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 00000000..6d7a0f8c Binary files /dev/null and b/plugins/nonebot_plugin_manager/__pycache__/__init__.cpython-39.pyc differ diff --git a/plugins/nonebot_plugin_manager/__pycache__/data.cpython-38.pyc b/plugins/nonebot_plugin_manager/__pycache__/data.cpython-38.pyc new file mode 100644 index 00000000..adcdae69 Binary files /dev/null and b/plugins/nonebot_plugin_manager/__pycache__/data.cpython-38.pyc differ diff --git a/plugins/nonebot_plugin_manager/__pycache__/data.cpython-39.pyc b/plugins/nonebot_plugin_manager/__pycache__/data.cpython-39.pyc new file mode 100644 index 00000000..4fcf6459 Binary files /dev/null and b/plugins/nonebot_plugin_manager/__pycache__/data.cpython-39.pyc differ diff --git a/plugins/nonebot_plugin_manager/__pycache__/handle.cpython-38.pyc b/plugins/nonebot_plugin_manager/__pycache__/handle.cpython-38.pyc new file mode 100644 index 00000000..4f9dc5cf Binary files /dev/null and b/plugins/nonebot_plugin_manager/__pycache__/handle.cpython-38.pyc differ diff --git a/plugins/nonebot_plugin_manager/__pycache__/handle.cpython-39.pyc b/plugins/nonebot_plugin_manager/__pycache__/handle.cpython-39.pyc new file mode 100644 index 00000000..681d10ea Binary files /dev/null and b/plugins/nonebot_plugin_manager/__pycache__/handle.cpython-39.pyc differ diff --git a/plugins/nonebot_plugin_manager/__pycache__/parser.cpython-38.pyc b/plugins/nonebot_plugin_manager/__pycache__/parser.cpython-38.pyc new file mode 100644 index 00000000..1dabebd2 Binary files /dev/null and b/plugins/nonebot_plugin_manager/__pycache__/parser.cpython-38.pyc differ diff --git a/plugins/nonebot_plugin_manager/__pycache__/parser.cpython-39.pyc b/plugins/nonebot_plugin_manager/__pycache__/parser.cpython-39.pyc new file mode 100644 index 00000000..301f46fc Binary files /dev/null and b/plugins/nonebot_plugin_manager/__pycache__/parser.cpython-39.pyc differ diff --git a/plugins/nonebot_plugin_manager/data.py b/plugins/nonebot_plugin_manager/data.py new file mode 100644 index 00000000..56c0c486 --- /dev/null +++ b/plugins/nonebot_plugin_manager/data.py @@ -0,0 +1,121 @@ +import json +import httpx +from pathlib import Path +from configs.config import plugins2name_dict + +_DATA_PATH = Path() / "data" / "manager" / "plugin_list.json" + + +def get_store_plugin_info(plugin: str) -> str: + store_plugin_list = _get_store_plugin_list() + if plugin in store_plugin_list: + plugin = store_plugin_list[plugin] + return ( + f"ID: {plugin['id']}\n" + f"Name: {plugin['name']}\n" + f"Description: {plugin['desc']}\n" + f"Version: {httpx.get('https://pypi.org/pypi/'+plugin['link']+'/json').json()['info']['version']}\n" + f"Author: {plugin['author']}\n" + f"Repo: https://github.com/{plugin['repo']}" + ) + else: + return "查无此插件!" + + +def get_group_plugin_list(group_id: str) -> dict: + plugin_list = _load_plugin_list() + group_plugin_list = {} + for plugin in plugin_list: + if group_id in plugin_list[plugin]: + group_plugin_list[plugin] = plugin_list[plugin][group_id] + else: + group_plugin_list[plugin] = plugin_list[plugin]["default"] + return group_plugin_list + + +def get_store_pulgin_list() -> str: + message = "商店插件列表如下:" + for plugin in _get_store_plugin_list(): + if plugin in _load_plugin_list() or plugin == "nonebot_plugin_manager": + message += f"\n[o] {plugin}" + else: + message += f"\n[x] {plugin}" + return message + + +def auto_update_plugin_list(loaded_plugin_list: list, keep_history: bool = False): + plugin_list = _load_plugin_list() + for plugin in loaded_plugin_list: + if plugin not in plugin_list: + plugin_list[plugin] = {"default": True} + if not keep_history: + plugin_list = { + key: plugin_list[key] for key in plugin_list if key in loaded_plugin_list + } + _dump_plugin_list(plugin_list) + return plugin_list + + +def block_plugin(group_id: str, *plugins: str): + return _update_plugin_list(group_id, True, *plugins) + + +def unblock_plugin(group_id: str, *plugins: str): + return _update_plugin_list(group_id, False, *plugins) + + +# 获取商店插件列表 +def _get_store_plugin_list() -> dict: + store_plugin_list = {} + for plugin in httpx.get( + "https://cdn.jsdelivr.net/gh/nonebot/nonebot2@master/docs/.vuepress/public/plugins.json" + ).json(): + store_plugin_list.update({plugin["id"]: plugin}) + return store_plugin_list + + +# 更新插件列表 +def _update_plugin_list(group_id: str, block: bool, *plugins: str) -> str: + plugin_list = _load_plugin_list() + message = "结果如下:" + operate = "屏蔽" if block else "启用" + for plugin in plugins: + for values in plugins2name_dict.values(): + if plugin in values: + plugin = list(plugins2name_dict.keys())[list(plugins2name_dict.values()).index(values)] + # print(plugin) + break + message += "\n" + if plugin in plugin_list: + if ( + not group_id in plugin_list[plugin] + or plugin_list[plugin][group_id] == block + ): + plugin_list[plugin][group_id] = not block + message += f"插件{plugin}{operate}成功!" + print(plugin_list[plugin][group_id]) + else: + message += f"插件{plugin}已经{operate}!" + else: + message += f"插件{plugin}不存在!" + _dump_plugin_list(plugin_list) + return message + + +# 加载插件列表 +def _load_plugin_list() -> dict: + try: + return json.load(_DATA_PATH.open("r", encoding="utf-8")) + except FileNotFoundError: + return {} + + +# 保存插件列表 +def _dump_plugin_list(plugin_list: dict): + _DATA_PATH.parent.mkdir(parents=True, exist_ok=True) + json.dump( + plugin_list, + _DATA_PATH.open("w", encoding="utf-8"), + indent=4, + separators=(",", ": "), + ) diff --git a/plugins/nonebot_plugin_manager/handle.py b/plugins/nonebot_plugin_manager/handle.py new file mode 100644 index 00000000..1900ed2f --- /dev/null +++ b/plugins/nonebot_plugin_manager/handle.py @@ -0,0 +1,138 @@ +from argparse import Namespace + +from .data import * + + +def handle_list( + args: Namespace, + group_id: str, + is_admin: bool, + is_superuser: bool, +) -> str: + message = "" + + if args.store: + if is_superuser: + return get_store_pulgin_list() + else: + return "获取商店插件列表需要超级用户权限!" + + if args.default: + if is_superuser: + group_id = "default" + message += "默认" + else: + return "获取默认插件列表需要超级用户权限!" + + if args.group: + if is_superuser: + group_id = args.group + message += f"群{args.group}" + else: + return "获取指定群插件列表需要超级用户权限!" + + message += "插件列表如下:\n" + message += "\n".join( + f"[{'o' if get_group_plugin_list(group_id)[plugin] else 'x'}] {plugin}" + for plugin in get_group_plugin_list(group_id) + ) + return message + + +def handle_block( + args: Namespace, + group_id: str, + is_admin: bool, + is_superuser: bool, +) -> str: + + if not is_admin and not is_superuser: + return "管理插件需要群管理员权限!" + + message = "" + + if args.default: + if is_superuser: + group_id = "default" + message += "默认" + else: + return "管理默认插件需要超级用户权限!" + + if args.group: + if is_superuser: + group_id = args.group + message += f"群{args.group}" + else: + return "管理指定群插件需要超级用户权限!" + + message += block_plugin(group_id, *args.plugins) + return message + + +def handle_unblock( + args: Namespace, + group_id: str, + is_admin: bool, + is_superuser: bool, +) -> str: + message = "" + + if not is_admin and not is_superuser: + return "管理插件需要群管理员权限!" + + if args.default: + if is_superuser: + group_id = "default" + message += "默认" + else: + return "管理默认插件需要超级用户权限!" + + if args.group: + if is_superuser: + group_id = args.group + message += f"群{args.group}" + else: + return "管理指定群插件需要超级用户权限!" + + message += unblock_plugin(group_id, *args.plugins) + return message + + +def handle_info( + args: Namespace, + group_id: str, + is_admin: bool, + is_superuser: bool, +) -> str: + + if not is_admin and not is_superuser: + return "管理插件需要超级权限!" + + return get_store_plugin_info(args.plugin) + + +def handle_install( + args: Namespace, + group_id: str, + is_admin: bool, + is_superuser: bool, +) -> str: + pass + + +def handle_update( + args: Namespace, + group_id: str, + is_admin: bool, + is_superuser: bool, +) -> str: + pass + + +def handle_uninstall( + args: Namespace, + group_id: str, + is_admin: bool, + is_superuser: bool, +) -> str: + pass diff --git a/plugins/nonebot_plugin_manager/parser.py b/plugins/nonebot_plugin_manager/parser.py new file mode 100644 index 00000000..71d2455d --- /dev/null +++ b/plugins/nonebot_plugin_manager/parser.py @@ -0,0 +1,60 @@ +from nonebot.rule import ArgumentParser + +from .handle import * + +npm_parser = ArgumentParser("npm", add_help=False) +npm_parser.add_argument( + "-h", "--help", action="store_true", help="show this help message and exit" +) + +npm_subparsers = npm_parser.add_subparsers() + +list_parser = npm_subparsers.add_parser("list", help="show plugin list") +list_parser.add_argument( + "-s", "--store", action="store_true", help="show plugin store list" +) +list_parser.add_argument( + "-d", "--default", action="store_true", help="show default plugin list" +) +list_parser.add_argument("-g", "--group", action="store", help="show group plugin list") +list_parser.set_defaults(handle=handle_list) + +block_parser = npm_subparsers.add_parser("block", help="block plugin") +block_parser.add_argument("plugins", nargs="*", help="plugins you want to block") +block_parser.add_argument("-d", "--default", action="store_true", help="set default") +block_parser.add_argument("-a", "--all", action="store_true", help="select all plugin") +block_parser.add_argument("-g", "--group", action="store", help="set in group") +block_parser.set_defaults(handle=handle_block) + +unblock_parser = npm_subparsers.add_parser("unblock", help="unblock plugin") +unblock_parser.add_argument("plugins", nargs="*", help="plugins you want to unblock") +unblock_parser.add_argument("-d", "--default", action="store_true", help="set default") +unblock_parser.add_argument( + "-a", "--all", action="store_true", help="select all plugin" +) +unblock_parser.add_argument("-g", "--group", action="store", help="set in group") +unblock_parser.set_defaults(handle=handle_unblock) + +info_parser = npm_subparsers.add_parser("info", help="show plugin info") +info_parser.add_argument("plugin", help="plugins you want to know") +info_parser.set_defaults(handle=handle_info) + +install_parser = npm_subparsers.add_parser("install", help="install plugin") +install_parser.add_argument("plugins", nargs="*", help="plugins you want to install") +install_parser.add_argument("-i", "--index", action="store", help="point to a mirror") +install_parser.set_defaults(handle=handle_install) + +update_parser = npm_subparsers.add_parser("update", help="update plugin") +update_parser.add_argument("plugins", nargs="*", help="plugins you want to update") +update_parser.add_argument("-a", "--all", action="store_true", help="select all plugin") +update_parser.add_argument("-i", "--index", action="store", help="point to a mirror") +update_parser.set_defaults(handle=handle_update) + +uninstall_parser = npm_subparsers.add_parser("uninstall", help="uninstall plugin") +uninstall_parser.add_argument( + "plugins", nargs="*", help="plugins you want to uninstall" +) +uninstall_parser.add_argument( + "-a", "--all", action="store_true", help="select all plugin" +) +uninstall_parser.set_defaults(handle=handle_uninstall) diff --git a/plugins/nonebot_plugin_picsearcher/__init__.py b/plugins/nonebot_plugin_picsearcher/__init__.py new file mode 100644 index 00000000..4fb2ee55 --- /dev/null +++ b/plugins/nonebot_plugin_picsearcher/__init__.py @@ -0,0 +1,149 @@ +# -*- coding: utf-8 -*- +import traceback +from typing import Dict + +from aiohttp.client_exceptions import ClientError +from nonebot.plugin import on_command, on_message +from nonebot.adapters.cqhttp import Bot, MessageEvent, GroupMessageEvent +from nonebot.typing import T_State +from services.log import logger +from util.utils import get_message_text, get_message_imgs +from configs.config import MAX_FIND_IMG_COUNT + +from .ex import get_des as get_des_ex +from .iqdb import get_des as get_des_iqdb +from .saucenao import get_des as get_des_sau +from .ascii2d import get_des as get_des_asc +from .trace import get_des as get_des_trace +from .yandex import get_des as get_des_yandex + + +async def get_des(url: str, mode: str, user_id: int): + """ + :param url: 图片链接 + :param mode: 图源 + :return: + """ + if mode == "iqdb": + async for msg in get_des_iqdb(url): + yield msg + elif mode == "ex": + async for msg in get_des_ex(url): + yield msg + elif mode == "trace": + async for msg in get_des_trace(url): + yield msg + elif mode == "yandex": + async for msg in get_des_yandex(url): + yield msg + elif mode.startswith("asc"): + async for msg in get_des_asc(url, user_id): + yield msg + else: + async for msg in get_des_sau(url, user_id): + yield msg + + +setu = on_command("识图", aliases={"search"}, block=True, priority=5) + + +@setu.handle() +async def handle_first_receive(bot: Bot, event: MessageEvent, state: T_State): + msg = get_message_text(event.json()) + imgs = get_message_imgs(event.json()) + if msg in ['帮助']: + await setu.finish('示例:\n\t识图 (图片)\n\t识图asc (图片)') + if imgs: + state["setu"] = imgs[0] + if msg: + state["mod"] = msg + + +# ex/nao/trace/iqdb/ascii2d +# @setu.got("mod", prompt="从哪里查找呢? ex/nao/trace/iqdb/ascii2d") +# async def get_func(bot: Bot, event: MessageEvent, state: dict): +# pass + +@setu.args_parser +async def get_setu(bot: Bot, event: MessageEvent, state: T_State): + imgs = get_message_imgs(event.json()) + msg = get_message_text(event.json()) + if not imgs: + await setu.reject() + if msg: + state['mod'] = msg + state["setu"] = imgs[0] + + +@setu.got("setu", prompt="图呢?") +async def get_setu(bot: Bot, event: MessageEvent, state: T_State): + """ + 发现没有的时候要发问 + :return: + """ + url: str = state["setu"] + mod: str = state["mod"] if state.get("mod") else "nao" # 模式 + try: + await bot.send(event=event, message="正在处理图片") + idx = 1 + async for msg in get_des(url, mod, event.user_id): + await bot.send(event=event, message=msg) + if idx == MAX_FIND_IMG_COUNT: + break + idx += 1 + logger.info(f"(USER {event.user_id}, GROUP " + f"{event.group_id if event.message_type != 'private' else 'private'}) 识图:{url}") + # image_data: List[Tuple] = await get_pic_from_url(url) + # await setu.finish("hso") + except IndexError: + # await bot.send(event, traceback.format_exc()) + await setu.finish("参数错误") + except ClientError: + await setu.finish("连接失败") + + +pic_map: Dict[str, str] = {} # 保存这个群的其阿金一张色图 {"123456":http://xxx"} + + +async def check_pic(bot: Bot, event: MessageEvent, state: T_State) -> bool: + if isinstance(event, MessageEvent): + for msg in event.message: + if msg.type == "image": + url: str = msg.data["url"] + state["url"] = url + return True + return False + + +notice_pic = on_message(check_pic, block=False, priority=1) + + +@notice_pic.handle() +async def handle_pic(bot: Bot, event: GroupMessageEvent, state: T_State): + try: + group_id: str = str(event.group_id) + pic_map.update({group_id: state["url"]}) + except AttributeError: + pass + + +previous = on_command("上一张图是什么", aliases={"上一张", "这是什么"}) + + +@previous.handle() +async def handle_previous(bot: Bot, event: GroupMessageEvent, state: T_State): + await bot.send(event=event, message="processing...") + try: + url: str = pic_map[str(event.group_id)] + idx = 1 + async for msg in get_des(url, "nao", event.user_id): + await bot.send(event=event, message=msg) + if idx == MAX_FIND_IMG_COUNT: + break + idx += 1 + except IndexError: + await previous.finish("参数错误") + except ClientError: + await previous.finish("连接错误") + except KeyError: + await previous.finish("没有图啊QAQ") diff --git a/plugins/nonebot_plugin_picsearcher/__pycache__/__init__.cpython-39.pyc b/plugins/nonebot_plugin_picsearcher/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 00000000..44e61484 Binary files /dev/null and b/plugins/nonebot_plugin_picsearcher/__pycache__/__init__.cpython-39.pyc differ diff --git a/plugins/nonebot_plugin_picsearcher/__pycache__/ascii2d.cpython-39.pyc b/plugins/nonebot_plugin_picsearcher/__pycache__/ascii2d.cpython-39.pyc new file mode 100644 index 00000000..d4e82141 Binary files /dev/null and b/plugins/nonebot_plugin_picsearcher/__pycache__/ascii2d.cpython-39.pyc differ diff --git a/plugins/nonebot_plugin_picsearcher/__pycache__/ex.cpython-39.pyc b/plugins/nonebot_plugin_picsearcher/__pycache__/ex.cpython-39.pyc new file mode 100644 index 00000000..0fda775b Binary files /dev/null and b/plugins/nonebot_plugin_picsearcher/__pycache__/ex.cpython-39.pyc differ diff --git a/plugins/nonebot_plugin_picsearcher/__pycache__/formdata.cpython-39.pyc b/plugins/nonebot_plugin_picsearcher/__pycache__/formdata.cpython-39.pyc new file mode 100644 index 00000000..42824c48 Binary files /dev/null and b/plugins/nonebot_plugin_picsearcher/__pycache__/formdata.cpython-39.pyc differ diff --git a/plugins/nonebot_plugin_picsearcher/__pycache__/iqdb.cpython-39.pyc b/plugins/nonebot_plugin_picsearcher/__pycache__/iqdb.cpython-39.pyc new file mode 100644 index 00000000..76b42d3e Binary files /dev/null and b/plugins/nonebot_plugin_picsearcher/__pycache__/iqdb.cpython-39.pyc differ diff --git a/plugins/nonebot_plugin_picsearcher/__pycache__/saucenao.cpython-39.pyc b/plugins/nonebot_plugin_picsearcher/__pycache__/saucenao.cpython-39.pyc new file mode 100644 index 00000000..838941ff Binary files /dev/null and b/plugins/nonebot_plugin_picsearcher/__pycache__/saucenao.cpython-39.pyc differ diff --git a/plugins/nonebot_plugin_picsearcher/__pycache__/trace.cpython-39.pyc b/plugins/nonebot_plugin_picsearcher/__pycache__/trace.cpython-39.pyc new file mode 100644 index 00000000..2b5c289a Binary files /dev/null and b/plugins/nonebot_plugin_picsearcher/__pycache__/trace.cpython-39.pyc differ diff --git a/plugins/nonebot_plugin_picsearcher/__pycache__/yandex.cpython-39.pyc b/plugins/nonebot_plugin_picsearcher/__pycache__/yandex.cpython-39.pyc new file mode 100644 index 00000000..f2797bf1 Binary files /dev/null and b/plugins/nonebot_plugin_picsearcher/__pycache__/yandex.cpython-39.pyc differ diff --git a/plugins/nonebot_plugin_picsearcher/ascii2d.py b/plugins/nonebot_plugin_picsearcher/ascii2d.py new file mode 100644 index 00000000..941e9d0e --- /dev/null +++ b/plugins/nonebot_plugin_picsearcher/ascii2d.py @@ -0,0 +1,63 @@ +# -*- coding: utf-8 -*- +from typing import List, Tuple +from urllib.parse import urljoin +import aiofiles +from util.utils import get_local_proxy +from util.user_agent import get_user_agent +from configs.path_config import IMAGE_PATH +from asyncio.exceptions import TimeoutError +from util.init_result import image + +from lxml.html import fromstring +import aiohttp + + +def parse_html(html: str): + selector = fromstring(html) + for tag in selector.xpath('//div[@class="container"]/div[@class="row"]/div/div[@class="row item-box"]')[1:5]: + if pic_url := tag.xpath('./div/img[@loading="lazy"]/@src'): # 缩略图url + pic_url = urljoin("https://ascii2d.net/", pic_url[0]) + if description := tag.xpath('./div/div/h6/a[1]/text()'): # 名字 + description = description[0] + if author := tag.xpath('./div/div/h6/a[2]/text()'): # 作者 + author = author[0] + if origin_url := tag.xpath('./div/div/h6/a[1]/@href'): # 原图地址 + origin_url = origin_url[0] + if author_url := tag.xpath('./div/div/h6/a[2]/@href'): # 作者地址 + author_url = author_url[0] + yield pic_url, description, author, origin_url, author_url + + pass + + +async def get_pic_from_url(url: str): + real_url = "https://ascii2d.net/search/url/" + url + async with aiohttp.ClientSession() as session: + async with session.get(real_url) as resp: + html: str = await resp.text() + return [i for i in parse_html(html)] + + +async def get_des(url: str, user_id): + image_data: List[Tuple] = await get_pic_from_url(url) + if not image_data: + msg: str = "找不到高相似度的" + yield msg + return + for pic in image_data: + msg = await download_img(pic[0], user_id) + "\n" + for i in pic[1:]: + msg = msg + f"{i}\n" + yield msg + + +async def download_img(url, user_id): + try: + async with aiohttp.ClientSession(headers=get_user_agent()) as session: + async with session.get(url, proxy=get_local_proxy(), timeout=7) as response: + async with aiofiles.open(IMAGE_PATH + f'temp/{user_id}_pic_find.png', 'wb') as f: + await f.write(await response.read()) + return image(f'{user_id}_pic_find.png', 'temp') + except TimeoutError: + return image(url) + diff --git a/plugins/nonebot_plugin_picsearcher/ex.py b/plugins/nonebot_plugin_picsearcher/ex.py new file mode 100644 index 00000000..172ac391 --- /dev/null +++ b/plugins/nonebot_plugin_picsearcher/ex.py @@ -0,0 +1,107 @@ +# -*- coding: utf-8 -*- +from base64 import b64encode +from typing import List, Tuple +import io + +from lxml.html import fromstring +import aiohttp +import nonebot +from aiohttp.client_exceptions import InvalidURL +from nonebot.adapters.cqhttp import MessageSegment + +from .formdata import FormData + +driver = nonebot.get_driver() +cookie: str = driver.config.ex_cookie +proxy: str = driver.config.proxy +target: str = "https://exhentai.org/upload/image_lookup.php" + +headers = { + 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', + 'Accept-Encoding': 'gzip, deflate', + 'Accept-Language': 'zh-CN,zh;q=0.9', + 'Cache-Control': 'max-age=0', + 'Connection': 'keep-alive', + 'Content-Type': 'multipart/form-data; boundary=----WebKitFormBoundaryB0NrMSYMfjY5r0l1', + 'Host': 'exhentai.org', + 'Origin': 'https://exhentai.org', + 'Referer': 'https://exhentai.org/?filesearch=1', + 'Sec-Fetch-Dest': 'document', + 'Sec-Fetch-Mode': 'navigate', + 'Sec-Fetch-Site': 'same-origin', + 'Sec-Fetch-User': '?1', + 'Upgrade-Insecure-Requests': '1', + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36'} + +if cookie: + headers['Cookie'] = cookie +else: + headers['Host'] = 'e-hentai.org' + headers['Origin'] = 'https://e-hentai.org' + headers['Referer'] = 'https://e-hentai.org/?filesearch=1' + target: str = "https://e-hentai.org/upload/image_lookup.php" + + +def parse_html(html: str): + """ + 解析exhentai返回的数据 + :param html: + :return: + """ + selector = fromstring(html) + hrefs = selector.xpath('//td[@class="gl3c glname"]/a/@href') + names = selector.xpath('//td[@class="gl3c glname"]/a/div[1]/text()') + pics = selector.xpath('//tr/td[@class="gl2c"]/div[@class="glthumb"]/div[1]/img/@src') # 缩略图 + for name, href, pic in zip(names, hrefs, pics): + yield name, href, pic + + +async def get_pic_from_url(url: str): + """ + 从接受到的picurl获取图片信息 + :param url: + :return: + """ + async with aiohttp.ClientSession() as session: + async with session.get(url) as resp: + content = io.BytesIO(await resp.read()) + # Content_Length = resp.content_length + data = FormData(boundary="----WebKitFormBoundaryB0NrMSYMfjY5r0l1") + data.add_field(name="sfile", value=content, content_type="image/jpeg", + filename="0.jpg") + data.add_field(name="f_sfile", value="search") + data.add_field(name="fs_similar", value="on") + async with session.post(target, data=data, headers=headers, proxy=proxy) as res: + html = await res.text() + return [i for i in parse_html(html)] + + +async def get_content_from_url(url: str): + """ + 从url 获得b64 encode + :param url: + :return: + """ + try: + async with aiohttp.ClientSession() as session: + async with session.get(url, headers=headers) as resp: + return "base64://" + b64encode(await resp.read()).decode() + except aiohttp.client_exceptions.InvalidURL: + return url + + +async def get_des(url: str): + """ + 迭代要发送的信息 + :param url: + :return: + """ + image_data: List[Tuple] = await get_pic_from_url(url) + if not image_data: + msg: str = "找不到高相似度的" + yield msg + return + for name, href, pic_url in image_data: + content = await get_content_from_url(pic_url) + msg = MessageSegment.image(file=content) + f"\n本子名称:{name}\n" + f"链接{href}\n" + yield msg diff --git a/plugins/nonebot_plugin_picsearcher/formdata.py b/plugins/nonebot_plugin_picsearcher/formdata.py new file mode 100644 index 00000000..f70f040e --- /dev/null +++ b/plugins/nonebot_plugin_picsearcher/formdata.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +from typing import Any, Iterable, List, Optional + +from aiohttp import FormData as _FormData +import aiohttp.multipart as multipart + + +class FormData(_FormData): + def __init__( + self, + fields: Iterable[Any] = (), + quote_fields: bool = True, + charset: Optional[str] = None, + boundary: Optional[str] = None + ) -> None: + self._writer = multipart.MultipartWriter("form-data", boundary=boundary) + self._fields = [] # type: List[Any] + self._is_multipart = False + self._is_processed = False + self._quote_fields = quote_fields + self._charset = charset + + if isinstance(fields, dict): + fields = list(fields.items()) + elif not isinstance(fields, (list, tuple)): + fields = (fields,) + self.add_fields(*fields) diff --git a/plugins/nonebot_plugin_picsearcher/iqdb.py b/plugins/nonebot_plugin_picsearcher/iqdb.py new file mode 100644 index 00000000..60b9f934 --- /dev/null +++ b/plugins/nonebot_plugin_picsearcher/iqdb.py @@ -0,0 +1,79 @@ +# -*- coding: utf-8 -*- +import asyncio +from typing import List, Tuple +import io + +from urllib.parse import urljoin +from lxml.html import fromstring +import aiohttp +from nonebot.adapters.cqhttp import MessageSegment + +from .formdata import FormData + +headers = { + 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', + 'Accept-Encoding': 'gzip, deflate', 'Accept-Language': 'zh-CN,zh;q=0.9', 'Cache-Control': 'max-age=0', + 'Connection': 'keep-alive', + 'Content-Type': 'multipart/form-data; boundary=----WebKitFormBoundaryuwjSiBcpPag4k159', + 'Cookie': 'Hm_lvt_765ecde8c11b85f1ac5f168fa6e6821f=1602471368; Hm_lpvt_765ecde8c11b85f1ac5f168fa6e6821f=1602472300', + 'Host': 'iqdb.org', 'Origin': 'http://iqdb.org', 'Referer': 'http://iqdb.org/', 'Upgrade-Insecure-Requests': '1', + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36'} + + +def parse_html(html: str): + selector = fromstring(html) + for tag in selector.xpath('//div[@id="pages"]/div[position()>1]/table'): + # 第一个是bestmatch + if pic_url := tag.xpath('./tr[2]/td/a/img/@src'): + pic_url = urljoin("http://iqdb.org/", pic_url[0]) # 缩略图 + else: + pic_url = "没有最相似的" + similarity = tag.xpath('./tr[last()]/td/text()')[0] # 相似度 + href: List[str] = tag.xpath('./tr/td/a/@href') # 第一个href + href.extend(tag.xpath('./tr/td/span/a/@href')) # 第二个 可能是空 + href = list(map(lambda x: "https:" + x if not x.startswith("https") else x, href)) + yield pic_url, similarity, href + + pass + + +async def get_pic_from_url(url: str): + """ + 返回信息元祖 + :param url: + :return: + """ + async with aiohttp.ClientSession() as session: + async with session.get(url) as resp: + content = io.BytesIO(await resp.read()) + data = FormData(boundary="----WebKitFormBoundaryuwjSiBcpPag4k159") + data.add_field(name="MAX_FILE_SIZE", value="") + for i in range(1, 7): + data.add_field(name="service[]", value=str(i)) + data.add_field(name="service[]", value="11") + data.add_field(name="service[]", value="13") + data.add_field(name="file", value=content, content_type="application/octet-stream", filename="0.jpg") + data.add_field(name="url", value="") + async with session.post("http://iqdb.org/", data=data, headers=headers) as res: + html = await res.text() + return [i for i in parse_html(html)] + pass + + +async def get_des(url: str): + """ + 返回详细简介 cq码转义 + :param url: + :return: + """ + image_data: List[Tuple] = await get_pic_from_url(url) + if not image_data: + msg: str = "找不到高相似度的" + yield msg + return + for pic in image_data: + msg = MessageSegment.image(file=pic[0]) + f"\n{pic[1]}\n" + for i in pic[2]: + msg = msg + f"{i}\n" + yield msg + diff --git a/plugins/nonebot_plugin_picsearcher/saucenao.py b/plugins/nonebot_plugin_picsearcher/saucenao.py new file mode 100644 index 00000000..14987b83 --- /dev/null +++ b/plugins/nonebot_plugin_picsearcher/saucenao.py @@ -0,0 +1,116 @@ +# -*- coding: utf-8 -*- +import io +from typing import List, Tuple, Union +import aiofiles +from util.utils import get_local_proxy +from util.user_agent import get_user_agent +from configs.path_config import IMAGE_PATH +from asyncio.exceptions import TimeoutError +from util.init_result import image + +import aiohttp +from lxml.html import fromstring +from nonebot.adapters.cqhttp import Message + +from .formdata import FormData + +header = { + 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', + 'Accept-Encoding': 'gzip, deflate', 'Accept-Language': 'zh-CN,zh;q=0.9', + 'Cache-Control': 'max-age=0', + "Content-Type": "multipart/form-data; boundary=----WebKitFormBoundaryPpuR3EZ1Ap2pXv8W", + 'Connection': 'keep-alive', + 'Host': 'saucenao.com', 'Origin': 'https://saucenao.com', 'Referer': 'https://saucenao.com/index.php', + 'Sec-Fetch-Dest': 'document', 'Sec-Fetch-Mode': 'navigate', 'Sec-Fetch-Site': 'same-origin', 'Sec-Fetch-User': '?1', + 'Upgrade-Insecure-Requests': '1', + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36'} + + +def parse_html(html: str): + """ + 解析nao返回的html + :param html: + :return: + """ + selector = fromstring(html) + for tag in selector.xpath('//div[@class="result"]/table'): + pic_url = tag.xpath('./tr/td/div/a/img/@src') + if pic_url: + pic_url = pic_url[0] + else: + pic_url = None # 相似度 + xsd: List[str] = tag.xpath( + './tr/td[@class="resulttablecontent"]/div[@class="resultmatchinfo"]/div[@class="resultsimilarityinfo"]/text()') + if xsd: + xsd = xsd[0] + else: + xsd = "没有写" # 相似度 + title: List[str] = tag.xpath( + './tr/td[@class="resulttablecontent"]/div[@class="resultcontent"]/div[@class="resulttitle"]/strong/text()') + if title: + title = title[0] + else: + title = "没有写" # 标题 + # pixiv id + pixiv_id: List[str] = tag.xpath( + './tr/td[@class="resulttablecontent"]/div[@class="resultcontent"]/div[@class="resultcontentcolumn"]/a[1]/@href') + if pixiv_id: + pixiv_id = pixiv_id[0] + else: + pixiv_id = "没有说" + member: List[str] = tag.xpath( + './tr/td[@class="resulttablecontent"]/div[@class="resultcontent"]/div[@class="resultcontentcolumn"]/a[2]/@href') + if member: + member = member[0] + else: + member = "没有说" + yield pic_url, xsd, title, pixiv_id, member + + +async def get_pic_from_url(url: str): + """ + 从url搜图 + :param url: + :return: + """ + async with aiohttp.ClientSession() as session: + async with session.get(url) as resp: + content = io.BytesIO(await resp.read()) + data = FormData(boundary="----WebKitFormBoundaryPpuR3EZ1Ap2pXv8W") + data.add_field(name="file", value=content, content_type="image/jpeg", + filename="blob") + async with session.post("https://saucenao.com/search.php", data=data, headers=header) as res: + html = await res.text() + image_data = [each for each in parse_html(html)] + return image_data + + +async def get_des(url: str, user_id: int): + image_data: List[Tuple] = await get_pic_from_url(url) + if not image_data: + msg: Union[str, Message] = "找不到高相似度的" + yield msg + return + for pic in image_data: + # print(pic) + msg = await download_img(pic[0], user_id) \ + + f"\n相似度:{pic[1]}" \ + f"\n标题:{pic[2] if (str(pic[2]).strip() != 'Creator:' and len(str(pic[2]).split('-')) < 3) else '未知'}" \ + f"\nPID:{pic[3]}" \ + f"\nmember:{pic[4]}\n" + yield msg + pass + + +async def download_img(url, user_id): + try: + async with aiohttp.ClientSession(headers=get_user_agent()) as session: + async with session.get(url, proxy=get_local_proxy(), timeout=7) as response: + async with aiofiles.open(IMAGE_PATH + f'temp/{user_id}_pic_find.png', 'wb') as f: + await f.write(await response.read()) + return image(f'{user_id}_pic_find.png', 'temp') + except TimeoutError: + return image(url) + + + diff --git a/plugins/nonebot_plugin_picsearcher/trace.py b/plugins/nonebot_plugin_picsearcher/trace.py new file mode 100644 index 00000000..0c28d2f2 --- /dev/null +++ b/plugins/nonebot_plugin_picsearcher/trace.py @@ -0,0 +1,89 @@ +# -*- coding: utf-8 -*- +import io +from copy import deepcopy + +from base64 import b64encode +from typing import List, Tuple + +import aiohttp +from nonebot.adapters.cqhttp import MessageSegment + +header = {':authority': 'api.trace.moe', + 'accept': '*/*', + 'accept-encoding': 'gzip, deflate, br', + 'accept-language': 'zh-CN,zh;q=0.9', + 'content-type': 'multipart/form-data; boundary=----WebKitFormBoundary9cyjY8YBBN8SGdG4', + 'origin': 'https://trace.moe', + 'sec-fetch-dest': 'empty', 'sec-fetch-mode': 'cors', 'sec-fetch-site': 'same-site', + 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) ' + 'Chrome/84.0.4147.105 Safari/537.36'} + + +async def parse_json(session: aiohttp.ClientSession, data: dict): + count = 0 + for i in data["result"]: + title: dict = i["anilist"]["title"] + similarity = i["similarity"] + from_ = i["from"] + to = i["to"] + file = i["filename"] # 名字 + is_adult = i["anilist"]["isAdult"] + episode = i["episode"] # 集 + header_new = deepcopy(header) + del header_new["content-type"] + header_new[":method"] = 'GET' + header_new["accept"] = "image/webp,image/apng,image/*,*/*;q=0.8" + header_new["sec-fetch-dest"] = "image" + header_new["sec-fetch-mode"] = "no-cors" + async with session.get(i["image"], headers=header_new) as resp: + pic = "base64://" + b64encode(await resp.read()).decode() + yield pic, similarity, file, is_adult, from_, to, title, episode + count += 1 + if count > 4: + break + + +# POST https://api.trace.moe/search?cutBorders=1&anilistID= +async def get_pic_from_url(url: str): + """ + 从url搜图 + :param url: + :return: + """ + async with aiohttp.ClientSession() as session: + async with session.get(url) as resp: + content = io.BytesIO(await resp.read()) + # with open("F:\elu.PNG", "rb") as f: + # content = io.BytesIO(f.read()) + data = aiohttp.FormData(boundary="----WebKitFormBoundary9cyjY8YBBN8SGdG4") + data.add_field(name="image", value=content, content_type="image/jpeg", + filename="blob") + # data.add_field(name="filter", value="") + # data.add_field(name="trial", value="0") + async with session.post("https://api.trace.moe/search?cutBorders=1&anilistID=", data=data, + headers=header) as res: + data: dict = await res.json() + image_data = [each async for each in parse_json(session, data)] + return image_data + + +async def get_des(url: str): + image_data: List[Tuple] = await get_pic_from_url(url) + if not image_data: + msg: str = "找不到高相似度的" + yield msg + return + for pic in image_data: + msg = MessageSegment.image( + file=pic[ + 0]) + f"\n相似度:{pic[1]}%\n标题:{pic[6]['native'] + ' ' + pic[6]['chinese']}\n第{pic[7]}集\nR18:{pic[3]}\n开始时间:{pic[4]}s\n结束时间{pic[5]}s" + yield msg + pass + + +if __name__ == "__main__": + import asyncio + + data = asyncio.run(get_pic_from_url( + "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1606681978562&di=6d6c90aef5ff1f9f8915bbc2e18e3c98&imgtype=0&src=http%3A%2F%2Fc-ssl.duitang.com%2Fuploads%2Fblog%2F202011%2F15%2F20201115190356_c5b95.thumb.1000_0.jpg")) + pass diff --git a/plugins/nonebot_plugin_picsearcher/yandex.py b/plugins/nonebot_plugin_picsearcher/yandex.py new file mode 100644 index 00000000..0632e442 --- /dev/null +++ b/plugins/nonebot_plugin_picsearcher/yandex.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +from typing import List, Tuple + +import nonebot +from nonebot.adapters.cqhttp import MessageSegment +from lxml.html import fromstring +import aiohttp + +""" +http://yandex.com/clck/jsredir?from=yandex.com%3Bimages%2Fsearch%3Bimages%3B%3B&text=&etext=9185.K4iyzsNBG9xrJrSJCUTF4i-XPMAfmBQYR_Igss1ESRc.65568e796f3375fae39da91273ae8a1a82410929&uuid=&state=iric5OQ0sS2054x1_o8yG9mmGMT8WeQxqpuwa4Ft4KVzd9aE_Y4Dfw,,&data=eEwyM2lDYU9Gd1VROE1ZMXhZYkJTYW5fZC1TWjIzaFh5TmR1Z09fQm5DdDB3bFJSSUpVdUxfZmUzcVhfaXhTN1BCU2dINGxmdkY4NFVNcHYyUmw0emFKT2pnOWJoVmlPVzAzX1FIbWh6aXVFV3F0YWFaMGdxeGFtY2dxTzFZZl9VY1huZmlLaGVGOFZleUthZXBlM1pxUGM2elVDLXdvZEo3OGJwdVFqYmVkTDJxWElHSzFZR2NVQUhVcTdzelJwSXlrTjhlS0txdHpYY1RMMHRLOU5HSTYtT0VDb0hpdll6YjVYRXNVcUhCRFJaeDExNTQwZlhMdjh4M2YtTVFUbVJ5ZzBxMTVJcG9DNW51UWhvRzE0WjlFS19uS0VUZWhNRGxOZWlPUkFlRUUs&sign=7ba9ee25d3716868ec8464fb766c9e25&keyno=IMGS_0&b64e=2&l10n=en +""" + +driver = nonebot.get_driver() +proxy: str = driver.config.proxy + + +def parse_html(html: str): + selector = fromstring(html) + for item in selector.xpath('//li[@class="other-sites__item"]'): + pic_url = item.xpath('./a[@class="other-sites__preview-link"]/img/@src')[0].lstrip("//") # 图床 + des = item.xpath( + './div[@class="other-sites__snippet"]/div[@class="other-sites__snippet-title"]/a/text()')[0] # 简介 + url = item.xpath( + './div[@class="other-sites__snippet"]/div[@class="other-sites__snippet-site"]/a/@href')[0] # 链接 + yield pic_url, des, url + + +async def get_pic_from_url(url: str): + real_url = f"https://yandex.com/images/search?rpt=imageview&url={url}" + async with aiohttp.ClientSession() as session: + async with session.get(real_url, proxy=proxy) as resp: + html: str = await resp.text() + return [i for i in parse_html(html)] + + +async def get_des(url: str): + image_data: List[Tuple] = await get_pic_from_url(url) + if not image_data: + msg: str = "找不到高相似度的" + yield msg + return + for pic in image_data: + msg = MessageSegment.image(file=pic[0]) + "\n" + for i in pic[1:]: + msg = msg + f"{i}\n" + yield msg + + +if __name__ == "__main__": + with open("yandex.html", "r", encoding="utf-8") as f: + data = f.read() + for item in parse_html(data): + print(item) diff --git a/plugins/one_friend/__init__.py b/plugins/one_friend/__init__.py new file mode 100644 index 00000000..9be83244 --- /dev/null +++ b/plugins/one_friend/__init__.py @@ -0,0 +1,68 @@ +import json +import os +import aiohttp +from util.user_agent import get_user_agent +from io import BytesIO +from random import choice +from PIL import Image, ImageDraw, ImageFont +from nonebot import on_regex +from nonebot.typing import T_State +from nonebot.adapters.cqhttp import Bot, GroupMessageEvent +from util.utils import get_message_text, get_local_proxy +from util.img_utils import pic2b64 +from configs.path_config import TTF_PATH +import re +from nonebot.adapters.cqhttp import MessageSegment + +one_friend = on_regex('^我.*?朋友.*?(想问问|说|让我问问|想问|让我问|想知道|让我帮他问问|让我' + '帮他问|让我帮忙问|让我帮忙问问|问).*', priority=5, block=True) + + +async def get_pic(qq): + url = f'http://q1.qlogo.cn/g?b=qq&nk={qq}&s=100' + async with aiohttp.ClientSession(headers=get_user_agent()) as session: + async with session.get(url, proxy=get_local_proxy(), timeout=5) as response: + return await response.read() + + +@one_friend.handle() +async def _(bot: Bot, event: GroupMessageEvent, state: T_State): + arr = [] + member_list = await bot.get_group_member_list(self_id=event.self_id, group_id=event.group_id) + for member in member_list: + arr.append(member['user_id']) + msg = get_message_text(event.json()) + msg = re.search(r'^我.*?朋友.*?' + r'(想问问|说|让我问问|想问|让我问|想知道|让我帮他问问|让我帮他问|让我帮忙问|让我帮忙问问|问)(.*)', + msg) + msg = msg.group(2) + if not msg: + msg = '都不知道问什么' + msg = msg.replace('他', '我').replace('她', '我') + image = Image.open(BytesIO(await get_pic(choice(arr)))) + img_origin = Image.new('RGBA', (100, 100), (255, 255, 255)) + scale = 3 + # 使用新的半径构建alpha层 + r = 100 * scale + alpha_layer = Image.new('L', (r, r), 0) + draw = ImageDraw.Draw(alpha_layer) + draw.ellipse((0, 0, r, r), fill=255) + # 使用ANTIALIAS采样器缩小图像 + alpha_layer = alpha_layer.resize((100, 100), Image.ANTIALIAS) + img_origin.paste(image, (0, 0), alpha_layer) + + # 创建Font对象: + font = ImageFont.truetype(os.path.join(os.path.dirname(__file__), TTF_PATH + 'yz.ttf'), 30) + font2 = ImageFont.truetype(os.path.join(os.path.dirname(__file__), TTF_PATH + 'yz.ttf'), 25) + + # 创建Draw对象: + image_text = Image.new('RGB', (450, 150), (255, 255, 255)) + draw = ImageDraw.Draw(image_text) + draw.text((0, 0), '朋友', fill=(0, 0, 0), font=font) + draw.text((0, 40), msg, fill=(125, 125, 125), font=font2) + + image_back = Image.new('RGB', (700, 150), (255, 255, 255)) + image_back.paste(img_origin, (25, 25)) + image_back.paste(image_text, (150, 40)) + + await one_friend.send(MessageSegment.image(pic2b64(image_back))) diff --git a/plugins/one_friend/__pycache__/__init__.cpython-38.pyc b/plugins/one_friend/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..4f995113 Binary files /dev/null and b/plugins/one_friend/__pycache__/__init__.cpython-38.pyc differ diff --git a/plugins/one_friend/__pycache__/__init__.cpython-39.pyc b/plugins/one_friend/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 00000000..e8a92ca1 Binary files /dev/null and b/plugins/one_friend/__pycache__/__init__.cpython-39.pyc differ diff --git a/plugins/open_cases/__init__.py b/plugins/open_cases/__init__.py new file mode 100644 index 00000000..ed963e5a --- /dev/null +++ b/plugins/open_cases/__init__.py @@ -0,0 +1,181 @@ +from nonebot import on_command +from util.utils import FreqLimiter, scheduler, get_message_text, is_number +from nonebot.adapters.cqhttp.permission import GROUP +from nonebot.typing import T_State +from nonebot.adapters.cqhttp import Bot, GroupMessageEvent, MessageEvent +from nonebot.permission import SUPERUSER +import random +from nonebot.plugin import MatcherGroup +import re +from .open_cases_c import open_case, total_open_statistics, group_statistics, my_knifes_name, open_shilian_case +from .utils import util_get_buff_price, util_get_buff_img, update_count_daily + +__plugin_name__ = '开箱' +__plugin_usage__ = ( + '用法:\n' + '看看你的人品罢了\n' + '目前只支持\n\t' + '1.狂牙大行动武器箱\n\t' + '2.突围大行动武器箱\n\t' + '3.命悬一线武器箱\n\t' + '4.裂空武器箱\n\t' + '5.光谱武器箱\n\t' + '示例:小真寻开箱 突围大行动(不输入指定武器箱则随机)\n' + '示例:我的开箱(开箱统计)\n' + '示例:群开箱统计\n' + '示例:我的金色' +) + +_flmt = FreqLimiter(3) + +cases_name = ['狂牙大行动', '突围大行动', '命悬一线', '裂空'] + +cases_matcher_group = MatcherGroup(priority=5, permission=GROUP, block=True) + + +k_open_case = cases_matcher_group.on_command("开箱") + + +@k_open_case.handle() +async def _(bot: Bot, event: GroupMessageEvent, state: T_State): + if str(event.get_message()).strip() in ['帮助']: + await k_open_case.finish(__plugin_usage__) + if not _flmt.check(event.user_id): + await k_open_case.finish('着什么急啊,慢慢来!', at_sender=True) + _flmt.start_cd(event.user_id) + case_name = get_message_text(event.json()) + if case_name: + result = await open_case(event.user_id, event.group_id, case_name) + else: + result = await open_case(event.user_id, event.group_id, random.choice(cases_name)) + await k_open_case.finish(result, at_sender=True) + + +total_case_data = cases_matcher_group.on_command("我的开箱", aliases={'开箱统计', '开箱查询', '查询开箱'}) + + +@total_case_data.handle() +async def _(bot: Bot, event: GroupMessageEvent, state: T_State): + await total_case_data.finish( + await total_open_statistics(event.user_id, event.group_id), + at_sender=True, + ) + + +group_open_case_statistics = cases_matcher_group.on_command("群开箱统计") + + +@group_open_case_statistics.handle() +async def _(bot: Bot, event: GroupMessageEvent, state: T_State): + await group_open_case_statistics.finish(await group_statistics(event.group_id)) + + +my_kinfes = on_command("我的金色", priority=1, permission=GROUP, block=True) + + +@my_kinfes.handle() +async def _(bot: Bot, event: GroupMessageEvent, state: T_State): + await my_kinfes.finish(await my_knifes_name(event.user_id, event.group_id), at_sender=True) + + +open_shilian = cases_matcher_group.on_regex(".*连开箱") + + +@open_shilian.handle() +async def _(bot: Bot, event: GroupMessageEvent, state: T_State): + # if not _flmt.check(event.user_id): + # await k_open_case.finish('着什么急啊,慢慢来!', at_sender=True) + _flmt.start_cd(event.user_id) + msg = get_message_text(event.json()) + rs = re.search(r'(.*)连开箱(.*)', msg) + if rs: + num = rs.group(1).strip() + if is_number(num) or num_dict.get(num): + try: + num = num_dict[num] + except KeyError: + num = int(num) + if num > 30: + await open_shilian.finish('开箱次数不要超过30啊笨蛋!', at_sender=True) + else: + await open_shilian.finish('必须要是数字切不要超过30啊笨蛋!中文也可!', at_sender=True) + case_name = rs.group(2).strip() + if case_name.find('武器箱') != -1: + case_name = case_name.replace('武器箱', '').strip() + if not case_name: + case_name = random.choice(cases_name) + elif case_name not in cases_name: + await open_shilian.finish('武器箱未收录!', at_sender=True) + await open_shilian.finish(await open_shilian_case(event.user_id, event.group_id, case_name, num), at_sender=True) + # await open_shilian.send("嘟嘟嘟...开箱中...") + # num = 10 + # if str(state["_prefix"]["raw_command"]).find('十') != -1: + # num = 10 + # elif str(state["_prefix"]["raw_command"]).find('五') != -1: + # num = 5 + # if case_name: + # await open_shilian.finish(await open_shilian_case(event.user_id, event.group_id, case_name, num), at_sender=True) + # else: + # await open_shilian.finish(await open_shilian_case(event.user_id, event.group_id, random.choice(cases_name), num), + # at_sender=True) + + +num_dict = { + '一': 1, + '二': 2, + '三': 3, + '四': 4, + '五': 5, + '六': 6, + '七': 7, + '八': 8, + '九': 9, + '十': 10, + '十一': 11, + '十二': 12, + '十三': 13, + '十四': 14, + '十五': 15, + '十六': 16, + '十七': 17, + '十八': 18, + '十九': 19, + '二十': 20, + '二十一': 21, + '二十二': 22, + '二十三': 23, + '二十四': 24, + '二十五': 25, + '二十六': 26, + '二十七': 27, + '二十八': 28, + '二十九': 29, + '三十': 30 +} + + +update_price = on_command("更新价格", priority=1, permission=SUPERUSER, block=True) + + +@update_price.handle() +async def _(bot: Bot, event: MessageEvent, state: T_State): + await update_price.send(await util_get_buff_price(str(event.get_message()))) + + +update_img = on_command("更新图片", priority=1, permission=SUPERUSER, block=True) + + +@update_img.handle() +async def _(bot: Bot, event: MessageEvent, state: T_State): + await update_img.send(await util_get_buff_img(str(event.get_message()))) + + +# 重置开箱 +@scheduler.scheduled_job( + 'cron', + hour=0, + minute=1, +) +async def _(): + await update_count_daily() + diff --git a/plugins/open_cases/__pycache__/__init__.cpython-38.pyc b/plugins/open_cases/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..39862d4d Binary files /dev/null and b/plugins/open_cases/__pycache__/__init__.cpython-38.pyc differ diff --git a/plugins/open_cases/__pycache__/__init__.cpython-39.pyc b/plugins/open_cases/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 00000000..88e0a41d Binary files /dev/null and b/plugins/open_cases/__pycache__/__init__.cpython-39.pyc differ diff --git a/plugins/open_cases/__pycache__/config.cpython-38.pyc b/plugins/open_cases/__pycache__/config.cpython-38.pyc new file mode 100644 index 00000000..fe783ec3 Binary files /dev/null and b/plugins/open_cases/__pycache__/config.cpython-38.pyc differ diff --git a/plugins/open_cases/__pycache__/config.cpython-39.pyc b/plugins/open_cases/__pycache__/config.cpython-39.pyc new file mode 100644 index 00000000..2c42809d Binary files /dev/null and b/plugins/open_cases/__pycache__/config.cpython-39.pyc differ diff --git a/plugins/open_cases/__pycache__/open_cases_c.cpython-38.pyc b/plugins/open_cases/__pycache__/open_cases_c.cpython-38.pyc new file mode 100644 index 00000000..801f85d5 Binary files /dev/null and b/plugins/open_cases/__pycache__/open_cases_c.cpython-38.pyc differ diff --git a/plugins/open_cases/__pycache__/open_cases_c.cpython-39.pyc b/plugins/open_cases/__pycache__/open_cases_c.cpython-39.pyc new file mode 100644 index 00000000..f57de18c Binary files /dev/null and b/plugins/open_cases/__pycache__/open_cases_c.cpython-39.pyc differ diff --git a/plugins/open_cases/__pycache__/utils.cpython-38.pyc b/plugins/open_cases/__pycache__/utils.cpython-38.pyc new file mode 100644 index 00000000..ac76c69e Binary files /dev/null and b/plugins/open_cases/__pycache__/utils.cpython-38.pyc differ diff --git a/plugins/open_cases/__pycache__/utils.cpython-39.pyc b/plugins/open_cases/__pycache__/utils.cpython-39.pyc new file mode 100644 index 00000000..bf1fefef Binary files /dev/null and b/plugins/open_cases/__pycache__/utils.cpython-39.pyc differ diff --git a/plugins/open_cases/config.py b/plugins/open_cases/config.py new file mode 100644 index 00000000..fd118ff7 --- /dev/null +++ b/plugins/open_cases/config.py @@ -0,0 +1,180 @@ +import random +import pypinyin + +BLUE = 0.7981 +BLUE_ST = 0.0699 +PURPLE = 0.1626 +PURPLE_ST = 0.0164 +PINK = 0.0315 +PINK_ST = 0.0048 +RED = 0.0057 +RED_ST = 0.00021 +KNIFE = 0.0021 +KNIFE_ST = 0.000041 + +# 崭新 +FACTORY_NEW_S = 0 +FACTORY_NEW_E = 0.0699999 +# 略磨 +MINIMAL_WEAR_S = 0.07 +MINIMAL_WEAR_E = 0.14999 +# 久经 +FIELD_TESTED_S = 0.15 +FIELD_TESTED_E = 0.37999 +# 破损 +WELL_WORN_S = 0.38 +WELL_WORN_E = 0.44999 +# 战痕 +BATTLE_SCARED_S = 0.45 +BATTLE_SCARED_E = 0.99999 + +# 狂牙大行动 +KUANGYADAXINGDONG_CASE_KNIFE = ['摩托手套 | 第三特种兵连', '狂牙手套 | 翡翠', '驾驶手套 | 美洲豹女王', '运动手套 | 弹弓', '专业手套 | 老虎精英' + , '专业手套 | 渐变大理石', '运动手套 | 夜行衣', '驾驶手套 | 西装革履', '摩托手套 | 终点线', '摩托手套 | 血压', + '运动手套 | 猩红头巾', '驾驶手套 | 雪豹', '裹手 | 长颈鹿', '驾驶手套 | 绯红列赞', '裹手 | 沙漠头巾', + '专业手套 | 一线特工', '狂牙手套 | 黄色斑纹', '摩托手套 | 小心烟幕弹', '裹手 | 蟒蛇', '裹手 | 警告!', + '狂牙手套 | 精神错乱', '运动手套 | 大型猎物', '狂牙手套 | 针尖', '专业手套 | 陆军少尉长官'] +KUANGYADAXINGDONG_CASE_RED = ['M4A1 | 印花集', '格洛克 | 黑色魅影'] +KUANGYADAXINGDONG_CASE_PINK = ['FN57 | 童话城堡', 'M4A4 | 赛博', 'USP | 小绿怪'] +KUANGYADAXINGDONG_CASE_PURPLE = ['AWP | 亡灵之主', '双持贝瑞塔 | 灾难', '新星 | 一见青心', 'SSG 08 | 抖枪', 'UMP-45 | 金铋辉煌'] +KUANGYADAXINGDONG_CASE_BLUE = ['CZ75 | 世仇', 'P90 | 大怪兽RUSH', 'G3SG1 | 血腥迷彩', '加利尔 AR | 破坏者', 'P250 | 污染物', + 'M249 | 等高线', 'MP5-SD | 零点行动'] + +# 突围大行动 +TUWEIDAXINGDONG_CASE_KNIFE = ['蝴蝶刀 | 无涂装', '蝴蝶刀 | 蓝钢', '蝴蝶刀 | 屠夫', '蝴蝶刀 | 森林 DDPAT', '蝴蝶刀 | 北方森林', + '蝴蝶刀 | 狩猎网格', '蝴蝶刀 | 枯焦之色', '蝴蝶刀 | 人工染色', '蝴蝶刀 | 都市伪装', '蝴蝶刀 | 表面淬火', + '蝴蝶刀 | 深红之网', '蝴蝶刀 | 渐变之色', '蝴蝶刀 | 噩梦之夜'] +TUWEIDAXINGDONG_CASE_RED = ['P90 | 二西莫夫', 'M4A1 | 次时代'] +TUWEIDAXINGDONG_CASE_PINK = ['沙漠之鹰 | 阴谋者', 'FN57 | 狩猎利器', '格洛克 | 水灵'] +TUWEIDAXINGDONG_CASE_PURPLE = ['PP-野牛 | 死亡主宰者', 'CZ75 | 猛虎', '新星 | 锦鲤', 'P250 | 超新星'] +TUWEIDAXINGDONG_CASE_BLUE = ['MP7 | 都市危机', '内格夫 | 沙漠精英', 'P2000 | 乳白象牙', 'SSG 08 | 无尽深海', 'UMP-45 | 迷之宫'] + + +# 命悬一线 +MINGXUANYIXIAN_CASE_KNIFE = ['专业手套 | 大腕', '专业手套 | 深红之网', '专业手套 | 渐变之色', '专业手套 | 狩鹿', '九头蛇手套 | 响尾蛇', + '九头蛇手套 | 红树林', '九头蛇手套 | 翡翠色调', '九头蛇手套 | 表面淬火', '摩托手套 | 交运', '摩托手套 | 嘭!', + '摩托手套 | 多边形', '摩托手套 | 玳瑁', '裹手 | 套印', '裹手 | 森林色调', '裹手 | 钴蓝骷髅', '裹手 | 防水布胶带', + '运动手套 | 双栖', '运动手套 | 欧米伽', '运动手套 | 迈阿密风云', '运动手套 | 青铜形态', '驾驶手套 | 墨绿色调', + '驾驶手套 | 王蛇', '驾驶手套 | 蓝紫格子', '驾驶手套 | 超越'] +MINGXUANYIXIAN_CASE_RED = ['M4A4 | 黑色魅影', 'MP7 | 血腥运动'] +MINGXUANYIXIAN_CASE_PINK = ['AUG | 湖怪鸟', 'AWP | 死神', 'USP | 脑洞大开'] +MINGXUANYIXIAN_CASE_PURPLE = ['MAG-7 | SWAG-7', 'UMP-45 | 白狼', '内格夫 | 狮子鱼', '新星 | 狂野六号', '格洛克 | 城里的月光'] +MINGXUANYIXIAN_CASE_BLUE = ['FN57 | 焰色反应', 'MP9 | 黑砂', 'P2000 | 都市危机', 'PP-野牛 | 黑夜暴乱', 'R8 左轮手枪 | 稳', + 'SG 553 | 阿罗哈', 'XM1014 | 锈蚀烈焰'] + + +LIEKONG_CASE_KNIFE = ['求生匕首 | 无涂装', '求生匕首 | 人工染色', '求生匕首 | 北方森林', '求生匕首 | 夜色', '求生匕首 | 屠夫', + '求生匕首 | 枯焦之色', '求生匕首 | 森林 DDPAT', '求生匕首 | 深红之网', '求生匕首 | 渐变之色', '求生匕首 | 狩猎网格', + '求生匕首 | 蓝钢', '求生匕首 | 表面淬火', '求生匕首 | 都市伪装', '流浪者匕首 | 无涂装', '流浪者匕首 | 人工染色', + '流浪者匕首 | 北方森林', '流浪者匕首 | 夜色', '流浪者匕首 | 屠夫', '流浪者匕首 | 枯焦之色', '流浪者匕首 | 森林 DDPAT', + '流浪者匕首 | 深红之网', '流浪者匕首 | 渐变之色', '流浪者匕首 | 狩猎网格', '流浪者匕首 | 蓝钢', '流浪者匕首 | 表面淬火', + '流浪者匕首 | 都市伪装', '系绳匕首 | 无涂装', '系绳匕首 | 人工染色', '系绳匕首 | 北方森林', '系绳匕首 | 夜色', + '系绳匕首 | 屠夫', '系绳匕首 | 枯焦之色', '系绳匕首 | 森林 DDPAT', '系绳匕首 | 深红之网', '系绳匕首 | 渐变之色', + '系绳匕首 | 狩猎网格', '系绳匕首 | 蓝钢', '系绳匕首 | 表面淬火', '系绳匕首 | 都市伪装', '骷髅匕首 | 无涂装', + '骷髅匕首 | 人工染色', '骷髅匕首 | 北方森林', '骷髅匕首 | 夜色', '骷髅匕首 | 屠夫', '骷髅匕首 | 枯焦之色', + '骷髅匕首 | 森林 DDPAT', '骷髅匕首 | 深红之网', '骷髅匕首 | 渐变之色', '骷髅匕首 | 狩猎网格', '骷髅匕首 | 蓝钢', + '骷髅匕首 | 表面淬火', '骷髅匕首 | 都市伪装'] +LIEKONG_CASE_RED = ['AK-47 | 阿努比斯军团', '沙漠之鹰 | 印花集'] +LIEKONG_CASE_PINK = ['M4A4 | 齿仙', 'XM1014 | 埋葬之影', '格洛克 | 摩登时代'] +LIEKONG_CASE_PURPLE = ['加利尔 AR | 凤凰商号', 'Tec-9 | 兄弟连', 'MP5-SD | 猛烈冲锋', 'MAG-7 | 北冥有鱼', 'MAC-10 | 魅惑'] +LIEKONG_CASE_BLUE = ['内格夫 | 飞羽', 'SSG 08 | 主机001', 'SG 553 | 锈蚀之刃', 'PP-野牛 | 神秘碑文', 'P90 | 集装箱', 'P250 | 卡带', + 'P2000 | 盘根错节'] + + +GUANGPU_CASE_KNIFE = ['弯刀 | 外表生锈', '弯刀 | 多普勒', '弯刀 | 大马士革钢', '弯刀 | 渐变大理石', '弯刀 | 致命紫罗兰', '弯刀 | 虎牙', + '暗影双匕 | 外表生锈', '暗影双匕 | 多普勒', '暗影双匕 | 大马士革钢', '暗影双匕 | 渐变大理石', '暗影双匕 | 致命紫罗兰', + '暗影双匕 | 虎牙', '猎杀者匕首 | 外表生锈', '猎杀者匕首 | 多普勒', '猎杀者匕首 | 大马士革钢', '猎杀者匕首 | 渐变大理石', + '猎杀者匕首 | 致命紫罗兰', '猎杀者匕首 | 虎牙', '蝴蝶刀 | 外表生锈', '蝴蝶刀 | 多普勒', '蝴蝶刀 | 大马士革钢', + '蝴蝶刀 | 渐变大理石', '蝴蝶刀 | 致命紫罗兰', '蝴蝶刀 | 虎牙', '鲍伊猎刀 | 外表生锈', '鲍伊猎刀 | 多普勒', + '鲍伊猎刀 | 大马士革钢', '鲍伊猎刀 | 渐变大理石', '鲍伊猎刀 | 致命紫罗兰', '鲍伊猎刀 | 虎牙'] +GUANGPU_CASE_RED = ['USP | 黑色魅影', 'AK-47 | 血腥运动'] +GUANGPU_CASE_PINK = ['M4A1 | 毁灭者 2000', 'CZ75 | 相柳', 'AWP | 浮生如梦'] +GUANGPU_CASE_PURPLE = ['加利尔 AR | 深红海啸', 'XM1014 | 四季', 'UMP-45 | 支架', 'MAC-10 | 绝界之行', 'M249 | 翠绿箭毒蛙'] +GUANGPU_CASE_BLUE = ['沙漠之鹰 | 锈蚀烈焰', '截短霰弹枪 | 梭鲈', 'SCAR-20 | 蓝图', 'PP-野牛 | 丛林滑流', 'P250 | 涟漪', 'MP7 | 非洲部落', + 'FN57 | 毛细血管'] + + +NO_STA_KNIFE = ['求生匕首 | 北方森林', '求生匕首 | 夜色', '求生匕首 | 枯焦之色', '流浪者匕首 | 夜色', '流浪者匕首 | 枯焦之色', '流浪者匕首 | 森林 DDPAT', + '系绳匕首 | 夜色', '系绳匕首 | 狩猎网格', '骷髅匕首 | 夜色', '骷髅匕首 | 森林 DDPAT', '骷髅匕首 | 狩猎网格'] + + +def get_wear(num: float) -> str: + if num <= FACTORY_NEW_E: + return "崭新出厂" + if MINIMAL_WEAR_S <= num <= MINIMAL_WEAR_E: + return "略有磨损" + if FIELD_TESTED_S <= num <= FIELD_TESTED_E: + return "久经沙场" + if WELL_WORN_S <= num <= WELL_WORN_E: + return "破损不堪" + return "战痕累累" + + +def get_color_quality(rand: float, case_name: str): + case = "" + mosun = random.random()/2 + random.random()/2 + for i in pypinyin.pinyin(case_name, style=pypinyin.NORMAL): + case += ''.join(i) + case = case.upper() + CASE_KNIFE = eval(case + "_CASE_KNIFE") + CASE_RED = eval(case + "_CASE_RED") + CASE_PINK = eval(case + "_CASE_PINK") + CASE_PURPLE = eval(case + "_CASE_PURPLE") + CASE_BLUE = eval(case + "_CASE_BLUE") + if rand <= KNIFE: + skin = "罕见级(金色): " + random.choice(CASE_KNIFE) + if random.random() <= KNIFE_ST and (skin[2:4] != "手套" or skin[:2] != "裹手") and skin.split(':')[1] \ + not in NO_STA_KNIFE: + skin_sp = skin.split("|") + skin = skin_sp[0] + "(StatTrak™) | " + skin_sp[1] + elif KNIFE < rand <= RED: + skin = "隐秘级(红色): " + random.choice(CASE_RED) + if random.random() <= RED_ST: + skin_sp = skin.split("|") + skin = skin_sp[0] + "(StatTrak™) | " + skin_sp[1] + elif RED < rand <= PINK: + skin = "保密级(粉色): " + random.choice(CASE_PINK) + if random.random() <= PINK_ST: + skin_sp = skin.split("|") + skin = skin_sp[0] + "(StatTrak™) | " + skin_sp[1] + elif PINK < rand <= PURPLE: + skin = "受限级(紫色): " + random.choice(CASE_PURPLE) + if random.random() <= PURPLE_ST: + skin_sp = skin.split("|") + skin = skin_sp[0] + "(StatTrak™) | " + skin_sp[1] + else: + skin = "军规级(蓝色): " + random.choice(CASE_BLUE) + if random.random() <= BLUE_ST: + skin_sp = skin.split("|") + skin = skin_sp[0] + "(StatTrak™) | " + skin_sp[1] + if skin.find("(") != -1: + cpskin = skin.split(":")[1] + ybskin = cpskin.split("|") + temp_skin = ybskin[0].strip()[:-11] + " | " + ybskin[1].strip() + else: + temp_skin = skin.split(":")[1].strip() + # 崭新 -> 略磨 + if temp_skin in [] or temp_skin.find('渐变之色') != -1 or temp_skin.find('多普勒') != -1 or temp_skin.find('虎牙') != -1\ + or temp_skin.find('渐变大理石') != -1: + mosun = random.uniform(FACTORY_NEW_S, MINIMAL_WEAR_E) / 2 + random.uniform(FACTORY_NEW_S, MINIMAL_WEAR_E) / 2 + # 崭新 -> 久经 + if temp_skin in ['沙漠之鹰 | 阴谋者', '新星 | 锦鲤'] or temp_skin.find('屠夫') != -1: + mosun = random.uniform(FACTORY_NEW_S, FIELD_TESTED_E) / 2 + random.uniform(FACTORY_NEW_S, FIELD_TESTED_E) / 2 + # 崭新 -> 破损 + if temp_skin in ['UMP-45 | 迷之宫', 'P250 | 超新星', '系绳匕首 | 深红之网', 'M249 | 翠绿箭毒蛙', 'AK-47 | 血腥运动']: + mosun = random.uniform(FACTORY_NEW_S, WELL_WORN_E) / 2 + random.uniform(FACTORY_NEW_S, WELL_WORN_E) / 2 + # 破损 -> 战痕 + if temp_skin in [] or temp_skin.find('外表生锈') != -1: + mosun = random.uniform(WELL_WORN_S, BATTLE_SCARED_E) / 2 + random.uniform(WELL_WORN_S, BATTLE_SCARED_E) / 2 + if mosun > MINIMAL_WEAR_E: + for _ in range(2): + if random.random() < 5: + if random.random() < 0.2: + mosun /= 3 + else: + mosun /= 2 + break + skin += " (" + get_wear(mosun) + ")" + return skin, mosun + +# M249(StatTrak™) | 等高线 \ No newline at end of file diff --git a/plugins/open_cases/open_cases_c.py b/plugins/open_cases/open_cases_c.py new file mode 100644 index 00000000..d2ba7688 --- /dev/null +++ b/plugins/open_cases/open_cases_c.py @@ -0,0 +1,381 @@ +from datetime import datetime, timedelta +from .config import * +from services.log import logger +from services.db_context import db +from models.open_cases_user import OpenCasesUser +from models.sigin_group_user import SignGroupUser +from util.init_result import image +import pypinyin +import random +from .utils import get_price +from models.buff_price import BuffPrice +from PIL import Image +from util.img_utils import alphabg2white_PIL, CreateImg +from configs.path_config import IMAGE_PATH +import asyncio +from util.utils import cn2py +from configs.config import INITIAL_OPEN_CASE_COUNT + + +MAX_COUNT = INITIAL_OPEN_CASE_COUNT + + +async def open_case(user_qq: int, group: int, case_name: str = "狂牙大行动") -> str: + if case_name not in ["狂牙大行动", "突围大行动", "命悬一线", '裂空', '光谱']: + return "武器箱未收录" + knifes_flag = False + # lan zi fen hong jin price + uplist = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0] + case = "" + for i in pypinyin.pinyin(case_name, style=pypinyin.NORMAL): + case += ''.join(i) + impression = (await SignGroupUser.ensure(user_qq, group)).impression + rand = random.random() + async with db.transaction(): + user = await OpenCasesUser.ensure(user_qq, group, for_update=True) + # 一天次数上限 + if user.today_open_total == int(MAX_COUNT + int(impression) / 3): + return _handle_is_MAX_COUNT() + skin, mosun = get_color_quality(rand, case_name) + # 调侃 + if skin[:2] == "军规": + if skin.find("StatTrak") == -1: + uplist[0] = 1 + else: + uplist[1] = 1 + ridicule_result = random.choice(['这样看着才舒服', + '是自己人,大伙把刀收好', + '非常舒适~']) + if skin[:2] == "受限": + if skin.find("StatTrak") == -1: + uplist[2] = 1 + else: + uplist[3] = 1 + ridicule_result = random.choice(['还行吧,勉强接受一下下', + '居然不是蓝色,太假了', + '运气-1-1-1-1-1...']) + if skin[:2] == "保密": + if skin.find("StatTrak") == -1: + uplist[4] = 1 + else: + uplist[5] = 1 + ridicule_result = random.choice(['开始不适....', + '你妈妈买菜必涨价!涨三倍!', + '你最近不适合出门,真的']) + if skin[:2] == "隐秘": + if skin.find("StatTrak") == -1: + uplist[6] = 1 + else: + uplist[7] = 1 + ridicule_result = random.choice(['已经非常不适', + '好兄弟你开的什么箱子啊,一般箱子不是只有蓝色的吗', + '开始拿阳寿开箱子了?']) + if skin[:2] == "罕见": + knifes_flag = True + if skin.find("StatTrak") == -1: + uplist[8] = 1 + else: + uplist[9] = 1 + ridicule_result = random.choice(['你的好运我收到了,你可以去喂鲨鱼了', + '最近该吃啥就迟点啥吧,哎,好好的一个人怎么就....哎', + '众所周知,欧皇寿命极短.']) + if skin.find("(") != -1: + cskin = skin.split("(") + skin = cskin[0].strip() + "(" + cskin[1].strip() + skin = skin.split("|")[0].strip() + " | " + skin.split("|")[1].strip() + # 价格 + if skin.find('无涂装') == -1: + dbprice = await BuffPrice.ensure(skin[9:]) + else: + dbprice = await BuffPrice.ensure(skin[9: skin.rfind('(')].strip()) + if dbprice.skin_price != 0: + price_result = dbprice.skin_price + print("数据库查询到价格: ", dbprice.skin_price) + uplist[10] = dbprice.skin_price + else: + price = -1 + price_result = "未查询到" + price_list, status = await get_price(skin[9:]) + if price_list not in ["访问超时! 请重试或稍后再试!", "访问失败!"]: + for price_l in price_list[1:]: + pcp = price_l.split(":") + if pcp[0] == skin[9:]: + price = float(pcp[1].strip()) + break + if price != -1: + print("存储入数据库---->", price) + uplist[10] = price + price_result = str(price) + await dbprice.update( + skin_price=price, + update_date=datetime.now(), + ).apply() + # sp = skin.split("|") + # cskin_word = sp[1][:sp[1].find("(") - 1].strip() + if knifes_flag: + await user.update( + knifes_name=user.knifes_name + f"{skin.split(':')[1].strip()} 磨损:{str(mosun)[:11]}, 价格:{uplist[10]}," + ).apply() + cskin_word = skin.split(':')[1].replace('|', '-').replace('(StatTrak™)', '') + cskin_word = cskin_word[: cskin_word.rfind('(')].strip() + skin_name = cn2py(cskin_word.replace('|', '-').replace('(StatTrak™)', '').strip()) + img = image(f'{skin_name}.png', "cases/" + case) + # if knifes_flag: + # await user.update( + # knifes_name=user.knifes_name + f"{skin} 磨损:{mosun}, 价格:{uplist[10]}" + # ).apply() + if await update_user_total(user, uplist): + logger.info(f"qq:{user_qq} 群:{group} 开启{case_name}武器箱 获得 {skin} 磨损:{mosun}, 价格:{uplist[10]}, 数据更新成功") + else: + logger.warning(f"qq:{user_qq} 群:{group} 开启{case_name}武器箱 获得 {skin} 磨损:{mosun}, 价格:{uplist[10]}, 数据更新失败") + user = await OpenCasesUser.ensure(user_qq, group, for_update=True) + over_count = int(MAX_COUNT + int(impression) / 3) - user.today_open_total + return f"开启{case_name}武器箱.\n剩余开箱次数:{over_count}.\n" \ + + img + "\n" + \ + f"皮肤:{skin}\n" \ + f"磨损:{mosun:.9f}\n" \ + f"价格:{price_result}\n" \ + f"{ridicule_result}" + + +async def open_shilian_case(user_qq: int, group: int, case_name: str, num: int = 10): + user = await OpenCasesUser.ensure(user_qq, group, for_update=True) + impression = (await SignGroupUser.ensure(user_qq, group)).impression + if user.today_open_total == int(MAX_COUNT + int(impression) / 3): + return _handle_is_MAX_COUNT() + if int(MAX_COUNT + int(impression) / 3) - user.today_open_total < num: + return f"今天开箱次数不足{num}次噢,请单抽试试看(也许单抽运气更好?)" \ + f"\n剩余开箱次数:{int(MAX_COUNT + int(impression) / 3) - user.today_open_total}" + if num < 5: + h = 270 + elif num % 5 == 0: + h = 270 * int(num / 5) + else: + h = 270 * int(num / 5) + 270 + case = cn2py(case_name) + # lan zi fen hong jin + # skin_list = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + # lan zi fen hong jin price + uplist = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0] + img_list = [] + name_list = ['蓝', '蓝(暗金)', '紫', '紫(暗金)', '粉', '粉(暗金)', '红', '红(暗金)', '金', '金(暗金)'] + async with db.transaction(): + for _ in range(num): + knifes_flag = False + rand = random.random() + skin, mosun = get_color_quality(rand, case_name) + if skin[:2] == "军规": + if skin.find("StatTrak") == -1: + uplist[0] += 1 + else: + uplist[1] += 1 + if skin[:2] == "受限": + if skin.find("StatTrak") == -1: + uplist[2] += 1 + else: + uplist[3] += 1 + if skin[:2] == "保密": + if skin.find("StatTrak") == -1: + uplist[4] += 1 + else: + uplist[5] += 1 + if skin[:2] == "隐秘": + if skin.find("StatTrak") == -1: + uplist[6] += 1 + else: + uplist[7] += 1 + if skin[:2] == "罕见": + knifes_flag = True + if skin.find("StatTrak") == -1: + uplist[8] += 1 + else: + uplist[9] += 1 + if skin.find("(") != -1: + cskin = skin.split("(") + skin = cskin[0].strip() + "(" + cskin[1].strip() + skin = skin.split("|")[0].strip() + " | " + skin.split("|")[1].strip() + # 价格 + if skin.find('无涂装') == -1: + dbprice = await BuffPrice.ensure(skin[9:]) + else: + dbprice = await BuffPrice.ensure(skin[9: skin.rfind('(')].strip()) + if dbprice.skin_price != 0: + price_result = dbprice.skin_price + uplist[10] += price_result + else: + price_result = '未查询到' + if knifes_flag: + await user.update( + knifes_name=user.knifes_name + f"{case}||{skin.split(':')[1].strip()} 磨损:{str(mosun)[:11]}, 价格:{dbprice.skin_price}," + ).apply() + cskin_word = skin.split(':')[1].replace('|', '-').replace('(StatTrak™)', '') + cskin_word = cskin_word[: cskin_word.rfind('(')].strip() + skin_name = "" + for i in pypinyin.pinyin(cskin_word.replace('|', '-').replace('(StatTrak™)', '').strip(), + style=pypinyin.NORMAL): + skin_name += ''.join(i) + # img = image(skin_name, "cases/" + case, "png") + wImg = CreateImg(200, 270, 200, 200) + wImg.paste(alphabg2white_PIL(Image.open(IMAGE_PATH + f'cases/{case}/{skin_name}.png').resize((200, 200), Image.ANTIALIAS)), (0, 0)) + wImg.text((5, 200), skin) + wImg.text((5, 220), f'磨损:{str(mosun)[:9]}') + wImg.text((5, 240), f'价格:{price_result}') + img_list.append(wImg) + logger.info(f"USER {user_qq} GROUP {group} 开启{case_name}武器箱 获得 {skin} 磨损:{mosun}, 价格:{uplist[10]}") + if await update_user_total(user, uplist, num): + logger.info(f"USER {user_qq} GROUP {group} 开启{case_name}武器箱 {num} 次, 数据更新成功") + else: + logger.warning(f"USER {user_qq} GROUP {group} 开启{case_name}武器箱 {num} 次, 价格:{uplist[10]}, 数据更新失败") + # markImg = CreateImg(1000, h, 200, 270) + # for img in img_list: + # markImg.paste(img) + markImg = await asyncio.get_event_loop().run_in_executor(None, paste_markImg, h, img_list) + over_count = int(MAX_COUNT + int(impression) / 3) - user.today_open_total + result = '' + for i in range(len(name_list)): + if uplist[i]: + result += f'[{name_list[i]}:{uplist[i]}] ' + return f"开启{case_name}武器箱\n剩余开箱次数:{over_count}\n" \ + + image(b64=markImg.pic2bs4()) + \ + '\n' + result[:-1] + f'\n总获取金额:{uplist[-1]:.2f}\n总花费:{17 * num}' + + +def paste_markImg(h: int, img_list: list): + markImg = CreateImg(1000, h, 200, 270) + for img in img_list: + markImg.paste(img) + return markImg + + +def _handle_is_MAX_COUNT() -> str: + return f"今天已达开箱上限了喔,明天再来吧\n(提升好感度可以增加每日开箱数 #疯狂暗示)" + + +async def update_user_total(user: OpenCasesUser, uplist: list, num: int = 1) -> bool: + try: + await user.update( + total_count=user.total_count + num, + blue_count=user.blue_count + uplist[0], + blue_st_count=user.blue_st_count + uplist[1], + purple_count=user.purple_count + uplist[2], + purple_st_count=user.purple_st_count + uplist[3], + pink_count=user.pink_count + uplist[4], + pink_st_count=user.pink_st_count + uplist[5], + red_count=user.red_count + uplist[6], + red_st_count=user.red_st_count + uplist[7], + knife_count=user.knife_count + uplist[8], + knife_st_count=user.knife_st_count + uplist[9], + spend_money=user.spend_money + 17 * num, + make_money=user.make_money + uplist[10], + today_open_total=user.today_open_total + num, + open_cases_time_last=datetime.now() + ).apply() + return True + except: + return False + + +async def total_open_statistics(user_qq: int, group: int) -> str: + async with db.transaction(): + user = await OpenCasesUser.ensure(user_qq, group, for_update=True) + return f"开箱总数:{user.total_count}\n" \ + f"今日开箱:{user.today_open_total}\n" \ + f"蓝色军规:{user.blue_count}\n" \ + f"蓝色暗金:{user.blue_st_count}\n" \ + f"紫色受限:{user.purple_count}\n" \ + f"紫色暗金:{user.purple_st_count}\n" \ + f"粉色保密:{user.pink_count}\n" \ + f"粉色暗金:{user.pink_st_count}\n" \ + f"红色隐秘:{user.red_count}\n" \ + f"红色暗金:{user.red_st_count}\n" \ + f"金色罕见:{user.knife_count}\n" \ + f"金色暗金:{user.knife_st_count}\n" \ + f"花费金额:{user.spend_money}\n" \ + f"获取金额:{user.make_money:.2f}\n" \ + f"最后开箱日期:{(user.open_cases_time_last + timedelta(hours=8)).date()}" + + +async def group_statistics(group: int): + user_list = await OpenCasesUser.get_user_all(group) + # lan zi fen hong jin pricei + uplist = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0, 0, 0] + for user in user_list: + uplist[0] += user.blue_count + uplist[1] += user.blue_st_count + uplist[2] += user.purple_count + uplist[3] += user.purple_st_count + uplist[4] += user.pink_count + uplist[5] += user.pink_st_count + uplist[6] += user.red_count + uplist[7] += user.red_st_count + uplist[8] += user.knife_count + uplist[9] += user.knife_st_count + uplist[10] += user.make_money + uplist[11] += user.total_count + uplist[12] += user.today_open_total + return f"群开箱总数:{uplist[11]}\n" \ + f"群今日开箱:{uplist[12]}\n" \ + f"蓝色军规:{uplist[0]}\n" \ + f"蓝色暗金:{uplist[1]}\n" \ + f"紫色受限:{uplist[2]}\n" \ + f"紫色暗金:{uplist[3]}\n" \ + f"粉色保密:{uplist[4]}\n" \ + f"粉色暗金:{uplist[5]}\n" \ + f"红色隐秘:{uplist[6]}\n" \ + f"红色暗金:{uplist[7]}\n" \ + f"金色罕见:{uplist[8]}\n" \ + f"金色暗金:{uplist[9]}\n" \ + f"花费金额:{uplist[11] * 17}\n" \ + f"获取金额:{uplist[10]:.2f}" + + +async def my_knifes_name(user_id: int, group: int): + knifes_name = (await OpenCasesUser.ensure(user_id, group)).knifes_name + if knifes_name: + knifes_list = knifes_name[:-1].split(",") + length = len(knifes_list) + if length < 5: + h = 600 + w = length * 540 + elif length % 5 == 0: + h = 600 * int(length / 5) + w = 540 * 5 + else: + h = 600 * int(length / 5) + 600 + w = 540 * 5 + A = await asyncio.get_event_loop().run_in_executor(None, _pst_my_knife, w, h, knifes_list) + return image(b64=A.pic2bs4()) + else: + return "您木有开出金色级别的皮肤喔" + + +def _pst_my_knife(w, h, knifes_list): + A = CreateImg(w, h, 540, 600) + for knife in knifes_list: + case = knife.split('||')[0] + knife = knife.split('||')[1] + name = knife[:knife.find('(')].strip() + itype = knife[knife.find('(')+1: knife.find(')')].strip() + mosun = knife[knife.find('磨损:')+3: knife.rfind('价格:')].strip() + if mosun[-1] == ',' or mosun[-1] == ',': + mosun = mosun[:-1] + price = knife[knife.find('价格:')+3:] + skin_name = "" + for i in pypinyin.pinyin(name.replace('|', '-').replace('(StatTrak™)', '').strip(), + style=pypinyin.NORMAL): + skin_name += ''.join(i) + knife_img = CreateImg(470, 600, 470, 470, font_size=20) + knife_img.paste(alphabg2white_PIL( + Image.open(IMAGE_PATH + f'cases/{case}/{skin_name}.png').resize((470, 470), Image.ANTIALIAS)), (0, 0)) + knife_img.text((5, 500), f'\t{name}({itype})') + knife_img.text((5, 530), f'\t磨损:{mosun}') + knife_img.text((5, 560), f'\t价格:{price}') + A.paste(knife_img) + return A + + + + +# G3SG1(StatTrak™) | 血腥迷彩 (战痕累累) +# G3SG1(StatTrak™) | 血腥迷彩 (战痕累累) +# G3SG1(StatTrak™) | 血腥迷彩 (战痕累累) diff --git a/plugins/open_cases/utils.py b/plugins/open_cases/utils.py new file mode 100644 index 00000000..8b28f162 --- /dev/null +++ b/plugins/open_cases/utils.py @@ -0,0 +1,283 @@ +from models.buff_price import BuffPrice +from services.db_context import db +from datetime import datetime, timedelta +from util.user_agent import get_user_agent +from configs.path_config import IMAGE_PATH +import aiohttp +import aiofiles +from models.open_cases_user import OpenCasesUser +import os +from services.log import logger +from util.utils import get_bot +from models.group_remind import GroupRemind +from util.utils import get_cookie_text +from asyncio.exceptions import TimeoutError +import pypinyin +from nonebot.adapters.cqhttp.exception import ActionFailed +from configs.config import buff_proxy + +url = "https://buff.163.com/api/market/goods" +# proxies = 'http://49.75.59.242:3128' + + +async def util_get_buff_price(case_name: str = "狂牙大行动") -> str: + cookie = {'session': get_cookie_text('buff')} + failed_list = [] + case = "" + for i in pypinyin.pinyin(case_name, style=pypinyin.NORMAL): + case += ''.join(i) + if case_name == "狂牙大行动": + case_id = 1 + elif case_name == "突围大行动": + case_id = 2 + elif case_name == "命悬一线": + case_id = 3 + elif case_name == '裂空': + case_id = 4 + elif case_name == '光谱': + case_id = 5 + else: + return "未查询到武器箱" + case = case.upper() + CASE_KNIFE = eval(case + "_CASE_KNIFE") + CASE_RED = eval(case + "_CASE_RED") + CASE_PINK = eval(case + "_CASE_PINK") + CASE_PURPLE = eval(case + "_CASE_PURPLE") + CASE_BLUE = eval(case + "_CASE_BLUE") + async with aiohttp.ClientSession(cookies=cookie, headers=get_user_agent()) as session: + for total_list in [CASE_KNIFE, CASE_RED, CASE_PINK, CASE_PURPLE, CASE_BLUE]: + print("----------------------------------") + for skin in total_list: + print(skin) + if skin in ["蝴蝶刀 | 无涂装", '求生匕首 | 无涂装', '流浪者匕首 | 无涂装', '系绳匕首 | 无涂装', '骷髅匕首 | 无涂装']: + skin = skin.split('|')[0].strip() + async with db.transaction(): + name_list = [] + price_list = [] + parameter = { + "game": "csgo", + "page_num": "1", + "search": skin + } + try: + async with session.get(url, proxy=buff_proxy, params=parameter, timeout=20) as response: + if response.status == 200: + data = (await response.json())["data"] + total_page = data["total_page"] + data = data["items"] + flag = False + if skin.find('|') == -1: # in ['蝴蝶刀', '求生匕首', '流浪者匕首', '系绳匕首', '骷髅匕首']: + for i in range(1, total_page + 1): + name_list = [] + price_list = [] + parameter = { + "game": "csgo", + "page_num": f"{i}", + "search": skin + } + async with session.get(url, params=parameter, timeout=20) as res: + data = (await response.json())["data"]["items"] + for j in range(len(data)): + if data[j]['name'] in [f'{skin}(★)']: + name = data[j]["name"] + price = data[j]["sell_reference_price"] + name_list.append(name.split('(')[0].strip() + ' | 无涂装') + price_list.append(price) + print(name_list[-1]) + print(price_list[-1]) + flag = True + break + if flag: + break + else: + try: + for _ in range(total_page): + for i in range(len(data)): + name = data[i]["name"] + price = data[i]["sell_reference_price"] + name_list.append(name) + price_list.append(price) + except Exception as e: + failed_list.append(skin) + print(f"{skin}更新失败") + else: + failed_list.append(skin) + print(f"{skin}更新失败") + except Exception: + failed_list.append(skin) + print(f"{skin}更新失败") + continue + for i in range(len(name_list)): + name = name_list[i].strip() + price = float(price_list[i]) + if name.find("(★)") != -1: + name = name[: name.find("(")] + name[name.find(")") + 1:] + if name.find("消音") != -1 and name.find("(S") != -1: + name = name.split("(")[0][:-4] + "(" + name.split("(")[1] + name = name.split("|")[0].strip() + " | " + name.split("|")[1].strip() + elif name.find("消音") != -1: + name = name.split("|")[0][:-5].strip() + " | " + name.split("|")[1].strip() + if name.find(" 18 ") != -1 and name.find("(S") != -1: + name = name.split("(")[0][:-5] + "(" + name.split("(")[1] + name = name.split("|")[0].strip() + " | " + name.split("|")[1].strip() + elif name.find(" 18 ") != -1: + name = name.split("|")[0][:-6].strip() + " | " + name.split("|")[1].strip() + dbskin = await BuffPrice.ensure(name, True) + if (dbskin.update_date + timedelta(8)).date() == datetime.now().date(): + continue + await dbskin.update( + case_id=case_id, + skin_price=price, + update_date=datetime.now(), + ).apply() + print(f"{name_list[i]}---------->成功更新") + result = None + if failed_list: + result = "" + for fail_skin in failed_list: + result += fail_skin + "\n" + return result[:-1] if result else "更新价格成功" + + +async def util_get_buff_img(case_name: str = "狂牙大行动") -> str: + cookie = {'session': get_cookie_text('buff')} + error_list = [] + case = "" + for i in pypinyin.pinyin(case_name, style=pypinyin.NORMAL): + case += ''.join(i) + path = "cases/" + case + "/" + if not os.path.exists(IMAGE_PATH + path): + os.mkdir(IMAGE_PATH + path) + case = case.upper() + CASE_KNIFE = eval(case + "_CASE_KNIFE") + CASE_RED = eval(case + "_CASE_RED") + CASE_PINK = eval(case + "_CASE_PINK") + CASE_PURPLE = eval(case + "_CASE_PURPLE") + CASE_BLUE = eval(case + "_CASE_BLUE") + async with aiohttp.ClientSession(cookies=cookie, headers=get_user_agent()) as session: + for total_list in [CASE_KNIFE, CASE_RED, CASE_PINK, CASE_PURPLE, CASE_BLUE]: + for skin in total_list: + parameter = { + "game": "csgo", + "page_num": "1", + "search": skin + } + if skin in ["蝴蝶刀 | 无涂装", '求生匕首 | 无涂装', '流浪者匕首 | 无涂装', '系绳匕首 | 无涂装', '骷髅匕首 | 无涂装']: + skin = skin.split('|')[0].strip() + print("开始更新----->", skin) + print(skin) + skin_name = '' + # try: + async with session.get(url, proxy=buff_proxy, params=parameter, timeout=20) as response: + if response.status == 200: + data = (await response.json())["data"] + total_page = data["total_page"] + flag = False + if skin.find('|') == -1: # in ['蝴蝶刀', '求生匕首', '流浪者匕首', '系绳匕首', '骷髅匕首']: + for i in range(1, total_page + 1): + async with session.get(url, params=parameter, timeout=20) as res: + data = (await response.json())["data"]["items"] + for j in range(len(data)): + if data[j]['name'] in [f'{skin}(★)']: + img_url = data[j]['goods_info']['icon_url'] + for k in pypinyin.pinyin(skin + '无涂装', style=pypinyin.NORMAL): + skin_name += ''.join(k) + async with aiofiles.open(IMAGE_PATH + path + skin_name + ".png", 'wb') as f: + print("------->开始写入 ", skin) + async with session.get(img_url, timeout=7) as res: + await f.write(await res.read()) + flag = True + break + if flag: + break + else: + img_url = (await response.json())["data"]['items'][0]['goods_info']['icon_url'] + for i in pypinyin.pinyin(skin.replace('|', '-').strip(), style=pypinyin.NORMAL): + skin_name += ''.join(i) + async with aiofiles.open(IMAGE_PATH + path + skin_name + ".png", 'wb') as f: + print("------->开始写入 ", skin) + async with session.get(img_url, timeout=7) as res: + await f.write(await res.read()) + # async with session.get(url, params=parameter, timeout=7) as response: + # if response.status == 200: + # img_url = (await response.json())["data"]['items'][0]['goods_info']['icon_url'] + # skin_name = '' + # for i in pypinyin.pinyin(skin.split("|")[1].strip(), style=pypinyin.NORMAL): + # skin_name += ''.join(i) + # async with aiofiles.open(IMAGE_PATH + path + skin_name + ".png", 'wb') as f: + # print("------->开始写入 ", skin) + # async with session.get(img_url, timeout=7) as res: + # await f.write(await res.read()) + # except Exception: + # print("图片更新失败 ---->", skin) + # error_list.append(skin) + result = None + if error_list: + result = "" + for errskin in error_list: + result += errskin + "\n" + return result[:-1] if result else "更新图片成功" + + +async def get_price(dname): + cookie = {'session': get_cookie_text('buff')} + name_list = [] + price_list = [] + parameter = { + "game": "csgo", + "page_num": "1", + "search": dname + } + try: + async with aiohttp.ClientSession(cookies=cookie, headers=get_user_agent()) as session: + async with session.get(url, params=parameter, timeout=7) as response: + if response.status == 200: + try: + data = (await response.json())["data"] + total_page = data["total_page"] + data = data["items"] + for _ in range(total_page): + for i in range(len(data)): + name = data[i]["name"] + price = data[i]["sell_reference_price"] + name_list.append(name) + price_list.append(price) + except Exception as e: + return "没有查询到...", 998 + else: + return "访问失败!", response.status + except TimeoutError as e: + return "访问超时! 请重试或稍后再试!", 997 + result = f"皮肤: {dname}({len(name_list)})\n" + # result = "皮肤: " + dname + "\n" + for i in range(len(name_list)): + result += name_list[i] + ": " + price_list[i] + "\n" + return result[:-1], 999 + + +async def update_count_daily(): + try: + users = await OpenCasesUser.get_user_all() + if users: + for user in users: + await user.update( + today_open_total=0, + ).apply() + 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: + if await GroupRemind.get_status(g, 'kxcz'): + try: + await bot.send_group_msg(group_id=g, message="今日开箱次数重置成功") + except ActionFailed: + logger.warning(f'{g} 群被禁言,无法发送 开箱重置提醒') + logger.info("今日开箱次数重置成功") + except Exception as e: + logger.error(f'开箱重置错误 e:{e}') + + + +# 蝴蝶刀(★) | 噩梦之夜 (久经沙场) +if __name__ == '__main__': + print(util_get_buff_img("xxxx/")) diff --git a/plugins/parse_bilibili_json.py b/plugins/parse_bilibili_json.py new file mode 100644 index 00000000..4ba0cde3 --- /dev/null +++ b/plugins/parse_bilibili_json.py @@ -0,0 +1,75 @@ +from nonebot import on_message +from services.log import logger +from nonebot.adapters.cqhttp import Bot, GroupMessageEvent +from nonebot.typing import T_State +from util.utils import get_message_json, get_local_proxy +import json +from util.user_agent import get_user_agent +from nonebot.adapters.cqhttp.permission import GROUP +from bilibili_api import video +from util.init_result import image +from models.group_remind import GroupRemind +from nonebot.adapters.cqhttp.exception import ActionFailed +import time +import aiohttp +import bilibili_api +if get_local_proxy(): + proxy_ip_port = get_local_proxy().split("//", maxsplit=1)[1] + bilibili_api.request_settings["proxies"] = {'http': f'http://{proxy_ip_port}', 'https': f'https://{proxy_ip_port}'} + + +parse_bilibili_json = on_message(priority=1, permission=GROUP, block=False) + + +@parse_bilibili_json.handle() +async def _(bot: Bot, event: GroupMessageEvent, state: T_State): + if await GroupRemind.get_status(event.group_id, 'blpar') and get_message_json(event.json()): + data = json.loads(get_message_json(event.json())['data']) + if data: + if data.get('desc') == '哔哩哔哩': + async with aiohttp.ClientSession(headers=get_user_agent()) as session: + async with session.get(data['meta']['detail_1']['qqdocurl'], proxy=get_local_proxy(), timeout=7) as response: + url = str(response.url).split("?")[0] + print(url) + bvid = url.split('/')[-1] + vd_info = video.get_video_info(bvid=bvid) + aid = vd_info['aid'] + title = vd_info['title'] + author = vd_info['owner']['name'] + reply = vd_info['stat']['reply'] # 回复 + favorite = vd_info['stat']['favorite'] # 收藏 + coin = vd_info['stat']['coin'] # 投币 + # like = vd_info['stat']['like'] # 点赞 + # danmu = vd_info['stat']['danmaku'] # 弹幕 + date = time.strftime("%Y-%m-%d", time.localtime(vd_info['ctime'])) + try: + await parse_bilibili_json.send( + image(vd_info["pic"]) + + f'\nav{aid}\n标题:{title}\n' + f'UP:{author}\n' + f'上传日期:{date}\n' + f'回复:{reply},收藏:{favorite},投币:{coin}\n' + f'{url}' + ) + except ActionFailed: + logger.warning(f'{event.group_id} 发送bilibili解析失败') + logger.info(f'USER {event.user_id} GROUP {event.group_id} 解析bilibili转发 {url}') + else: + return + else: + return + + + + + + + + + + + + + + + diff --git a/plugins/pixiv/__init__.py b/plugins/pixiv/__init__.py new file mode 100644 index 00000000..4e2dba29 --- /dev/null +++ b/plugins/pixiv/__init__.py @@ -0,0 +1,194 @@ +from nonebot.typing import T_State +from nonebot.adapters.cqhttp import Bot, MessageEvent +from nonebot import on_command +from util.utils import get_message_text, UserExistLimiter, is_number +from .data_source import get_pixiv_urls, download_pixiv_imgs, search_pixiv_urls +import time +from services.log import logger +from nonebot.adapters.cqhttp.exception import NetworkError + +__plugin_usage__1 = '''P站排行榜帮助: +可选参数: +类型: + 1. 日排行 + 2. 周排行 + 3. 月排行 + 4. 原创排行 + 5. 新人排行 + 6. R18日排行 + 7. R18周排行 + 8. R18受男性欢迎排行 + 9. R18重口排行【慎重!】 +【使用时选择参数序号即可,R18仅可私聊】 +p站排行榜 类型 数量(可选) 日期(可选) +示例: + p站排行榜 (无参数默认为日榜) + p站排行榜 1 + p站排行榜 1 5 + p站排行榜 1 5 2018-4-25 +【注意空格!!】【在线搜索会较慢】 +''' + +__plugin_usage__2 = '''P站搜图帮助: +可选参数: + 1.热度排序 + 2.时间排序 +【使用时选择参数序号即可,R18仅可私聊】 +搜图 关键词 数量(可选) 排序方式(可选) r18(可选) +示例: + 搜图 樱岛麻衣 + 搜图 樱岛麻衣 5 1 + 搜图 樱岛麻衣 5 2 r18 +【默认为 热度排序】 +【注意空格!!】【在线搜索会较慢】【数量可能不符】 +''' + +rank_dict = { + '1': 'day', + '2': 'week', + '3': 'month', + '4': 'week_original', + '5': 'week_rookie', + '6': 'day_r18', + '7': 'week_r18', + '8': 'day_male_r18', + '9': 'week_r18g' +} + +_ulmt = UserExistLimiter() + +pixiv_rank = on_command('p站排行', aliases={'P站排行榜', 'p站排行榜', 'P站排行榜'}, priority=5, block=True) +pixiv_keyword = on_command('搜图', priority=5, block=True) + + +@pixiv_rank.handle() +async def _(bot: Bot, event: MessageEvent, state: T_State): + msg = get_message_text(event.json()).strip() + if msg in ['帮助']: + await pixiv_rank.finish(__plugin_usage__1) + msg = msg.split(' ') + msg = [m for m in msg if m] + if not msg: + msg = ['1'] + if msg[0] in ['6', '7', '8', '9']: + if event.message_type == 'group': + await pixiv_rank.finish('羞羞脸!私聊里自己看!', at_sender=True) + # print(msg) + if _ulmt.check(event.user_id): + await pixiv_rank.finish("P站排行榜正在搜索噢,不要重复触发命令呀") + _ulmt.set_True(event.user_id) + if len(msg) == 0 or msg[0] == '': + text_list, urls, code = await get_pixiv_urls(rank_dict.get('1')) + elif len(msg) == 1: + if msg[0] not in ['1', '2', '3', '4', '5', '6', '7', '8', '9']: + await pixiv_rank.finish("要好好输入要看什么类型的排行榜呀!", at_sender=True) + text_list, urls, code = await get_pixiv_urls(rank_dict.get(msg[0])) + elif len(msg) == 2: + text_list, urls, code = await get_pixiv_urls(rank_dict.get(msg[0]), int(msg[1])) + elif len(msg) == 3: + if not check_date(msg[2]): + await pixiv_rank.finish('日期格式错误了', at_sender=True) + text_list, urls, code = await get_pixiv_urls(rank_dict.get(msg[0]), int(msg[1]), msg[2]) + else: + _ulmt.set_False(event.user_id) + await pixiv_rank.finish('格式错了噢,看看帮助?', at_sender=True) + if code != 200: + await pixiv_keyword.finish(text_list[0]) + else: + if not text_list or not urls: + await pixiv_rank.finish('没有找到啊,等等再试试吧~V', at_sender=True) + for i in range(len(text_list)): + try: + await pixiv_rank.send(text_list[i] + await download_pixiv_imgs(urls[i], event.user_id)) + except NetworkError: + await pixiv_keyword.send('这张图网络炸了!', at_sender=True) + logger.info( + f"(USER {event.user_id}, GROUP {event.group_id if event.message_type != 'private' else 'private'})" + f" 查看了P站排行榜 code:{msg[0]}") + _ulmt.set_False(event.user_id) + + +@pixiv_keyword.handle() +async def _(bot: Bot, event: MessageEvent, state: T_State): + msg = get_message_text(event.json()).strip() + if msg in ['帮助'] or not msg: + await pixiv_keyword.finish(__plugin_usage__2) + if event.message_type == 'group': + if msg.find('r18') != -1: + await pixiv_keyword.finish('(脸红#) 你不会害羞的 八嘎!', at_sender=True) + if msg.find('r18') == -1: + r18 = 1 + else: + r18 = 2 + msg = msg.replace('r18', '').strip() + if _ulmt.check(event.user_id): + await pixiv_rank.finish("P站关键词正在搜索噢,不要重复触发命令呀") + _ulmt.set_True(event.user_id) + msg = msg.split(' ') + msg = [m for m in msg if m] + if len(msg) == 1: + keyword = msg[0].strip() + num = 5 + order = 'popular' + elif len(msg) == 2: + keyword = msg[0].strip() + if not is_number(msg[1].strip()): + _ulmt.set_False(event.user_id) + await pixiv_keyword.finish('图片数量必须是数字!', at_sender=True) + num = int(msg[1].strip()) + order = 'popular' + elif len(msg) == 3: + keyword = msg[0].strip() + if not is_number(msg[1].strip()): + _ulmt.set_False(event.user_id) + await pixiv_keyword.finish('图片数量必须是数字!', at_sender=True) + num = int(msg[1].strip()) + if not is_number(msg[2].strip()): + _ulmt.set_False(event.user_id) + await pixiv_keyword.finish('排序方式必须是数字!', at_sender=True) + if msg[2].strip() == '1': + order = 'popular' + else: + order = 'xxx' + else: + _ulmt.set_False(event.user_id) + await pixiv_keyword.finish('参数不正确,一定要好好看看帮助啊!', at_sender=True) + text_list, urls, code = await search_pixiv_urls(keyword, num, order, r18) + if code != 200: + _ulmt.set_False(event.user_id) + await pixiv_keyword.finish(text_list[0]) + else: + for i in range(len(text_list)): + try: + await pixiv_keyword.send(text_list[i] + await download_pixiv_imgs(urls[i], event.user_id)) + except NetworkError: + await pixiv_keyword.send('这张图网络炸了!', at_sender=True) + logger.info( + f"(USER {event.user_id}, GROUP {event.group_id if event.message_type != 'private' else 'private'})" + f" 查看了搜索 {keyword} R18:{r18}") + _ulmt.set_False(event.user_id) + + +def check_date(date): + try: + time.strptime(date, "%Y-%m-%d") + return True + except: + return False + + + + + + + + + + + + + + + + + diff --git a/plugins/pixiv/__pycache__/__init__.cpython-38.pyc b/plugins/pixiv/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..7cbf7fe4 Binary files /dev/null and b/plugins/pixiv/__pycache__/__init__.cpython-38.pyc differ diff --git a/plugins/pixiv/__pycache__/__init__.cpython-39.pyc b/plugins/pixiv/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 00000000..061d6060 Binary files /dev/null and b/plugins/pixiv/__pycache__/__init__.cpython-39.pyc differ diff --git a/plugins/pixiv/__pycache__/data_source.cpython-38.pyc b/plugins/pixiv/__pycache__/data_source.cpython-38.pyc new file mode 100644 index 00000000..ab89cbec Binary files /dev/null and b/plugins/pixiv/__pycache__/data_source.cpython-38.pyc differ diff --git a/plugins/pixiv/__pycache__/data_source.cpython-39.pyc b/plugins/pixiv/__pycache__/data_source.cpython-39.pyc new file mode 100644 index 00000000..48f809bb Binary files /dev/null and b/plugins/pixiv/__pycache__/data_source.cpython-39.pyc differ diff --git a/plugins/pixiv/data_source.py b/plugins/pixiv/data_source.py new file mode 100644 index 00000000..71839a8d --- /dev/null +++ b/plugins/pixiv/data_source.py @@ -0,0 +1,84 @@ +import aiohttp +import aiofiles +from configs.path_config import IMAGE_PATH +from util.utils import get_local_proxy +from util.user_agent import get_user_agent +from bs4 import BeautifulSoup +import feedparser +from util.init_result import image +from asyncio.exceptions import TimeoutError +import platform +if platform.system() == 'Windows': + import asyncio + asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy()) + + +async def get_pixiv_urls(mode: str, num: int = 5, date: str = '') -> 'list, list, int': + url = 'https://rsshub.app/pixiv/ranking/{}' + iurl = url.format(mode) + if date: + iurl += f'/{date}' + return await parser_data(iurl, num) + + +async def download_pixiv_imgs(urls: list, user_id: int) -> str: + result = '' + index = 0 + for img in urls: + async with aiohttp.ClientSession(headers=get_user_agent()) as session: + for _ in range(3): + async with session.get(img, proxy=get_local_proxy(), timeout=3) as response: + async with aiofiles.open(IMAGE_PATH + f'temp/{user_id}_{index}_pixiv.jpg', 'wb') as f: + try: + await f.write(await response.read()) + result += image(f'{user_id}_{index}_pixiv.jpg', 'temp') + index += 1 + break + except TimeoutError: + # result += '\n这张图下载失败了..\n' + pass + else: + result += '\n这张图下载失败了..\n' + return result + + +async def search_pixiv_urls(keyword: str, num: int, order: str, r18: int) -> 'list, list': + url = 'https://rsshub.app/pixiv/search/{}/{}/{}'.format(keyword, order, r18) + return await parser_data(url, num) + + +async def parser_data(url: str, num: int) -> 'list, list, int': + text_list = [] + urls = [] + async with aiohttp.ClientSession() as session: + for _ in range(3): + try: + async with session.get(url, proxy=get_local_proxy(), timeout=4) as response: + data = feedparser.parse(await response.text())['entries'] + break + except TimeoutError: + pass + else: + return ['网络不太好,也许过一会就好了'], [], 998 + try: + if len(data) == 0: + return ['没有搜索到喔'], [], 997 + if num > len(data): + num = len(data) + data = data[:num] + for data in data: + soup = BeautifulSoup(data['summary'], 'lxml') + title = "标题:" + data['title'] + pl = soup.find_all('p') + author = pl[0].text.split('-')[0].strip() + imgs = [] + text_list.append(f'{title}\n{author}\n') + for p in pl[1:]: + imgs.append(p.find('img').get('src')) + urls.append(imgs) + except ValueError: + return ['是网站坏了啊,也许过一会就好了'], [], 999 + return text_list, urls, 200 + + +# asyncio.get_event_loop().run_until_complete(get_pixiv_urls('day')) diff --git a/plugins/poke/__init__.py b/plugins/poke/__init__.py new file mode 100644 index 00000000..727788e2 --- /dev/null +++ b/plugins/poke/__init__.py @@ -0,0 +1,52 @@ +from nonebot import on_notice +from nonebot.adapters.cqhttp import Bot, PokeNotifyEvent +from nonebot.typing import T_State +from configs.path_config import VOICE_PATH, IMAGE_PATH +import os +from util.init_result import record, image, poke +from services.log import logger +import random +from util.utils import CountLimiter +from models.ban_user import BanUser + +# 戳 一 戳 + +poke__reply = [ + "lsp你再戳?", "连个可爱美少女都要戳的肥宅真恶心啊。", + "你再戳!", "?再戳试试?", "别戳了别戳了再戳就坏了555", "我爪巴爪巴,球球别再戳了", "你戳你🐎呢?!", + "那...那里...那里不能戳...绝对...", "(。´・ω・)ん?", "有事恁叫我,别天天一个劲戳戳戳!", "欸很烦欸!你戳🔨呢", + "?", "再戳一下试试?", "???", "正在关闭对您的所有服务...关闭成功", "啊呜,太舒服刚刚竟然睡着了。什么事?", "正在定位您的真实地址。。。\r\n定位成功。轰炸机已起飞" +] + + +_clmt = CountLimiter(3) + +poke_ = on_notice(priority=5) + + +@poke_.handle() +async def _poke_(bot: Bot, event: PokeNotifyEvent, state: T_State) -> None: + if event.notice_type == 'notify' and event.sub_type == 'poke' and event.self_id == event.target_id: + _clmt.add(event.user_id) + if _clmt.check(event.user_id) or random.random() < 0.3: + rst = '' + if random.random() < 0.15: + await BanUser.ban(event.user_id, 1, 60) + rst = '气死我了!' + await poke_.finish(rst + random.choice(poke__reply), at_sender=True) + rand = random.random() + if rand <= 0.3: + path = random.choice(['loli/', 'meitu/']) + index = random.randint(0, len(os.listdir(IMAGE_PATH + path))) + result = f'id:{index}' + image(f'{index}.jpg', path) + await poke_.send(result) + logger.info(f'USER {event.user_id} 戳了戳我 回复: {result} \n {result}') + elif 0.3 < rand < 0.6: + voice = random.choice(os.listdir(VOICE_PATH + 'dinggong/')) + result = record(voice, "dinggong") + await poke_.send(result) + await poke_.send(voice.split('_')[1]) + logger.info(f'USER {event.user_id} 戳了戳我 回复: {result} \n {voice.split("_")[1]}') + else: + await poke_.send(poke(event.user_id)) + diff --git a/plugins/poke/__pycache__/__init__.cpython-38.pyc b/plugins/poke/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..75ef2c42 Binary files /dev/null and b/plugins/poke/__pycache__/__init__.cpython-38.pyc differ diff --git a/plugins/poke/__pycache__/__init__.cpython-39.pyc b/plugins/poke/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 00000000..8890b3dc Binary files /dev/null and b/plugins/poke/__pycache__/__init__.cpython-39.pyc differ diff --git a/plugins/quotations.py b/plugins/quotations.py new file mode 100644 index 00000000..3ae02463 --- /dev/null +++ b/plugins/quotations.py @@ -0,0 +1,29 @@ +from nonebot import on_command +import random +from util.utils import get_lines +from configs.path_config import TXT_PATH +from services.log import logger +from nonebot.adapters.cqhttp import Bot, MessageEvent +from nonebot.typing import T_State + + +__plugin_name__ = '语录' +__plugin_usage__ = '用法: 二次元语录给你力量' + + +lines = get_lines(TXT_PATH + "yulu.txt") + + +quotations = on_command("语录", aliases={'二次元', '二次元语录'}, priority=5, block=True) + + +@quotations.handle() +async def _(bot: Bot, event: MessageEvent, state: T_State): + if str(event.get_message()) in ['帮助']: + await quotations.finish(__plugin_usage__) + result = random.choice(lines) + logger.info( + f"(USER {event.user_id}, GROUP {event.group_id if event.message_type != 'private' else 'private'}) 发送语录:" + + result[:-1]) + await quotations.finish(result[:-1]) + diff --git a/plugins/reimu/__init__.py b/plugins/reimu/__init__.py new file mode 100644 index 00000000..031da058 --- /dev/null +++ b/plugins/reimu/__init__.py @@ -0,0 +1,96 @@ +from nonebot import on_command +from nonebot.adapters.cqhttp.permission import PRIVATE +from .data_source import from_reimu_get_info +from services.log import logger +from nonebot.adapters.cqhttp import Bot, Event +from nonebot.typing import T_State +from util.utils import is_number, get_message_text, UserExistLimiter, scheduler +from models.count_user import UserCount +from configs.config import COUNT_PER_DAY_REIMU + +__plugin_name__ = '上车' +__plugin_usage__ = r""" +* 请各位使用后不要转发 * +* 大部分解压密码是⑨ * +/ 每人每天仅提供 5 次上车机会(只能私聊)更多次数请向管理员申请(用爱发电)限制小色批乱搜 / +/ 并不推荐小色批使用此功能(主要是不够色,目的不够明确) / +上车 [目的地] +上车 5 [目的地] 该目的地第5页停车场 +ps: 请尽量提供具体的目的地名称 +""".strip() + + +_ulmt = UserExistLimiter() + +reimu = on_command('上车', permission=PRIVATE, block=True, priority=1) + + +@reimu.args_parser +async def _(bot: Bot, event: Event, state: T_State): + if get_message_text(event.json()) in ['取消', '算了']: + await reimu.finish("已取消操作..", at_sender=True) + if not get_message_text(event.json()): + await reimu.reject('没时间等了!快说你要去哪里?', at_sender=True) + state['keyword'] = get_message_text(event.json()) + state['page'] = 1 + + +@reimu.handle() +async def _(bot: Bot, event: Event, state: T_State): + if str(event.get_message()) in ['帮助']: + await reimu.finish(__plugin_usage__) + if await UserCount.check_count(event.user_id, 'reimu', COUNT_PER_DAY_REIMU): + await reimu.finish('今天已经没车了,请明天再来...', at_sender=True) + if _ulmt.check(event.user_id): + await reimu.finish('您还没下车呢,请稍等...', at_sender=True) + _ulmt.set_True(event.user_id) + msg = get_message_text(event.json()) + args = msg.split(" ") + if msg in ['!', '!', '?', '?', ',', ',', '.', '。']: + await reimu.finish(__plugin_usage__) + if msg: + if len(args) > 1 and is_number(args[0]): + state['keyword'] = args[1] + state['page'] = args[0] + else: + state['keyword'] = msg + state['page'] = 1 + + +@reimu.got('keyword', '你的目的地是哪?') +async def _(bot: Bot, event: Event, state: T_State): + try: + keyword = state['keyword'] + page = state['page'] + print(keyword, page) + await UserCount.add_count(event.user_id, 'reimu') + await reimu.send('已经帮你关好车门了', at_sender=True) + reimu_report = await from_reimu_get_info(keyword, page) + if reimu_report: + await reimu.send(reimu_report) + else: + logger.error("Not found reimuInfo") + await reimu.send("没找着") + _ulmt.set_False(event.user_id) + except: + _ulmt.set_False(event.user_id) + + +@scheduler.scheduled_job( + 'cron', + # year=None, + # month=None, + # day=None, + # week=None, + # day_of_week="mon,tue,wed,thu,fri", + hour=0, + minute=1, + # second=None, + # start_date=None, + # end_date=None, + # timezone=None, +) +async def _(): + await UserCount.reset_count() + + diff --git a/plugins/reimu/__pycache__/__init__.cpython-38.pyc b/plugins/reimu/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..e151d6f6 Binary files /dev/null and b/plugins/reimu/__pycache__/__init__.cpython-38.pyc differ diff --git a/plugins/reimu/__pycache__/__init__.cpython-39.pyc b/plugins/reimu/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 00000000..550ca6b3 Binary files /dev/null and b/plugins/reimu/__pycache__/__init__.cpython-39.pyc differ diff --git a/plugins/reimu/__pycache__/data_source.cpython-38.pyc b/plugins/reimu/__pycache__/data_source.cpython-38.pyc new file mode 100644 index 00000000..20057281 Binary files /dev/null and b/plugins/reimu/__pycache__/data_source.cpython-38.pyc differ diff --git a/plugins/reimu/__pycache__/data_source.cpython-39.pyc b/plugins/reimu/__pycache__/data_source.cpython-39.pyc new file mode 100644 index 00000000..984b9878 Binary files /dev/null and b/plugins/reimu/__pycache__/data_source.cpython-39.pyc differ diff --git a/plugins/reimu/data_source.py b/plugins/reimu/data_source.py new file mode 100644 index 00000000..266d1045 --- /dev/null +++ b/plugins/reimu/data_source.py @@ -0,0 +1,116 @@ +from lxml import etree +import time +import aiohttp +from services.log import logger +from configs.config import MAXINFO_REIMU +from util.user_agent import get_user_agent +from util.utils import get_local_proxy +from asyncio.exceptions import TimeoutError + + +async def from_reimu_get_info(key_word: str, page: int) -> str: + if "miku" in key_word.lower(): + logger.warning("Taboo words are being triggered") + return None + repass = "" + url = 'https://blog.reimu.net/search/' + key_word + '/page/' + str(page) + url_s = 'https://blog.reimu.net/' + try: + if key_word == "最近的存档": + logger.debug("Now starting get the {}".format(url_s)) + repass = await get_repass(url_s) + else: + logger.debug("Now starting get the {}".format(url)) + repass = await get_repass(url) + except TimeoutError as e: + logger.error("Timeout! {}".format(e)) + + return repass + + +async def get_repass(url: str) -> str: + repass = "" + info = "[Note]注意大部分资源解压密码为⑨\n" + fund = None + print(url) + async with aiohttp.ClientSession(headers=get_user_agent()) as session: + async with session.get(url, proxy=get_local_proxy(), timeout=15) as response: + html = etree.HTML(await response.text()) + + fund_l = html.xpath('//h1[@class="page-title"]/text()') + if fund_l: + fund = fund_l[0] + if fund == "未找到": + return "老司机也找不到路了……" + else: + pass + + headers = html.xpath('//article/header/h2/a/text()') + urls = html.xpath('//article/header/h2/a/@href') + logger.debug("Now get {} post from search page".format(len(headers))) + + headers_d = [] + urls_d = [] + for i, header in enumerate(headers): + if check_need_list(header): + headers_d.append(headers[i]) + urls_d.append(urls[i]) + else: + logger.debug("This title {} does not meet the requirements".format(header)) + + header_len = len(headers_d) + logger.debug("Get {} post after processing".format(header_len)) + if header_len > MAXINFO_REIMU: + headers_d = headers_d[:MAXINFO_REIMU] + urls_d = urls_d[:MAXINFO_REIMU] + + for h_s, url_s in zip(headers_d, urls_d): + if h_s != "审核结果存档": + time.sleep(1.5) + putline = await get_son_html_info(h_s, url_s) + if putline: + if repass: + repass = "\n\n- - - - - - - - \n".join([repass, putline]) + else: + repass = putline + else: + logger.info("审核归档页面已跳过") + + if repass: + repass = info + repass + return repass + + +async def get_son_html_info(h_s, url_s) -> str: + repass = "" + logger.debug("Now starting get the {}".format(url_s)) + async with aiohttp.ClientSession(headers=get_user_agent()) as session: + async with session.get(url_s, proxy=get_local_proxy(), timeout=15) as response: + html = etree.HTML(await response.text()) + pres = html.xpath('//div[@class="entry-content"]/pre/text()') + a_texts = html.xpath('//div[@class="entry-content"]/pre//a/text()') + a_hrefs = html.xpath('//div[@class="entry-content"]/pre//a/@href') + + if pres and a_texts and a_hrefs: + while "" in pres: + pres.remove("") + + repass = "【资源名称】 {}\n\n{}".format(h_s, pres[0].strip()) + for i, (a_t_s, a_h_s) in enumerate(zip(a_texts, a_hrefs)): + a = "\n {} {} {} ".format(a_t_s, a_h_s, pres[i + 1].strip()) + repass += a + else: + logger.warning("Not get putline from {}".format(url_s)) + + return repass + + +def check_need_list(header: str) -> bool: + not_need = ['音乐', '御所动态'] + for nd in not_need: + if nd in header: + return False + return True + + +# print(asyncio.get_event_loop().run_until_complete(from_reimu_get_info('萝莉'))) \ No newline at end of file diff --git a/plugins/remind/__init__.py b/plugins/remind/__init__.py new file mode 100644 index 00000000..8aa57f32 --- /dev/null +++ b/plugins/remind/__init__.py @@ -0,0 +1,194 @@ +from util.init_result import image +from util.utils import scheduler, get_bot +from services.log import logger +from models.group_remind import GroupRemind +from models.group_info import GroupInfo +from models.friend_user import FriendUser +from nonebot.adapters.cqhttp.exception import ActionFailed + +__name__ = "早晚安 [Hidden]" + + +# 早上好 +@scheduler.scheduled_job( + 'cron', + # year=None, + # month=None, + # day=None, + # week=None, + # day_of_week="mon,tue,wed,thu,fri", + hour=6, + minute=1, + # second=None, + # start_date=None, + # end_date=None, + # timezone=None, +) +async def _(): + try: + 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: + if await GroupRemind.get_status(g, 'zwa'): + result = image("zao.jpg", "zhenxun") + try: + await bot.send_group_msg(group_id=g, + message="早上好" + result) + except ActionFailed: + logger.warning(f'{g} 群被禁言中,无法发送早安') + except Exception as e: + logger.error(f'早晚安错误 e:{e}') + + +# 睡觉了 +@scheduler.scheduled_job( + 'cron', + hour=23, + minute=59, +) +async def _(): + try: + 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: + if await GroupRemind.get_status(g, 'zwa'): + result = image("sleep.jpg", "zhenxun") + try: + await bot.send_group_msg(group_id=g, + message="小真寻要睡觉了,你们也要早点睡呀" + result) + except ActionFailed: + logger.warning(f'{g} 群被禁言中,无法发送晚安') + except Exception as e: + logger.error(f'早晚安错误 e:{e}') + + +# 自动更新群组信息 +@scheduler.scheduled_job( + 'cron', + hour=3, + minute=1, +) +async def _(): + try: + 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: + group_info = await bot.get_group_info(group_id=g) + await GroupInfo.add_group_info(group_info['group_id'], group_info['group_name'], + group_info['max_member_count'], group_info['member_count']) + logger.info(f'自动更新群组 {g} 信息成功') + except Exception as e: + logger.error(f'自动更新群组信息错误 e:{e}') + + +# 自动更新好友信息 +@scheduler.scheduled_job( + 'cron', + hour=3, + minute=1, +) +async def _(): + try: + bot = get_bot() + fl = await bot.get_friend_list(self_id=bot.self_id) + for f in fl: + if await FriendUser.add_friend_info(f['user_id'], f['nickname']): + logger.info(f'自动更新好友 {f["user_id"]} 信息成功') + else: + logger.warning(f'自动更新好友 {f["user_id"]} 信息失败') + except Exception as e: + logger.error(f'自动更新群组信息错误 e:{e}') + +# 一次性任务 +# 固定时间触发,仅触发一次: +# +# from datetime import datetime +# +# @nonebot.scheduler.scheduled_job( +# 'date', +# run_date=datetime(2021, 1, 1, 0, 0), +# # timezone=None, +# ) +# async def _(): +# await bot.send_group_msg(group_id=123456, +# message="2021,新年快乐!") + +# 定期任务 +# 从 start_date 开始到 end_date 结束,根据类似 Cron +# +# 的规则触发任务: +# +# @nonebot.scheduler.scheduled_job( +# 'cron', +# # year=None, +# # month=None, +# # day=None, +# # week=None, +# day_of_week="mon,tue,wed,thu,fri", +# hour=7, +# # minute=None, +# # second=None, +# # start_date=None, +# # end_date=None, +# # timezone=None, +# ) +# async def _(): +# await bot.send_group_msg(group_id=123456, +# message="起床啦!") + +# 间隔任务 +# +# interval 触发器 +# +# 从 start_date 开始,每间隔一段时间触发,到 end_date 结束: +# +# @nonebot.scheduler.scheduled_job( +# 'interval', +# # weeks=0, +# # days=0, +# # hours=0, +# minutes=5, +# # seconds=0, +# # start_date=time.now(), +# # end_date=None, +# ) +# async def _(): +# has_new_item = check_new_item() +# if has_new_item: +# await bot.send_group_msg(group_id=123456, +# message="XX有更新啦!") + + +# 动态的计划任务 +# import datetime +# +# from apscheduler.triggers.date import DateTrigger # 一次性触发器 +# # from apscheduler.triggers.cron import CronTrigger # 定期触发器 +# # from apscheduler.triggers.interval import IntervalTrigger # 间隔触发器 +# from nonebot import on_command, scheduler +# +# @on_command('赖床') +# async def _(session: CommandSession): +# await session.send('我会在5分钟后再喊你') +# +# # 制作一个“5分钟后”触发器 +# delta = datetime.timedelta(minutes=5) +# trigger = DateTrigger( +# run_date=datetime.datetime.now() + delta +# ) +# +# # 添加任务 +# scheduler.add_job( +# func=session.send, # 要添加任务的函数,不要带参数 +# trigger=trigger, # 触发器 +# args=('不要再赖床啦!',), # 函数的参数列表,注意:只有一个值时,不能省略末尾的逗号 +# # kwargs=None, +# misfire_grace_time=60, # 允许的误差时间,建议不要省略 +# # jobstore='default', # 任务储存库,在下一小节中说明 +# ) + + + diff --git a/plugins/remind/__pycache__/__init__.cpython-38.pyc b/plugins/remind/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..66b01987 Binary files /dev/null and b/plugins/remind/__pycache__/__init__.cpython-38.pyc differ diff --git a/plugins/remind/__pycache__/__init__.cpython-39.pyc b/plugins/remind/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 00000000..0bdff1fb Binary files /dev/null and b/plugins/remind/__pycache__/__init__.cpython-39.pyc differ diff --git a/plugins/search_anime/__init__.py b/plugins/search_anime/__init__.py new file mode 100644 index 00000000..5935cb11 --- /dev/null +++ b/plugins/search_anime/__init__.py @@ -0,0 +1,56 @@ +from nonebot import on_command +from .data_source import from_anime_get_info +from services.log import logger +from nonebot.adapters.cqhttp import Bot, Event +from nonebot.typing import T_State +from configs.config import MAXINFO_GROUP_ANIME, MAXINFO_PRIVATE_ANIME +from util.utils import get_message_text, get_message_type, UserExistLimiter + + +__plugin_name__ = '搜番' +__plugin_usage__ = r""" +在群内使用此功能只返还5个结果,私聊返还 20 个结果(绝不能打扰老色批们看色图!) +搜索动漫资源 +搜番 [番剧名称或者关键词] +搜番 Aria +""".strip() +_ulmt = UserExistLimiter() + +search_anime = on_command('搜番', aliases={'搜动漫'}, priority=5, block=True) + + +@search_anime.args_parser +async def _(bot: Bot, event: Event, state: T_State): + msg = get_message_text(event.json()) + if not msg: + await search_anime.reject('番名番名番名呢?', at_sender=True) + state['anime'] = msg + + +@search_anime.handle() +async def _(bot: Bot, event: Event, state: T_State): + if get_message_text(event.json()) in ['帮助'] or get_message_text(event.json()) == '': + await search_anime.finish(__plugin_usage__) + if _ulmt.check(event.user_id): + await search_anime.finish('您有动漫正在搜索,请稍等...', at_sender=True) + _ulmt.set_True(event.user_id) + if get_message_text(event.json()): + state['anime'] = get_message_text(event.json()) + + +@search_anime.got('anime', prompt='是不是少了番名?') +async def _(bot: Bot, event: Event, state: T_State): + key_word = state['anime'] + await search_anime.send(f'开始搜番 {key_word}', at_sender=True) + anime_report = await from_anime_get_info(key_word, MAXINFO_GROUP_ANIME if get_message_type(event.json()) in ['group', 'discuss'] else MAXINFO_PRIVATE_ANIME) + if anime_report: + await search_anime.send(anime_report) + logger.info(f"USER {event.user_id} GROUP" + f" {event.group_id if event.message_type != 'private' else 'private'} 搜索番剧 {key_word} 成功") + else: + logger.warning(f"未找到番剧 {key_word}") + await search_anime.send(f"未找到番剧 {key_word}(也有可能是超时,再尝试一下?)") + _ulmt.set_False(event.user_id) + + + diff --git a/plugins/search_anime/__pycache__/__init__.cpython-38.pyc b/plugins/search_anime/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..d76b6f08 Binary files /dev/null and b/plugins/search_anime/__pycache__/__init__.cpython-38.pyc differ diff --git a/plugins/search_anime/__pycache__/__init__.cpython-39.pyc b/plugins/search_anime/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 00000000..fe2b4e6d Binary files /dev/null and b/plugins/search_anime/__pycache__/__init__.cpython-39.pyc differ diff --git a/plugins/search_anime/__pycache__/data_source.cpython-38.pyc b/plugins/search_anime/__pycache__/data_source.cpython-38.pyc new file mode 100644 index 00000000..d8695b62 Binary files /dev/null and b/plugins/search_anime/__pycache__/data_source.cpython-38.pyc differ diff --git a/plugins/search_anime/__pycache__/data_source.cpython-39.pyc b/plugins/search_anime/__pycache__/data_source.cpython-39.pyc new file mode 100644 index 00000000..523f3a71 Binary files /dev/null and b/plugins/search_anime/__pycache__/data_source.cpython-39.pyc differ diff --git a/plugins/search_anime/data_source.py b/plugins/search_anime/data_source.py new file mode 100644 index 00000000..d0cd330a --- /dev/null +++ b/plugins/search_anime/data_source.py @@ -0,0 +1,47 @@ +from lxml import etree +import feedparser +from urllib import parse +from services.log import logger +import aiohttp +import time +from util.utils import get_local_proxy + + +async def from_anime_get_info(key_word: str, max: int) -> str: + s_time = time.time() + repass = "" + url = 'https://share.dmhy.org/topics/rss/rss.xml?keyword=' + parse.quote(key_word) + try: + logger.debug("Now starting get the {}".format(url)) + repass = await get_repass(url, max) + except Exception as e: + logger.error("Timeout! {}".format(e)) + + return f"搜索 {key_word} 结果(耗时 {int(time.time() - s_time)} 秒):\n" + repass + + +async def get_repass(url: str, max: int) -> str: + putline = [] + async with aiohttp.ClientSession() as session: + async with session.get(url, proxy=get_local_proxy(), timeout=20) as response: + d = feedparser.parse(await response.text()) + url_list = [e.link for e in d.entries][:max] + for u in url_list: + print(u) + try: + async with session.get(u, proxy=get_local_proxy(), timeout=20) as res: + html = etree.HTML(await res.text()) + magent = html.xpath('.//a[@id="a_magnet"]/text()')[0] + title = html.xpath('.//h3/text()')[0] + item = html.xpath('//div[@class="info resource-info right"]/ul/li') + class_a = item[0].xpath('string(.)')[5:].strip().replace("\xa0", "").replace("\t", "") + size = item[3].xpath('string(.)')[5:].strip() + + putline.append("【{}】| {}\n【{}】| {}".format(class_a, title, size, magent)) + except Exception as e: + logger.warning(f'搜番超时 e:{e}') + + repass = '\n\n'.join(putline) + + return repass +# print(asyncio.get_event_loop().run_until_complete(from_anime_get_info('进击的巨人', 1234556))) \ No newline at end of file diff --git a/plugins/search_buff_skin_price/__init__.py b/plugins/search_buff_skin_price/__init__.py new file mode 100644 index 00000000..bbb2d276 --- /dev/null +++ b/plugins/search_buff_skin_price/__init__.py @@ -0,0 +1,75 @@ +from nonebot import on_command +from .data_source import get_price, update_buff_cookie +from services.log import logger +from nonebot.typing import T_State +from nonebot.adapters import Bot, Event +from nonebot.rule import to_me +from nonebot.permission import SUPERUSER +from util.utils import UserExistLimiter, get_message_text + + +__plugin_name__ = '查询皮肤' +__plugin_usage__ = '查询皮肤帮助:\n\t' \ + '对我说 "查询皮肤 xxx yyyy",我会回复xxx的底价哦\n\t' \ + '示例: 查询皮肤 awp 二西莫夫' + + +_ulmt = UserExistLimiter() + + +search_skin = on_command('查询皮肤', aliases={'皮肤查询'}, priority=5, block=True) + + +@search_skin.args_parser +async def parse(bot: Bot, event: Event, state: T_State): + if get_message_text(event.json()) in ['取消', '算了']: + await search_skin.finish("已取消操作..", at_sender=True) + state[state["_current_key"]] = str(event.get_message()) + + +@search_skin.handle() +async def _(bot: Bot, event: Event, state: T_State): + if str(event.get_message()) in ['帮助']: + await search_skin.finish(__plugin_usage__) + raw_arg = get_message_text(event.json()) + if _ulmt.check(event.user_id): + await search_skin.finish('您有皮肤正在搜索,请稍等...', at_sender=True) + if raw_arg: + args = raw_arg.split(" ") + if len(args) >= 2: + state['name'] = args[0] + state['skin'] = args[1] + + +@search_skin.got('name', prompt="要查询什么武器呢?") +@search_skin.got('skin', prompt="要查询该武器的什么皮肤呢?") +async def arg_handle(bot: Bot, event: Event, state: T_State): + _ulmt.set_True(event.user_id) + if state['name'] in ['ak', 'ak47']: + state['name'] = 'ak-47' + name = state['name'] + " | " + state['skin'] + try: + result, status_code = await get_price(name) + except FileNotFoundError: + await search_skin.finish('请先对真寻说"设置cookie"来设置cookie!') + if status_code in [996, 997, 998]: + _ulmt.set_False(event.user_id) + await search_skin.finish(result) + if result: + logger.info( + f"(USER {event.user_id}, GROUP {event.group_id if event.message_type != 'private' else 'private'}) 查询皮肤:" + name) + _ulmt.set_False(event.user_id) + await search_skin.finish(result) + else: + logger.info(f"USER {event.user_id}, GROUP {event.group_id if event.message_type != 'private' else 'private'}" + f" 查询皮肤:{name} 没有查询到") + _ulmt.set_False(event.user_id) + await search_skin.finish("没有查询到哦,请检查格式吧") + + +update_buff_session = on_command("更新cookie", rule=to_me(), permission=SUPERUSER, priority=1) + + +@update_buff_session.handle() +async def _(bot: Bot, event: Event, state: T_State): + await update_buff_session.finish(update_buff_cookie(str(event.get_message())), at_sender=True) diff --git a/plugins/search_buff_skin_price/__pycache__/__init__.cpython-38.pyc b/plugins/search_buff_skin_price/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..ed820bdf Binary files /dev/null and b/plugins/search_buff_skin_price/__pycache__/__init__.cpython-38.pyc differ diff --git a/plugins/search_buff_skin_price/__pycache__/__init__.cpython-39.pyc b/plugins/search_buff_skin_price/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 00000000..dd938c3f Binary files /dev/null and b/plugins/search_buff_skin_price/__pycache__/__init__.cpython-39.pyc differ diff --git a/plugins/search_buff_skin_price/__pycache__/data_source.cpython-38.pyc b/plugins/search_buff_skin_price/__pycache__/data_source.cpython-38.pyc new file mode 100644 index 00000000..98aff86a Binary files /dev/null and b/plugins/search_buff_skin_price/__pycache__/data_source.cpython-38.pyc differ diff --git a/plugins/search_buff_skin_price/__pycache__/data_source.cpython-39.pyc b/plugins/search_buff_skin_price/__pycache__/data_source.cpython-39.pyc new file mode 100644 index 00000000..ad827da6 Binary files /dev/null and b/plugins/search_buff_skin_price/__pycache__/data_source.cpython-39.pyc differ diff --git a/plugins/search_buff_skin_price/data_source.py b/plugins/search_buff_skin_price/data_source.py new file mode 100644 index 00000000..192925d0 --- /dev/null +++ b/plugins/search_buff_skin_price/data_source.py @@ -0,0 +1,66 @@ +from util.user_agent import get_user_agent +import aiohttp +from util.utils import get_cookie_text +from configs.path_config import TXT_PATH +from asyncio.exceptions import TimeoutError +from configs.config import buff_proxy +from pathlib import Path +from services.log import logger + + +url = "https://buff.163.com/api/market/goods" + + +async def get_price(dname): + cookie = {'session': get_cookie_text('buff')} + name_list = [] + price_list = [] + parameter = { + "game": "csgo", + "page_num": "1", + "search": dname + } + try: + async with aiohttp.ClientSession(cookies=cookie, headers=get_user_agent()) as session: + async with session.get(url, proxy=buff_proxy, params=parameter, timeout=5) as response: + if response.status == 200: + try: + if str(await response.text()).find("Login Required") != -1: + return "BUFF登录被重置,请联系管理员重新登入", 996 + data = (await response.json())["data"] + total_page = data["total_page"] + data = data["items"] + for _ in range(total_page): + for i in range(len(data)): + name = data[i]["name"] + price = data[i]["sell_reference_price"] + name_list.append(name) + price_list.append(price) + except Exception as e: + return "没有查询到...", 998 + else: + return "访问失败!", response.status + except TimeoutError as e: + return "访问超时! 请重试或稍后再试!", 997 + result = f"皮肤: {dname}({len(name_list)})\n" + # result = "皮肤: " + dname + "\n" + for i in range(len(name_list)): + result += name_list[i] + ": " + price_list[i] + "\n" + return result[:-1], 999 + + +def update_buff_cookie(cookie: str): + _cookie = Path(TXT_PATH + "cookie/buff.txt") + try: + _cookie.parent.mkdir(parents=True, exist_ok=True) + with open(_cookie, 'w') as f: + f.write(cookie) + return "更新cookie成功" + except Exception as e: + logger.error(f'更新cookie失败 e:{e}') + return "更新cookie失败" + + +if __name__ == '__main__': + print(get_price("awp 二西莫夫")) + diff --git a/plugins/send_dinggong_voice/__init__.py b/plugins/send_dinggong_voice/__init__.py new file mode 100644 index 00000000..04c7ea09 --- /dev/null +++ b/plugins/send_dinggong_voice/__init__.py @@ -0,0 +1,33 @@ +from nonebot import on_keyword +from util.init_result import record +from configs.path_config import VOICE_PATH +import random +from services.log import logger +from util.utils import FreqLimiter +from nonebot.typing import T_State +from nonebot.adapters.cqhttp import Bot, MessageEvent +from nonebot.rule import to_me +import os + +__plugin_name__ = '骂我' +__plugin_usage__ = '对我说 "骂我",我真的会骂你哦' + +_flmt = FreqLimiter(3) + + +dg_voice = on_keyword({'骂'}, rule=to_me(), priority=5, block=True) + + +@dg_voice.handle() +async def _(bot: Bot, event: MessageEvent, state: T_State): + if len(str((event.get_message()))) == 1: + return + if not _flmt.check(event.user_id): + await dg_voice.finish('就...就算求我骂你也得慢慢来...', at_sender=True) + _flmt.start_cd(event.user_id) + voice = random.choice(os.listdir(VOICE_PATH + 'dinggong/')) + result = record(voice, "dinggong") + await dg_voice.send(result) + await dg_voice.send(voice.split('_')[1]) + logger.info( + f"(USER {event.user_id}, GROUP {event.group_id if event.message_type != 'private' else 'private'}) 发送钉宫骂人:" + result) \ No newline at end of file diff --git a/plugins/send_dinggong_voice/__pycache__/__init__.cpython-38.pyc b/plugins/send_dinggong_voice/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..23a3bd0f Binary files /dev/null and b/plugins/send_dinggong_voice/__pycache__/__init__.cpython-38.pyc differ diff --git a/plugins/send_dinggong_voice/__pycache__/__init__.cpython-39.pyc b/plugins/send_dinggong_voice/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 00000000..a68a0c8e Binary files /dev/null and b/plugins/send_dinggong_voice/__pycache__/__init__.cpython-39.pyc differ diff --git a/plugins/send_img/__init__.py b/plugins/send_img/__init__.py new file mode 100644 index 00000000..bee83a16 --- /dev/null +++ b/plugins/send_img/__init__.py @@ -0,0 +1,68 @@ +from nonebot import on_command, on_keyword +from configs.path_config import IMAGE_PATH +from util.init_result import image +import os +import random +from util.utils import is_number +from services.log import logger +from nonebot.typing import T_State +from nonebot.adapters import Bot, Event +from util.utils import FreqLimiter, cn2py +from models.group_remind import GroupRemind +from configs.config import IMAGE_DIR_LIST + + +__plugin_name__ = '壁纸/萝莉/美图' +__plugin_usage__ = '用法: 发送"壁纸/萝莉/美图", 回复图片,后添加id获得指定图片' + +_flmt = FreqLimiter(1) + +IMAGE_DIR_LIST.remove('色图') +cmd = set(IMAGE_DIR_LIST) + +# print(cmd) + +send_img = on_command("img", aliases=cmd, priority=5, block=True) + + +@send_img.handle() +async def _(bot: Bot, event: Event, state: T_State): + img_id = str(event.get_message()) + if img_id in ['帮助']: + await send_img.finish(__plugin_usage__) + path = cn2py(state["_prefix"]["raw_command"]) + '/' + if not os.path.exists(IMAGE_PATH + path): + logger.warning(f'未找到 {path} 文件夹,调用取消!') + return + length = len(os.listdir(IMAGE_PATH + path)) - 1 + index = img_id if img_id else str(random.randint(0, length)) + if not is_number(index): + await send_img.finish("id错误!") + if int(index) > length or int(index) < 0: + await send_img.finish(f"超过当前上下限!({length - 1})") + result = image(f'{index}.jpg', path) + if result: + logger.info( + f"(USER {event.user_id}, GROUP {event.group_id if event.message_type != 'private' else 'private'}) 发送{path}:" + result) + await send_img.finish(f"id:{index}" + result) + else: + logger.info( + f"(USER {event.user_id}, GROUP {event.group_id if event.message_type != 'private' else 'private'}) 发送 {path} 失败") + await send_img.finish(f"不想给你看Ov|") + + +pa = on_keyword({"爬"}, priority=1, block=True) + + +@pa.handle() +async def _(bot: Bot, event: Event, state: T_State): + if await GroupRemind.get_status(event.group_id, 'pa'): + try: + if str(event.get_message()[:2]) in ['开启', '关闭']: + return + except: + return + if not _flmt.check(event.user_id): + return + _flmt.start_cd(event.user_id) + await pa.finish(image(random.choice(os.listdir(IMAGE_PATH + "pa")), 'pa')) diff --git a/plugins/send_img/__pycache__/__init__.cpython-38.pyc b/plugins/send_img/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..3b704098 Binary files /dev/null and b/plugins/send_img/__pycache__/__init__.cpython-38.pyc differ diff --git a/plugins/send_img/__pycache__/__init__.cpython-39.pyc b/plugins/send_img/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 00000000..b273a113 Binary files /dev/null and b/plugins/send_img/__pycache__/__init__.cpython-39.pyc differ diff --git a/plugins/send_setu/__init__.py b/plugins/send_setu/__init__.py new file mode 100644 index 00000000..53c47585 --- /dev/null +++ b/plugins/send_setu/__init__.py @@ -0,0 +1,276 @@ +import random +from nonebot import on_command, on_regex +from services.log import logger +from models.sigin_group_user import SignGroupUser +from util.utils import FreqLimiter, UserExistLimiter, is_number, get_message_text, get_message_imgs +from nonebot.typing import T_State +from nonebot.adapters.cqhttp import Bot, MessageEvent, GroupMessageEvent, PrivateMessageEvent +from .data_source import get_setu, get_luoxiang, search_online_setu, get_setu_urls, \ + check_r18_and_keyword, find_img_index +from nonebot.adapters.cqhttp.exception import ActionFailed +import re +from models.count_user import UserCount +from aiohttp.client_exceptions import ClientConnectorError +from configs.config import LOCAL_SETU + +__plugin_name__ = '色图' +__plugin_usage__ = '''示例: + 1. 色图 (随机本地色图) + 2. 色图r (随机在线十张r18涩图) + 3. 色图 666 (本地色图id) + 4. 色图 xx (在线搜索xx色图) + 5. 色图r xx (搜索十张xx的r18涩图,注意空格)(仅私聊) + 6. 来n张涩图 (本地涩图连发)(1<=n<=9) + 7. 来n张xx的涩图 (在线搜索xx涩图)(较慢,看网速) +注:【色图r每日提供5次 + 本地涩图没有r18! + 联网搜索会较慢! + 如果图片数量与数字不符, + 原因1:网络不好,网线被拔QAQ + 原因2:搜索到的总数小于数字 + 原因3:图太色或者小错误了】''' + +url = "https://api.lolicon.app/setu/" +_flmt = FreqLimiter(5) +_ulmt = UserExistLimiter() +path = "setu/" +MAX_COUNT = 5 + + +setu = on_command("色图", aliases={"涩图", "不够色", "来一发", "再来点"}, priority=5, block=True) +setu_reg = on_regex('(.*)[份|发|张|个|次|点](.*)[瑟|色|涩]图', priority=5, block=True) +find_setu = on_command("查色图", priority=5, block=True) + + +@setu.handle() +async def _(bot: Bot, event: GroupMessageEvent, state: T_State): + img_id = get_message_text(event.json()) + if img_id in ['帮助']: + await setu.finish(__plugin_usage__) + impression = (await SignGroupUser.ensure(event.user_id, event.group_id)).impression + luox = get_luoxiang(impression) + if luox: + await setu.finish(luox) + if not _flmt.check(event.user_id): + await setu.finish('您冲得太快了,请稍候再冲', at_sender=True) + _flmt.start_cd(event.user_id) + if _ulmt.check(event.user_id): + await setu.finish(f"您有色图正在处理,请稍等") + _ulmt.set_True(event.user_id) + setu_img, index = get_setu(img_id) + if setu_img and LOCAL_SETU: + try: + await setu.send(setu_img) + except: + _ulmt.set_False(event.user_id) + await setu.finish('这张图色过头了,我自己看看就行了!', at_sender=True) + logger.info( + f"USER {event.user_id} GROUP {event.group_id} 发送色图 {index}.jpg 成功") + else: + msg = img_id + if msg.find(list(bot.config.nickname)[0]) != -1: + _ulmt.set_False(event.user_id) + await setu.finish('咳咳咳,虽然我很可爱,但是我木有自己的色图~~~有的话记得发我一份呀') + keyword, r18, num = await check_r18_and_keyword(msg, event.user_id) + if r18 == 1: + _ulmt.set_False(event.user_id) + await setu.finish(random.choice([ + "这种不好意思的东西怎么可能给这么多人看啦", + "羞羞脸!给我滚出克私聊!", + "变态变态变态变态大变态!" + ])) + try: + urls, text_list, code = await get_setu_urls(keyword, num, r18=r18) + except ClientConnectorError: + await setu.finish('网络失败了..别担心!正在靠运气上网!', at_sender=True) + else: + if code == 200: + for i in range(num): + try: + setu_img, index = await search_online_setu(urls[i]) + await setu.send(text_list[i] + setu_img) + logger.info( + f"USER {event.user_id} GROUP {event.group_id}" + f" 发送在线色图 {keyword}.jpg 成功") + except Exception as e: + logger.error(f'色图发送错误 e:{e}') + await setu.send('图片下载惜败!', at_sender=True) + else: + await setu.send(urls) + _ulmt.set_False(event.user_id) + + +@setu.handle() +async def _(bot: Bot, event: PrivateMessageEvent, state: T_State): + img_id = get_message_text(event.json()) + if img_id in ['帮助']: + await setu.finish(__plugin_usage__) + if not _flmt.check(event.user_id): + await setu.finish('您冲得太快了,请稍候再冲', at_sender=True) + _flmt.start_cd(event.user_id) + if _ulmt.check(event.user_id): + await setu.finish(f"您有色图正在处理,请稍等") + _ulmt.set_True(event.user_id) + setu_img, index = get_setu(img_id) + if setu_img: + await setu.send(setu_img) + logger.info( + f"USER {event.user_id} GROUP private 发送色图 {index}.jpg 成功") + else: + msg = img_id + if msg.find(list(bot.config.nickname)[0]) != -1: + _ulmt.set_False(event.user_id) + await setu.finish('咳咳咳,虽然我很可爱,但是我木有自己的色图~~~有的话记得发我一份呀') + keyword, r18, num = await check_r18_and_keyword(msg, event.user_id) + if r18 == 1: + if await UserCount.check_count(event.user_id, 'setu_r18', MAX_COUNT): + _ulmt.set_False(event.user_id) + await setu.finish('要节制啊,请明天再来...\n【每日提供5次】', at_sender=True) + try: + urls, text_list, code = await get_setu_urls(keyword, num, r18=r18) + except ClientConnectorError: + await UserCount.add_count(event.user_id, 'setu_r18', count=-1) + await setu.finish('网络失败了..别担心!这次搜索不算数喔', at_sender=True) + else: + count = 0 + if code == 200: + for i in range(num): + try: + setu_img, index = await search_online_setu(urls[i]) + await setu.send(text_list[i] + setu_img) + logger.info( + f"USER {event.user_id} GROUP private" + f" 发送{'r18' if img_id == 'r' else ''}色图 {index}.jpg 成功") + except Exception as e: + logger.error(f'色图发送错误 e:{e}') + await setu.send('图片下载惜败!', at_sender=True) + count += 1 + if count > 6: + await setu.send('检测到下载惜败的图片过多,这次就不算数了,果咩..', at_sender=True) + await UserCount.add_count(event.user_id, 'setu_r18', count=-1) + else: + if code == 401: + if r18 == 1: + await UserCount.add_count(event.user_id, 'setu_r18', count=-1) + await setu.send(urls + ' 色图r次数返还!') + else: + await setu.send(urls, at_sender=True) + else: + if r18 == 1: + await setu.send('这次不是小真寻的戳!色图r次数返还!', at_sender=True) + await UserCount.add_count(event.user_id, 'setu_r18', count=-1) + else: + await setu.send(urls, at_sender=True) + _ulmt.set_False(event.user_id) + + +num_key = { + '一': 1, + '二': 2, + '两': 2, + '双': 2, + '三': 3, + '四': 4, + '五': 5, + '六': 6, + '七': 7, + '八': 8, + '九': 9 +} + + +@setu_reg.handle() +async def _(bot: Bot, event: MessageEvent, state: T_State): + if event.message_type == "group": + impression = (await SignGroupUser.ensure(event.user_id, event.group_id)).impression + luox = get_luoxiang(impression) + if luox: + await setu.finish(luox, at_sender=True) + if _ulmt.check(event.user_id): + await setu.finish(f"您有色图正在处理,请稍等") + _ulmt.set_True(event.user_id) + if not _flmt.check(event.user_id): + _ulmt.set_False(event.user_id) + await setu.finish('您冲得太快了,请稍候再冲', at_sender=True) + _flmt.start_cd(event.user_id) + msg = get_message_text(event.json()) + num = 1 + msg = re.search(r'(.*)[份|发|张|个|次|点](.*)[瑟|涩|色]图', msg) + if msg: + num = msg.group(1) + keyword = msg.group(2) + if keyword: + if keyword[-1] == '的': + keyword = keyword[:-1] + if num: + num = num[-1] + if num_key.get(num): + num = num_key[num] + elif is_number(num): + try: + num = int(num) + except ValueError: + num = 1 + else: + num = 1 + else: + return + # try: + if not keyword: + for _ in range(num): + try: + img, index = get_setu('') + await setu_reg.send(img) + except Exception as e: + await setu_reg.send('有图太色了发不出来...') + else: + logger.info( + f"USER {event.user_id} GROUP {event.group_id if event.message_type != 'private' else 'private'}" + f" 发送 {index} 色图成功") + else: + urls, text_list, code = await get_setu_urls(keyword, num) + if code == 200: + for i in range(len(urls)): + try: + setu_img, index = await search_online_setu(urls[i]) + await setu_reg.send(text_list[i] + '\n' + setu_img) + except ActionFailed as e: + await setu_reg.send('这图太色了,会教坏小孩子的,不给看..') + else: + logger.info( + f"USER {event.user_id} GROUP {event.group_id if event.message_type != 'private' else 'private'}" + f" 发送 {keyword} {num}连 色图成功") + else: + _ulmt.set_False(event.user_id) + await setu_reg.finish(urls, at_sender=True) + _ulmt.set_False(event.user_id) + + +@find_setu.args_parser +async def _(bot: Bot, event: MessageEvent, state: T_State): + if str(event.message) == '取消': + await find_setu.finish('取消了操作', at_sender=True) + imgs = get_message_imgs(event.json()) + if not imgs: + await find_setu.reject("不搞错了,俺要图!") + state['img'] = imgs[0] + + +@find_setu.handle() +async def _(bot: Bot, event: MessageEvent, state: T_State): + if get_message_text(event.json()) in ['帮助']: + await find_setu.finish('通过图片获取本地色图id\n\t示例:查色图(图片)') + imgs = get_message_imgs(event.json()) + if imgs: + state['img'] = imgs[0] + + +@find_setu.got('img', prompt="速速来图!") +async def _(bot: Bot, event: MessageEvent, state: T_State): + img = state['img'] + await find_setu.send(await find_img_index(img, event.user_id), at_sender=True) + + + + + diff --git a/plugins/send_setu/__pycache__/__init__.cpython-38.pyc b/plugins/send_setu/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..5be3bf33 Binary files /dev/null and b/plugins/send_setu/__pycache__/__init__.cpython-38.pyc differ diff --git a/plugins/send_setu/__pycache__/__init__.cpython-39.pyc b/plugins/send_setu/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 00000000..e338e02f Binary files /dev/null and b/plugins/send_setu/__pycache__/__init__.cpython-39.pyc differ diff --git a/plugins/send_setu/__pycache__/data_source.cpython-38.pyc b/plugins/send_setu/__pycache__/data_source.cpython-38.pyc new file mode 100644 index 00000000..a8fdc4be Binary files /dev/null and b/plugins/send_setu/__pycache__/data_source.cpython-38.pyc differ diff --git a/plugins/send_setu/__pycache__/data_source.cpython-39.pyc b/plugins/send_setu/__pycache__/data_source.cpython-39.pyc new file mode 100644 index 00000000..579aaa8a Binary files /dev/null and b/plugins/send_setu/__pycache__/data_source.cpython-39.pyc differ diff --git a/plugins/send_setu/check_setu_hash.py b/plugins/send_setu/check_setu_hash.py new file mode 100644 index 00000000..efbd9e6d --- /dev/null +++ b/plugins/send_setu/check_setu_hash.py @@ -0,0 +1,62 @@ +import os +import imagehash +from PIL import Image +try: + import ujson as json +except ModuleNotFoundError: + import json + +IMAGE_PATH = r"/home/hibiki/hibikibot/resources/img/" +TXT_PATH = r"/home/hibiki/hibikibot/resources/txt/" + + +def get_img_hash(image_file): + with open(image_file, 'rb') as fp: + hash_value = imagehash.average_hash(Image.open(fp)) + return hash_value + + +def check_file_index(): + for dir_name in ['setu/', 'r18/']: + lens = len(os.listdir(IMAGE_PATH + dir_name)) + for i in range(lens): + if i > lens: + return + if not os.path.exists(f"{IMAGE_PATH}{dir_name}{i}.jpg"): + os.rename(f"{IMAGE_PATH}{dir_name}{lens}.jpg", f"{IMAGE_PATH}{dir_name}{i}.jpg") + print(f'{lens}.jpg --> {i}.jpg') + lens -= 1 + if not i % 100: + print(f'已检测 {i} 份数据') + print(f'{dir_name} 检测完毕') + + +def check_setu_hash(): + check_file_index() + for dir_name in ['setu/', 'r18/']: + img_data = {} + if dir_name == 'setu/': + fn = 'setu_img_hash.json' + else: + fn = 'r18_setu_img_hash.json' + file_list_len = len(os.listdir(IMAGE_PATH + dir_name)) - 1 + print(file_list_len) + for i in range(file_list_len): + file = f"{i}.jpg" + index = file.split(".")[0] + img_hash = str(get_img_hash(IMAGE_PATH + dir_name + file)) + print(f'{index}.jpg --> {img_hash}') + if img_hash in img_data.values(): + k = [k for k, v in img_data.items() if v == img_hash] + print(f'文件 {index}.jpg 与 {k}.jpg 重复,使用 {file_list_len}.jpg 进行替换') + os.remove(IMAGE_PATH + dir_name + file) + os.rename(IMAGE_PATH + f'{dir_name}{file_list_len}.jpg', IMAGE_PATH + dir_name + file) + file_list_len -= 1 + continue + img_data[index] = img_hash + # print(f'{index}.jpg --> {img_data}') + with open(TXT_PATH + fn, 'w') as f: + json.dump(img_data, f, indent=4) + + +check_setu_hash() \ No newline at end of file diff --git a/plugins/send_setu/data_source.py b/plugins/send_setu/data_source.py new file mode 100644 index 00000000..43af3045 --- /dev/null +++ b/plugins/send_setu/data_source.py @@ -0,0 +1,168 @@ +from configs.path_config import IMAGE_PATH, TXT_PATH +import os +import random +from util.init_result import image +from configs.config import LOLICON_KEY +import aiohttp +import aiofiles +from services.log import logger +from util.img_utils import get_img_hash +from util.utils import get_local_proxy, is_number +from asyncio.exceptions import TimeoutError +from models.count_user import UserCount +from configs.config import DOWNLOAD_SETU +try: + import ujson as json +except ModuleNotFoundError: + import json + + +url = "https://api.lolicon.app/setu/" +path = 'setu/' + + +async def get_setu_urls(keyword: str, num: int = 1, r18: int = 0): + # print(keyword) + if r18 == 1: + file_name = 'setu_r18_url.txt' + else: + file_name = 'setu_url.txt' + try: + with open(TXT_PATH + file_name, 'r') as f: + txt_data = f.read() + except FileNotFoundError: + txt_data = '' + params = { + "apikey": LOLICON_KEY, # 添加apikey + 'r18': r18, # 添加r18参数 0为否,1为是,2为混合 + 'keyword': keyword, # 若指定关键字,将会返回从插画标题、作者、标签中模糊搜索的结果 + 'num': num, # 一次返回的结果数量,范围为1到10,不提供 APIKEY 时固定为1 + 'size1200': 1, # 是否使用 master_1200 缩略图,以节省流量或提升加载速度 + } + urls = [] + text_list = [] + for count in range(3): + print(f'get_setu_url: count --> {count}') + async with aiohttp.ClientSession() as session: + try: + async with session.get(url, proxy=get_local_proxy(), timeout=5, params=params) as response: + if response.status == 429: + return '调用达到上限,明日赶早呀~', '', 429 + if response.status == 404: + return "网站裂开了...", '', 998 + if response.status == 200: + data = await response.json() + if data['code'] == 0: + # print(len(data['data'])) + for i in range(len(data['data'])): + img_url = data['data'][i]['url'] + title = data['data'][i]['title'] + author = data['data'][i]['author'] + pid = data['data'][i]['pid'] + urls.append(img_url) + text_list.append(f'title:{title}\nauthor:{author}\nPID:{pid}') + img_url = str(img_url).replace('img-master', 'img-original').replace('_master1200', '') + txt_data += img_url + ',' + if DOWNLOAD_SETU: + with open(TXT_PATH + file_name, 'w') as f: + f.write(txt_data) + return urls, text_list, 200 + else: + return "没找到符合条件的色图...", '', 401 + except TimeoutError: + pass + return '我网线被人拔了..QAQ', '', 999 + + +async def search_online_setu(url: str): + async with aiohttp.ClientSession() as session: + for i in range(3): + print(f'search_online_setu --> {i}') + try: + async with session.get(url, proxy=get_local_proxy(), timeout=7) as res: + if res.status == 200: + index = str(random.randint(1, 100000)) + async with aiofiles.open(IMAGE_PATH + 'temp/' + index + "_temp_setu.jpg", 'wb') as f: + try: + await f.write(await res.read()) + except TimeoutError: + # return '\n这图没下载过来~(网太差?)', -1, False + continue + logger.info(f"下载 lolicon图片 {url} 成功, id:{index}") + return image(f'{index}_temp_setu.jpg', 'temp'), index + else: + logger.warning(f"访问 lolicon图片 {url} 失败 status:{res.status}") + # return '\n这图好难下载啊!QAQ', -1, False + except TimeoutError: + pass + return '\n图片被小怪兽恰掉啦..!QAQ', -1 + + +def get_setu(index: str): + length = len(os.listdir(IMAGE_PATH + path)) + if not index: + index = random.randint(0, length - 1) + if is_number(index): + if int(index) > length or int(index) < 0: + return f"超过当前上下限!({length - 1})", 999 + else: + return f'id:{index}' + image(f'{index}.jpg', 'setu'), index + return None, None + + +def get_luoxiang(impression): + probability = impression + 70 + if probability < random.randint(1, 101): + return "我为什么要给你发这个?" + image(random.choice(os.listdir(IMAGE_PATH + "luoxiang/")), 'luoxiang') + \ + "\n(快向小真寻签到提升好感度吧!)" + return None + + +async def check_r18_and_keyword(msg: str, user_id) -> 'str, int, int': + msg_list = msg.split(' ') + num = 1 + r18 = 0 + keyword = '' + if len(msg_list) == 1: + if msg_list[0].strip().lower() in ['r', 'r18']: + r18 = 1 + num = 10 + else: + keyword = msg_list[0] + elif len(msg_list) == 2: + keyword = msg_list[1].strip() + if msg_list[0].strip().lower() in ['r', 'r18']: + r18 = 1 + num = 10 + else: + keyword = msg[0] + if r18 == 1: + await UserCount.add_user(user_id) + return keyword, r18, num + + +# def delete_img(index): +# if os.path.exists(IMAGE_PATH + path + f"{index}.jpg"): +# img_hash = str(get_img_hash(IMAGE_PATH + f"setu/{index}.jpg")) +# tp = list(setu_hash_dict.keys())[list(setu_hash_dict.values()).index(img_hash)] +# logger.info(f"色图 {index}.jpg 与 {tp}.jpg 相似, 删除....") +# os.remove(IMAGE_PATH + path + f"{index}.jpg") + + +async def find_img_index(img_url, user_id): + try: + setu_hash_dict = json.load(open(TXT_PATH + 'setu_img_hash.json')) + except (FileNotFoundError, ValueError): + setu_hash_dict = {} + async with aiohttp.ClientSession() as session: + async with session.get(img_url, proxy=get_local_proxy(), timeout=5) as res: + async with aiofiles.open(IMAGE_PATH + f"temp/{user_id}_find_setu_index.jpg", 'wb') as f: + await f.write(await res.read()) + img_hash = str(get_img_hash(IMAGE_PATH + f"temp/{user_id}_find_setu_index.jpg")) + try: + tp = list(setu_hash_dict.keys())[list(setu_hash_dict.values()).index(img_hash)] + return "id --> " + str(tp) + except ValueError: + return "该图不在色图库中!" + + diff --git a/plugins/server_ip.py b/plugins/server_ip.py new file mode 100644 index 00000000..4305a684 --- /dev/null +++ b/plugins/server_ip.py @@ -0,0 +1,36 @@ +from nonebot import on_command +from nonebot.adapters.cqhttp import Bot, PrivateMessageEvent, GroupMessageEvent +from nonebot.typing import T_State +from nonebot.rule import to_me + +__plugin_name__ = '服务器' +__plugin_usage__ = '用法: 无' + + +server_ip = on_command("服务器", aliases={'ip'}, rule=to_me(), priority=5, block=True) + + +@server_ip.handle() +async def _(bot: Bot, event: PrivateMessageEvent, state: T_State): + await server_ip.finish("|* 请不要发给其他人! *|\n" + "\t121.40.195.22\n" + "|* 请不要发给其他人! *|\n" + "csgo ~号键控制台输入 connect 121.40.195.22 进入服务器\n" + "然后再公屏输入 !diy 来使用皮肤(英文感叹号,注意)\n" + "【说不定可以凑到内战噢,欢迎~{娱乐为主,别骂人球球了}】", at_sender=True) + + +@server_ip.handle() +async def _(bot: Bot, event: GroupMessageEvent, state: T_State): + if event.group_id == 698279647: + await server_ip.finish("嗨呀!当前服务器地址是:" + "\ncsgo:\n\tay: 121.40.195.22\n\twzt: 101.200.199.143\n我的世界:\n\t47.111.1.220:25565") + elif event.group_id == 1046451860: + await server_ip.finish("嗨呀!当前服务器地址是:\n121.40.195.22\n !diy") + else: + await server_ip.finish("不好意思呀,小真寻不能为你使用此功能,因为服务器IP是真寻的小秘密呀!", at_sender=True) + + + + + diff --git a/plugins/shop/__init__.py b/plugins/shop/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/plugins/shop/__pycache__/__init__.cpython-38.pyc b/plugins/shop/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..3cf9d4e4 Binary files /dev/null and b/plugins/shop/__pycache__/__init__.cpython-38.pyc differ diff --git a/plugins/shop/__pycache__/__init__.cpython-39.pyc b/plugins/shop/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 00000000..bc7edeb0 Binary files /dev/null and b/plugins/shop/__pycache__/__init__.cpython-39.pyc differ diff --git a/plugins/shop/__pycache__/buy.cpython-38.pyc b/plugins/shop/__pycache__/buy.cpython-38.pyc new file mode 100644 index 00000000..5e1525e8 Binary files /dev/null and b/plugins/shop/__pycache__/buy.cpython-38.pyc differ diff --git a/plugins/shop/__pycache__/buy.cpython-39.pyc b/plugins/shop/__pycache__/buy.cpython-39.pyc new file mode 100644 index 00000000..de8a0300 Binary files /dev/null and b/plugins/shop/__pycache__/buy.cpython-39.pyc differ diff --git a/plugins/shop/__pycache__/my_gold.cpython-38.pyc b/plugins/shop/__pycache__/my_gold.cpython-38.pyc new file mode 100644 index 00000000..995594e6 Binary files /dev/null and b/plugins/shop/__pycache__/my_gold.cpython-38.pyc differ diff --git a/plugins/shop/__pycache__/my_gold.cpython-39.pyc b/plugins/shop/__pycache__/my_gold.cpython-39.pyc new file mode 100644 index 00000000..209a70a7 Binary files /dev/null and b/plugins/shop/__pycache__/my_gold.cpython-39.pyc differ diff --git a/plugins/shop/__pycache__/my_props.cpython-38.pyc b/plugins/shop/__pycache__/my_props.cpython-38.pyc new file mode 100644 index 00000000..252321fe Binary files /dev/null and b/plugins/shop/__pycache__/my_props.cpython-38.pyc differ diff --git a/plugins/shop/__pycache__/my_props.cpython-39.pyc b/plugins/shop/__pycache__/my_props.cpython-39.pyc new file mode 100644 index 00000000..eb865329 Binary files /dev/null and b/plugins/shop/__pycache__/my_props.cpython-39.pyc differ diff --git a/plugins/shop/__pycache__/reset_today_gold.cpython-38.pyc b/plugins/shop/__pycache__/reset_today_gold.cpython-38.pyc new file mode 100644 index 00000000..6f89e622 Binary files /dev/null and b/plugins/shop/__pycache__/reset_today_gold.cpython-38.pyc differ diff --git a/plugins/shop/__pycache__/reset_today_gold.cpython-39.pyc b/plugins/shop/__pycache__/reset_today_gold.cpython-39.pyc new file mode 100644 index 00000000..b463febb Binary files /dev/null and b/plugins/shop/__pycache__/reset_today_gold.cpython-39.pyc differ diff --git a/plugins/shop/__pycache__/shop_help.cpython-38.pyc b/plugins/shop/__pycache__/shop_help.cpython-38.pyc new file mode 100644 index 00000000..ceb8081a Binary files /dev/null and b/plugins/shop/__pycache__/shop_help.cpython-38.pyc differ diff --git a/plugins/shop/__pycache__/shop_help.cpython-39.pyc b/plugins/shop/__pycache__/shop_help.cpython-39.pyc new file mode 100644 index 00000000..f0727ef6 Binary files /dev/null and b/plugins/shop/__pycache__/shop_help.cpython-39.pyc differ diff --git a/plugins/shop/buy.py b/plugins/shop/buy.py new file mode 100644 index 00000000..6b4379c0 --- /dev/null +++ b/plugins/shop/buy.py @@ -0,0 +1,78 @@ +from nonebot import on_command +from services.log import logger +from nonebot.adapters.cqhttp import Bot, GroupMessageEvent +from nonebot.typing import T_State +from util.utils import get_message_text, is_number +from models.bag_user import UserBag +from services.db_context import db +from nonebot.adapters.cqhttp.permission import GROUP + + +__plugin_name__ = '商店购买' +__plugin_usage__ = '格式:购买 名称或序号 数量(选填,默认为1)\n\t示例:购买 好感双倍加持卡Ⅰ\n\t示例:购买 1 4' + + +buy = on_command("购买", aliases={'购买道具'}, priority=5, block=True, permission=GROUP) + +goods = [ + '好感双倍加持卡Ⅰ\t\t售价:30金币\n\t\t今日双倍好感度的概率 + 10%(谁才是真命天子?)(同类道具将覆盖)', + '好感双倍加持卡Ⅱ\t\t售价:140金币\n\t\t今日双倍好感度的概率 + 20%(平平庸庸~)(同类道具将覆盖)', + '好感双倍加持卡Ⅲ\t\t售价:250金币\n\t\t今日双倍好感度的概率 + 30%(金币才是真命天子!)(同类道具将覆盖)' +] +glist = [] +plist = [] +for i in range(len(goods)): + glist.append(goods[i].split('\t\t')[0]) + plist.append(int(goods[i].split('\t\t')[1].split(':')[1].split('金币')[0])) + + +@buy.handle() +async def _(bot: Bot, event: GroupMessageEvent, state: T_State): + if get_message_text(event.json()) in ['', '帮助']: + await buy.finish(__plugin_usage__) + if get_message_text(event.json()) in ['神秘药水']: + await buy.finish("你们看看就好啦,这是不可能卖给你们的~", at_sender=True) + msg = get_message_text(event.json()).strip().split(' ') + index = -1 + num = 1 + if len(msg) > 1: + if is_number(msg[1]): + num = int(msg[1]) + print(msg, num) + if is_number(msg[0]): + msg = int(msg[0]) + if msg > len(goods) or msg < 1: + await buy.finish('请输入正确的商品id!', at_sender=True) + index = msg - 1 + else: + if msg[0] in glist: + for i in range(len(glist)): + if msg == glist[i]: + index = i + break + else: + await buy.finish('请输入正确的商品名称!', at_sender=True) + async with db.transaction(): + if index != -1: + if (await UserBag.get_gold(event.user_id, event.group_id)) < plist[index] * num: + await buy.finish('您的金币好像不太够哦', at_sender=True) + if await UserBag.spend_glod(event.user_id, event.group_id, plist[index] * num): + for _ in range(num): + await UserBag.add_props(event.user_id, event.group_id, glist[index]) + await buy.send(f'花费 {plist[index]*num} 金币购买 {glist[index]} ×{num} 成功!', at_sender=True) + logger.info(f'USER {event.user_id} GROUP {event.group_id} ' + f'花费 {plist[index]*num} 金币购买 {glist[index]} ×{num} 成功!') + else: + await buy.send(f'{glist[index]} 购买失败!', at_sender=True) + logger.info(f'USER {event.user_id} GROUP {event.group_id} ' + f'花费 {plist[index]*num} 金币购买 {glist[index]} ×{num} 失败!') + + + + + + + + + + diff --git a/plugins/shop/my_gold.py b/plugins/shop/my_gold.py new file mode 100644 index 00000000..8228f2a0 --- /dev/null +++ b/plugins/shop/my_gold.py @@ -0,0 +1,26 @@ +from nonebot import on_command +from nonebot.adapters.cqhttp import Bot, GroupMessageEvent +from nonebot.typing import T_State +from models.bag_user import UserBag +from nonebot.adapters.cqhttp.permission import GROUP + + +__plugin_name__ = '我的金币' + + +my_gold = on_command("我的金币", priority=5, block=True, permission=GROUP) + + +@my_gold.handle() +async def _(bot: Bot, event: GroupMessageEvent, state: T_State): + await my_gold.finish(await UserBag.get_my_total_gold(event.user_id, event.group_id)) + + + + + + + + + + diff --git a/plugins/shop/my_props.py b/plugins/shop/my_props.py new file mode 100644 index 00000000..f9e147f7 --- /dev/null +++ b/plugins/shop/my_props.py @@ -0,0 +1,46 @@ +from nonebot import on_command +from services.log import logger +from nonebot.adapters.cqhttp import Bot, GroupMessageEvent +from nonebot.typing import T_State +from models.bag_user import UserBag +from nonebot.adapters.cqhttp.permission import GROUP + + +__plugin_name__ = '商店基础显示' + + +my_props = on_command("我的道具", priority=5, block=True, permission=GROUP) + + +@my_props.handle() +async def _(bot: Bot, event: GroupMessageEvent, state: T_State): + props = await UserBag.get_props(event.user_id, event.group_id) + if props: + pname_list = [] + pnum_list = [] + rst = '' + props = props[:-1].split(',') + for p in props: + if p != '': + if p in pname_list: + pnum_list[pname_list.index(p)] += 1 + else: + pname_list.append(p) + pnum_list.append(1) + for i in range(len(pname_list)): + rst += f'{i+1}.{pname_list[i]}\t×{pnum_list[i]}\n' + await my_props.send('\n' + rst[:-1], at_sender=True) + logger.info(f'USER {event.user_id} GROUP {event.group_id} 查看我的道具') + else: + await my_props.finish('您的背包里没有任何的道具噢~', at_sender=True) + + + + + + + + + + + diff --git a/plugins/shop/reset_today_gold.py b/plugins/shop/reset_today_gold.py new file mode 100644 index 00000000..7e0cfb05 --- /dev/null +++ b/plugins/shop/reset_today_gold.py @@ -0,0 +1,41 @@ +from util.utils import scheduler +from models.bag_user import UserBag +from services.log import logger + + +# 重置每日金币 +@scheduler.scheduled_job( + 'cron', + # year=None, + # month=None, + # day=None, + # week=None, + # day_of_week="mon,tue,wed,thu,fri", + hour=0, + minute=1, + # second=None, + # start_date=None, + # end_date=None, + # timezone=None, +) +async def _(): + try: + user_list = await UserBag.get_user_all() + if user_list: + for user in user_list: + await user.update( + get_today_gold=0, + spend_today_gold=0, + ).apply() + except Exception as e: + logger.error(f'重置每日金币错误 e:{e}') + + + + + + + + + + diff --git a/plugins/shop/shop_help.py b/plugins/shop/shop_help.py new file mode 100644 index 00000000..85c8aa0f --- /dev/null +++ b/plugins/shop/shop_help.py @@ -0,0 +1,41 @@ +from nonebot import on_command +from nonebot.adapters.cqhttp import Bot, GroupMessageEvent +from nonebot.typing import T_State +from util.img_utils import CreateImg +from configs.path_config import IMAGE_PATH +from util.init_result import image + + +__plugin_name__ = '商店' + + +shop_help = on_command("商店", priority=5, block=True) + +goods = [ + '好感双倍加持卡Ⅰ\t\t售价:30金币\n\t\t下次签到双倍好感度的概率 + 10%(谁才是真命天子?)(同类商品将覆盖)', + '好感双倍加持卡Ⅱ\t\t售价:150金币\n\t\t下次签到双倍好感度的概率 + 20%(平平庸庸~)(同类商品将覆盖)', + '好感双倍加持卡Ⅲ\t\t售价:250金币\n\t\t下次签到双倍好感度的概率 + 30%(金币才是真命天子!)(同类商品将覆盖)' +] + +result = '' +for i in range(len(goods)): + result += f'{i + 1}.{goods[i]}\n' +shop = CreateImg(1000, 1000, background=IMAGE_PATH + 'other/shop.png', font_size=20) +shop.text((100, 170), '注【通过 数字 或者 商品名称 购买】') +shop.text((20, 230), result) +shop.text((20, 900), '神秘药水\t\t售价:9999999金币\n\t\t鬼知道会有什么效果~') +shop.save(IMAGE_PATH + 'shop.png') + + +@shop_help.handle() +async def _(bot: Bot, event: GroupMessageEvent, state: T_State): + await shop_help.send(image('shop.png')) + + + + + + + + + diff --git a/plugins/shop/use/__init__.py b/plugins/shop/use/__init__.py new file mode 100644 index 00000000..b6bb532c --- /dev/null +++ b/plugins/shop/use/__init__.py @@ -0,0 +1,61 @@ +from nonebot import on_command +from services.log import logger +from nonebot.adapters.cqhttp import Bot, GroupMessageEvent +from nonebot.typing import T_State +from util.utils import is_number, get_message_text +from models.bag_user import UserBag +from nonebot.adapters.cqhttp.permission import GROUP +from services.db_context import db +from .data_source import effect + + +__plugin_name__ = '使用道具' +__plugin_usage__ = '输入 “使用道具 xxx(序号 或 道具名称)“ 即可使用道具\n【注】序号以我的道具序号为准,更推荐使用道具名称使用道具(怕出错)' + + +use_props = on_command("使用道具", priority=5, block=True, permission=GROUP) + + +@use_props.handle() +async def _(bot: Bot, event: GroupMessageEvent, state: T_State): + msg = get_message_text(event.json()) + if msg in ['', '帮助']: + await use_props.finish(__plugin_usage__) + props = await UserBag.get_props(event.user_id, event.group_id) + if props: + async with db.transaction(): + pname_list = [] + props = props[:-1].split(',') + for p in props: + if p != '': + if p not in pname_list: + pname_list.append(p) + if is_number(msg): + if 0 < int(msg) <= len(pname_list): + name = pname_list[int(msg) - 1] + else: + await use_props.finish('仔细看看自己的道具仓库有没有这个道具?', at_sender=True) + else: + if msg not in pname_list: + await use_props.finish('道具名称错误!', at_sender=True) + name = msg + if await UserBag.del_props(event.user_id, event.group_id, name) and\ + await effect(event.user_id, event.group_id, name): + await use_props.send(f'使用道具 {name} 成功!', at_sender=True) + logger.info(f'USER {event.user_id} GROUP {event.group_id} 使用道具 {name} 成功') + else: + await use_props.send(f'使用道具 {name} 失败!', at_sender=True) + logger.info(f'USER {event.user_id} GROUP {event.group_id} 使用道具 {name} 失败') + else: + await use_props.send('您的背包里没有任何的道具噢~', at_sender=True) + + + + + + + + + + + diff --git a/plugins/shop/use/__pycache__/__init__.cpython-38.pyc b/plugins/shop/use/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..e07bac44 Binary files /dev/null and b/plugins/shop/use/__pycache__/__init__.cpython-38.pyc differ diff --git a/plugins/shop/use/__pycache__/__init__.cpython-39.pyc b/plugins/shop/use/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 00000000..20c5b6d7 Binary files /dev/null and b/plugins/shop/use/__pycache__/__init__.cpython-39.pyc differ diff --git a/plugins/shop/use/__pycache__/data_source.cpython-38.pyc b/plugins/shop/use/__pycache__/data_source.cpython-38.pyc new file mode 100644 index 00000000..4409ecf9 Binary files /dev/null and b/plugins/shop/use/__pycache__/data_source.cpython-38.pyc differ diff --git a/plugins/shop/use/__pycache__/data_source.cpython-39.pyc b/plugins/shop/use/__pycache__/data_source.cpython-39.pyc new file mode 100644 index 00000000..c134c79a Binary files /dev/null and b/plugins/shop/use/__pycache__/data_source.cpython-39.pyc differ diff --git a/plugins/shop/use/data_source.py b/plugins/shop/use/data_source.py new file mode 100644 index 00000000..b0f79be6 --- /dev/null +++ b/plugins/shop/use/data_source.py @@ -0,0 +1,40 @@ +from models.sigin_group_user import SignGroupUser + + +async def effect(user_id: int, group_id: int, name: str) -> bool: + print(name) + # try: + if name == '好感双倍加持卡Ⅰ': + user = await SignGroupUser.ensure(user_id, group_id) + await user.update( + add_probability=0.1 + ).apply() + if name == '好感双倍加持卡Ⅱ': + user = await SignGroupUser.ensure(user_id, group_id) + await user.update( + add_probability=0.2 + ).apply() + if name == '好感双倍加持卡Ⅲ': + user = await SignGroupUser.ensure(user_id, group_id) + print(user.user_qq) + await user.update( + add_probability=0.3 + ).apply() + return True + # except Exception: + # return False + + + + + + + + + + + + + + + diff --git a/plugins/sign_in/__init__.py b/plugins/sign_in/__init__.py new file mode 100644 index 00000000..65193ee3 --- /dev/null +++ b/plugins/sign_in/__init__.py @@ -0,0 +1,53 @@ +from .group_user_checkin import group_user_check_in, group_user_check, group_impression_rank +from nonebot.typing import T_State +from nonebot.adapters.cqhttp import Bot, Event, GroupMessageEvent +from nonebot.adapters.cqhttp.permission import GROUP +from util.utils import get_message_text +from nonebot.plugin import MatcherGroup + + +__plugin_name__ = '签到' +__plugin_usage__ = ( + '用法:\n' + '对我说 “签到” 来签到\n' + '“我的签到” 来获取历史签到信息\n' + '“好感度排行” 来查看当前好感度前十的伙伴\n' + '/ 签到时有 3% 概率 * 2 /' + +) + + +sign_match_group = MatcherGroup(priority=5, permission=GROUP, block=True) + +sign = sign_match_group.on_command("签到") + + +@sign.handle() +async def _(bot: Bot, event: GroupMessageEvent, state: T_State): + if get_message_text(event.json()) in ['帮助']: + await sign.finish(__plugin_usage__) + await sign.send( + await group_user_check_in(event.user_id, event.group_id), + at_sender=True, + ) + + +my_sign = sign_match_group.on_command(cmd="我的签到", aliases={'好感度'}) + + +@my_sign.handle() +async def _(bot: Bot, event: GroupMessageEvent, state: T_State): + await my_sign.send( + await group_user_check(event.user_id, event.group_id), + at_sender=True, + ) + +sign_ranking = sign_match_group.on_command(cmd="积分排行", aliases={'好感度排行', '签到排行', '积分排行', '好感排行', + '好感度排名,签到排名,积分排名'}) + + +@sign_ranking.handle() +async def _(bot: Bot, event: GroupMessageEvent, state: T_State): + await sign_ranking.send( + await group_impression_rank(event.group_id) + ) \ No newline at end of file diff --git a/plugins/sign_in/__pycache__/__init__.cpython-38.pyc b/plugins/sign_in/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..bc5c2af5 Binary files /dev/null and b/plugins/sign_in/__pycache__/__init__.cpython-38.pyc differ diff --git a/plugins/sign_in/__pycache__/__init__.cpython-39.pyc b/plugins/sign_in/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 00000000..a78968c1 Binary files /dev/null and b/plugins/sign_in/__pycache__/__init__.cpython-39.pyc differ diff --git a/plugins/sign_in/__pycache__/group_user_checkin.cpython-38.pyc b/plugins/sign_in/__pycache__/group_user_checkin.cpython-38.pyc new file mode 100644 index 00000000..84bce2f2 Binary files /dev/null and b/plugins/sign_in/__pycache__/group_user_checkin.cpython-38.pyc differ diff --git a/plugins/sign_in/__pycache__/group_user_checkin.cpython-39.pyc b/plugins/sign_in/__pycache__/group_user_checkin.cpython-39.pyc new file mode 100644 index 00000000..63a19b98 Binary files /dev/null and b/plugins/sign_in/__pycache__/group_user_checkin.cpython-39.pyc differ diff --git a/plugins/sign_in/group_user_checkin.py b/plugins/sign_in/group_user_checkin.py new file mode 100644 index 00000000..b695aede --- /dev/null +++ b/plugins/sign_in/group_user_checkin.py @@ -0,0 +1,119 @@ +import random +from datetime import datetime, timedelta + +from services.log import logger +from services.db_context import db +from models.sigin_group_user import SignGroupUser +from models.group_member_info import GroupInfoUser +from models.bag_user import UserBag +from configs.config import MAX_SIGN_GOLD + + +async def group_user_check_in(user_qq: int, group: int) -> str: + 'Returns string describing the result of checking in' + present = datetime.now() + async with db.transaction(): + # 取得相应用户 + user = await SignGroupUser.ensure(user_qq, group, for_update=True) + # 如果同一天签到过,特殊处理 + if user.checkin_time_last.date() == present.date(): + return _handle_already_checked_in(user) + return await _handle_check_in(user_qq, group, present) # ok + + +def _handle_already_checked_in(user: SignGroupUser) -> str: + return f'已经签到过啦~ 好感度:{user.impression:.2f}' + + +async def _handle_check_in(user_qq: int, group: int, present: datetime) -> str: + user = await SignGroupUser.ensure(user_qq, group, for_update=True) + impression_added = random.random() + present = present + timedelta(hours=8) + critx2 = random.random() + add_probability = user.add_probability + specify_probability = user.specify_probability + if critx2 + add_probability > 0.97: + impression_added *= 2 + elif critx2 < specify_probability: + impression_added *= 2 + new_impression = user.impression + impression_added + message = random.choice(( + '谢谢,你是个好人!', + '对了,来喝杯茶吗?', + )) + await user.update( + checkin_count=user.checkin_count + 1, + checkin_time_last=present, + impression=new_impression, + add_probability=0, + specify_probability=0, + ).apply() + # glod = await random_glod(user_qq, group, specify_probability) + if user.impression < 1: + impression = 1 + else: + impression = user.impression + gold = random.randint(1, 100) + imgold = random.randint(1, int(impression)) + if imgold > MAX_SIGN_GOLD: + imgold = MAX_SIGN_GOLD + await UserBag.add_glod(user_qq, group, gold + imgold) + if critx2 + add_probability > 0.97 or critx2 < specify_probability: + logger.info(f'(USER {user.user_qq}, GROUP {user.belonging_group})' + f' CHECKED IN successfully. score: {new_impression:.2f} (+{impression_added * 2:.2f}).获取金币:{gold+imgold}') + return f'{message} 好感度:{new_impression:.2f} (+{impression_added/2:.2f}×2)!!!\n获取金币:{gold} \n好感度额外获得金币:{imgold}' + else: + logger.info(f'(USER {user.user_qq}, GROUP {user.belonging_group})' + f' CHECKED IN successfully. score: {new_impression:.2f} (+{impression_added:.2f}).获取金币:{gold+imgold}') + return f'{message} 好感度:{new_impression:.2f} (+{impression_added:.2f})\n获取金币:{gold} \n好感度额外获得金币:{imgold}' + + +async def group_user_check(user_qq: int, group: int) -> str: + # heuristic: if users find they have never checked in they are probable to check in + user = await SignGroupUser.ensure(user_qq, group) + glod = await UserBag.get_gold(user_qq, group) + return '好感度:{:.2f}\n金币:{}\n历史签到数:{}\n上次签到日期:{}'.format( + user.impression, + glod, + user.checkin_count, + user.checkin_time_last.date() if user.checkin_time_last != datetime.min else '从未', + ) + + +async def group_impression_rank(group: int) -> str: + result = "\t好感度排行榜\t\n" + user_qq_list, impression_list = await SignGroupUser.query_impression_all(group) + _count = 11 + if user_qq_list and impression_list: + for i in range(1, 100): + if len(user_qq_list) == 0 or len(impression_list) == 0 or i == _count: + break + impression = max(impression_list) + index = impression_list.index(impression) + user_qq = user_qq_list[index] + print(user_qq, group) + try: + user_name = (await GroupInfoUser.select_member_info(user_qq, group)).user_name + except Exception as e: + logger.info(f"USER {user_qq}, GROUP {group} 不在群内") + _count += 1 + impression_list.remove(impression) + user_qq_list.remove(user_qq) + continue + result += f"{i - _count + 11}. {user_name}: {impression:.2f}\n" + impression_list.remove(impression) + user_qq_list.remove(user_qq) + return result[:-1] + + +async def random_glod(user_id, group_id, impression): + if impression < 1: + impression = 1 + glod = random.randint(1, 100) + random.randint(1, int(impression)) + if await UserBag.add_glod(user_id, group_id, glod): + return glod + else: + return 0 + + + diff --git a/plugins/songpicker2/__init__.py b/plugins/songpicker2/__init__.py new file mode 100644 index 00000000..31e271ee --- /dev/null +++ b/plugins/songpicker2/__init__.py @@ -0,0 +1,81 @@ +from .data_source import dataGet, dataProcess +from nonebot.adapters import Bot, Event +from nonebot.typing import T_State +from nonebot import on_command + + +dataget = dataGet() + +songpicker = on_command("点歌", priority=5, block=True) + + +@songpicker.handle() +async def handle_first_receive(bot: Bot, event: Event, state: T_State): + args = str(event.get_message()).strip() + # if args.isdigit(): + # if "songName" in state: + # state["songNum"] = int(args) + if args: + state["songName"] = args + + +@songpicker.got("songName", prompt="歌名是?") +async def handle_songName(bot: Bot, event: Event, state: T_State): + songName = state["songName"] + songIdList = await dataget.songIds(songName=songName) + if not songIdList: + await songpicker.reject("没有找到这首歌,请发送其它歌名!") + songInfoList = list() + for songId in songIdList: + songInfoDict = await dataget.songInfo(songId) + songInfoList.append(songInfoDict) + # songInfoMessage = await dataProcess.mergeSongInfo(songInfoList) + # await songpicker.send(songInfoMessage) + state["songIdList"] = songIdList + + +@songpicker.got("songName") +async def handle_songNum(bot: Bot, event: Event, state: T_State): + songIdList = state["songIdList"] + # songNum = state["songNum"] + songNum = 0 + # 处理重选 + # if not songNum.isdigit(): + # await songpicker.finish() + # else: + # songNum = int(songNum) + # + # if songNum >= len(songIdList) or songNum < 0: + # await songpicker.reject("数字序号错误") + + selectedSongId = songIdList[int(songNum)] + + songContent = [ + { + "type": "music", + "data": { + "type": 163, + "id": selectedSongId + } + } + ] + await songpicker.send(songContent) + + # songCommentsDict = await dataget.songComments(songId=selectedSongId) + # songCommentsMessage = await dataProcess.mergeSongComments(songCommentsDict) + # commentContent = [ + # { + # "type": "text", + # "data": { + # "text": "下面为您播送热评:\n" + # } + # }, + # { + # "type": "text", + # "data": { + # "text": songCommentsMessage + # } + # } + # ] + # + # await songpicker.send(commentContent) \ No newline at end of file diff --git a/plugins/songpicker2/__pycache__/__init__.cpython-38.pyc b/plugins/songpicker2/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..5d305878 Binary files /dev/null and b/plugins/songpicker2/__pycache__/__init__.cpython-38.pyc differ diff --git a/plugins/songpicker2/__pycache__/__init__.cpython-39.pyc b/plugins/songpicker2/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 00000000..ccf46987 Binary files /dev/null and b/plugins/songpicker2/__pycache__/__init__.cpython-39.pyc differ diff --git a/plugins/songpicker2/__pycache__/data_source.cpython-38.pyc b/plugins/songpicker2/__pycache__/data_source.cpython-38.pyc new file mode 100644 index 00000000..7a3c32ab Binary files /dev/null and b/plugins/songpicker2/__pycache__/data_source.cpython-38.pyc differ diff --git a/plugins/songpicker2/__pycache__/data_source.cpython-39.pyc b/plugins/songpicker2/__pycache__/data_source.cpython-39.pyc new file mode 100644 index 00000000..5b07d814 Binary files /dev/null and b/plugins/songpicker2/__pycache__/data_source.cpython-39.pyc differ diff --git a/plugins/songpicker2/data_source.py b/plugins/songpicker2/data_source.py new file mode 100644 index 00000000..d2786d87 --- /dev/null +++ b/plugins/songpicker2/data_source.py @@ -0,0 +1,156 @@ +import aiohttp +import json + + +class dataApi(): + ''' + 从网易云音乐接口直接获取数据(实验性) + ''' + headers = {"referer": "http://music.163.com"} + cookies = {"appver": "2.0.2"} + + async def search(self, songName: str): + ''' + 搜索接口,用于由歌曲名查找id + ''' + async with aiohttp.ClientSession(headers=self.headers, cookies=self.cookies) as session: + async with session.post(f"http://music.163.com/api/search/get/", data={"s": songName, "limit": 5, "type": 1, "offset": 0},) as r: + if r.status != 200: + return None + r = await r.text() + return json.loads(r) + + # async def getHotComments(self, songId: int): + # ''' + # 获取热评 + # ''' + # async with httpx.AsyncClient() as client: + # async with aiohttp.ClientSession(headers=self.headers, cookies=self.cookies) as session: + # async with session.post( + # f"https://music.163.com/weapi/v1/resource/hotcomments/R_SO_4_{songId}?csrf_token=", + # data={ + # "params": 'D33zyir4L/58v1qGPcIPjSee79KCzxBIBy507IYDB8EL7jEnp41aDIqpHBhowfQ6iT1Xoka8jD+0p + # 44nRKNKUA0dv+n5RWPOO57dZLVrd+T1J/sNrTdzUhdHhoKRIgegVcXYjYu+CshdtCBe6WEJozBRlaHyLeJtGrA + # BfMOEb4PqgI3h/uELC82S05NtewlbLZ3TOR/TIIhNV6hVTtqHDVHjkekrvEmJzT5pk1UY6r0=', + # "encSecKey": '45c8bcb07e69c6b545d3045559bd300db897509b8720ee2b45a72bf2d3b216ddc77fb10dae + # c4ca54b466f2da1ffac1e67e245fea9d842589dc402b92b262d3495b12165a721aed880bf09a0a99ff94c959d + # 04e49085dc21c78bbbe8e3331827c0ef0035519e89f097511065643120cbc478f9c0af96400ba4649265781fc9079' + # }, + # ) as r: + # if r.status != 200: + # return None + # r = await r.json() + # return r + + async def getSongInfo(self, songId: int): + ''' + 获取歌曲信息 + ''' + async with aiohttp.ClientSession(headers=self.headers, cookies=self.cookies) as session: + async with session.post(f"http://music.163.com/api/song/detail/?id={songId}&ids=%5B{songId}%5D",) as r: + if r.status != 200: + return None + r = await r.text() + return json.loads(r) + + +class dataGet(dataApi): + ''' + 从dataApi获取数据,并做简单处理 + ''' + + api = dataApi() + + async def songIds(self, songName: str, amount=5) -> list: + ''' + 根据用户输入的songName 获取候选songId列表 [默认songId数量:5] + ''' + songIds = list() + r = await self.api.search(songName=songName) + if r is None: + raise WrongDataError + idRange = amount if amount < len( + r["result"]["songs"]) else len(r["result"]["songs"]) + for i in range(idRange): + songIds.append(r["result"]["songs"][i]["id"]) + return songIds + + # async def songComments(self, songId: int, amount=3) -> dict: + # ''' + # 根据传递的单一songId,获取songComments dict [默认评论数量上限:3] + # ''' + # songComments = dict() + # r = await self.api.getHotComments(songId) + # if r is None: + # raise WrongDataError + # commentsRange = amount if amount < len( + # r['hotComments']) else len(r['hotComments']) + # for i in range(commentsRange): + # songComments[r['hotComments'][i]['user'] + # ['nickname']] = r['hotComments'][i]['content'] + # return songComments + + async def songInfo(self, songId: int) -> dict: + ''' + 根据传递的songId,获取歌曲名、歌手、专辑等信息,作为dict返回 + ''' + songInfo = dict() + r = await self.api.getSongInfo(songId) + if r is None: + raise WrongDataError + songInfo["songName"] = r["songs"][0]["name"] + + songArtists = list() + for ars in r["songs"][0]["artists"]: + songArtists.append(ars["name"]) + songArtistsStr = "、".join(songArtists) + songInfo["songArtists"] = songArtistsStr + + songInfo["songAlbum"] = r["songs"][0]["album"]["name"] + + return songInfo + + +class dataProcess(): + ''' + 将获取的数据处理为用户能看懂的形式 + ''' + + @staticmethod + async def mergeSongInfo(songInfos: list) -> str: + ''' + 将歌曲信息list处理为字符串,供用户点歌 + 传递进的歌曲信息list含有多个歌曲信息dict + ''' + songInfoMessage = "请输入欲点播歌曲的序号:\n" + numId = 0 + for songInfo in songInfos: + songInfoMessage += f"{numId}:" + songInfoMessage += songInfo["songName"] + songInfoMessage += "-" + songInfoMessage += songInfo["songArtists"] + songInfoMessage += " 专辑:" + songInfoMessage += songInfo["songAlbum"] + songInfoMessage += "\n" + numId += 1 + return songInfoMessage + + @staticmethod + async def mergeSongComments(songComments: dict) -> str: + songCommentsMessage = '\n'.join( + ['%s: %s' % (key, value) for (key, value) in songComments.items()]) + return songCommentsMessage + + +class Error(Exception): + ''' + 谁知道网易的接口会出什么幺蛾子 + ''' + pass + + +class WrongDataError(Error): + def __init__(self, expression, message): + self.expression = expression + self.message = message + self.message += "\n未从网易接口获取到有效的数据!" \ No newline at end of file diff --git a/plugins/statistics_hook.py b/plugins/statistics_hook.py new file mode 100644 index 00000000..0abfe2c2 --- /dev/null +++ b/plugins/statistics_hook.py @@ -0,0 +1,143 @@ +from configs.path_config import DATA_PATH +from nonebot.matcher import Matcher +from nonebot.message import run_postprocessor +from nonebot.typing import T_State +from nonebot.adapters.cqhttp import Bot, GroupMessageEvent +from datetime import datetime +from configs.config import plugins2name_dict +from util.utils import scheduler +from nonebot.typing import Optional +try: + import ujson as json +except ModuleNotFoundError: + import json + + +try: + with open(DATA_PATH + '_prefix_count.json', 'r', encoding='utf8') as f: + _prefix_count_dict = json.load(f) +except (FileNotFoundError, ValueError): + _prefix_count_dict = { + 'total_statistics': { + 'total': {}, + }, + 'day_statistics': { + 'total': {}, + }, + 'week_statistics': { + 'total': {}, + }, + 'month_statistics': { + 'total': {}, + }, + 'start_time': str(datetime.now().date()) + } + + +# 添加命令次数 +@run_postprocessor +async def _(matcher: Matcher, exception: Optional[Exception], bot: Bot, event: GroupMessageEvent, state: T_State): + if matcher.type == 'message' and matcher.priority not in [1, 9]: + model = matcher.module + # print(f'model --> {model}') + for plugin in plugins2name_dict: + if plugin == model: + # print(f'plugin --> {plugin}') + try: + group_id = str(event.group_id) + except AttributeError: + group_id = 'total' + plugin_name = plugins2name_dict[plugin][0] + check_exists_key(group_id, plugin_name) + _prefix_count_dict['total_statistics']['total'][plugin_name] += 1 + _prefix_count_dict['day_statistics']['total'][plugin_name] += 1 + _prefix_count_dict['week_statistics']['total'][plugin_name] += 1 + _prefix_count_dict['month_statistics']['total'][plugin_name] += 1 + if group_id != 'total': + _prefix_count_dict['total_statistics'][group_id][plugin_name] += 1 + _prefix_count_dict['day_statistics'][group_id][plugin_name] += 1 + _prefix_count_dict['week_statistics'][group_id][plugin_name] += 1 + _prefix_count_dict['month_statistics'][group_id][plugin_name] += 1 + with open(DATA_PATH + '_prefix_count.json', 'w', encoding='utf8') as f: + json.dump(_prefix_count_dict, f, indent=4, ensure_ascii=False) + break + + +def check_exists_key(group_id, plugin_name): + if not _prefix_count_dict['total_statistics']['total'].get(plugin_name): + _prefix_count_dict['total_statistics']['total'][plugin_name] = 0 + if not _prefix_count_dict['day_statistics']['total'].get(plugin_name): + _prefix_count_dict['day_statistics']['total'][plugin_name] = 0 + if not _prefix_count_dict['week_statistics']['total'].get(plugin_name): + _prefix_count_dict['week_statistics']['total'][plugin_name] = 0 + if not _prefix_count_dict['month_statistics']['total'].get(plugin_name): + _prefix_count_dict['month_statistics']['total'][plugin_name] = 0 + if not _prefix_count_dict['total_statistics'].get(group_id): + _prefix_count_dict['total_statistics'][group_id] = { + plugin_name: 0, + } + elif not _prefix_count_dict['total_statistics'][group_id].get(plugin_name): + _prefix_count_dict['total_statistics'][group_id][plugin_name] = 0 + if not _prefix_count_dict['day_statistics'].get(group_id): + _prefix_count_dict['day_statistics'][group_id] = { + plugin_name: 0, + } + elif not _prefix_count_dict['day_statistics'][group_id].get(plugin_name): + _prefix_count_dict['day_statistics'][group_id][plugin_name] = 0 + if not _prefix_count_dict['week_statistics'].get(group_id): + _prefix_count_dict['week_statistics'][group_id] = { + plugin_name: 0, + } + elif not _prefix_count_dict['week_statistics'][group_id].get(plugin_name): + _prefix_count_dict['week_statistics'][group_id][plugin_name] = 0 + if not _prefix_count_dict['month_statistics'].get(group_id): + _prefix_count_dict['month_statistics'][group_id] = { + plugin_name: 0, + } + elif not _prefix_count_dict['month_statistics'][group_id].get(plugin_name): + _prefix_count_dict['month_statistics'][group_id][plugin_name] = 0 + + +# 天 +@scheduler.scheduled_job( + 'cron', + hour=0, + minute=1, +) +async def _(): + for group_id in _prefix_count_dict['day_statistics'].keys(): + for key in _prefix_count_dict['day_statistics'][group_id].keys(): + _prefix_count_dict['day_statistics'][group_id][key] = 0 + with open(DATA_PATH + '_prefix_count.json', 'w', encoding='utf8') as f: + json.dump(_prefix_count_dict, f, indent=4, ensure_ascii=False) + + +# 早上好 +@scheduler.scheduled_job( + 'cron', + day_of_week="mon", + hour=0, + minute=1, +) +async def _(): + for group_id in _prefix_count_dict['week_statistics'].keys(): + for key in _prefix_count_dict['week_statistics'][group_id].keys(): + _prefix_count_dict['week_statistics'][group_id][key] = 0 + with open(DATA_PATH + '_prefix_count.json', 'w', encoding='utf8') as f: + json.dump(_prefix_count_dict, f, indent=4, ensure_ascii=False) + + +# 早上好 +@scheduler.scheduled_job( + 'cron', + day=1, + hour=0, + minute=1, +) +async def _(): + for group_id in _prefix_count_dict['month_statistics'].keys(): + for key in _prefix_count_dict['month_statistics'][group_id].keys(): + _prefix_count_dict['month_statistics'][group_id][key] = 0 + with open(DATA_PATH + '_prefix_count.json', 'w', encoding='utf8') as f: + json.dump(_prefix_count_dict, f, indent=4, ensure_ascii=False) + diff --git a/plugins/super_cmd/__init__.py b/plugins/super_cmd/__init__.py new file mode 100644 index 00000000..522f78f5 --- /dev/null +++ b/plugins/super_cmd/__init__.py @@ -0,0 +1,158 @@ +from nonebot import on_command +from nonebot.permission import SUPERUSER +from models.level_user import LevelUser +from nonebot.typing import T_State +from nonebot.adapters import Bot, Event +from nonebot.rule import to_me +from util.utils import get_message_at, get_message_text, is_number, get_bot +from services.log import logger +from .data_source import open_remind, close_remind +from models.group_info import GroupInfo +from models.friend_user import FriendUser + + +__plugin_name__ = '超级用户指令 [Hidden]' +__plugin_usage__ = '用法' + + +super_cmd = on_command("添加管理", aliases={'删除管理', '添加权限', '删除权限'}, rule=to_me(), priority=1, permission=SUPERUSER, block=True) +oc_gb = on_command('开启广播通知', aliases={'关闭广播通知'}, rule=to_me(), permission=SUPERUSER, priority=1, block=True) +cls_group = on_command("所有群组", rule=to_me(), permission=SUPERUSER, priority=1, block=True) +cls_friend = on_command("所有好友", rule=to_me(), permission=SUPERUSER, priority=1, block=True) +del_group = on_command('退群', rule=to_me(), permission=SUPERUSER, priority=1, block=True) +update_group_info = on_command('更新群信息', rule=to_me(), permission=SUPERUSER, priority=1, block=True) +update_friend_info = on_command('更新好友信息', rule=to_me(), permission=SUPERUSER, priority=1, block=True) +# update_cmd = on_command('更新命令开关', rule=to_me(), permission=SUPERUSER, priority=1, block=True) + + +@super_cmd.handle() +async def _(bot: Bot, event: Event, state: T_State): + try: + args = get_message_text(event.json()).strip().split(" ") + qq = int(get_message_at(event.json())[0]) + if state["_prefix"]["raw_command"][:2] == "添加": + level = int(args[0]) + if await LevelUser.set_level(qq, event.group_id, level, 1): + result = "添加管理成功, 权限: " + str(level) + else: + result = "管理已存在, 更新权限: " + str(level) + else: + if await LevelUser.delete_level(qq, event.group_id, True): + result = "删除管理成功!" + else: + result = "该账号无管理权限!" + await super_cmd.send(result) + except Exception as e: + await super_cmd.send("执行指令失败!") + logger.error(f'执行指令失败 e{e}') + + +@oc_gb.handle() +async def _(bot: Bot, event: Event, state: T_State): + group = get_message_text(event.json()) + if group: + if is_number(group): + group = int(group) + for g in await bot.get_group_list(): + if g['group_id'] == group: + break + else: + await oc_gb.finish('没有加入这个群...', at_sender=True) + # try: + if state["_prefix"]["raw_command"] == '开启广播通知': + logger.info(f'USER {event.user_id} 开启了 GROUP {group} 的广播') + await oc_gb.finish(await open_remind(group, 'gb'), at_sender=True) + else: + logger.info(f'USER {event.user_id} 关闭了 GROUP {group} 的广播') + await oc_gb.finish(await close_remind(group, 'gb'), at_sender=True) + # except Exception as e: + # await oc_gb.finish(f'关闭 {group} 的广播失败', at_sender=True) + else: + await oc_gb.finish('请输入正确的群号', at_sender=True) + else: + await oc_gb.finish('请输入要关闭广播的群号', at_sender=True) + + +@del_group.handle() +async def _(bot: Bot, event: Event, state: T_State): + group = get_message_text(event.json()) + if group: + if is_number(group): + try: + await bot.set_group_leave(group_id=int(group)) + logger.info(f'退出群聊 {group} 成功') + await del_group.finish(f'退出群聊 {group} 成功', at_sender=True) + except Exception as e: + logger.info(f'退出群聊 {group} 失败 e:{e}') + else: + await del_group.finish(f'请输入正确的群号', at_sender=True) + else: + await del_group.finish(f'请输入群号', at_sender=True) + + +@cls_group.handle() +async def _(bot: Bot, event: Event, state: T_State): + gl = await bot.get_group_list(self_id=bot.self_id) + msg = ["{group_id} {group_name}".format_map(g) for g in gl] + msg = "\n".join(msg) + msg = f"bot:{bot.self_id}\n| 群号 | 群名 | 共{len(gl)}个群\n" + msg + await bot.send_private_msg(self_id=bot.self_id, user_id=int(list(bot.config.superusers)[0]), message=msg) + + +@cls_friend.handle() +async def _(bot: Bot, event: Event, state: T_State): + gl = await bot.get_friend_list(self_id=bot.self_id) + msg = ["{user_id} {nickname}".format_map(g) for g in gl] + msg = "\n".join(msg) + msg = f"| QQ号 | 昵称 | 共{len(gl)}个好友\n" + msg + await bot.send_private_msg(self_id=bot.self_id, user_id=int(list(bot.config.superusers)[0]), message=msg) + + +@update_group_info.handle() +async def _(bot: Bot, event: Event, state: T_State): + bot = get_bot() + gl = await bot.get_group_list(self_id=bot.self_id) + gl = [g['group_id'] for g in gl] + num = 0 + rst = '' + for g in gl: + group_info = await bot.get_group_info(group_id=g) + if await GroupInfo.add_group_info(group_info['group_id'], group_info['group_name'], + group_info['max_member_count'], group_info['member_count']): + num += 1 + logger.info(f'自动更新群组 {g} 信息成功') + else: + logger.info(f'自动更新群组 {g} 信息失败') + rst += f'{g} 更新失败\n' + await update_group_info.send(f'成功更新了 {num} 个群的信息\n{rst[:-1]}') + + +@update_friend_info.handle() +async def _(bot: Bot, event: Event, state: T_State): + num = 0 + rst = '' + fl = await get_bot().get_friend_list(self_id=bot.self_id) + for f in fl: + if await FriendUser.add_friend_info(f['user_id'], f['nickname']): + logger.info(f'自动更新好友 {f["user_id"]} 信息成功') + num += 1 + else: + logger.warning(f'自动更新好友 {f["user_id"]} 信息失败') + rst += f'{f["user_id"]} 更新失败\n' + await update_friend_info.send(f'成功更新了 {num} 个好友的信息\n{rst[:-1]}') + + +# @update_cmd.handle() +# async def _(bot: Bot, event: Event, state: T_State): +# gl = await bot.get_group_list(self_id=bot.self_id) +# gl = [g['group_id'] for g in gl] +# for g in gl: +# check_group_switch_json(g) +# for file in os.listdir(DATA_PATH + 'group_help'): +# os.remove(DATA_PATH + f'group_help/{file}') +# await update_cmd.finish('更新命令完成!', at_sender=True) + + + + + diff --git a/plugins/super_cmd/__pycache__/__init__.cpython-38.pyc b/plugins/super_cmd/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..e66c1331 Binary files /dev/null and b/plugins/super_cmd/__pycache__/__init__.cpython-38.pyc differ diff --git a/plugins/super_cmd/__pycache__/__init__.cpython-39.pyc b/plugins/super_cmd/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 00000000..ab671aa2 Binary files /dev/null and b/plugins/super_cmd/__pycache__/__init__.cpython-39.pyc differ diff --git a/plugins/super_cmd/__pycache__/data_source.cpython-38.pyc b/plugins/super_cmd/__pycache__/data_source.cpython-38.pyc new file mode 100644 index 00000000..8fd1428b Binary files /dev/null and b/plugins/super_cmd/__pycache__/data_source.cpython-38.pyc differ diff --git a/plugins/super_cmd/__pycache__/data_source.cpython-39.pyc b/plugins/super_cmd/__pycache__/data_source.cpython-39.pyc new file mode 100644 index 00000000..3622359d Binary files /dev/null and b/plugins/super_cmd/__pycache__/data_source.cpython-39.pyc differ diff --git a/plugins/super_cmd/data_source.py b/plugins/super_cmd/data_source.py new file mode 100644 index 00000000..c9f837bd --- /dev/null +++ b/plugins/super_cmd/data_source.py @@ -0,0 +1,76 @@ +from models.group_remind import GroupRemind + + +async def open_remind(group: int, name: str) -> str: + _name = '' + if name == 'zwa': + _name = '早晚安' + if name == 'dz': + _name = '地震播报' + if name == 'hy': + _name = '群欢迎' + if name == 'kxcz': + _name = '开箱重置提醒' + if name == 'gb': + _name = '广播' + if await GroupRemind.get_status(group, name): + return f'该群已经开启过 {_name} 通知,请勿重复开启!' + if await GroupRemind.set_status(group, name, True): + return f'成功开启 {_name} 通知!0v0' + else: + return f'开启 {_name} 通知失败了...' + + +async def close_remind(group: int, name: str) -> str: + _name = '' + if name == 'zwa': + _name = '早晚安' + if name == 'dz': + _name = '地震播报' + if name == 'hy': + _name = '群欢迎' + if name == 'kxcz': + _name = '开箱重置提醒' + if name == 'gb': + _name = '广播' + if not await GroupRemind.get_status(group, name): + return f'该群已经取消过 {_name} 通知,请勿重复取消!' + if await GroupRemind.set_status(group, name, False): + return f'成功关闭 {_name} 通知!0v0' + else: + return f'关闭 {_name} 通知失败了...' + + +# cmd_list = ['总开关', '签到', '发送图片', '色图', '黑白草图', 'coser', '鸡汤/语录', '骂我', '开箱', '鲁迅说', '假消息', '商店系统', +# '操作图片', '查询皮肤', '天气', '疫情', '识番', '搜番', '点歌', 'pixiv', 'rss', '方舟一井', '查干员', '骰子娘', '原神一井'] +# +# +# def check_group_switch_json(group_id): +# if not os.path.exists(DATA_PATH + f'rule/group_switch/'): +# os.mkdir(DATA_PATH + f'rule/group_switch/') +# if not os.path.exists(DATA_PATH + f'rule/group_switch/{group_id}.json'): +# with open(DATA_PATH + f'rule/group_switch/{group_id}.json', 'w', encoding='utf8') as f: +# data = {} +# for cmd in cmd_list: +# data[cmd] = True +# f.write(json.dumps(data, ensure_ascii=False)) +# else: +# with open(DATA_PATH + f'rule/group_switch/{group_id}.json', 'r', encoding='utf8') as f: +# try: +# data = json.load(f) +# except ValueError: +# data = {} +# if len(data.keys()) - 1 != len(cmd_list): +# for cmd in cmd_list: +# if cmd not in data.keys(): +# data[cmd] = True +# with open(DATA_PATH + f'rule/group_switch/{group_id}.json', 'w', encoding='utf8') as wf: +# wf.write(json.dumps(data, ensure_ascii=False)) +# reload(data) +# for file in os.listdir(DATA_PATH + 'group_help'): +# os.remove(DATA_PATH + f'group_help/{file}') + + +def reload(data): + static_group_dict = data + diff --git a/plugins/super_help/__init__.py b/plugins/super_help/__init__.py new file mode 100644 index 00000000..fdec2b34 --- /dev/null +++ b/plugins/super_help/__init__.py @@ -0,0 +1,25 @@ +from nonebot import on_command +from nonebot.permission import SUPERUSER +from nonebot.typing import T_State +from nonebot.adapters import Bot, Event +from nonebot.rule import to_me + + +super_help = on_command("超级用户帮助", rule=to_me(), priority=1, permission=SUPERUSER, block=True) + + +@super_help.handle() +async def _(bot: Bot, event: Event, state: T_State): + result = '''超级用户帮助: + 1.添加/删除管理 + 2.查看群组/查看好友 + 3.广播 --> 指令:广播- + 4.更新色图 + 5.回复 --> 指令:/t 用户 群号 + 6.更新cookie --> 指令:更新cookie text + 7.开启广播通知 --> 指令:开启广播通知 群号 + 8.退群 --> 指令:退群 群号 + 9.自检 + 10.更新好友信息 + 11.更新群群信息''' + await super_help.finish(result, at_sender=True) \ No newline at end of file diff --git a/plugins/super_help/__pycache__/__init__.cpython-38.pyc b/plugins/super_help/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..6755e6d4 Binary files /dev/null and b/plugins/super_help/__pycache__/__init__.cpython-38.pyc differ diff --git a/plugins/super_help/__pycache__/__init__.cpython-39.pyc b/plugins/super_help/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 00000000..5487f85a Binary files /dev/null and b/plugins/super_help/__pycache__/__init__.cpython-39.pyc differ diff --git a/plugins/test.py b/plugins/test.py new file mode 100644 index 00000000..4fa87c0c --- /dev/null +++ b/plugins/test.py @@ -0,0 +1,36 @@ +from nonebot.rule import to_me +from nonebot.typing import T_State +from nonebot.adapters.cqhttp import Bot, GroupMessageEvent, MessageEvent +from nonebot import on_command, on_keyword +from nonebot.plugin import MatcherGroup +from nonebot.adapters.cqhttp.event import GroupRequestEvent +import nonebot +from models.open_cases_user import OpenCasesUser +from tzlocal import get_localzone +from datetime import datetime, timezone, timedelta +from util.utils import get_bot, get_message_imgs, get_local_proxy +from util.init_result import * +from nonebot.adapters.cqhttp.message import MessageSegment +import requests +import aiohttp +from models.bag_user import UserBag +from nonebot.adapters.cqhttp.message import Message +import asyncio +from models.group_member_info import GroupInfoUser + +# erm = on_command('异世相遇,尽享美味', aliases={'异世相遇 尽享美味', '异世相遇,尽享美味'}, priority=5, block=True) + +matcher = on_keyword({"test"}) + + +@matcher.handle() +async def _(bot: Bot, event: MessageEvent, state: T_State): + for i in range(1001, len(os.listdir(IMAGE_PATH + 'setu/'))): + await matcher.send(f"id:{i}" + image(f'{i}.jpg', 'setu')) + await asyncio.sleep(0.5) + + +# @erm.handle() +# async def first_receive(bot: Bot, event: Event, state: T_State): +# print(record('erm')) +# await matcher.send(record('erm')) diff --git a/plugins/translate/__init__.py b/plugins/translate/__init__.py new file mode 100644 index 00000000..e436eb88 --- /dev/null +++ b/plugins/translate/__init__.py @@ -0,0 +1,37 @@ +from nonebot import on_command +from util.utils import get_message_text +from services.log import logger +from nonebot.adapters.cqhttp import Bot, MessageEvent +from nonebot.typing import T_State +from .data_source import translate_msg + + +__plugin_name__ = '翻译' + + +translate = on_command("translate", aliases={'英翻', '翻英', + '日翻', '翻日', + '韩翻', '翻韩' + }, priority=5, block=True) + + +@translate.handle() +async def _(bot: Bot, event: MessageEvent, state: T_State): + msg = get_message_text(event.json()) + if msg: + state['msg'] = msg + + +@translate.got('msg', prompt='你要翻译的消息是啥?') +async def _(bot: Bot, event: MessageEvent, state: T_State): + msg = state['msg'] + if len(msg) > 150: + await translate.finish('翻译过长!请不要超过150字', at_sender=True) + await translate.send(await translate_msg(state["_prefix"]["raw_command"], msg)) + logger.info( + f"(USER {event.user_id}, GROUP " + f"{event.group_id if event.message_type != 'private' else 'private'}) 使用翻译:{msg}") + + + + diff --git a/plugins/translate/__pycache__/__init__.cpython-38.pyc b/plugins/translate/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..a9261592 Binary files /dev/null and b/plugins/translate/__pycache__/__init__.cpython-38.pyc differ diff --git a/plugins/translate/__pycache__/__init__.cpython-39.pyc b/plugins/translate/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 00000000..336f5431 Binary files /dev/null and b/plugins/translate/__pycache__/__init__.cpython-39.pyc differ diff --git a/plugins/translate/__pycache__/data_source.cpython-38.pyc b/plugins/translate/__pycache__/data_source.cpython-38.pyc new file mode 100644 index 00000000..006b8c7e Binary files /dev/null and b/plugins/translate/__pycache__/data_source.cpython-38.pyc differ diff --git a/plugins/translate/__pycache__/data_source.cpython-39.pyc b/plugins/translate/__pycache__/data_source.cpython-39.pyc new file mode 100644 index 00000000..f181e919 Binary files /dev/null and b/plugins/translate/__pycache__/data_source.cpython-39.pyc differ diff --git a/plugins/translate/data_source.py b/plugins/translate/data_source.py new file mode 100644 index 00000000..ff8c350d --- /dev/null +++ b/plugins/translate/data_source.py @@ -0,0 +1,69 @@ +import aiohttp +from util.utils import get_local_proxy +from util.user_agent import get_user_agent + +url = f'http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule&smartresult=ugc&sessionFrom=null' + + +async def translate_msg(language_type, msg): + data = { + 'type': parse_language(language_type), + 'i': msg, + "doctype": "json", + "version": "2.1", + "keyfrom": "fanyi.web", + "ue": "UTF-8", + "action": "FY_BY_CLICKBUTTON", + "typoResult": "true" + } + async with aiohttp.ClientSession(headers=get_user_agent()) as session: + async with session.post(url, data=data, proxy=get_local_proxy()) as res: + data = await res.json() + if data['errorCode'] == 0: + return data['translateResult'][0][0]['tgt'] + return '翻译惜败..' + +# ZH_CN2EN 中文 » 英语 +# ZH_CN2JA 中文 » 日语 +# ZH_CN2KR 中文 » 韩语 +# ZH_CN2FR 中文 » 法语 +# ZH_CN2RU 中文 » 俄语 +# ZH_CN2SP 中文 » 西语 +# EN2ZH_CN 英语 » 中文 +# JA2ZH_CN 日语 » 中文 +# KR2ZH_CN 韩语 » 中文 +# FR2ZH_CN 法语 » 中文 +# RU2ZH_CN 俄语 » 中文 +# SP2ZH_CN 西语 » 中文 + + +def parse_language(language_type): + if language_type == '英翻': + return 'EN2ZH_CN' + if language_type == '日翻': + return 'JA2ZH_CN' + if language_type == '韩翻': + return 'KR2ZH_CN' + # if language_type == '法翻': + # return 'FR2ZH_CN' + # if language_type == '俄翻': + # return 'RU2ZH_CN' + if language_type == '翻英': + return 'ZH_CN2EN' + if language_type == '翻日': + return 'ZH_CN2JA' + if language_type == '翻韩': + return 'ZH_CN2KR' + # if language_type == '翻法': + # return 'ZH_CN2FR' + # if language_type == '翻俄': + # return 'ZH_CN2RU' + + + + + + + + + diff --git a/plugins/update_gocqhttp/__init__.py b/plugins/update_gocqhttp/__init__.py new file mode 100644 index 00000000..56ff418c --- /dev/null +++ b/plugins/update_gocqhttp/__init__.py @@ -0,0 +1,61 @@ +from nonebot import on_command +from nonebot.typing import T_State +from nonebot.adapters.cqhttp import Bot, GroupMessageEvent +from .data_source import download_gocq_lasted, upload_gocq_lasted +import os +from nonebot.adapters.cqhttp.permission import GROUP +from services.log import logger +from util.utils import scheduler, get_bot, UserExistLimiter +from configs.config import UPDATE_GOCQ_GROUP +from pathlib import Path + +path = str(Path('/resources/gocqhttp_file/').absolute()) + '/' + +lasted_gocqhttp = on_command("更新gocq", permission=GROUP, priority=5, block=True) + + +_ulmt = UserExistLimiter() + + +@lasted_gocqhttp.handle() +async def _(bot: Bot, event: GroupMessageEvent, state: T_State): + # try: + if event.group_id in UPDATE_GOCQ_GROUP: + await lasted_gocqhttp.send('检测中...') + info = await download_gocq_lasted() + if info == 'gocqhttp没有更新!': + await lasted_gocqhttp.finish('gocqhttp没有更新!') + if _ulmt.check(event.group_id): + await lasted_gocqhttp.finish('gocqhttp正在更新,请勿重复使用该命令', at_sender=True) + _ulmt.set_True(event.group_id) + try: + for file in os.listdir(path): + await upload_gocq_lasted(file, event.group_id) + logger.info(f'更新了cqhttp...{file}') + await lasted_gocqhttp.send(f'gocqhttp更新了,已上传成功!\n更新内容:\n{info}') + except Exception as e: + logger.error(f'更新gocq错误 e:{e}') + _ulmt.set_False(event.group_id) + + +# 更新gocq +@scheduler.scheduled_job( + 'cron', + hour=3, + minute=1, +) +async def _(): + if UPDATE_GOCQ_GROUP: + bot = get_bot() + try: + info = await download_gocq_lasted() + if info == 'gocqhttp没有更新!': + logger.info('gocqhttp没有更新!') + return + for group in UPDATE_GOCQ_GROUP: + for file in os.listdir(path): + await upload_gocq_lasted(file, group) + await bot.send_group_msg(group_id=group, message=f"gocqhttp更新了,已上传成功!\n更新内容:\n{info}") + except Exception as e: + logger.error(f'自动更新gocq出错 e:{e}') + diff --git a/plugins/update_gocqhttp/__pycache__/__init__.cpython-38.pyc b/plugins/update_gocqhttp/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..d5285901 Binary files /dev/null and b/plugins/update_gocqhttp/__pycache__/__init__.cpython-38.pyc differ diff --git a/plugins/update_gocqhttp/__pycache__/__init__.cpython-39.pyc b/plugins/update_gocqhttp/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 00000000..fa5e7fbe Binary files /dev/null and b/plugins/update_gocqhttp/__pycache__/__init__.cpython-39.pyc differ diff --git a/plugins/update_gocqhttp/__pycache__/data_source.cpython-38.pyc b/plugins/update_gocqhttp/__pycache__/data_source.cpython-38.pyc new file mode 100644 index 00000000..0c5aa246 Binary files /dev/null and b/plugins/update_gocqhttp/__pycache__/data_source.cpython-38.pyc differ diff --git a/plugins/update_gocqhttp/__pycache__/data_source.cpython-39.pyc b/plugins/update_gocqhttp/__pycache__/data_source.cpython-39.pyc new file mode 100644 index 00000000..534c95d4 Binary files /dev/null and b/plugins/update_gocqhttp/__pycache__/data_source.cpython-39.pyc differ diff --git a/plugins/update_gocqhttp/data_source.py b/plugins/update_gocqhttp/data_source.py new file mode 100644 index 00000000..4dc669cd --- /dev/null +++ b/plugins/update_gocqhttp/data_source.py @@ -0,0 +1,76 @@ +import aiohttp +from util.utils import get_local_proxy, get_bot +from util.user_agent import get_user_agent +import asyncio +import platform +import aiofiles +from bs4 import BeautifulSoup +import os +if platform.system() == 'Windows': + path = os.getcwd() + '/resources/gocqhttp_file/' + asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy()) +else: + path = r'/home/hibiki/hibikibot/resources/gocqhttp_file/' + + +url = 'https://github.com/Mrs4s/go-cqhttp/releases' + + +async def download_gocq_lasted(): + async with aiohttp.ClientSession(headers=get_user_agent()) as session: + async with session.get(url, proxy=get_local_proxy()) as response: + soup = BeautifulSoup(await response.text(), 'lxml') + a = soup.find('div', {'class': 'release-header'}).find('a') + title = a.text + _url = a.get('href') + for file in os.listdir(path): + if file.endswith('.zip'): + if file == title + '-windows-amd64.zip' or file == title + '_windows_amd64.zip': + return 'gocqhttp没有更新!' + for file in os.listdir(path): + os.remove(path + file) + async with session.get("https://github.com" + _url, proxy=get_local_proxy()) as res: + update_info = '' + soup = BeautifulSoup(await res.text(), 'lxml') + info_div = soup.find('div', {'class': 'markdown-body'}) + for p in info_div.find_all('p'): + update_info += p.text.replace('
', '\n') + '\n' + div_all = soup.select('div.d-flex.flex-justify-between.flex-items-center.py-1.py-md-2.Box-body.px-2') + for div in div_all: + if div.find('a').find('span').text == title + '-windows-amd64.zip' or\ + div.find('a').find('span').text == title + '-linux-arm64.tar.gz' or\ + div.find('a').find('span').text == 'go-cqhttp_windows_amd64.zip' or \ + div.find('a').find('span').text == 'go-cqhttp_linux_arm64.tar.gz': + file_url = div.find('a').get('href') + if div.find('a').find('span').text.find('windows') == -1: + tag = '-linux-arm64.tar.gz' + else: + tag = '-windows-amd64.zip' + async with session.get("https://github.com" + file_url, proxy=get_local_proxy()) as res_file: + async with aiofiles.open(path + title + tag, 'wb') as f: + await f.write(await res_file.read()) + return update_info + + +async def upload_gocq_lasted(name, group_id): + bot = get_bot() + folder_id = 0 + for folder in (await bot.get_group_root_files(group_id=group_id))['folders']: + if folder['folder_name'] == 'gocq': + folder_id = folder['folder_id'] + if not folder_id: + await bot.send_group_msg(group_id=group_id, + message=f'请创建gocq文件夹后重试!') + for file in os.listdir(path): + os.remove(path+file) + else: + await bot.upload_group_file( + group_id=group_id, + folder=folder_id, + file=path + name, + name=name + ) + + +# asyncio.get_event_loop().run_until_complete(download_gocq_lasted()) + diff --git a/plugins/update_info.py b/plugins/update_info.py new file mode 100644 index 00000000..4c2d3ce7 --- /dev/null +++ b/plugins/update_info.py @@ -0,0 +1,23 @@ +from nonebot import on_command +from nonebot.adapters.cqhttp import Bot, Event +from nonebot.typing import T_State +from util.init_result import image + +__plugin_name__ = '更新信息' + + +update_info = on_command("更新信息", priority=5, block=True) + + +@update_info.handle() +async def _(bot: Bot, event: Event, state: T_State): + img = image('update_info.png') + if img: + await update_info.finish(image('update_info.png')) + else: + await update_info.finish('目前没有更新信息哦') + + + + + diff --git a/plugins/update_pic.py b/plugins/update_pic.py new file mode 100644 index 00000000..0ab3532f --- /dev/null +++ b/plugins/update_pic.py @@ -0,0 +1,250 @@ +from nonebot import on_command +from PIL import Image, ImageFilter +from util.init_result import image +from configs.path_config import IMAGE_PATH +from services.log import logger +from nonebot.rule import to_me +from nonebot.adapters.cqhttp import Bot, MessageEvent +from nonebot.typing import T_State +from util.utils import get_message_imgs +import aiofiles +import aiohttp +from util.utils import is_number, get_message_text +from util.img_utils import CreateImg, pic2b64 +import cv2 +import numpy as np + + +__plugin_name__ = '图片' +__plugin_usage__ = '''图片用法(目前): +可以输入 指定操作 或 序号 来进行选择 + 1.修改尺寸 宽(x) 高(y) 图片(在文字后跟图片即可) + 示例:小真寻修改图片 修改尺寸 200 300 图片(在文字后跟图片即可) + 2.等比压缩 比例(x) 图片(在文字后跟图片即可) + 示例:小真寻修改图片 等比压缩 2 图片(在文字后跟图片即可) + 3.旋转图片 角度(x) 图片(在文字后跟图片即可) + 示例:小真寻修改图片 旋转图片 45 图片(在文字后跟图片即可) + 4.水平翻转 + 示例:小真寻修改图片 水平翻转 图片 + 5.铅笔滤镜 + 示例:小真寻修改图片 铅笔滤镜 图片 + 6.模糊效果 + 示例:小真寻修改图片 模糊效果 图片 + 7.锐化效果 + 示例:小真寻修改图片 锐化效果 图片 + 8.高斯模糊 + 示例:小真寻修改图片 高斯模糊 图片 + 9.边缘检测 + 示例:小真寻修改图片 边缘检测 图片 + 10.底色替换 颜色 颜色 图片 (不专业)支持:(红,蓝)->(红,蓝,白,绿,黄) + 示例:小真寻修改图片 底色替换 蓝色 红色 图片''' + +# IMAGE_LOCAL = IMAGE_PATH + "temp/{}_update.png" +method_flag = '' + +update_img = on_command("修改图片", aliases={'图片', '操作图片', '改图'}, priority=5, rule=to_me(), block=True) + +method_list = ['修改尺寸', '等比压缩', '旋转图片', '水平翻转', '铅笔滤镜', '模糊效果', '锐化效果', '高斯模糊', '边缘检测', '底色替换'] +method_str = '' +method_oper = [] +for i in range(len(method_list)): + method_str += f'\n{i + 1}.{method_list[i]}' + method_oper.append(method_list[i]) + method_oper.append(str(i + 1)) + +update_img_help = CreateImg(960, 700, font_size=24) +update_img_help.text((10, 10), __plugin_usage__) +update_img_help.save(IMAGE_PATH + 'update_img_help.png') + + +@update_img.args_parser +async def _(bot: Bot, event: MessageEvent, state: T_State): + global method_flag + if str(event.get_message()) in ['取消', '算了']: + await update_img.finish("已取消操作..", at_sender=True) + if state["_current_key"] in ['method']: + if str(event.get_message()) not in method_oper: + await update_img.reject(f"操作不正确,请重新输入!{method_str}") + state[state["_current_key"]] = str(event.get_message()) + method_flag = str(event.get_message()) + if method_flag in ['1', '修改尺寸']: + if state["_current_key"] == 'x': + if not is_number(str(event.get_message())): + await update_img.reject("宽度不正确!请重新输入数字...") + state[state["_current_key"]] = str(event.get_message()) + if state["_current_key"] == 'y': + if not is_number(str(event.get_message())): + await update_img.reject("长度不正确!请重新输入数字...") + state[state["_current_key"]] = str(event.get_message()) + elif method_flag in ['2', '等比压缩', '3', '旋转图片']: + if state["_current_key"] == 'x': + if not is_number(str(event.get_message())): + await update_img.reject("比率不正确!请重新输入数字...") + state[state["_current_key"]] = str(event.get_message()) + state['y'] = '' + elif method_flag in ['4', '水平翻转', '5', '铅笔滤镜', '6', '模糊效果', '7', '锐化效果', '8', '高斯模糊', '9', '边缘检测']: + state['x'] = '' + state['y'] = '' + elif method_flag in ['10', '底色替换']: + if state["_current_key"] == 'x': + if str(event.get_message()) not in ['红色', '蓝色', '红', '蓝']: + await update_img.reject('请输入支持的被替换的底色:\n红色 蓝色') + state['x'] = str(event.get_message()) + if state["_current_key"] == 'y': + if str(event.get_message()) not in ['红色', '白色', '蓝色', '绿色', '黄色', '红', '白', '蓝', '绿', '黄']: + await update_img.reject('请输入支持的替换的底色:\n红色 蓝色 白色 绿色') + state['y'] = str(event.get_message()) + if state["_current_key"] == 'imgs': + if not get_message_imgs(event.json()): + await update_img.reject("没图?没图?没图?来图速来!") + state[state["_current_key"]] = get_message_imgs(event.json()) + + +@update_img.handle() +async def _(bot: Bot, event: MessageEvent, state: T_State): + if str(event.get_message()) in ['帮助']: + await update_img.finish(image('update_img_help.png')) + raw_arg = get_message_text(event.json()) + img_list = get_message_imgs(event.json()) + if raw_arg: + args = raw_arg.split("[")[0].split(" ") + print(args) + state['method'] = args[0] + if len(args) == 2: + if args[0] in ["等比压缩", '旋转图片']: + if is_number(args[1]): + state['x'] = args[1] + state['y'] = '' + elif len(args) > 2: + if args[0] in ["修改尺寸"]: + if is_number(args[1]): + state['x'] = args[1] + if is_number(args[2]): + state['y'] = args[2] + if args[0] in ['底色替换']: + if args[1] in ['红色', '蓝色', '蓝', '红']: + state['x'] = args[1] + if args[2] in ['红色', '白色', '蓝色', '绿色', '黄色', '红', '白', '蓝', '绿', '黄']: + state['y'] = args[2] + if args[0] in ['水平翻转', '铅笔滤镜', '模糊效果', '锐化效果', '高斯模糊', '边缘检测']: + state['x'] = '' + state['y'] = '' + if img_list: + state['imgs'] = img_list + + +@update_img.got("method", prompt=f"要使用图片的什么操作呢?{method_str}") +@update_img.got("x", prompt="[宽度? 比率? 旋转角度? 底色?]") +@update_img.got("y", prompt="[长度? 0 0 底色?]") +@update_img.got("imgs", prompt="图呢图呢图呢图呢?GKD!") +async def _(bot: Bot, event: MessageEvent, state: T_State): + method = state['method'] + x = state['x'] if state['x'] else '' + y = state['y'] if state['y'] else '' + img_list = state['imgs'] + if is_number(x): + x = float(x) + if is_number(y): + y = int(y) + index = 0 + result = '' + async with aiohttp.ClientSession() as session: + for img_url in img_list: + async with session.get(img_url, timeout=7) as response: + if response.status == 200: + async with aiofiles.open(IMAGE_PATH + f'temp/{event.user_id}_{index}_update.png', 'wb') as f: + await f.write(await response.read()) + index += 1 + else: + logger.warning(f"USER {event.user_id} GROUP " + f"{event.group_id if event.message_type != 'private' else 'private'} " + f"使用 {method} 时下载图片超时") + await update_img.finish("获取图片超时了...", at_sender=True) + if index == 0: + return + if method in ['修改尺寸', '1']: + for i in range(index): + img = Image.open(IMAGE_PATH + f'temp/{event.user_id}_{i}_update.png') + img = img.convert('RGB') + img = img.resize((int(x), int(y)), Image.ANTIALIAS) + result += image(b64=pic2b64(img)) + await update_img.finish(result, at_sender=True) + if method in ['等比压缩', '2']: + for i in range(index): + img = Image.open(IMAGE_PATH + f'temp/{event.user_id}_{i}_update.png') + width, height = img.size + img = img.convert('RGB') + if width * x < 8000 and height * x < 8000: + img = img.resize((int(x * width), int(x * height))) + result += image(b64=pic2b64(img)) + else: + await update_img.finish('小真寻不支持图片压缩后宽或高大于8000的存在!!') + if method in ['旋转图片', '3']: + for i in range(index): + img = Image.open(IMAGE_PATH + f'temp/{event.user_id}_{i}_update.png') + img = img.rotate(x) + result += image(b64=pic2b64(img)) + if method in ['水平翻转', '4']: + for i in range(index): + img = Image.open(IMAGE_PATH + f'temp/{event.user_id}_{i}_update.png') + img = img.transpose(Image.FLIP_LEFT_RIGHT) + result += image(b64=pic2b64(img)) + if method in ['铅笔滤镜', '5']: + for i in range(index): + img = Image.open(IMAGE_PATH + f'temp/{event.user_id}_{i}_update.png').filter(ImageFilter.CONTOUR) + result += image(b64=pic2b64(img)) + if method in ['模糊效果', '6']: + for i in range(index): + img = Image.open(IMAGE_PATH + f'temp/{event.user_id}_{i}_update.png').filter(ImageFilter.BLUR) + result += image(b64=pic2b64(img)) + if method in ['锐化效果', '7']: + for i in range(index): + img = Image.open(IMAGE_PATH + f'temp/{event.user_id}_{i}_update.png').filter(ImageFilter.EDGE_ENHANCE) + result += image(b64=pic2b64(img)) + if method in ['高斯模糊', '8']: + for i in range(index): + img = Image.open(IMAGE_PATH + f'temp/{event.user_id}_{i}_update.png').filter(ImageFilter.GaussianBlur) + result += image(b64=pic2b64(img)) + if method in ['边缘检测', '9']: + for i in range(index): + img = Image.open(IMAGE_PATH + f'temp/{event.user_id}_{i}_update.png').filter(ImageFilter.FIND_EDGES) + result += image(b64=pic2b64(img)) + if method in ['底色替换', '10']: + if x in ['蓝色', '蓝']: + lower = np.array([90, 70, 70]) + upper = np.array([110, 255, 255]) + if x in ['红色', '红']: + lower = np.array([0, 135, 135]) + upper = np.array([180, 245, 230]) + if y in ['蓝色', '蓝']: + color = (255, 0, 0) + if y in ['红色', '红']: + color = (0, 0, 255) + if y in ['白色', '白']: + color = (255, 255, 255) + if y in ['绿色', '绿']: + color = (0, 255, 0) + if y in ['黄色', '黄']: + color = (0, 255, 255) + for k in range(index): + img = cv2.imread(IMAGE_PATH + f'temp/{event.user_id}_{k}_update.png') + img = cv2.resize(img, None, fx=0.3, fy=0.3) + rows, cols, channels = img.shape + hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) + mask = cv2.inRange(hsv, lower, upper) + # erode = cv2.erode(mask, None, iterations=1) + dilate = cv2.dilate(mask, None, iterations=1) + for i in range(rows): + for j in range(cols): + if dilate[i, j] == 255: + img[i, j] = color + cv2.imwrite(IMAGE_PATH + f'temp/{event.user_id}_{k}_ok_update.png', img) + for i in range(index): + result += image(f'{event.user_id}_{i}_ok_update.png', 'temp') + if is_number(method): + method = method_list[int(method) - 1] + logger.info( + f"(USER {event.user_id}, GROUP" + f" {event.group_id if event.message_type != 'private' else 'private'}) 使用{method}") + await update_img.finish(result, at_sender=True) + diff --git a/plugins/update_setu/__init__.py b/plugins/update_setu/__init__.py new file mode 100644 index 00000000..4a0ba2c5 --- /dev/null +++ b/plugins/update_setu/__init__.py @@ -0,0 +1,43 @@ +from util.utils import scheduler +from nonebot import on_command +from nonebot.permission import SUPERUSER +from nonebot.typing import T_State +from nonebot.adapters import Bot, Event +from nonebot.rule import to_me +from .data_source import update_setu_img +from configs.config import DOWNLOAD_SETU + + +__name__ = "更新色图 [Hidden]" + + +update_setu = on_command("更新色图", rule=to_me(), permission=SUPERUSER, priority=1, block=True) + + +@update_setu.handle() +async def _(bot: Bot, event: Event, state: T_State): + if DOWNLOAD_SETU: + await update_setu.send("开始更新色图...", at_sender=True) + await update_setu.finish(await update_setu_img(), at_sender=True) + else: + await update_setu.finish('更新色图配置未开启') + + +# 更新色图 +@scheduler.scheduled_job( + 'cron', + # year=None, + # month=None, + # day=None, + # week=None, + # day_of_week="mon,tue,wed,thu,fri", + hour=4, + minute=30, + # second=None, + # start_date=None, + # end_date=None, + # timezone=None, +) +async def _(): + if DOWNLOAD_SETU: + await update_setu_img() diff --git a/plugins/update_setu/__pycache__/__init__.cpython-38.pyc b/plugins/update_setu/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..487f7d7b Binary files /dev/null and b/plugins/update_setu/__pycache__/__init__.cpython-38.pyc differ diff --git a/plugins/update_setu/__pycache__/__init__.cpython-39.pyc b/plugins/update_setu/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 00000000..e7f2f438 Binary files /dev/null and b/plugins/update_setu/__pycache__/__init__.cpython-39.pyc differ diff --git a/plugins/update_setu/__pycache__/data_source.cpython-38.pyc b/plugins/update_setu/__pycache__/data_source.cpython-38.pyc new file mode 100644 index 00000000..5e57ef3b Binary files /dev/null and b/plugins/update_setu/__pycache__/data_source.cpython-38.pyc differ diff --git a/plugins/update_setu/__pycache__/data_source.cpython-39.pyc b/plugins/update_setu/__pycache__/data_source.cpython-39.pyc new file mode 100644 index 00000000..6e349f93 Binary files /dev/null and b/plugins/update_setu/__pycache__/data_source.cpython-39.pyc differ diff --git a/plugins/update_setu/data_source.py b/plugins/update_setu/data_source.py new file mode 100644 index 00000000..08db0937 --- /dev/null +++ b/plugins/update_setu/data_source.py @@ -0,0 +1,86 @@ +from configs.path_config import IMAGE_PATH, TXT_PATH +import os +from util.user_agent import get_user_agent +from services.log import logger +from datetime import datetime +from util.img_utils import rar_imgs, get_img_hash +from util.utils import get_bot, get_local_proxy +from asyncio.exceptions import TimeoutError +import aiofiles +import aiohttp +try: + import ujson as json +except ModuleNotFoundError: + import json + + +async def update_setu_img(): + async with aiohttp.ClientSession(headers=get_user_agent()) as session: + for file_name in ['setu_url.txt', 'setu_r18_url.txt']: + if file_name == 'setu_url.txt': + json_name = 'setu_img_hash.json' + path = 'setu/' + else: + json_name = 'r18_setu_img_hash.json' + path = 'r18/' + try: + data = json.load(open(TXT_PATH + json_name)) + if not data: + continue + except (FileNotFoundError, TypeError): + continue + _success = 0 + _similar = 0 + try: + with open(TXT_PATH + file_name, 'r') as f: + txt_data = f.read() + if not txt_data: + continue + except FileNotFoundError: + continue + urls = list(set(txt_data[:-1].split(','))) + total = len(urls) + for url in urls: + index = str(len(os.listdir(IMAGE_PATH + path))) + logger.info(f'开始更新 index:{index} --> {url}') + for _ in range(3): + try: + async with session.get(url, proxy=get_local_proxy(), timeout=15) as response: + if response.status == 200: + async with aiofiles.open(IMAGE_PATH + 'rar/' + index + ".jpg", 'wb') as f: + await f.write(await response.read()) + _success += 1 + else: + logger.info(f'{url} 不存在,跳过更新') + break + if os.path.getsize(IMAGE_PATH + 'rar/' + str(index) + ".jpg") > 1024 * 1024 * 1.5: + rar_imgs( + 'rar/', + path, + in_file_name=index, + out_file_name=index + ) + else: + logger.info('不需要压缩,移动图片 ' + IMAGE_PATH + 'rar/' + index + ".jpg --> " + + IMAGE_PATH + path + index + ".jpg") + os.rename(IMAGE_PATH + 'rar/' + index + ".jpg", + IMAGE_PATH + path + index + ".jpg") + img_hash = str(get_img_hash(f'{IMAGE_PATH}{path}{index}.jpg')) + if img_hash in data.values(): + logger.info(f'index:{index} 与 ' + f'{list(data.keys())[list(data.values()).index(img_hash)]} 存在重复,删除') + os.remove(IMAGE_PATH + path + index + ".jpg") + _similar += 1 + data[index] = img_hash + break + except TimeoutError: + continue + with open(TXT_PATH + json_name, 'w', encoding='utf-8') as f: + json.dump(data, f, indent=4) + open(TXT_PATH + file_name, 'w') + logger.info( + f'{str(datetime.now()).split(".")[0]} 更新 {file_name.split(".")[0]}完成,预计更新 {total} 张,实际更新 {_success} 张,相似 {_similar} 张,实际存入 {_success - _similar} 张') + await get_bot().send_private_msg( + user_id=775757368, + message=f'{str(datetime.now()).split(".")[0]} 更新{file_name.split(".")[0]}完成,预计更新 {total} 张,实际更新 {_success} 张,相似 {_similar} 张,实际存入 {_success - _similar} 张' + ) diff --git a/plugins/upload_img/__init__.py b/plugins/upload_img/__init__.py new file mode 100644 index 00000000..a2b51151 --- /dev/null +++ b/plugins/upload_img/__init__.py @@ -0,0 +1,87 @@ +from nonebot import on_command +from configs.path_config import IMAGE_PATH +from services.log import logger +import os +from nonebot.rule import to_me +from nonebot.typing import T_State +from nonebot.adapters import Bot, Event +from util.utils import get_message_imgs, get_message_text +import aiohttp +import aiofiles +from util.utils import cn2py +from configs.config import IMAGE_DIR_LIST + +__plugin_name__ = '上传图片' +__plugin_usage__ = '上传图片帮助:\n\t' \ + '1.查看列表 --> 指令: 上传图片 列表/目录\n\t' \ + '2.上传图片 序号 图片(在文字后跟图片即可), 即在相应目录下添加图片\n\t\t示例: 上传图片 1 图片(在文字后跟图片即可)' + + +upload_img = on_command("上传图片", rule=to_me(), priority=5, block=True) + + +@upload_img.args_parser +async def parse(bot: Bot, event: Event, state: T_State): + if str(event.get_message()) in ['取消', '算了']: + await upload_img.finish("已取消操作..", at_sender=True) + if state["_current_key"] in ['path']: + if str(event.get_message()) not in IMAGE_DIR_LIST: + await upload_img.reject("此目录不正确,请重新输入目录!") + state[state["_current_key"]] = str(event.get_message()) + if state["_current_key"] in ['imgs']: + if not get_message_imgs(event.json()): + await upload_img.reject("图呢图呢图呢图呢!GKD!") + state[state['_current_key']] = get_message_imgs(event.json()) + + +@upload_img.handle() +async def _(bot: Bot, event: Event, state: T_State): + raw_arg = get_message_text(event.json()) + img_list = get_message_imgs(event.json()) + if raw_arg: + if str(event.get_message()) in ['帮助']: + await upload_img.finish(__plugin_usage__) + if raw_arg.split("[")[0] in IMAGE_DIR_LIST: + state['path'] = raw_arg.split("[")[0] + if img_list: + state['imgs'] = img_list + + +@upload_img.got("path", prompt="要将图片上传至什么图库呢?") +@upload_img.got("imgs", prompt="图呢图呢图呢图呢!GKD!") +async def _(bot: Bot, event: Event, state: T_State): + path = IMAGE_PATH + cn2py(state['path']) + img_list = state['imgs'] + img_id = len(os.listdir(path)) + failed_list = [] + success_id = "" + async with aiohttp.ClientSession() as session: + for img_url in img_list: + try: + async with session.get(img_url, timeout=7) as response: + if response.status == 200: + async with aiofiles.open(path + str(img_id) + ".jpg", 'wb') as f: + await f.write(await response.read()) + success_id += str(img_id) + "," + img_id += 1 + else: + failed_list.append(img_url) + logger.warning(f"图片:{img_url} 下载失败....") + except TimeoutError as e: + logger.warning(f"图片:{img_url} 下载超时....e:{e}") + if img_url not in failed_list: + failed_list.append(img_url) + failed_result = "" + for img in failed_list: + failed_result += str(img) + "\n" + logger.info(f"USER {event.user_id} GROUP {event.group_id if event.message_type != 'private' else 'private'}" + f" 上传图片至 {state['path']} 共 {len(img_list)} 张,失败 {len(failed_list)} 张,id={success_id[:-1]}") + if failed_result: + await upload_img.finish(f"这次一共为 {state['path']}库 添加了 {len(img_list) - len(failed_list)} 张图片\n" + f"依次的Id为:{success_id[:-1]}\n" + f"上传失败:{failed_result[:-1]}\n" + f"小真寻感谢您对图库的扩充!WW", at_sender=True) + else: + await upload_img.finish(f"这次一共为 {state['path']}库 添加了 {len(img_list)} 张图片\n" + f"依次的Id为:{success_id[:-1]}\n" + f"小真寻感谢您对图库的扩充!WW", at_sender=True) diff --git a/plugins/upload_img/__pycache__/__init__.cpython-38.pyc b/plugins/upload_img/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..4722abc2 Binary files /dev/null and b/plugins/upload_img/__pycache__/__init__.cpython-38.pyc differ diff --git a/plugins/upload_img/__pycache__/__init__.cpython-39.pyc b/plugins/upload_img/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 00000000..fabac69a Binary files /dev/null and b/plugins/upload_img/__pycache__/__init__.cpython-39.pyc differ diff --git a/plugins/weather/__init__.py b/plugins/weather/__init__.py new file mode 100644 index 00000000..509d2274 --- /dev/null +++ b/plugins/weather/__init__.py @@ -0,0 +1,95 @@ +from nonebot import on_keyword, on_regex +from .data_source import get_weather_of_city +from nonebot.adapters.cqhttp import Bot, Event +from jieba import posseg +from services.log import logger +from nonebot.typing import T_State +from .config import city_list +import re +from util.utils import get_message_text + +__plugin_name__ = '天气查询' +__plugin_usage__ = "普普通通的查天气吧\n示例:北京天气" + + +weather = on_regex(r".*?(.*)市?的?天气.*?", priority=5, block=True) + + +@weather.handle() +async def _(bot: Bot, event: Event, state: T_State): + if str(event.get_message()) in ['帮助']: + await weather.finish(__plugin_usage__) + msg = get_message_text(event.json()) + msg = re.search(r'.*?(.*)市?的?天气.*?', msg) + msg = msg.group(1) + if msg[-1] == '的': + msg = msg[:-1] + if msg[-1] != '市': + msg += '市' + city = '' + if msg: + for word in posseg.lcut(msg): + if word.word in city_list.keys(): + await weather.finish("不要查一个省的天气啊,这么大查起来很累人的..", at_sender=True) + if word.flag == 'ns': + city = str(word.word).strip() + break + if word.word == '火星': + await weather.finish('没想到你个小呆子还真的想看火星天气!\n火星大气中含有95%的二氧化碳,气压低,加之极度的干燥,' + '就阻止了水的形成积聚。这意味着火星几乎没有云,冰层覆盖了火星的两极,它们的融化和冻结受到火星与太' + '阳远近距离的影响,它产生了强大的尘埃云,阻挡了太阳光,使冰层的融化慢下来。\n所以说火星天气太恶劣了,' + '去过一次就不想再去第二次了') + if city: + city_weather = await get_weather_of_city(city) + logger.info(f'(USER {event.user_id}, GROUP {event.group_id if event.message_type != "private" else "private"} ) ' + f'查询天气:' + city) + await weather.finish(city_weather) + # if str(event.get_message()).strip() == '天气': + # state['city'] = '-1' + # return + # msg = str(event.get_message()).strip() + # print(msg) + # flag = True + # if msg.find('开启') != -1 or msg.find('关闭') != -1: + # state['city'] = '-1' + # return + # if msg.startswith('天气'): + # if not msg.endswith('市'): + # state['city'] = msg[2:] + '市' + # else: + # state['city'] = msg[2:] + # flag = False + # elif msg.find('的天气') != -1: + # i = msg.find('的天气') + # msg = msg[:i] + '市' + msg[i:] + # elif msg.find('天气') != -1: + # i = msg.find('天气') + # msg = msg[:i] + '市' + msg[i:] + # if msg != "天气" and flag: + # print(posseg.lcut(msg)) + # for word in posseg.lcut(msg): + # if word.word in city_list.keys():# and word.word in ['北京', '上海', '天津', '重庆', '台湾']: + # await weather.finish("不要查一个省的天气啊,这么大查起来很累人的..", at_sender=True) + # if word.flag == 'ns': + # state["city"] = word.word + # break + # if word.word == '火星': + # await weather.finish('没想到你个小呆子还真的想看火星天气!\n火星大气中含有95%的二氧化碳,气压低,加之极度的干燥,' + # '就阻止了水的形成积聚。这意味着火星几乎没有云,冰层覆盖了火星的两极,它们的融化和冻结受到火星与太' + # '阳远近距离的影响,它产生了强大的尘埃云,阻挡了太阳光,使冰层的融化慢下来。\n所以说火星天气太恶劣了,' + # '去过一次就不想再去第二次了') + + +# @weather.got("city", prompt="你想查询哪个城市的天气呢?") +# async def _(bot: Bot, event: Event, state: dict): +# if state['city'] == '-1' or not state['city'].strip(): +# return +# if state['city'] in ['取消', '算了']: +# await weather.finish('已取消此次调用..') +# if state['city'][-1] != '市': +# state['city'] += '市' +# city_weather = await get_weather_of_city(state['city'].strip()) +# logger.info(f'(USER {event.user_id}, GROUP {event.group_id if event.message_type != "private" else "private"} ) ' +# f'查询天气:' + state['city']) +# await weather.finish(city_weather) + diff --git a/plugins/weather/__pycache__/__init__.cpython-38.pyc b/plugins/weather/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..02657382 Binary files /dev/null and b/plugins/weather/__pycache__/__init__.cpython-38.pyc differ diff --git a/plugins/weather/__pycache__/__init__.cpython-39.pyc b/plugins/weather/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 00000000..4cb3d4d7 Binary files /dev/null and b/plugins/weather/__pycache__/__init__.cpython-39.pyc differ diff --git a/plugins/weather/__pycache__/config.cpython-38.pyc b/plugins/weather/__pycache__/config.cpython-38.pyc new file mode 100644 index 00000000..0189b6b1 Binary files /dev/null and b/plugins/weather/__pycache__/config.cpython-38.pyc differ diff --git a/plugins/weather/__pycache__/config.cpython-39.pyc b/plugins/weather/__pycache__/config.cpython-39.pyc new file mode 100644 index 00000000..21697e90 Binary files /dev/null and b/plugins/weather/__pycache__/config.cpython-39.pyc differ diff --git a/plugins/weather/__pycache__/data_source.cpython-38.pyc b/plugins/weather/__pycache__/data_source.cpython-38.pyc new file mode 100644 index 00000000..0be8a36e Binary files /dev/null and b/plugins/weather/__pycache__/data_source.cpython-38.pyc differ diff --git a/plugins/weather/__pycache__/data_source.cpython-39.pyc b/plugins/weather/__pycache__/data_source.cpython-39.pyc new file mode 100644 index 00000000..b90430cc Binary files /dev/null and b/plugins/weather/__pycache__/data_source.cpython-39.pyc differ diff --git a/plugins/weather/config.py b/plugins/weather/config.py new file mode 100644 index 00000000..95b8313e --- /dev/null +++ b/plugins/weather/config.py @@ -0,0 +1,34 @@ +city_list = { + "北京": ["北京"], + "天津": ["天津"], + "山西": ["太原", "阳泉", "晋城", "长治", "临汾", "运城", "忻州", "吕梁", "晋中", "大同", "朔州"], + "河北": ["沧州", "石家庄", "唐山", "保定", "廊坊", "衡水", "邯郸", "邢台", "张家口", "辛集", "秦皇岛", "定州", "承德", "涿州"], + "山东": ["济南", "淄博", "聊城", "德州", "滨州", "济宁", "菏泽", "枣庄", "烟台", "威海", "泰安", "青岛", "临沂", "莱芜", "东营", "潍坊", "日照"], + "河南": ["郑州", "新乡", "鹤壁", "安阳", "焦作", "濮阳", "开封", "驻马店", "商丘", "三门峡", "南阳", "洛阳", "周口", "许昌", "信阳", "漯河", "平顶山", "济源"], + "广东": ["珠海", "中山", "肇庆", "深圳", "清远", "揭阳", "江门", "惠州", "河源", "广州", "佛山", "东莞", "潮州", "汕尾", "梅州", "阳江", "云浮", "韶关", "湛江", "汕头", "茂名"], + "浙江": ["舟山", "温州", "台州", "绍兴", "衢州", "宁波", "丽水", "金华", "嘉兴", "湖州", "杭州"], + "宁夏": ["中卫", "银川", "吴忠", "石嘴山", "固原"], + "江苏": ["镇江", "扬州", "盐城", "徐州", "宿迁", "无锡", "苏州", "南通", "南京", "连云港", "淮安", "常州", "泰州"], + "湖南": ["长沙", "邵阳", "怀化", "株洲", "张家界", "永州", "益阳", "湘西", "娄底", "衡阳", "郴州", "岳阳", "常德", "湘潭"], + "吉林": ["长春", "长春", "通化", "松原", "四平", "辽源", "吉林", "延边", "白山", "白城"], + "福建": ["漳州", "厦门", "福州", "三明", "莆田", "宁德", "南平", "龙岩", "泉州"], + "甘肃": ["张掖", "陇南", "兰州", "嘉峪关", "白银", "武威", "天水", "庆阳", "平凉", "临夏", "酒泉", "金昌", "甘南", "定西"], + "陕西": ["榆林", "西安", "延安", "咸阳", "渭南", "铜川", "商洛", "汉中", "宝鸡", "安康"], + "辽宁": ["营口", "铁岭", "沈阳", "盘锦", "辽阳", "锦州", "葫芦岛", "阜新", "抚顺", "丹东", "大连", "朝阳", "本溪", "鞍山"], + "江西": ["鹰潭", "宜春", "上饶", "萍乡", "南昌", "景德镇", "吉安", "抚州", "新余", "九江", "赣州"], + "黑龙江": ["伊春", "七台河", "牡丹江", "鸡西", "黑河", "鹤岗", "哈尔滨", "大兴安岭", "绥化", "双鸭山", "齐齐哈尔", "佳木斯", "大庆"], + "安徽": ["宣城", "铜陵", "六安", "黄山", "淮南", "合肥", "阜阳", "亳州", "安庆", "池州", "宿州", "芜湖", "马鞍山", "淮北", "滁州", "蚌埠"], + "湖北": ["孝感", "武汉", "十堰", "荆门", "黄冈", "襄阳", "咸宁", "随州", "黄石", "恩施", "鄂州", "荆州", "宜昌", "潜江", "天门", "神农架", "仙桃"], + "青海": ["西宁", "海西", "海东", "玉树", "黄南", "海南", "海北", "果洛"], + "新疆": ["乌鲁木齐", "克州", "阿勒泰", "五家渠", "石河子", "伊犁", "吐鲁番", "塔城", "克拉玛依", "喀什", "和田", "哈密", "昌吉", "博尔塔拉", "阿克苏", "巴音郭楞", "阿拉尔", "图木舒克", "铁门关"], + "贵州": ["铜仁", "黔东南", "贵阳", "安顺", "遵义", "黔西南", "黔南", "六盘水", "毕节"], + "四川": ["遂宁", "攀枝花", "眉山", "凉山", "成都", "巴中", "广安", "自贡", "甘孜", "资阳", "宜宾", "雅安", "内江", "南充", "绵阳", "泸州", "凉山", "乐山", "广元", "甘孜", "德阳", "达州", "阿坝"], + "上海": ["上海"], + "广西": ["南宁", "贵港", "玉林", "梧州", "钦州", "柳州", "来宾", "贺州", "河池", "桂林", "防城港", "崇左", "北海", "百色"], + "西藏": ["拉萨", "山南", "日喀则", "那曲", "林芝", "昌都", "阿里"], + "云南": ["昆明", "红河", "大理", "玉溪", "昭通", "西双版纳", "文山", "曲靖", "普洱", "怒江", "临沧", "丽江", "红河", "迪庆", "德宏", "大理", "楚雄", "保山"], + "内蒙古": ["呼和浩特", "乌兰察布", "兴安", "赤峰", "呼伦贝尔", "锡林郭勒", "乌海", "通辽", "巴彦淖尔", "阿拉善", "鄂尔多斯", "包头"], + "海南": ["海口", "三沙", "三亚", "临高", "五指山", "陵水", "文昌", "万宁", "白沙", "乐东", "澄迈", "屯昌", "定安", "东方", "保亭", "琼中", "琼海", "儋州", "昌江"], + "重庆": ["重庆"], + "台湾": ["台北", "高雄", "基隆", "台中", "台南", "新竹", "嘉义", "新北", "桃园"] +} \ No newline at end of file diff --git a/plugins/weather/data_source.py b/plugins/weather/data_source.py new file mode 100644 index 00000000..3f054066 --- /dev/null +++ b/plugins/weather/data_source.py @@ -0,0 +1,21 @@ +import requests +from util.init_result import image + + +async def get_weather_of_city(city) -> str: + url = 'http://wthrcdn.etouch.cn/weather_mini?city=' + city + data_json = requests.get(url).json() + if 'desc' in data_json: + if data_json['desc'] == "invilad-citykey": + return "你为啥不查火星的天气呢?小真寻只支持国内天气查询!!" + image("shengqi", "zhenxun") + elif data_json['desc'] == "OK": + w_type = data_json['data']['forecast'][0]['type'] + w_max = data_json['data']['forecast'][0]['high'][3:] + w_min = data_json['data']['forecast'][0]['low'][3:] + fengli = data_json['data']['forecast'][0]['fengli'][9:-3] + ganmao = data_json['data']["ganmao"] + fengxiang = data_json['data']['forecast'][0]['fengxiang'] + repass = f'{city}的天气是 {w_type} 天\n最高温度: {w_max}\n最低温度: {w_min}\n风力: {fengli} {fengxiang}\n{ganmao}' + return repass + else: + return '好像出错了?' diff --git a/plugins/what_anime/__init__.py b/plugins/what_anime/__init__.py new file mode 100644 index 00000000..5bc61afe --- /dev/null +++ b/plugins/what_anime/__init__.py @@ -0,0 +1,76 @@ + +from .data_source import get_anime +from nonebot import on_command +from nonebot.typing import T_State +from nonebot.adapters import Bot, Event +from util.utils import get_message_imgs +from services.log import logger +from util.utils import UserExistLimiter + + +__plugin_name__ = '识番' +__plugin_usage__ = r""" +以图识番 +识番 [图片] +""".strip() + +_ulmt = UserExistLimiter() + +what_anime = on_command('识番', priority=5, block=True) + + +@what_anime.args_parser +async def _(bot: Bot, event: Event, state: T_State): + if str(event.get_message()) in ['取消', '算了']: + await what_anime.finish("已取消操作..", at_sender=True) + img_url = get_message_imgs(event.json()) + if not img_url: + await what_anime.reject(prompt='图呢图呢图呢图呢GKD', at_sender=True) + state['img_url'] = img_url + + +@what_anime.handle() +async def _(bot: Bot, event: Event, state: T_State): + if str(event.get_message()) in ['帮助']: + await what_anime.finish(__plugin_usage__) + if _ulmt.check(event.user_id): + await what_anime.finish('您有识番任务正在进行,请稍等...', at_sender=True) + img_url = get_message_imgs(event.json()) + if img_url: + state['img_url'] = img_url + + +@what_anime.got('img_url', prompt='虚空识番?来图来图GKD') +async def _(bot: Bot, event: Event, state: T_State): + img_url = state['img_url'][0] + _ulmt.set_True(event.user_id) + await what_anime.send('开始识别.....') + anime_data_report = await get_anime(img_url) + if anime_data_report: + await what_anime.send(anime_data_report, at_sender=True) + logger.info(f"USER {event.user_id} GROUP "f"{event.group_id if event.message_type != 'private' else 'private'}" + f" 识番 {img_url} --> {anime_data_report}") + else: + logger.info(f"USER {event.user_id} GROUP " + f"{event.group_id if event.message_type != 'private' else 'private'} 识番 {img_url} 未找到!!") + await what_anime.send(f"没有寻找到该番剧,果咩..", at_sender=True) + _ulmt.set_False(event.user_id) + +# @whatanime.args_parser +# async def _(session: CommandSession): +# image_arg = session.current_arg_images +# +# if session.is_first_run: +# if image_arg: +# session.state['whatanime'] = image_arg[0] +# return +# +# if not image_arg: +# session.pause('没图说个J*,GKD!') +# +# session.state[session.current_key] = image_arg +# +# @on_natural_language(keywords={'whatanime', '识番', '識番'}, permission=get_bot().level) +# async def _(session: NLPSession): +# msg = session.msg +# return IntentCommand(90.0, 'whatanime', current_arg=msg or '') \ No newline at end of file diff --git a/plugins/what_anime/__pycache__/__init__.cpython-38.pyc b/plugins/what_anime/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..539fb2be Binary files /dev/null and b/plugins/what_anime/__pycache__/__init__.cpython-38.pyc differ diff --git a/plugins/what_anime/__pycache__/__init__.cpython-39.pyc b/plugins/what_anime/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 00000000..8e75f115 Binary files /dev/null and b/plugins/what_anime/__pycache__/__init__.cpython-39.pyc differ diff --git a/plugins/what_anime/__pycache__/data_source.cpython-38.pyc b/plugins/what_anime/__pycache__/data_source.cpython-38.pyc new file mode 100644 index 00000000..a4ed989e Binary files /dev/null and b/plugins/what_anime/__pycache__/data_source.cpython-38.pyc differ diff --git a/plugins/what_anime/__pycache__/data_source.cpython-39.pyc b/plugins/what_anime/__pycache__/data_source.cpython-39.pyc new file mode 100644 index 00000000..a5e20255 Binary files /dev/null and b/plugins/what_anime/__pycache__/data_source.cpython-39.pyc differ diff --git a/plugins/what_anime/data_source.py b/plugins/what_anime/data_source.py new file mode 100644 index 00000000..cdc661cf --- /dev/null +++ b/plugins/what_anime/data_source.py @@ -0,0 +1,35 @@ + +import time +from services.log import logger +from util.langconv import * +import aiohttp +from util.user_agent import get_user_agent + + +async def get_anime(anime: str) -> str: + s_time = time.time() + url = 'https://trace.moe/api/search?url={}'.format(anime) + logger.debug("[info]Now starting get the {}".format(url)) + try: + async with aiohttp.ClientSession(headers=get_user_agent()) as session: + async with session.get(url, timeout=45) as response: + if response.status == 200: + anime_json = await response.json() + if anime_json == 'Error reading imagenull': + return "图像源错误,注意必须是静态图片哦" + repass = "" + for anime in anime_json["docs"][:5]: + anime_name = anime["anime"] + episode = anime["episode"] + at = int(anime["at"]) + m, s = divmod(at, 60) + similarity = anime["similarity"] + putline = "[ {} ][{}][{}:{}] 相似度:{:.2%}". \ + format(Converter("zh-hans").convert(anime_name), + episode if episode else '?', m, s, similarity) + repass += putline + '\n' + return f'耗时 {int(time.time() - s_time)} 秒\n' + repass[:-1] + else: + return f'访问失败,请再试一次吧, status: {response.status}' + except Exception: + return '直接超时,那就没办法了,再试一次?' diff --git a/plugins/white2black_img.py b/plugins/white2black_img.py new file mode 100644 index 00000000..8cf478b6 --- /dev/null +++ b/plugins/white2black_img.py @@ -0,0 +1,136 @@ +from nonebot.typing import T_State +from nonebot.adapters.cqhttp import Bot, MessageEvent +from nonebot import on_command +from util.utils import get_message_imgs, get_local_proxy, get_message_text, is_Chinese +from util.init_result import image +import aiohttp +import aiofiles +from configs.path_config import IMAGE_PATH +from util.img_utils import CreateImg +from util.user_agent import get_user_agent +from services.log import logger + +# ZH_CN2EN 中文 » 英语 +# ZH_CN2JA 中文 » 日语 +# ZH_CN2KR 中文 » 韩语 +# ZH_CN2FR 中文 » 法语 +# ZH_CN2RU 中文 » 俄语 +# ZH_CN2SP 中文 » 西语 +# EN2ZH_CN 英语 » 中文 +# JA2ZH_CN 日语 » 中文 +# KR2ZH_CN 韩语 » 中文 +# FR2ZH_CN 法语 » 中文 +# RU2ZH_CN 俄语 » 中文 +# SP2ZH_CN 西语 » 中文 + + +__plugin_usage__ = '用法: \n\t黑白图 文字 图片\n示例:黑白草图 没有人不喜欢萝莉 (图片)' + +w2b_img = on_command('黑白草图', aliases={'黑白图'}, priority=5, block=True) + + +@w2b_img.handle() +async def _(bot: Bot, event: MessageEvent, state: T_State): + if not get_message_text(event.json()) or get_message_text(event.json()) in ['帮助']: + await w2b_img.finish(__plugin_usage__) + # try: + img = get_message_imgs(event.json()) + msg = get_message_text(event.json()) + if not img or not msg: + await w2b_img.finish(f"格式错误:\n" + __plugin_usage__) + img = img[0] + async with aiohttp.ClientSession(headers=get_user_agent()) as session: + async with session.get(img, proxy=get_local_proxy()) as response: + async with aiofiles.open(IMAGE_PATH + f'temp/{event.user_id}_w2b.png', 'wb') as f: + await f.write(await response.read()) + msg = await get_translate(msg) + w2b = CreateImg(0, 0, background=IMAGE_PATH + f'temp/{event.user_id}_w2b.png') + w2b.convert('L') + msg_sp = msg.split('<|>') + w, h = w2b.size + add_h, font_size = init_h_font_size(h) + bg = CreateImg(w, h + add_h, color='black', font_size=font_size) + bg.paste(w2b) + chinese_msg = formalization_msg(msg) + if not bg.check_font_size(chinese_msg): + if len(msg_sp) == 1: + centered_text(bg, chinese_msg, add_h) + else: + centered_text(bg, chinese_msg + '<|>' + msg_sp[1], add_h) + elif not bg.check_font_size(msg_sp[0]): + centered_text(bg, msg, add_h) + else: + ratio = (bg.getsize(msg_sp[0])[0] + 20) / bg.w + add_h = add_h * ratio + bg.resize(ratio) + centered_text(bg, msg, add_h) + await w2b_img.send(image(b64=bg.pic2bs4())) + logger.info( + f"(USER {event.user_id}, GROUP {event.group_id if event.message_type != 'private' else 'private'})" + f" 制作黑白草图 {msg}") + + +def centered_text(img: CreateImg, text: str, add_h: int): + top_h = img.h - add_h + (img.h / 100) + bottom_h = img.h - (img.h / 100) + text_sp = text.split('<|>') + w, h = img.getsize(text_sp[0]) + if len(text_sp) == 1: + w = (img.w - w) / 2 + h = top_h + (bottom_h - top_h - h) / 2 + img.text((w, h), text_sp[0], (255, 255, 255)) + else: + br_h = top_h + (bottom_h - top_h) / 2 + w = (img.w - w) / 2 + h = top_h + (br_h - top_h - h) / 2 + img.text((w, h), text_sp[0], (255, 255, 255)) + w, h = img.getsize(text_sp[1]) + w = (img.w - w) / 2 + h = br_h + (bottom_h - br_h - h) / 2 + img.text((w, h), text_sp[1], (255, 255, 255)) + + +async def get_translate(msg: str) -> str: + url = f'http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule&smartresult=ugc&sessionFrom=null' + data = { + 'type': "ZH_CN2JA", + 'i': msg, + "doctype": "json", + "version": "2.1", + "keyfrom": "fanyi.web", + "ue": "UTF-8", + "action": "FY_BY_CLICKBUTTON", + "typoResult": "true" + } + async with aiohttp.ClientSession(headers=get_user_agent()) as session: + try: + async with session.post(url, data=data, proxy=get_local_proxy()) as res: + data = await res.json() + if data['errorCode'] == 0: + translate = data['translateResult'][0][0]['tgt'] + msg += '<|>' + translate + except Exception as e: + logger.warning(f'黑白草图翻译出错 e:{e}') + return msg + + +def formalization_msg(msg: str) -> str: + rst = '' + for i in range(len(msg)): + if is_Chinese(msg[i]): + rst += msg[i] + ' ' + else: + rst += msg[i] + if i + 1 < len(msg) and is_Chinese(msg[i + 1]) and msg[i].isalpha(): + rst += ' ' + return rst + + +def init_h_font_size(h): + # 高度 字体 + if h < 400: + return init_h_font_size(400) + elif 400 < h < 800: + return init_h_font_size(800) + return h * 0.2, h * 0.05 + diff --git a/plugins/yiqing/__init__.py b/plugins/yiqing/__init__.py new file mode 100644 index 00000000..5ee1a92d --- /dev/null +++ b/plugins/yiqing/__init__.py @@ -0,0 +1,53 @@ +from nonebot import on_command +from .data_source import get_yiqing_data, clear_data +from services.log import logger +from nonebot.adapters.cqhttp import Bot, Event +from nonebot.typing import T_State +from .config import city_list +from util.utils import scheduler + +__plugin_name__ = '疫情查询' +__plugin_usage__ = '查询疫情帮助:\n\t对我说 查询疫情 省份/城市,我会回复疫情的实时数据\n\t示例: 查询疫情 温州' + + +yiqing = on_command("疫情", aliases={"查询疫情", "疫情查询"}, priority=5, block=True) + + +@yiqing.handle() +async def _(bot: Bot, event: Event, state: T_State): + if str(event.get_message()).strip() in ['帮助']: + await yiqing.finish(__plugin_usage__) + msg = str(event.get_message()).strip() + if msg: + if msg in city_list.keys(): + province = msg + city = '' + else: + for key in city_list.keys(): + if msg in city_list.get(key): + province = key + city = msg + break + else: + await yiqing.finish(__plugin_usage__) + try: + result = await get_yiqing_data(province, city) + if result: + await yiqing.send(result) + logger.info( + f"(USER {event.user_id}, GROUP {event.group_id if event.message_type != 'private' else 'private'}) 查询疫情:" + result) + else: + await yiqing.send("查询失败!!!!", at_sender=True) + logger.info( + f"(USER {event.user_id}, GROUP {event.group_id if event.message_type != 'private' else 'private'}) 查询疫情失败") + except UnboundLocalError: + await yiqing.finish('参数正确吗?只要一个参数啊', at_sender=True) + + +@scheduler.scheduled_job( + 'cron', + hour=0, + minute=1, +) +async def _(): + clear_data() diff --git a/plugins/yiqing/__pycache__/__init__.cpython-38.pyc b/plugins/yiqing/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 00000000..ad52899d Binary files /dev/null and b/plugins/yiqing/__pycache__/__init__.cpython-38.pyc differ diff --git a/plugins/yiqing/__pycache__/__init__.cpython-39.pyc b/plugins/yiqing/__pycache__/__init__.cpython-39.pyc new file mode 100644 index 00000000..48f76158 Binary files /dev/null and b/plugins/yiqing/__pycache__/__init__.cpython-39.pyc differ diff --git a/plugins/yiqing/__pycache__/config.cpython-38.pyc b/plugins/yiqing/__pycache__/config.cpython-38.pyc new file mode 100644 index 00000000..35048ce2 Binary files /dev/null and b/plugins/yiqing/__pycache__/config.cpython-38.pyc differ diff --git a/plugins/yiqing/__pycache__/config.cpython-39.pyc b/plugins/yiqing/__pycache__/config.cpython-39.pyc new file mode 100644 index 00000000..98558138 Binary files /dev/null and b/plugins/yiqing/__pycache__/config.cpython-39.pyc differ diff --git a/plugins/yiqing/__pycache__/data_source.cpython-38.pyc b/plugins/yiqing/__pycache__/data_source.cpython-38.pyc new file mode 100644 index 00000000..3192db06 Binary files /dev/null and b/plugins/yiqing/__pycache__/data_source.cpython-38.pyc differ diff --git a/plugins/yiqing/__pycache__/data_source.cpython-39.pyc b/plugins/yiqing/__pycache__/data_source.cpython-39.pyc new file mode 100644 index 00000000..406f2258 Binary files /dev/null and b/plugins/yiqing/__pycache__/data_source.cpython-39.pyc differ diff --git a/plugins/yiqing/config.py b/plugins/yiqing/config.py new file mode 100644 index 00000000..95b8313e --- /dev/null +++ b/plugins/yiqing/config.py @@ -0,0 +1,34 @@ +city_list = { + "北京": ["北京"], + "天津": ["天津"], + "山西": ["太原", "阳泉", "晋城", "长治", "临汾", "运城", "忻州", "吕梁", "晋中", "大同", "朔州"], + "河北": ["沧州", "石家庄", "唐山", "保定", "廊坊", "衡水", "邯郸", "邢台", "张家口", "辛集", "秦皇岛", "定州", "承德", "涿州"], + "山东": ["济南", "淄博", "聊城", "德州", "滨州", "济宁", "菏泽", "枣庄", "烟台", "威海", "泰安", "青岛", "临沂", "莱芜", "东营", "潍坊", "日照"], + "河南": ["郑州", "新乡", "鹤壁", "安阳", "焦作", "濮阳", "开封", "驻马店", "商丘", "三门峡", "南阳", "洛阳", "周口", "许昌", "信阳", "漯河", "平顶山", "济源"], + "广东": ["珠海", "中山", "肇庆", "深圳", "清远", "揭阳", "江门", "惠州", "河源", "广州", "佛山", "东莞", "潮州", "汕尾", "梅州", "阳江", "云浮", "韶关", "湛江", "汕头", "茂名"], + "浙江": ["舟山", "温州", "台州", "绍兴", "衢州", "宁波", "丽水", "金华", "嘉兴", "湖州", "杭州"], + "宁夏": ["中卫", "银川", "吴忠", "石嘴山", "固原"], + "江苏": ["镇江", "扬州", "盐城", "徐州", "宿迁", "无锡", "苏州", "南通", "南京", "连云港", "淮安", "常州", "泰州"], + "湖南": ["长沙", "邵阳", "怀化", "株洲", "张家界", "永州", "益阳", "湘西", "娄底", "衡阳", "郴州", "岳阳", "常德", "湘潭"], + "吉林": ["长春", "长春", "通化", "松原", "四平", "辽源", "吉林", "延边", "白山", "白城"], + "福建": ["漳州", "厦门", "福州", "三明", "莆田", "宁德", "南平", "龙岩", "泉州"], + "甘肃": ["张掖", "陇南", "兰州", "嘉峪关", "白银", "武威", "天水", "庆阳", "平凉", "临夏", "酒泉", "金昌", "甘南", "定西"], + "陕西": ["榆林", "西安", "延安", "咸阳", "渭南", "铜川", "商洛", "汉中", "宝鸡", "安康"], + "辽宁": ["营口", "铁岭", "沈阳", "盘锦", "辽阳", "锦州", "葫芦岛", "阜新", "抚顺", "丹东", "大连", "朝阳", "本溪", "鞍山"], + "江西": ["鹰潭", "宜春", "上饶", "萍乡", "南昌", "景德镇", "吉安", "抚州", "新余", "九江", "赣州"], + "黑龙江": ["伊春", "七台河", "牡丹江", "鸡西", "黑河", "鹤岗", "哈尔滨", "大兴安岭", "绥化", "双鸭山", "齐齐哈尔", "佳木斯", "大庆"], + "安徽": ["宣城", "铜陵", "六安", "黄山", "淮南", "合肥", "阜阳", "亳州", "安庆", "池州", "宿州", "芜湖", "马鞍山", "淮北", "滁州", "蚌埠"], + "湖北": ["孝感", "武汉", "十堰", "荆门", "黄冈", "襄阳", "咸宁", "随州", "黄石", "恩施", "鄂州", "荆州", "宜昌", "潜江", "天门", "神农架", "仙桃"], + "青海": ["西宁", "海西", "海东", "玉树", "黄南", "海南", "海北", "果洛"], + "新疆": ["乌鲁木齐", "克州", "阿勒泰", "五家渠", "石河子", "伊犁", "吐鲁番", "塔城", "克拉玛依", "喀什", "和田", "哈密", "昌吉", "博尔塔拉", "阿克苏", "巴音郭楞", "阿拉尔", "图木舒克", "铁门关"], + "贵州": ["铜仁", "黔东南", "贵阳", "安顺", "遵义", "黔西南", "黔南", "六盘水", "毕节"], + "四川": ["遂宁", "攀枝花", "眉山", "凉山", "成都", "巴中", "广安", "自贡", "甘孜", "资阳", "宜宾", "雅安", "内江", "南充", "绵阳", "泸州", "凉山", "乐山", "广元", "甘孜", "德阳", "达州", "阿坝"], + "上海": ["上海"], + "广西": ["南宁", "贵港", "玉林", "梧州", "钦州", "柳州", "来宾", "贺州", "河池", "桂林", "防城港", "崇左", "北海", "百色"], + "西藏": ["拉萨", "山南", "日喀则", "那曲", "林芝", "昌都", "阿里"], + "云南": ["昆明", "红河", "大理", "玉溪", "昭通", "西双版纳", "文山", "曲靖", "普洱", "怒江", "临沧", "丽江", "红河", "迪庆", "德宏", "大理", "楚雄", "保山"], + "内蒙古": ["呼和浩特", "乌兰察布", "兴安", "赤峰", "呼伦贝尔", "锡林郭勒", "乌海", "通辽", "巴彦淖尔", "阿拉善", "鄂尔多斯", "包头"], + "海南": ["海口", "三沙", "三亚", "临高", "五指山", "陵水", "文昌", "万宁", "白沙", "乐东", "澄迈", "屯昌", "定安", "东方", "保亭", "琼中", "琼海", "儋州", "昌江"], + "重庆": ["重庆"], + "台湾": ["台北", "高雄", "基隆", "台中", "台南", "新竹", "嘉义", "新北", "桃园"] +} \ No newline at end of file diff --git a/plugins/yiqing/data_source.py b/plugins/yiqing/data_source.py new file mode 100644 index 00000000..f9b9c691 --- /dev/null +++ b/plugins/yiqing/data_source.py @@ -0,0 +1,50 @@ +from datetime import datetime +import aiohttp +from util.user_agent import get_user_agent +import json +import os +from configs.path_config import TXT_PATH +from util.utils import get_local_proxy + + +url = "https://api.yimian.xyz/coro/" + + +async def get_yiqing_data(province, city_=''): + if not os.path.exists(TXT_PATH + "yiqing/"): + os.mkdir(TXT_PATH + "yiqing/") + if not os.path.exists(TXT_PATH + "yiqing/" + str(datetime.now().date()) + ".json"): + async with aiohttp.ClientSession(headers=get_user_agent()) as session: + async with session.get(url, proxy=get_local_proxy(), timeout=7) as response: + datalist = await response.json() + with open(TXT_PATH + "yiqing/" + str(datetime.now().date()) + ".json", 'w') as f: + json.dump(datalist, f) + datalist = json.load(open(TXT_PATH + "yiqing/" + str(datetime.now().date()) + ".json", 'r')) + result = '' + for data in datalist: + if data['provinceShortName'] == province: + if city_ == '': + result = province + "疫情数据:\n现存确诊: " + \ + str(data['currentConfirmedCount']) + "\n累计确诊: " + \ + str(data['confirmedCount']) + "\n治愈: " + \ + str(data['curedCount']) + "\n死亡: " + \ + str(data['deadCount']) + break + else: + for city in data['cities']: + if city['cityName'] == city_: + result = city_ + "疫情数据:\n现存确诊: " + \ + str(city['currentConfirmedCount']) + "\n累计确诊: " + str(city['confirmedCount']) +\ + "\n治愈: " + str(city['curedCount']) + "\n死亡: " + str(city['deadCount']) + break + return result + + +def clear_data(): + for file in os.listdir(TXT_PATH + "yiqing/"): + os.remove(TXT_PATH + "yiqing/" + file) + + +if __name__ == '__main__': + print(get_yiqing_data("浙江", city_='')) + diff --git a/resources/gocqhttp_file/v0.9.40-fix5-linux-arm64.tar.gz b/resources/gocqhttp_file/v0.9.40-fix5-linux-arm64.tar.gz new file mode 100644 index 00000000..1a337e80 Binary files /dev/null and b/resources/gocqhttp_file/v0.9.40-fix5-linux-arm64.tar.gz differ diff --git a/resources/gocqhttp_file/v0.9.40-fix5-windows-amd64.zip b/resources/gocqhttp_file/v0.9.40-fix5-windows-amd64.zip new file mode 100644 index 00000000..9eb55425 Binary files /dev/null and b/resources/gocqhttp_file/v0.9.40-fix5-windows-amd64.zip differ diff --git a/resources/img/cases/guangpu/AK-47 - xuexingyundong.png b/resources/img/cases/guangpu/AK-47 - xuexingyundong.png new file mode 100644 index 00000000..03679673 Binary files /dev/null and b/resources/img/cases/guangpu/AK-47 - xuexingyundong.png differ diff --git a/resources/img/cases/guangpu/AWP - fushengrumeng.png b/resources/img/cases/guangpu/AWP - fushengrumeng.png new file mode 100644 index 00000000..dfa897e1 Binary files /dev/null and b/resources/img/cases/guangpu/AWP - fushengrumeng.png differ diff --git a/resources/img/cases/guangpu/CZ75 - xiangliu.png b/resources/img/cases/guangpu/CZ75 - xiangliu.png new file mode 100644 index 00000000..762b046d Binary files /dev/null and b/resources/img/cases/guangpu/CZ75 - xiangliu.png differ diff --git a/resources/img/cases/guangpu/FN57 - maoxixueguan.png b/resources/img/cases/guangpu/FN57 - maoxixueguan.png new file mode 100644 index 00000000..55b3b3cf Binary files /dev/null and b/resources/img/cases/guangpu/FN57 - maoxixueguan.png differ diff --git a/resources/img/cases/guangpu/M249 - cuilvjianduwa.png b/resources/img/cases/guangpu/M249 - cuilvjianduwa.png new file mode 100644 index 00000000..9189ae27 Binary files /dev/null and b/resources/img/cases/guangpu/M249 - cuilvjianduwa.png differ diff --git a/resources/img/cases/guangpu/M4A1 - huimiezhe 2000.png b/resources/img/cases/guangpu/M4A1 - huimiezhe 2000.png new file mode 100644 index 00000000..a96c295f Binary files /dev/null and b/resources/img/cases/guangpu/M4A1 - huimiezhe 2000.png differ diff --git a/resources/img/cases/guangpu/MAC-10 - juejiezhixing.png b/resources/img/cases/guangpu/MAC-10 - juejiezhixing.png new file mode 100644 index 00000000..5215e106 Binary files /dev/null and b/resources/img/cases/guangpu/MAC-10 - juejiezhixing.png differ diff --git a/resources/img/cases/guangpu/MP7 - feizhoubuluo.png b/resources/img/cases/guangpu/MP7 - feizhoubuluo.png new file mode 100644 index 00000000..f4df11f0 Binary files /dev/null and b/resources/img/cases/guangpu/MP7 - feizhoubuluo.png differ diff --git a/resources/img/cases/guangpu/P250 - lianyi.png b/resources/img/cases/guangpu/P250 - lianyi.png new file mode 100644 index 00000000..d25a8673 Binary files /dev/null and b/resources/img/cases/guangpu/P250 - lianyi.png differ diff --git a/resources/img/cases/guangpu/PP-yeniu - conglinhualiu.png b/resources/img/cases/guangpu/PP-yeniu - conglinhualiu.png new file mode 100644 index 00000000..9da72469 Binary files /dev/null and b/resources/img/cases/guangpu/PP-yeniu - conglinhualiu.png differ diff --git a/resources/img/cases/guangpu/SCAR-20 - lantu.png b/resources/img/cases/guangpu/SCAR-20 - lantu.png new file mode 100644 index 00000000..0fef06db Binary files /dev/null and b/resources/img/cases/guangpu/SCAR-20 - lantu.png differ diff --git a/resources/img/cases/guangpu/UMP-45 - zhijia.png b/resources/img/cases/guangpu/UMP-45 - zhijia.png new file mode 100644 index 00000000..8b71a062 Binary files /dev/null and b/resources/img/cases/guangpu/UMP-45 - zhijia.png differ diff --git a/resources/img/cases/guangpu/USP - heisemeiying.png b/resources/img/cases/guangpu/USP - heisemeiying.png new file mode 100644 index 00000000..169ce1c4 Binary files /dev/null and b/resources/img/cases/guangpu/USP - heisemeiying.png differ diff --git a/resources/img/cases/guangpu/XM1014 - siji.png b/resources/img/cases/guangpu/XM1014 - siji.png new file mode 100644 index 00000000..caad273c Binary files /dev/null and b/resources/img/cases/guangpu/XM1014 - siji.png differ diff --git a/resources/img/cases/guangpu/anyingshuangbi - damashigegang.png b/resources/img/cases/guangpu/anyingshuangbi - damashigegang.png new file mode 100644 index 00000000..4f3fb07e Binary files /dev/null and b/resources/img/cases/guangpu/anyingshuangbi - damashigegang.png differ diff --git a/resources/img/cases/guangpu/anyingshuangbi - duopulei.png b/resources/img/cases/guangpu/anyingshuangbi - duopulei.png new file mode 100644 index 00000000..85173f28 Binary files /dev/null and b/resources/img/cases/guangpu/anyingshuangbi - duopulei.png differ diff --git a/resources/img/cases/guangpu/anyingshuangbi - huya.png b/resources/img/cases/guangpu/anyingshuangbi - huya.png new file mode 100644 index 00000000..1d847cea Binary files /dev/null and b/resources/img/cases/guangpu/anyingshuangbi - huya.png differ diff --git a/resources/img/cases/guangpu/anyingshuangbi - jianbiandalishi.png b/resources/img/cases/guangpu/anyingshuangbi - jianbiandalishi.png new file mode 100644 index 00000000..da77c554 Binary files /dev/null and b/resources/img/cases/guangpu/anyingshuangbi - jianbiandalishi.png differ diff --git a/resources/img/cases/guangpu/anyingshuangbi - waibiaoshengxiu.png b/resources/img/cases/guangpu/anyingshuangbi - waibiaoshengxiu.png new file mode 100644 index 00000000..7b8c2e64 Binary files /dev/null and b/resources/img/cases/guangpu/anyingshuangbi - waibiaoshengxiu.png differ diff --git a/resources/img/cases/guangpu/anyingshuangbi - zhimingziluolan.png b/resources/img/cases/guangpu/anyingshuangbi - zhimingziluolan.png new file mode 100644 index 00000000..74894a10 Binary files /dev/null and b/resources/img/cases/guangpu/anyingshuangbi - zhimingziluolan.png differ diff --git a/resources/img/cases/guangpu/baoyiliedao - damashigegang.png b/resources/img/cases/guangpu/baoyiliedao - damashigegang.png new file mode 100644 index 00000000..8a6862e9 Binary files /dev/null and b/resources/img/cases/guangpu/baoyiliedao - damashigegang.png differ diff --git a/resources/img/cases/guangpu/baoyiliedao - duopulei.png b/resources/img/cases/guangpu/baoyiliedao - duopulei.png new file mode 100644 index 00000000..39091a44 Binary files /dev/null and b/resources/img/cases/guangpu/baoyiliedao - duopulei.png differ diff --git a/resources/img/cases/guangpu/baoyiliedao - huya.png b/resources/img/cases/guangpu/baoyiliedao - huya.png new file mode 100644 index 00000000..7c4e1981 Binary files /dev/null and b/resources/img/cases/guangpu/baoyiliedao - huya.png differ diff --git a/resources/img/cases/guangpu/baoyiliedao - jianbiandalishi.png b/resources/img/cases/guangpu/baoyiliedao - jianbiandalishi.png new file mode 100644 index 00000000..ae7d4ed5 Binary files /dev/null and b/resources/img/cases/guangpu/baoyiliedao - jianbiandalishi.png differ diff --git a/resources/img/cases/guangpu/baoyiliedao - waibiaoshengxiu.png b/resources/img/cases/guangpu/baoyiliedao - waibiaoshengxiu.png new file mode 100644 index 00000000..d02a4010 Binary files /dev/null and b/resources/img/cases/guangpu/baoyiliedao - waibiaoshengxiu.png differ diff --git a/resources/img/cases/guangpu/baoyiliedao - zhimingziluolan.png b/resources/img/cases/guangpu/baoyiliedao - zhimingziluolan.png new file mode 100644 index 00000000..53b759d6 Binary files /dev/null and b/resources/img/cases/guangpu/baoyiliedao - zhimingziluolan.png differ diff --git a/resources/img/cases/guangpu/hudiedao - damashigegang.png b/resources/img/cases/guangpu/hudiedao - damashigegang.png new file mode 100644 index 00000000..464408e4 Binary files /dev/null and b/resources/img/cases/guangpu/hudiedao - damashigegang.png differ diff --git a/resources/img/cases/guangpu/hudiedao - duopulei.png b/resources/img/cases/guangpu/hudiedao - duopulei.png new file mode 100644 index 00000000..9bba8f34 Binary files /dev/null and b/resources/img/cases/guangpu/hudiedao - duopulei.png differ diff --git a/resources/img/cases/guangpu/hudiedao - huya.png b/resources/img/cases/guangpu/hudiedao - huya.png new file mode 100644 index 00000000..c46b83c4 Binary files /dev/null and b/resources/img/cases/guangpu/hudiedao - huya.png differ diff --git a/resources/img/cases/guangpu/hudiedao - jianbiandalishi.png b/resources/img/cases/guangpu/hudiedao - jianbiandalishi.png new file mode 100644 index 00000000..e7a22b33 Binary files /dev/null and b/resources/img/cases/guangpu/hudiedao - jianbiandalishi.png differ diff --git a/resources/img/cases/guangpu/hudiedao - waibiaoshengxiu.png b/resources/img/cases/guangpu/hudiedao - waibiaoshengxiu.png new file mode 100644 index 00000000..1c5541b8 Binary files /dev/null and b/resources/img/cases/guangpu/hudiedao - waibiaoshengxiu.png differ diff --git a/resources/img/cases/guangpu/hudiedao - zhimingziluolan.png b/resources/img/cases/guangpu/hudiedao - zhimingziluolan.png new file mode 100644 index 00000000..dd703adc Binary files /dev/null and b/resources/img/cases/guangpu/hudiedao - zhimingziluolan.png differ diff --git a/resources/img/cases/guangpu/jialier AR - shenhonghaixiao.png b/resources/img/cases/guangpu/jialier AR - shenhonghaixiao.png new file mode 100644 index 00000000..e6e58be5 Binary files /dev/null and b/resources/img/cases/guangpu/jialier AR - shenhonghaixiao.png differ diff --git a/resources/img/cases/guangpu/jieduanxiandanqiang - suolu.png b/resources/img/cases/guangpu/jieduanxiandanqiang - suolu.png new file mode 100644 index 00000000..c4e425ed Binary files /dev/null and b/resources/img/cases/guangpu/jieduanxiandanqiang - suolu.png differ diff --git a/resources/img/cases/guangpu/lieshazhebishou - damashigegang.png b/resources/img/cases/guangpu/lieshazhebishou - damashigegang.png new file mode 100644 index 00000000..432bcb67 Binary files /dev/null and b/resources/img/cases/guangpu/lieshazhebishou - damashigegang.png differ diff --git a/resources/img/cases/guangpu/lieshazhebishou - duopulei.png b/resources/img/cases/guangpu/lieshazhebishou - duopulei.png new file mode 100644 index 00000000..08cb33c5 Binary files /dev/null and b/resources/img/cases/guangpu/lieshazhebishou - duopulei.png differ diff --git a/resources/img/cases/guangpu/lieshazhebishou - huya.png b/resources/img/cases/guangpu/lieshazhebishou - huya.png new file mode 100644 index 00000000..f47a840b Binary files /dev/null and b/resources/img/cases/guangpu/lieshazhebishou - huya.png differ diff --git a/resources/img/cases/guangpu/lieshazhebishou - jianbiandalishi.png b/resources/img/cases/guangpu/lieshazhebishou - jianbiandalishi.png new file mode 100644 index 00000000..ed91a161 Binary files /dev/null and b/resources/img/cases/guangpu/lieshazhebishou - jianbiandalishi.png differ diff --git a/resources/img/cases/guangpu/lieshazhebishou - waibiaoshengxiu.png b/resources/img/cases/guangpu/lieshazhebishou - waibiaoshengxiu.png new file mode 100644 index 00000000..65688380 Binary files /dev/null and b/resources/img/cases/guangpu/lieshazhebishou - waibiaoshengxiu.png differ diff --git a/resources/img/cases/guangpu/lieshazhebishou - zhimingziluolan.png b/resources/img/cases/guangpu/lieshazhebishou - zhimingziluolan.png new file mode 100644 index 00000000..0b290ddb Binary files /dev/null and b/resources/img/cases/guangpu/lieshazhebishou - zhimingziluolan.png differ diff --git a/resources/img/cases/guangpu/shamozhiying - xiushilieyan.png b/resources/img/cases/guangpu/shamozhiying - xiushilieyan.png new file mode 100644 index 00000000..685c58db Binary files /dev/null and b/resources/img/cases/guangpu/shamozhiying - xiushilieyan.png differ diff --git a/resources/img/cases/guangpu/wandao - damashigegang.png b/resources/img/cases/guangpu/wandao - damashigegang.png new file mode 100644 index 00000000..0f29cfbf Binary files /dev/null and b/resources/img/cases/guangpu/wandao - damashigegang.png differ diff --git a/resources/img/cases/guangpu/wandao - duopulei.png b/resources/img/cases/guangpu/wandao - duopulei.png new file mode 100644 index 00000000..6d661dae Binary files /dev/null and b/resources/img/cases/guangpu/wandao - duopulei.png differ diff --git a/resources/img/cases/guangpu/wandao - huya.png b/resources/img/cases/guangpu/wandao - huya.png new file mode 100644 index 00000000..7b56e548 Binary files /dev/null and b/resources/img/cases/guangpu/wandao - huya.png differ diff --git a/resources/img/cases/guangpu/wandao - jianbiandalishi.png b/resources/img/cases/guangpu/wandao - jianbiandalishi.png new file mode 100644 index 00000000..ae0ceaa0 Binary files /dev/null and b/resources/img/cases/guangpu/wandao - jianbiandalishi.png differ diff --git a/resources/img/cases/guangpu/wandao - waibiaoshengxiu.png b/resources/img/cases/guangpu/wandao - waibiaoshengxiu.png new file mode 100644 index 00000000..24c9209f Binary files /dev/null and b/resources/img/cases/guangpu/wandao - waibiaoshengxiu.png differ diff --git a/resources/img/cases/guangpu/wandao - zhimingziluolan.png b/resources/img/cases/guangpu/wandao - zhimingziluolan.png new file mode 100644 index 00000000..eb9d1e68 Binary files /dev/null and b/resources/img/cases/guangpu/wandao - zhimingziluolan.png differ diff --git a/resources/img/cases/kuangyadaxingdong/AWP - wanglingzhizhu.png b/resources/img/cases/kuangyadaxingdong/AWP - wanglingzhizhu.png new file mode 100644 index 00000000..2a90e22e Binary files /dev/null and b/resources/img/cases/kuangyadaxingdong/AWP - wanglingzhizhu.png differ diff --git a/resources/img/cases/kuangyadaxingdong/CZ75 - shichou.png b/resources/img/cases/kuangyadaxingdong/CZ75 - shichou.png new file mode 100644 index 00000000..40f46b81 Binary files /dev/null and b/resources/img/cases/kuangyadaxingdong/CZ75 - shichou.png differ diff --git a/resources/img/cases/kuangyadaxingdong/FN57 - tonghuachengbao.png b/resources/img/cases/kuangyadaxingdong/FN57 - tonghuachengbao.png new file mode 100644 index 00000000..3e0926d0 Binary files /dev/null and b/resources/img/cases/kuangyadaxingdong/FN57 - tonghuachengbao.png differ diff --git a/resources/img/cases/kuangyadaxingdong/G3SG1 - xuexingmicai.png b/resources/img/cases/kuangyadaxingdong/G3SG1 - xuexingmicai.png new file mode 100644 index 00000000..dd75718b Binary files /dev/null and b/resources/img/cases/kuangyadaxingdong/G3SG1 - xuexingmicai.png differ diff --git a/resources/img/cases/kuangyadaxingdong/M249 - denggaoxian.png b/resources/img/cases/kuangyadaxingdong/M249 - denggaoxian.png new file mode 100644 index 00000000..4e20683e Binary files /dev/null and b/resources/img/cases/kuangyadaxingdong/M249 - denggaoxian.png differ diff --git a/resources/img/cases/kuangyadaxingdong/M4A1 - yinhuaji.png b/resources/img/cases/kuangyadaxingdong/M4A1 - yinhuaji.png new file mode 100644 index 00000000..2681ed4e Binary files /dev/null and b/resources/img/cases/kuangyadaxingdong/M4A1 - yinhuaji.png differ diff --git a/resources/img/cases/kuangyadaxingdong/M4A4 - saibo.png b/resources/img/cases/kuangyadaxingdong/M4A4 - saibo.png new file mode 100644 index 00000000..5a227b26 Binary files /dev/null and b/resources/img/cases/kuangyadaxingdong/M4A4 - saibo.png differ diff --git a/resources/img/cases/kuangyadaxingdong/MP5-SD - lingdianxingdong.png b/resources/img/cases/kuangyadaxingdong/MP5-SD - lingdianxingdong.png new file mode 100644 index 00000000..1936a136 Binary files /dev/null and b/resources/img/cases/kuangyadaxingdong/MP5-SD - lingdianxingdong.png differ diff --git a/resources/img/cases/kuangyadaxingdong/P250 - wuranwu.png b/resources/img/cases/kuangyadaxingdong/P250 - wuranwu.png new file mode 100644 index 00000000..0aab3c4e Binary files /dev/null and b/resources/img/cases/kuangyadaxingdong/P250 - wuranwu.png differ diff --git a/resources/img/cases/kuangyadaxingdong/P90 - daguaishouRUSH.png b/resources/img/cases/kuangyadaxingdong/P90 - daguaishouRUSH.png new file mode 100644 index 00000000..c7942d6e Binary files /dev/null and b/resources/img/cases/kuangyadaxingdong/P90 - daguaishouRUSH.png differ diff --git a/resources/img/cases/kuangyadaxingdong/SSG 08 - douqiang.png b/resources/img/cases/kuangyadaxingdong/SSG 08 - douqiang.png new file mode 100644 index 00000000..9fd88095 Binary files /dev/null and b/resources/img/cases/kuangyadaxingdong/SSG 08 - douqiang.png differ diff --git a/resources/img/cases/kuangyadaxingdong/UMP-45 - jinbihuihuang.png b/resources/img/cases/kuangyadaxingdong/UMP-45 - jinbihuihuang.png new file mode 100644 index 00000000..ed153db7 Binary files /dev/null and b/resources/img/cases/kuangyadaxingdong/UMP-45 - jinbihuihuang.png differ diff --git a/resources/img/cases/kuangyadaxingdong/USP - xiaolvguai.png b/resources/img/cases/kuangyadaxingdong/USP - xiaolvguai.png new file mode 100644 index 00000000..5acf33d7 Binary files /dev/null and b/resources/img/cases/kuangyadaxingdong/USP - xiaolvguai.png differ diff --git a/resources/img/cases/kuangyadaxingdong/geluoke - heisemeiying.png b/resources/img/cases/kuangyadaxingdong/geluoke - heisemeiying.png new file mode 100644 index 00000000..7d13767b Binary files /dev/null and b/resources/img/cases/kuangyadaxingdong/geluoke - heisemeiying.png differ diff --git a/resources/img/cases/kuangyadaxingdong/guoshou - changjinglu.png b/resources/img/cases/kuangyadaxingdong/guoshou - changjinglu.png new file mode 100644 index 00000000..df040fbc Binary files /dev/null and b/resources/img/cases/kuangyadaxingdong/guoshou - changjinglu.png differ diff --git a/resources/img/cases/kuangyadaxingdong/guoshou - jinggao!.png b/resources/img/cases/kuangyadaxingdong/guoshou - jinggao!.png new file mode 100644 index 00000000..ff2cc8fb Binary files /dev/null and b/resources/img/cases/kuangyadaxingdong/guoshou - jinggao!.png differ diff --git a/resources/img/cases/kuangyadaxingdong/guoshou - mangshe.png b/resources/img/cases/kuangyadaxingdong/guoshou - mangshe.png new file mode 100644 index 00000000..d825947a Binary files /dev/null and b/resources/img/cases/kuangyadaxingdong/guoshou - mangshe.png differ diff --git a/resources/img/cases/kuangyadaxingdong/guoshou - shamotoujin.png b/resources/img/cases/kuangyadaxingdong/guoshou - shamotoujin.png new file mode 100644 index 00000000..6539e1c0 Binary files /dev/null and b/resources/img/cases/kuangyadaxingdong/guoshou - shamotoujin.png differ diff --git a/resources/img/cases/kuangyadaxingdong/jialier AR - pohuaizhe.png b/resources/img/cases/kuangyadaxingdong/jialier AR - pohuaizhe.png new file mode 100644 index 00000000..01d6233e Binary files /dev/null and b/resources/img/cases/kuangyadaxingdong/jialier AR - pohuaizhe.png differ diff --git a/resources/img/cases/kuangyadaxingdong/jiashishoutao - feihongliezan.png b/resources/img/cases/kuangyadaxingdong/jiashishoutao - feihongliezan.png new file mode 100644 index 00000000..a64f2961 Binary files /dev/null and b/resources/img/cases/kuangyadaxingdong/jiashishoutao - feihongliezan.png differ diff --git a/resources/img/cases/kuangyadaxingdong/jiashishoutao - meizhoubaonvwang.png b/resources/img/cases/kuangyadaxingdong/jiashishoutao - meizhoubaonvwang.png new file mode 100644 index 00000000..7f25b98c Binary files /dev/null and b/resources/img/cases/kuangyadaxingdong/jiashishoutao - meizhoubaonvwang.png differ diff --git a/resources/img/cases/kuangyadaxingdong/jiashishoutao - xizhuanggelv.png b/resources/img/cases/kuangyadaxingdong/jiashishoutao - xizhuanggelv.png new file mode 100644 index 00000000..f16f4f7d Binary files /dev/null and b/resources/img/cases/kuangyadaxingdong/jiashishoutao - xizhuanggelv.png differ diff --git a/resources/img/cases/kuangyadaxingdong/jiashishoutao - xuebao.png b/resources/img/cases/kuangyadaxingdong/jiashishoutao - xuebao.png new file mode 100644 index 00000000..40a37619 Binary files /dev/null and b/resources/img/cases/kuangyadaxingdong/jiashishoutao - xuebao.png differ diff --git a/resources/img/cases/kuangyadaxingdong/kuangyashoutao - feicui.png b/resources/img/cases/kuangyadaxingdong/kuangyashoutao - feicui.png new file mode 100644 index 00000000..dd5d6c7f Binary files /dev/null and b/resources/img/cases/kuangyadaxingdong/kuangyashoutao - feicui.png differ diff --git a/resources/img/cases/kuangyadaxingdong/kuangyashoutao - huangsebanwen.png b/resources/img/cases/kuangyadaxingdong/kuangyashoutao - huangsebanwen.png new file mode 100644 index 00000000..d308e951 Binary files /dev/null and b/resources/img/cases/kuangyadaxingdong/kuangyashoutao - huangsebanwen.png differ diff --git a/resources/img/cases/kuangyadaxingdong/kuangyashoutao - jingshencuoluan.png b/resources/img/cases/kuangyadaxingdong/kuangyashoutao - jingshencuoluan.png new file mode 100644 index 00000000..834577b2 Binary files /dev/null and b/resources/img/cases/kuangyadaxingdong/kuangyashoutao - jingshencuoluan.png differ diff --git a/resources/img/cases/kuangyadaxingdong/kuangyashoutao - zhenjian.png b/resources/img/cases/kuangyadaxingdong/kuangyashoutao - zhenjian.png new file mode 100644 index 00000000..627728c0 Binary files /dev/null and b/resources/img/cases/kuangyadaxingdong/kuangyashoutao - zhenjian.png differ diff --git a/resources/img/cases/kuangyadaxingdong/motuoshoutao - disantezhongbinglian.png b/resources/img/cases/kuangyadaxingdong/motuoshoutao - disantezhongbinglian.png new file mode 100644 index 00000000..7f574dc6 Binary files /dev/null and b/resources/img/cases/kuangyadaxingdong/motuoshoutao - disantezhongbinglian.png differ diff --git a/resources/img/cases/kuangyadaxingdong/motuoshoutao - xiaoxinyanmudan.png b/resources/img/cases/kuangyadaxingdong/motuoshoutao - xiaoxinyanmudan.png new file mode 100644 index 00000000..0b5de0f4 Binary files /dev/null and b/resources/img/cases/kuangyadaxingdong/motuoshoutao - xiaoxinyanmudan.png differ diff --git a/resources/img/cases/kuangyadaxingdong/motuoshoutao - xueya.png b/resources/img/cases/kuangyadaxingdong/motuoshoutao - xueya.png new file mode 100644 index 00000000..7a63a4aa Binary files /dev/null and b/resources/img/cases/kuangyadaxingdong/motuoshoutao - xueya.png differ diff --git a/resources/img/cases/kuangyadaxingdong/motuoshoutao - zhongdianxian.png b/resources/img/cases/kuangyadaxingdong/motuoshoutao - zhongdianxian.png new file mode 100644 index 00000000..7188c831 Binary files /dev/null and b/resources/img/cases/kuangyadaxingdong/motuoshoutao - zhongdianxian.png differ diff --git a/resources/img/cases/kuangyadaxingdong/shuangchibeiruita - zainan.png b/resources/img/cases/kuangyadaxingdong/shuangchibeiruita - zainan.png new file mode 100644 index 00000000..7d180c42 Binary files /dev/null and b/resources/img/cases/kuangyadaxingdong/shuangchibeiruita - zainan.png differ diff --git a/resources/img/cases/kuangyadaxingdong/xinxing - yijianqingxin.png b/resources/img/cases/kuangyadaxingdong/xinxing - yijianqingxin.png new file mode 100644 index 00000000..cf9ac585 Binary files /dev/null and b/resources/img/cases/kuangyadaxingdong/xinxing - yijianqingxin.png differ diff --git a/resources/img/cases/kuangyadaxingdong/yundongshoutao - dangong.png b/resources/img/cases/kuangyadaxingdong/yundongshoutao - dangong.png new file mode 100644 index 00000000..873ea237 Binary files /dev/null and b/resources/img/cases/kuangyadaxingdong/yundongshoutao - dangong.png differ diff --git a/resources/img/cases/kuangyadaxingdong/yundongshoutao - daxingliewu.png b/resources/img/cases/kuangyadaxingdong/yundongshoutao - daxingliewu.png new file mode 100644 index 00000000..cf43276e Binary files /dev/null and b/resources/img/cases/kuangyadaxingdong/yundongshoutao - daxingliewu.png differ diff --git a/resources/img/cases/kuangyadaxingdong/yundongshoutao - xinghongtoujin.png b/resources/img/cases/kuangyadaxingdong/yundongshoutao - xinghongtoujin.png new file mode 100644 index 00000000..e4438d8c Binary files /dev/null and b/resources/img/cases/kuangyadaxingdong/yundongshoutao - xinghongtoujin.png differ diff --git a/resources/img/cases/kuangyadaxingdong/yundongshoutao - yexingyi.png b/resources/img/cases/kuangyadaxingdong/yundongshoutao - yexingyi.png new file mode 100644 index 00000000..33981bca Binary files /dev/null and b/resources/img/cases/kuangyadaxingdong/yundongshoutao - yexingyi.png differ diff --git a/resources/img/cases/kuangyadaxingdong/zhuanyeshoutao - jianbiandalishi.png b/resources/img/cases/kuangyadaxingdong/zhuanyeshoutao - jianbiandalishi.png new file mode 100644 index 00000000..66d00374 Binary files /dev/null and b/resources/img/cases/kuangyadaxingdong/zhuanyeshoutao - jianbiandalishi.png differ diff --git a/resources/img/cases/kuangyadaxingdong/zhuanyeshoutao - laohujingying.png b/resources/img/cases/kuangyadaxingdong/zhuanyeshoutao - laohujingying.png new file mode 100644 index 00000000..f40f3b2e Binary files /dev/null and b/resources/img/cases/kuangyadaxingdong/zhuanyeshoutao - laohujingying.png differ diff --git a/resources/img/cases/kuangyadaxingdong/zhuanyeshoutao - lujunshaoweizhangguan.png b/resources/img/cases/kuangyadaxingdong/zhuanyeshoutao - lujunshaoweizhangguan.png new file mode 100644 index 00000000..517d85d8 Binary files /dev/null and b/resources/img/cases/kuangyadaxingdong/zhuanyeshoutao - lujunshaoweizhangguan.png differ diff --git a/resources/img/cases/kuangyadaxingdong/zhuanyeshoutao - yixiantegong.png b/resources/img/cases/kuangyadaxingdong/zhuanyeshoutao - yixiantegong.png new file mode 100644 index 00000000..6dcd26c2 Binary files /dev/null and b/resources/img/cases/kuangyadaxingdong/zhuanyeshoutao - yixiantegong.png differ diff --git a/resources/img/cases/liekong/AK-47 - anubisijuntuan.png b/resources/img/cases/liekong/AK-47 - anubisijuntuan.png new file mode 100644 index 00000000..e3e6684c Binary files /dev/null and b/resources/img/cases/liekong/AK-47 - anubisijuntuan.png differ diff --git a/resources/img/cases/liekong/M4A4 - chixian.png b/resources/img/cases/liekong/M4A4 - chixian.png new file mode 100644 index 00000000..e36fb694 Binary files /dev/null and b/resources/img/cases/liekong/M4A4 - chixian.png differ diff --git a/resources/img/cases/liekong/MAC-10 - meihuo.png b/resources/img/cases/liekong/MAC-10 - meihuo.png new file mode 100644 index 00000000..fbe2bcc4 Binary files /dev/null and b/resources/img/cases/liekong/MAC-10 - meihuo.png differ diff --git a/resources/img/cases/liekong/MAG-7 - beimingyouyu.png b/resources/img/cases/liekong/MAG-7 - beimingyouyu.png new file mode 100644 index 00000000..a52c0380 Binary files /dev/null and b/resources/img/cases/liekong/MAG-7 - beimingyouyu.png differ diff --git a/resources/img/cases/liekong/MP5-SD - mengliechongfeng.png b/resources/img/cases/liekong/MP5-SD - mengliechongfeng.png new file mode 100644 index 00000000..43621867 Binary files /dev/null and b/resources/img/cases/liekong/MP5-SD - mengliechongfeng.png differ diff --git a/resources/img/cases/liekong/P2000 - pangencuojie.png b/resources/img/cases/liekong/P2000 - pangencuojie.png new file mode 100644 index 00000000..d54c53c9 Binary files /dev/null and b/resources/img/cases/liekong/P2000 - pangencuojie.png differ diff --git a/resources/img/cases/liekong/P250 - kadai.png b/resources/img/cases/liekong/P250 - kadai.png new file mode 100644 index 00000000..44204a2b Binary files /dev/null and b/resources/img/cases/liekong/P250 - kadai.png differ diff --git a/resources/img/cases/liekong/P90 - jizhuangxiang.png b/resources/img/cases/liekong/P90 - jizhuangxiang.png new file mode 100644 index 00000000..d146c120 Binary files /dev/null and b/resources/img/cases/liekong/P90 - jizhuangxiang.png differ diff --git a/resources/img/cases/liekong/PP-yeniu - shenmibeiwen.png b/resources/img/cases/liekong/PP-yeniu - shenmibeiwen.png new file mode 100644 index 00000000..22e3a21b Binary files /dev/null and b/resources/img/cases/liekong/PP-yeniu - shenmibeiwen.png differ diff --git a/resources/img/cases/liekong/SG 553 - xiushizhiren.png b/resources/img/cases/liekong/SG 553 - xiushizhiren.png new file mode 100644 index 00000000..4b2d4c67 Binary files /dev/null and b/resources/img/cases/liekong/SG 553 - xiushizhiren.png differ diff --git a/resources/img/cases/liekong/SSG 08 - zhuji001.png b/resources/img/cases/liekong/SSG 08 - zhuji001.png new file mode 100644 index 00000000..d5a72b8a Binary files /dev/null and b/resources/img/cases/liekong/SSG 08 - zhuji001.png differ diff --git a/resources/img/cases/liekong/Tec-9 - xiongdilian.png b/resources/img/cases/liekong/Tec-9 - xiongdilian.png new file mode 100644 index 00000000..b15b5730 Binary files /dev/null and b/resources/img/cases/liekong/Tec-9 - xiongdilian.png differ diff --git a/resources/img/cases/liekong/XM1014 - maizangzhiying.png b/resources/img/cases/liekong/XM1014 - maizangzhiying.png new file mode 100644 index 00000000..4d04d211 Binary files /dev/null and b/resources/img/cases/liekong/XM1014 - maizangzhiying.png differ diff --git a/resources/img/cases/liekong/geluoke - modengshidai.png b/resources/img/cases/liekong/geluoke - modengshidai.png new file mode 100644 index 00000000..30fdcc9d Binary files /dev/null and b/resources/img/cases/liekong/geluoke - modengshidai.png differ diff --git a/resources/img/cases/liekong/jialier AR - fenghuangshanghao.png b/resources/img/cases/liekong/jialier AR - fenghuangshanghao.png new file mode 100644 index 00000000..ca9e64da Binary files /dev/null and b/resources/img/cases/liekong/jialier AR - fenghuangshanghao.png differ diff --git a/resources/img/cases/liekong/jishengbishou - beifangsenlin.png b/resources/img/cases/liekong/jishengbishou - beifangsenlin.png new file mode 100644 index 00000000..1f7aba45 Binary files /dev/null and b/resources/img/cases/liekong/jishengbishou - beifangsenlin.png differ diff --git a/resources/img/cases/liekong/jishengbishou - biaomiancuihuo.png b/resources/img/cases/liekong/jishengbishou - biaomiancuihuo.png new file mode 100644 index 00000000..b6dbda8f Binary files /dev/null and b/resources/img/cases/liekong/jishengbishou - biaomiancuihuo.png differ diff --git a/resources/img/cases/liekong/jishengbishou - dushiweizhuang.png b/resources/img/cases/liekong/jishengbishou - dushiweizhuang.png new file mode 100644 index 00000000..69aee80f Binary files /dev/null and b/resources/img/cases/liekong/jishengbishou - dushiweizhuang.png differ diff --git a/resources/img/cases/liekong/jishengbishou - jianbianzhise.png b/resources/img/cases/liekong/jishengbishou - jianbianzhise.png new file mode 100644 index 00000000..c3cc49e3 Binary files /dev/null and b/resources/img/cases/liekong/jishengbishou - jianbianzhise.png differ diff --git a/resources/img/cases/liekong/jishengbishou - kujiaozhise.png b/resources/img/cases/liekong/jishengbishou - kujiaozhise.png new file mode 100644 index 00000000..e1822df3 Binary files /dev/null and b/resources/img/cases/liekong/jishengbishou - kujiaozhise.png differ diff --git a/resources/img/cases/liekong/jishengbishou - langang.png b/resources/img/cases/liekong/jishengbishou - langang.png new file mode 100644 index 00000000..7b0538e6 Binary files /dev/null and b/resources/img/cases/liekong/jishengbishou - langang.png differ diff --git a/resources/img/cases/liekong/jishengbishou - rengongranse.png b/resources/img/cases/liekong/jishengbishou - rengongranse.png new file mode 100644 index 00000000..562e358d Binary files /dev/null and b/resources/img/cases/liekong/jishengbishou - rengongranse.png differ diff --git a/resources/img/cases/liekong/jishengbishou - senlin DDPAT.png b/resources/img/cases/liekong/jishengbishou - senlin DDPAT.png new file mode 100644 index 00000000..f67b8c28 Binary files /dev/null and b/resources/img/cases/liekong/jishengbishou - senlin DDPAT.png differ diff --git a/resources/img/cases/liekong/jishengbishou - shenhongzhiwang.png b/resources/img/cases/liekong/jishengbishou - shenhongzhiwang.png new file mode 100644 index 00000000..b889b22e Binary files /dev/null and b/resources/img/cases/liekong/jishengbishou - shenhongzhiwang.png differ diff --git a/resources/img/cases/liekong/jishengbishou - shouliewangge.png b/resources/img/cases/liekong/jishengbishou - shouliewangge.png new file mode 100644 index 00000000..05523002 Binary files /dev/null and b/resources/img/cases/liekong/jishengbishou - shouliewangge.png differ diff --git a/resources/img/cases/liekong/jishengbishou - tufu.png b/resources/img/cases/liekong/jishengbishou - tufu.png new file mode 100644 index 00000000..63522214 Binary files /dev/null and b/resources/img/cases/liekong/jishengbishou - tufu.png differ diff --git a/resources/img/cases/liekong/jishengbishou - wutuzhuangg.png b/resources/img/cases/liekong/jishengbishou - wutuzhuangg.png new file mode 100644 index 00000000..f49e0d42 Binary files /dev/null and b/resources/img/cases/liekong/jishengbishou - wutuzhuangg.png differ diff --git a/resources/img/cases/liekong/jishengbishou - yese.png b/resources/img/cases/liekong/jishengbishou - yese.png new file mode 100644 index 00000000..e36bda86 Binary files /dev/null and b/resources/img/cases/liekong/jishengbishou - yese.png differ diff --git a/resources/img/cases/liekong/kuloubishou - beifangsenlin.png b/resources/img/cases/liekong/kuloubishou - beifangsenlin.png new file mode 100644 index 00000000..dfbf7bf5 Binary files /dev/null and b/resources/img/cases/liekong/kuloubishou - beifangsenlin.png differ diff --git a/resources/img/cases/liekong/kuloubishou - biaomiancuihuo.png b/resources/img/cases/liekong/kuloubishou - biaomiancuihuo.png new file mode 100644 index 00000000..e09dc1a0 Binary files /dev/null and b/resources/img/cases/liekong/kuloubishou - biaomiancuihuo.png differ diff --git a/resources/img/cases/liekong/kuloubishou - dushiweizhuang.png b/resources/img/cases/liekong/kuloubishou - dushiweizhuang.png new file mode 100644 index 00000000..55e11a2d Binary files /dev/null and b/resources/img/cases/liekong/kuloubishou - dushiweizhuang.png differ diff --git a/resources/img/cases/liekong/kuloubishou - jianbianzhise.png b/resources/img/cases/liekong/kuloubishou - jianbianzhise.png new file mode 100644 index 00000000..36ac2127 Binary files /dev/null and b/resources/img/cases/liekong/kuloubishou - jianbianzhise.png differ diff --git a/resources/img/cases/liekong/kuloubishou - kujiaozhise.png b/resources/img/cases/liekong/kuloubishou - kujiaozhise.png new file mode 100644 index 00000000..df25e854 Binary files /dev/null and b/resources/img/cases/liekong/kuloubishou - kujiaozhise.png differ diff --git a/resources/img/cases/liekong/kuloubishou - langang.png b/resources/img/cases/liekong/kuloubishou - langang.png new file mode 100644 index 00000000..63df47cb Binary files /dev/null and b/resources/img/cases/liekong/kuloubishou - langang.png differ diff --git a/resources/img/cases/liekong/kuloubishou - rengongranse.png b/resources/img/cases/liekong/kuloubishou - rengongranse.png new file mode 100644 index 00000000..82f1f4eb Binary files /dev/null and b/resources/img/cases/liekong/kuloubishou - rengongranse.png differ diff --git a/resources/img/cases/liekong/kuloubishou - senlin DDPAT.png b/resources/img/cases/liekong/kuloubishou - senlin DDPAT.png new file mode 100644 index 00000000..9a951926 Binary files /dev/null and b/resources/img/cases/liekong/kuloubishou - senlin DDPAT.png differ diff --git a/resources/img/cases/liekong/kuloubishou - shenhongzhiwang.png b/resources/img/cases/liekong/kuloubishou - shenhongzhiwang.png new file mode 100644 index 00000000..c2eb477c Binary files /dev/null and b/resources/img/cases/liekong/kuloubishou - shenhongzhiwang.png differ diff --git a/resources/img/cases/liekong/kuloubishou - shouliewangge.png b/resources/img/cases/liekong/kuloubishou - shouliewangge.png new file mode 100644 index 00000000..88a1a5d2 Binary files /dev/null and b/resources/img/cases/liekong/kuloubishou - shouliewangge.png differ diff --git a/resources/img/cases/liekong/kuloubishou - tufu.png b/resources/img/cases/liekong/kuloubishou - tufu.png new file mode 100644 index 00000000..d26aca9e Binary files /dev/null and b/resources/img/cases/liekong/kuloubishou - tufu.png differ diff --git a/resources/img/cases/liekong/kuloubishou - wutuzhuang.png b/resources/img/cases/liekong/kuloubishou - wutuzhuang.png new file mode 100644 index 00000000..c3f1a49b Binary files /dev/null and b/resources/img/cases/liekong/kuloubishou - wutuzhuang.png differ diff --git a/resources/img/cases/liekong/kuloubishou - yese.png b/resources/img/cases/liekong/kuloubishou - yese.png new file mode 100644 index 00000000..b9f0558a Binary files /dev/null and b/resources/img/cases/liekong/kuloubishou - yese.png differ diff --git a/resources/img/cases/liekong/liulangzhebishou - beifangsenlin.png b/resources/img/cases/liekong/liulangzhebishou - beifangsenlin.png new file mode 100644 index 00000000..5e3a4ae2 Binary files /dev/null and b/resources/img/cases/liekong/liulangzhebishou - beifangsenlin.png differ diff --git a/resources/img/cases/liekong/liulangzhebishou - biaomiancuihuo.png b/resources/img/cases/liekong/liulangzhebishou - biaomiancuihuo.png new file mode 100644 index 00000000..ff30c8b7 Binary files /dev/null and b/resources/img/cases/liekong/liulangzhebishou - biaomiancuihuo.png differ diff --git a/resources/img/cases/liekong/liulangzhebishou - dushiweizhuang.png b/resources/img/cases/liekong/liulangzhebishou - dushiweizhuang.png new file mode 100644 index 00000000..9cfe64d4 Binary files /dev/null and b/resources/img/cases/liekong/liulangzhebishou - dushiweizhuang.png differ diff --git a/resources/img/cases/liekong/liulangzhebishou - jianbianzhise.png b/resources/img/cases/liekong/liulangzhebishou - jianbianzhise.png new file mode 100644 index 00000000..a3ddb5af Binary files /dev/null and b/resources/img/cases/liekong/liulangzhebishou - jianbianzhise.png differ diff --git a/resources/img/cases/liekong/liulangzhebishou - kujiaozhise.png b/resources/img/cases/liekong/liulangzhebishou - kujiaozhise.png new file mode 100644 index 00000000..839fb423 Binary files /dev/null and b/resources/img/cases/liekong/liulangzhebishou - kujiaozhise.png differ diff --git a/resources/img/cases/liekong/liulangzhebishou - langang.png b/resources/img/cases/liekong/liulangzhebishou - langang.png new file mode 100644 index 00000000..2c521b09 Binary files /dev/null and b/resources/img/cases/liekong/liulangzhebishou - langang.png differ diff --git a/resources/img/cases/liekong/liulangzhebishou - rengongranse.png b/resources/img/cases/liekong/liulangzhebishou - rengongranse.png new file mode 100644 index 00000000..6036cbc2 Binary files /dev/null and b/resources/img/cases/liekong/liulangzhebishou - rengongranse.png differ diff --git a/resources/img/cases/liekong/liulangzhebishou - senlin DDPAT.png b/resources/img/cases/liekong/liulangzhebishou - senlin DDPAT.png new file mode 100644 index 00000000..75a29ff9 Binary files /dev/null and b/resources/img/cases/liekong/liulangzhebishou - senlin DDPAT.png differ diff --git a/resources/img/cases/liekong/liulangzhebishou - shenhongzhiwang.png b/resources/img/cases/liekong/liulangzhebishou - shenhongzhiwang.png new file mode 100644 index 00000000..20fd2aa7 Binary files /dev/null and b/resources/img/cases/liekong/liulangzhebishou - shenhongzhiwang.png differ diff --git a/resources/img/cases/liekong/liulangzhebishou - shouliewangge.png b/resources/img/cases/liekong/liulangzhebishou - shouliewangge.png new file mode 100644 index 00000000..9e49b676 Binary files /dev/null and b/resources/img/cases/liekong/liulangzhebishou - shouliewangge.png differ diff --git a/resources/img/cases/liekong/liulangzhebishou - tufu.png b/resources/img/cases/liekong/liulangzhebishou - tufu.png new file mode 100644 index 00000000..eb6c59ba Binary files /dev/null and b/resources/img/cases/liekong/liulangzhebishou - tufu.png differ diff --git a/resources/img/cases/liekong/liulangzhebishou - wutuzhuang.png b/resources/img/cases/liekong/liulangzhebishou - wutuzhuang.png new file mode 100644 index 00000000..cbabde8d Binary files /dev/null and b/resources/img/cases/liekong/liulangzhebishou - wutuzhuang.png differ diff --git a/resources/img/cases/liekong/liulangzhebishou - yese.png b/resources/img/cases/liekong/liulangzhebishou - yese.png new file mode 100644 index 00000000..241fc848 Binary files /dev/null and b/resources/img/cases/liekong/liulangzhebishou - yese.png differ diff --git a/resources/img/cases/liekong/neigefu - feiyu.png b/resources/img/cases/liekong/neigefu - feiyu.png new file mode 100644 index 00000000..04655408 Binary files /dev/null and b/resources/img/cases/liekong/neigefu - feiyu.png differ diff --git a/resources/img/cases/liekong/qiushengbishou - beifangsenlin.png b/resources/img/cases/liekong/qiushengbishou - beifangsenlin.png new file mode 100644 index 00000000..062d354a Binary files /dev/null and b/resources/img/cases/liekong/qiushengbishou - beifangsenlin.png differ diff --git a/resources/img/cases/liekong/qiushengbishou - biaomiancuihuo.png b/resources/img/cases/liekong/qiushengbishou - biaomiancuihuo.png new file mode 100644 index 00000000..e9242bb9 Binary files /dev/null and b/resources/img/cases/liekong/qiushengbishou - biaomiancuihuo.png differ diff --git a/resources/img/cases/liekong/qiushengbishou - dushiweizhuang.png b/resources/img/cases/liekong/qiushengbishou - dushiweizhuang.png new file mode 100644 index 00000000..c97d1b93 Binary files /dev/null and b/resources/img/cases/liekong/qiushengbishou - dushiweizhuang.png differ diff --git a/resources/img/cases/liekong/qiushengbishou - jianbianzhise.png b/resources/img/cases/liekong/qiushengbishou - jianbianzhise.png new file mode 100644 index 00000000..4a1358fd Binary files /dev/null and b/resources/img/cases/liekong/qiushengbishou - jianbianzhise.png differ diff --git a/resources/img/cases/liekong/qiushengbishou - kujiaozhise.png b/resources/img/cases/liekong/qiushengbishou - kujiaozhise.png new file mode 100644 index 00000000..abf86a82 Binary files /dev/null and b/resources/img/cases/liekong/qiushengbishou - kujiaozhise.png differ diff --git a/resources/img/cases/liekong/qiushengbishou - langang.png b/resources/img/cases/liekong/qiushengbishou - langang.png new file mode 100644 index 00000000..5581b86f Binary files /dev/null and b/resources/img/cases/liekong/qiushengbishou - langang.png differ diff --git a/resources/img/cases/liekong/qiushengbishou - rengongranse.png b/resources/img/cases/liekong/qiushengbishou - rengongranse.png new file mode 100644 index 00000000..15e8bd40 Binary files /dev/null and b/resources/img/cases/liekong/qiushengbishou - rengongranse.png differ diff --git a/resources/img/cases/liekong/qiushengbishou - senlin DDPAT.png b/resources/img/cases/liekong/qiushengbishou - senlin DDPAT.png new file mode 100644 index 00000000..f269caab Binary files /dev/null and b/resources/img/cases/liekong/qiushengbishou - senlin DDPAT.png differ diff --git a/resources/img/cases/liekong/qiushengbishou - shenhongzhiwang.png b/resources/img/cases/liekong/qiushengbishou - shenhongzhiwang.png new file mode 100644 index 00000000..3f3cd200 Binary files /dev/null and b/resources/img/cases/liekong/qiushengbishou - shenhongzhiwang.png differ diff --git a/resources/img/cases/liekong/qiushengbishou - shouliewangge.png b/resources/img/cases/liekong/qiushengbishou - shouliewangge.png new file mode 100644 index 00000000..3c99172a Binary files /dev/null and b/resources/img/cases/liekong/qiushengbishou - shouliewangge.png differ diff --git a/resources/img/cases/liekong/qiushengbishou - tufu.png b/resources/img/cases/liekong/qiushengbishou - tufu.png new file mode 100644 index 00000000..cc3417b5 Binary files /dev/null and b/resources/img/cases/liekong/qiushengbishou - tufu.png differ diff --git a/resources/img/cases/liekong/qiushengbishou - wutuzhuang .png b/resources/img/cases/liekong/qiushengbishou - wutuzhuang .png new file mode 100644 index 00000000..e8e75585 Binary files /dev/null and b/resources/img/cases/liekong/qiushengbishou - wutuzhuang .png differ diff --git a/resources/img/cases/liekong/qiushengbishou - yese.png b/resources/img/cases/liekong/qiushengbishou - yese.png new file mode 100644 index 00000000..4ea75ece Binary files /dev/null and b/resources/img/cases/liekong/qiushengbishou - yese.png differ diff --git a/resources/img/cases/liekong/shamozhiying - yinhuaji.png b/resources/img/cases/liekong/shamozhiying - yinhuaji.png new file mode 100644 index 00000000..fca25535 Binary files /dev/null and b/resources/img/cases/liekong/shamozhiying - yinhuaji.png differ diff --git a/resources/img/cases/mingxuanyixian/AUG - huguainiao.png b/resources/img/cases/mingxuanyixian/AUG - huguainiao.png new file mode 100644 index 00000000..2e5a3d93 Binary files /dev/null and b/resources/img/cases/mingxuanyixian/AUG - huguainiao.png differ diff --git a/resources/img/cases/mingxuanyixian/AWP - sishen.png b/resources/img/cases/mingxuanyixian/AWP - sishen.png new file mode 100644 index 00000000..d90fa3cb Binary files /dev/null and b/resources/img/cases/mingxuanyixian/AWP - sishen.png differ diff --git a/resources/img/cases/mingxuanyixian/FN57 - yansefanying.png b/resources/img/cases/mingxuanyixian/FN57 - yansefanying.png new file mode 100644 index 00000000..ab176b80 Binary files /dev/null and b/resources/img/cases/mingxuanyixian/FN57 - yansefanying.png differ diff --git a/resources/img/cases/mingxuanyixian/M4A4 - heisemeiying.png b/resources/img/cases/mingxuanyixian/M4A4 - heisemeiying.png new file mode 100644 index 00000000..fb3ebc91 Binary files /dev/null and b/resources/img/cases/mingxuanyixian/M4A4 - heisemeiying.png differ diff --git a/resources/img/cases/mingxuanyixian/MAG-7 - SWAG-7.png b/resources/img/cases/mingxuanyixian/MAG-7 - SWAG-7.png new file mode 100644 index 00000000..f5cefdb4 Binary files /dev/null and b/resources/img/cases/mingxuanyixian/MAG-7 - SWAG-7.png differ diff --git a/resources/img/cases/mingxuanyixian/MP7 - xuexingyundong.png b/resources/img/cases/mingxuanyixian/MP7 - xuexingyundong.png new file mode 100644 index 00000000..8bb420bb Binary files /dev/null and b/resources/img/cases/mingxuanyixian/MP7 - xuexingyundong.png differ diff --git a/resources/img/cases/mingxuanyixian/MP9 - heisha.png b/resources/img/cases/mingxuanyixian/MP9 - heisha.png new file mode 100644 index 00000000..98c85b51 Binary files /dev/null and b/resources/img/cases/mingxuanyixian/MP9 - heisha.png differ diff --git a/resources/img/cases/mingxuanyixian/P2000 - dushiweiji.png b/resources/img/cases/mingxuanyixian/P2000 - dushiweiji.png new file mode 100644 index 00000000..25df76ba Binary files /dev/null and b/resources/img/cases/mingxuanyixian/P2000 - dushiweiji.png differ diff --git a/resources/img/cases/mingxuanyixian/PP-yeniu - heiyebaoluan.png b/resources/img/cases/mingxuanyixian/PP-yeniu - heiyebaoluan.png new file mode 100644 index 00000000..ff68bbcc Binary files /dev/null and b/resources/img/cases/mingxuanyixian/PP-yeniu - heiyebaoluan.png differ diff --git a/resources/img/cases/mingxuanyixian/R8 zuolunshouqiang - wen.png b/resources/img/cases/mingxuanyixian/R8 zuolunshouqiang - wen.png new file mode 100644 index 00000000..6a0cd6db Binary files /dev/null and b/resources/img/cases/mingxuanyixian/R8 zuolunshouqiang - wen.png differ diff --git a/resources/img/cases/mingxuanyixian/SG 553 - aluoha.png b/resources/img/cases/mingxuanyixian/SG 553 - aluoha.png new file mode 100644 index 00000000..46f22650 Binary files /dev/null and b/resources/img/cases/mingxuanyixian/SG 553 - aluoha.png differ diff --git a/resources/img/cases/mingxuanyixian/UMP-45 - bailang.png b/resources/img/cases/mingxuanyixian/UMP-45 - bailang.png new file mode 100644 index 00000000..fb55230c Binary files /dev/null and b/resources/img/cases/mingxuanyixian/UMP-45 - bailang.png differ diff --git a/resources/img/cases/mingxuanyixian/USP - naodongdakai.png b/resources/img/cases/mingxuanyixian/USP - naodongdakai.png new file mode 100644 index 00000000..bd94143c Binary files /dev/null and b/resources/img/cases/mingxuanyixian/USP - naodongdakai.png differ diff --git a/resources/img/cases/mingxuanyixian/XM1014 - xiushilieyan.png b/resources/img/cases/mingxuanyixian/XM1014 - xiushilieyan.png new file mode 100644 index 00000000..ef0ed3f9 Binary files /dev/null and b/resources/img/cases/mingxuanyixian/XM1014 - xiushilieyan.png differ diff --git a/resources/img/cases/mingxuanyixian/geluoke - chenglideyueguang.png b/resources/img/cases/mingxuanyixian/geluoke - chenglideyueguang.png new file mode 100644 index 00000000..29fc57c7 Binary files /dev/null and b/resources/img/cases/mingxuanyixian/geluoke - chenglideyueguang.png differ diff --git a/resources/img/cases/mingxuanyixian/guoshou - fangshuibujiaodai.png b/resources/img/cases/mingxuanyixian/guoshou - fangshuibujiaodai.png new file mode 100644 index 00000000..57caa1d4 Binary files /dev/null and b/resources/img/cases/mingxuanyixian/guoshou - fangshuibujiaodai.png differ diff --git a/resources/img/cases/mingxuanyixian/guoshou - gulankulou.png b/resources/img/cases/mingxuanyixian/guoshou - gulankulou.png new file mode 100644 index 00000000..a5f9959c Binary files /dev/null and b/resources/img/cases/mingxuanyixian/guoshou - gulankulou.png differ diff --git a/resources/img/cases/mingxuanyixian/guoshou - senlinsediao.png b/resources/img/cases/mingxuanyixian/guoshou - senlinsediao.png new file mode 100644 index 00000000..ede6725e Binary files /dev/null and b/resources/img/cases/mingxuanyixian/guoshou - senlinsediao.png differ diff --git a/resources/img/cases/mingxuanyixian/guoshou - taoyin.png b/resources/img/cases/mingxuanyixian/guoshou - taoyin.png new file mode 100644 index 00000000..09959a61 Binary files /dev/null and b/resources/img/cases/mingxuanyixian/guoshou - taoyin.png differ diff --git a/resources/img/cases/mingxuanyixian/jiashishoutao - chaoyue.png b/resources/img/cases/mingxuanyixian/jiashishoutao - chaoyue.png new file mode 100644 index 00000000..28f91cfe Binary files /dev/null and b/resources/img/cases/mingxuanyixian/jiashishoutao - chaoyue.png differ diff --git a/resources/img/cases/mingxuanyixian/jiashishoutao - lanzigezi.png b/resources/img/cases/mingxuanyixian/jiashishoutao - lanzigezi.png new file mode 100644 index 00000000..29ef3a70 Binary files /dev/null and b/resources/img/cases/mingxuanyixian/jiashishoutao - lanzigezi.png differ diff --git a/resources/img/cases/mingxuanyixian/jiashishoutao - molvsediao.png b/resources/img/cases/mingxuanyixian/jiashishoutao - molvsediao.png new file mode 100644 index 00000000..dbe60e1c Binary files /dev/null and b/resources/img/cases/mingxuanyixian/jiashishoutao - molvsediao.png differ diff --git a/resources/img/cases/mingxuanyixian/jiashishoutao - wangshe.png b/resources/img/cases/mingxuanyixian/jiashishoutao - wangshe.png new file mode 100644 index 00000000..44131378 Binary files /dev/null and b/resources/img/cases/mingxuanyixian/jiashishoutao - wangshe.png differ diff --git a/resources/img/cases/mingxuanyixian/jiutousheshoutao - biaomiancuihuo.png b/resources/img/cases/mingxuanyixian/jiutousheshoutao - biaomiancuihuo.png new file mode 100644 index 00000000..aed17723 Binary files /dev/null and b/resources/img/cases/mingxuanyixian/jiutousheshoutao - biaomiancuihuo.png differ diff --git a/resources/img/cases/mingxuanyixian/jiutousheshoutao - feicuisediao.png b/resources/img/cases/mingxuanyixian/jiutousheshoutao - feicuisediao.png new file mode 100644 index 00000000..e9d0e079 Binary files /dev/null and b/resources/img/cases/mingxuanyixian/jiutousheshoutao - feicuisediao.png differ diff --git a/resources/img/cases/mingxuanyixian/jiutousheshoutao - hongshulin.png b/resources/img/cases/mingxuanyixian/jiutousheshoutao - hongshulin.png new file mode 100644 index 00000000..396668fe Binary files /dev/null and b/resources/img/cases/mingxuanyixian/jiutousheshoutao - hongshulin.png differ diff --git a/resources/img/cases/mingxuanyixian/jiutousheshoutao - xiangweishe.png b/resources/img/cases/mingxuanyixian/jiutousheshoutao - xiangweishe.png new file mode 100644 index 00000000..797cb7b7 Binary files /dev/null and b/resources/img/cases/mingxuanyixian/jiutousheshoutao - xiangweishe.png differ diff --git a/resources/img/cases/mingxuanyixian/motuoshoutao - daimao.png b/resources/img/cases/mingxuanyixian/motuoshoutao - daimao.png new file mode 100644 index 00000000..53861561 Binary files /dev/null and b/resources/img/cases/mingxuanyixian/motuoshoutao - daimao.png differ diff --git a/resources/img/cases/mingxuanyixian/motuoshoutao - duobianxing.png b/resources/img/cases/mingxuanyixian/motuoshoutao - duobianxing.png new file mode 100644 index 00000000..ccf1804c Binary files /dev/null and b/resources/img/cases/mingxuanyixian/motuoshoutao - duobianxing.png differ diff --git a/resources/img/cases/mingxuanyixian/motuoshoutao - jiaoyun.png b/resources/img/cases/mingxuanyixian/motuoshoutao - jiaoyun.png new file mode 100644 index 00000000..960a4957 Binary files /dev/null and b/resources/img/cases/mingxuanyixian/motuoshoutao - jiaoyun.png differ diff --git a/resources/img/cases/mingxuanyixian/motuoshoutao - peng!.png b/resources/img/cases/mingxuanyixian/motuoshoutao - peng!.png new file mode 100644 index 00000000..2b1bf522 Binary files /dev/null and b/resources/img/cases/mingxuanyixian/motuoshoutao - peng!.png differ diff --git a/resources/img/cases/mingxuanyixian/neigefu - shiziyu.png b/resources/img/cases/mingxuanyixian/neigefu - shiziyu.png new file mode 100644 index 00000000..3cfc6240 Binary files /dev/null and b/resources/img/cases/mingxuanyixian/neigefu - shiziyu.png differ diff --git a/resources/img/cases/mingxuanyixian/xinxing - kuangyeliuhao.png b/resources/img/cases/mingxuanyixian/xinxing - kuangyeliuhao.png new file mode 100644 index 00000000..c109130e Binary files /dev/null and b/resources/img/cases/mingxuanyixian/xinxing - kuangyeliuhao.png differ diff --git a/resources/img/cases/mingxuanyixian/yundongshoutao - maiamifengyun.png b/resources/img/cases/mingxuanyixian/yundongshoutao - maiamifengyun.png new file mode 100644 index 00000000..c54a235b Binary files /dev/null and b/resources/img/cases/mingxuanyixian/yundongshoutao - maiamifengyun.png differ diff --git a/resources/img/cases/mingxuanyixian/yundongshoutao - oumiga.png b/resources/img/cases/mingxuanyixian/yundongshoutao - oumiga.png new file mode 100644 index 00000000..6080c369 Binary files /dev/null and b/resources/img/cases/mingxuanyixian/yundongshoutao - oumiga.png differ diff --git a/resources/img/cases/mingxuanyixian/yundongshoutao - qingtongxingtai.png b/resources/img/cases/mingxuanyixian/yundongshoutao - qingtongxingtai.png new file mode 100644 index 00000000..8ebdaf4f Binary files /dev/null and b/resources/img/cases/mingxuanyixian/yundongshoutao - qingtongxingtai.png differ diff --git a/resources/img/cases/mingxuanyixian/yundongshoutao - shuangqi.png b/resources/img/cases/mingxuanyixian/yundongshoutao - shuangqi.png new file mode 100644 index 00000000..6f8cefcc Binary files /dev/null and b/resources/img/cases/mingxuanyixian/yundongshoutao - shuangqi.png differ diff --git a/resources/img/cases/mingxuanyixian/zhuanyeshoutao - dawan.png b/resources/img/cases/mingxuanyixian/zhuanyeshoutao - dawan.png new file mode 100644 index 00000000..06ecf370 Binary files /dev/null and b/resources/img/cases/mingxuanyixian/zhuanyeshoutao - dawan.png differ diff --git a/resources/img/cases/mingxuanyixian/zhuanyeshoutao - jianbianzhise.png b/resources/img/cases/mingxuanyixian/zhuanyeshoutao - jianbianzhise.png new file mode 100644 index 00000000..865c2613 Binary files /dev/null and b/resources/img/cases/mingxuanyixian/zhuanyeshoutao - jianbianzhise.png differ diff --git a/resources/img/cases/mingxuanyixian/zhuanyeshoutao - shenhongzhiwang.png b/resources/img/cases/mingxuanyixian/zhuanyeshoutao - shenhongzhiwang.png new file mode 100644 index 00000000..87ac08b4 Binary files /dev/null and b/resources/img/cases/mingxuanyixian/zhuanyeshoutao - shenhongzhiwang.png differ diff --git a/resources/img/cases/mingxuanyixian/zhuanyeshoutao - shoulu.png b/resources/img/cases/mingxuanyixian/zhuanyeshoutao - shoulu.png new file mode 100644 index 00000000..7b705fd4 Binary files /dev/null and b/resources/img/cases/mingxuanyixian/zhuanyeshoutao - shoulu.png differ diff --git a/resources/img/cases/tuweidaxingdong/CZ75 - menghu.png b/resources/img/cases/tuweidaxingdong/CZ75 - menghu.png new file mode 100644 index 00000000..7bd05cec Binary files /dev/null and b/resources/img/cases/tuweidaxingdong/CZ75 - menghu.png differ diff --git a/resources/img/cases/tuweidaxingdong/FN57 - shoulieliqi.png b/resources/img/cases/tuweidaxingdong/FN57 - shoulieliqi.png new file mode 100644 index 00000000..d6610c73 Binary files /dev/null and b/resources/img/cases/tuweidaxingdong/FN57 - shoulieliqi.png differ diff --git a/resources/img/cases/tuweidaxingdong/M4A1 - cishidai.png b/resources/img/cases/tuweidaxingdong/M4A1 - cishidai.png new file mode 100644 index 00000000..b8f9fd41 Binary files /dev/null and b/resources/img/cases/tuweidaxingdong/M4A1 - cishidai.png differ diff --git a/resources/img/cases/tuweidaxingdong/MP7 - dushiweiji.png b/resources/img/cases/tuweidaxingdong/MP7 - dushiweiji.png new file mode 100644 index 00000000..5b952d73 Binary files /dev/null and b/resources/img/cases/tuweidaxingdong/MP7 - dushiweiji.png differ diff --git a/resources/img/cases/tuweidaxingdong/P2000 - rubaixiangya.png b/resources/img/cases/tuweidaxingdong/P2000 - rubaixiangya.png new file mode 100644 index 00000000..66baa3ee Binary files /dev/null and b/resources/img/cases/tuweidaxingdong/P2000 - rubaixiangya.png differ diff --git a/resources/img/cases/tuweidaxingdong/P250 - chaoxinxing.png b/resources/img/cases/tuweidaxingdong/P250 - chaoxinxing.png new file mode 100644 index 00000000..11a34001 Binary files /dev/null and b/resources/img/cases/tuweidaxingdong/P250 - chaoxinxing.png differ diff --git a/resources/img/cases/tuweidaxingdong/P90 - erximofu.png b/resources/img/cases/tuweidaxingdong/P90 - erximofu.png new file mode 100644 index 00000000..a0abdff9 Binary files /dev/null and b/resources/img/cases/tuweidaxingdong/P90 - erximofu.png differ diff --git a/resources/img/cases/tuweidaxingdong/PP-yeniu - siwangzhuzaizhe.png b/resources/img/cases/tuweidaxingdong/PP-yeniu - siwangzhuzaizhe.png new file mode 100644 index 00000000..38083ee5 Binary files /dev/null and b/resources/img/cases/tuweidaxingdong/PP-yeniu - siwangzhuzaizhe.png differ diff --git a/resources/img/cases/tuweidaxingdong/SSG 08 - wujinshenhai.png b/resources/img/cases/tuweidaxingdong/SSG 08 - wujinshenhai.png new file mode 100644 index 00000000..db9f8017 Binary files /dev/null and b/resources/img/cases/tuweidaxingdong/SSG 08 - wujinshenhai.png differ diff --git a/resources/img/cases/tuweidaxingdong/UMP-45 - mizhigong.png b/resources/img/cases/tuweidaxingdong/UMP-45 - mizhigong.png new file mode 100644 index 00000000..237a2ac6 Binary files /dev/null and b/resources/img/cases/tuweidaxingdong/UMP-45 - mizhigong.png differ diff --git a/resources/img/cases/tuweidaxingdong/geluoke - shuiling.png b/resources/img/cases/tuweidaxingdong/geluoke - shuiling.png new file mode 100644 index 00000000..8392989c Binary files /dev/null and b/resources/img/cases/tuweidaxingdong/geluoke - shuiling.png differ diff --git a/resources/img/cases/tuweidaxingdong/hudiedao - beifangsenlin.png b/resources/img/cases/tuweidaxingdong/hudiedao - beifangsenlin.png new file mode 100644 index 00000000..a45a3326 Binary files /dev/null and b/resources/img/cases/tuweidaxingdong/hudiedao - beifangsenlin.png differ diff --git a/resources/img/cases/tuweidaxingdong/hudiedao - biaomiancuihuo.png b/resources/img/cases/tuweidaxingdong/hudiedao - biaomiancuihuo.png new file mode 100644 index 00000000..d708952f Binary files /dev/null and b/resources/img/cases/tuweidaxingdong/hudiedao - biaomiancuihuo.png differ diff --git a/resources/img/cases/tuweidaxingdong/hudiedao - dushiweizhuang.png b/resources/img/cases/tuweidaxingdong/hudiedao - dushiweizhuang.png new file mode 100644 index 00000000..92b69917 Binary files /dev/null and b/resources/img/cases/tuweidaxingdong/hudiedao - dushiweizhuang.png differ diff --git a/resources/img/cases/tuweidaxingdong/hudiedao - emengzhiye.png b/resources/img/cases/tuweidaxingdong/hudiedao - emengzhiye.png new file mode 100644 index 00000000..94709824 Binary files /dev/null and b/resources/img/cases/tuweidaxingdong/hudiedao - emengzhiye.png differ diff --git a/resources/img/cases/tuweidaxingdong/hudiedao - jianbianzhise.png b/resources/img/cases/tuweidaxingdong/hudiedao - jianbianzhise.png new file mode 100644 index 00000000..1f1bc2b7 Binary files /dev/null and b/resources/img/cases/tuweidaxingdong/hudiedao - jianbianzhise.png differ diff --git a/resources/img/cases/tuweidaxingdong/hudiedao - kujiaozhise.png b/resources/img/cases/tuweidaxingdong/hudiedao - kujiaozhise.png new file mode 100644 index 00000000..b91a210a Binary files /dev/null and b/resources/img/cases/tuweidaxingdong/hudiedao - kujiaozhise.png differ diff --git a/resources/img/cases/tuweidaxingdong/hudiedao - langang.png b/resources/img/cases/tuweidaxingdong/hudiedao - langang.png new file mode 100644 index 00000000..ec571671 Binary files /dev/null and b/resources/img/cases/tuweidaxingdong/hudiedao - langang.png differ diff --git a/resources/img/cases/tuweidaxingdong/hudiedao - rengongranse.png b/resources/img/cases/tuweidaxingdong/hudiedao - rengongranse.png new file mode 100644 index 00000000..4cf7e0e8 Binary files /dev/null and b/resources/img/cases/tuweidaxingdong/hudiedao - rengongranse.png differ diff --git a/resources/img/cases/tuweidaxingdong/hudiedao - senlin DDPAT.png b/resources/img/cases/tuweidaxingdong/hudiedao - senlin DDPAT.png new file mode 100644 index 00000000..5bd59f24 Binary files /dev/null and b/resources/img/cases/tuweidaxingdong/hudiedao - senlin DDPAT.png differ diff --git a/resources/img/cases/tuweidaxingdong/hudiedao - shenhongzhiwang.png b/resources/img/cases/tuweidaxingdong/hudiedao - shenhongzhiwang.png new file mode 100644 index 00000000..ff3ba092 Binary files /dev/null and b/resources/img/cases/tuweidaxingdong/hudiedao - shenhongzhiwang.png differ diff --git a/resources/img/cases/tuweidaxingdong/hudiedao - shouliewangge.png b/resources/img/cases/tuweidaxingdong/hudiedao - shouliewangge.png new file mode 100644 index 00000000..91c718d6 Binary files /dev/null and b/resources/img/cases/tuweidaxingdong/hudiedao - shouliewangge.png differ diff --git a/resources/img/cases/tuweidaxingdong/hudiedao - tufu.png b/resources/img/cases/tuweidaxingdong/hudiedao - tufu.png new file mode 100644 index 00000000..da75bb84 Binary files /dev/null and b/resources/img/cases/tuweidaxingdong/hudiedao - tufu.png differ diff --git a/resources/img/cases/tuweidaxingdong/hudiedao - wutuzhuang.png b/resources/img/cases/tuweidaxingdong/hudiedao - wutuzhuang.png new file mode 100644 index 00000000..1ffec5a8 Binary files /dev/null and b/resources/img/cases/tuweidaxingdong/hudiedao - wutuzhuang.png differ diff --git a/resources/img/cases/tuweidaxingdong/neigefu - shamojingying.png b/resources/img/cases/tuweidaxingdong/neigefu - shamojingying.png new file mode 100644 index 00000000..ce4cffd3 Binary files /dev/null and b/resources/img/cases/tuweidaxingdong/neigefu - shamojingying.png differ diff --git a/resources/img/cases/tuweidaxingdong/shamozhiying - yinmouzhe.png b/resources/img/cases/tuweidaxingdong/shamozhiying - yinmouzhe.png new file mode 100644 index 00000000..00f3c391 Binary files /dev/null and b/resources/img/cases/tuweidaxingdong/shamozhiying - yinmouzhe.png differ diff --git a/resources/img/cases/tuweidaxingdong/xinxing - jinli.png b/resources/img/cases/tuweidaxingdong/xinxing - jinli.png new file mode 100644 index 00000000..047b7279 Binary files /dev/null and b/resources/img/cases/tuweidaxingdong/xinxing - jinli.png differ diff --git a/resources/img/genshin/chars/10000003.png b/resources/img/genshin/chars/10000003.png new file mode 100644 index 00000000..ae6eab54 Binary files /dev/null and b/resources/img/genshin/chars/10000003.png differ diff --git a/resources/img/genshin/chars/10000005.png b/resources/img/genshin/chars/10000005.png new file mode 100644 index 00000000..bdea303a Binary files /dev/null and b/resources/img/genshin/chars/10000005.png differ diff --git a/resources/img/genshin/chars/10000006.png b/resources/img/genshin/chars/10000006.png new file mode 100644 index 00000000..bbb04a67 Binary files /dev/null and b/resources/img/genshin/chars/10000006.png differ diff --git a/resources/img/genshin/chars/10000007.png b/resources/img/genshin/chars/10000007.png new file mode 100644 index 00000000..b3294257 Binary files /dev/null and b/resources/img/genshin/chars/10000007.png differ diff --git a/resources/img/genshin/chars/10000014.png b/resources/img/genshin/chars/10000014.png new file mode 100644 index 00000000..7a6cc4d2 Binary files /dev/null and b/resources/img/genshin/chars/10000014.png differ diff --git a/resources/img/genshin/chars/10000015.png b/resources/img/genshin/chars/10000015.png new file mode 100644 index 00000000..890539ab Binary files /dev/null and b/resources/img/genshin/chars/10000015.png differ diff --git a/resources/img/genshin/chars/10000016.png b/resources/img/genshin/chars/10000016.png new file mode 100644 index 00000000..1539860c Binary files /dev/null and b/resources/img/genshin/chars/10000016.png differ diff --git a/resources/img/genshin/chars/10000020.png b/resources/img/genshin/chars/10000020.png new file mode 100644 index 00000000..df3ccc95 Binary files /dev/null and b/resources/img/genshin/chars/10000020.png differ diff --git a/resources/img/genshin/chars/10000021.png b/resources/img/genshin/chars/10000021.png new file mode 100644 index 00000000..48a405b8 Binary files /dev/null and b/resources/img/genshin/chars/10000021.png differ diff --git a/resources/img/genshin/chars/10000022.png b/resources/img/genshin/chars/10000022.png new file mode 100644 index 00000000..f05317f4 Binary files /dev/null and b/resources/img/genshin/chars/10000022.png differ diff --git a/resources/img/genshin/chars/10000023.png b/resources/img/genshin/chars/10000023.png new file mode 100644 index 00000000..151cf5d2 Binary files /dev/null and b/resources/img/genshin/chars/10000023.png differ diff --git a/resources/img/genshin/chars/10000024.png b/resources/img/genshin/chars/10000024.png new file mode 100644 index 00000000..b593ce11 Binary files /dev/null and b/resources/img/genshin/chars/10000024.png differ diff --git a/resources/img/genshin/chars/10000025.png b/resources/img/genshin/chars/10000025.png new file mode 100644 index 00000000..3793fd44 Binary files /dev/null and b/resources/img/genshin/chars/10000025.png differ diff --git a/resources/img/genshin/chars/10000027.png b/resources/img/genshin/chars/10000027.png new file mode 100644 index 00000000..36b9eef1 Binary files /dev/null and b/resources/img/genshin/chars/10000027.png differ diff --git a/resources/img/genshin/chars/10000029.png b/resources/img/genshin/chars/10000029.png new file mode 100644 index 00000000..e151f141 Binary files /dev/null and b/resources/img/genshin/chars/10000029.png differ diff --git a/resources/img/genshin/chars/10000031.png b/resources/img/genshin/chars/10000031.png new file mode 100644 index 00000000..b9c4d1a0 Binary files /dev/null and b/resources/img/genshin/chars/10000031.png differ diff --git a/resources/img/genshin/chars/10000032.png b/resources/img/genshin/chars/10000032.png new file mode 100644 index 00000000..8a9ef694 Binary files /dev/null and b/resources/img/genshin/chars/10000032.png differ diff --git a/resources/img/genshin/chars/10000033.png b/resources/img/genshin/chars/10000033.png new file mode 100644 index 00000000..7fc538ff Binary files /dev/null and b/resources/img/genshin/chars/10000033.png differ diff --git a/resources/img/genshin/chars/10000034.png b/resources/img/genshin/chars/10000034.png new file mode 100644 index 00000000..09aa4b24 Binary files /dev/null and b/resources/img/genshin/chars/10000034.png differ diff --git a/resources/img/genshin/chars/10000035.png b/resources/img/genshin/chars/10000035.png new file mode 100644 index 00000000..af654b1e Binary files /dev/null and b/resources/img/genshin/chars/10000035.png differ diff --git a/resources/img/genshin/chars/10000036.png b/resources/img/genshin/chars/10000036.png new file mode 100644 index 00000000..dbad18e4 Binary files /dev/null and b/resources/img/genshin/chars/10000036.png differ diff --git a/resources/img/genshin/chars/10000037.png b/resources/img/genshin/chars/10000037.png new file mode 100644 index 00000000..375a2ed8 Binary files /dev/null and b/resources/img/genshin/chars/10000037.png differ diff --git a/resources/img/genshin/chars/10000039.png b/resources/img/genshin/chars/10000039.png new file mode 100644 index 00000000..53656d47 Binary files /dev/null and b/resources/img/genshin/chars/10000039.png differ diff --git a/resources/img/genshin/chars/10000041.png b/resources/img/genshin/chars/10000041.png new file mode 100644 index 00000000..c1d04836 Binary files /dev/null and b/resources/img/genshin/chars/10000041.png differ diff --git a/resources/img/genshin/chars/10000042.png b/resources/img/genshin/chars/10000042.png new file mode 100644 index 00000000..80d12631 Binary files /dev/null and b/resources/img/genshin/chars/10000042.png differ diff --git a/resources/img/genshin/chars/10000043.png b/resources/img/genshin/chars/10000043.png new file mode 100644 index 00000000..cd29e228 Binary files /dev/null and b/resources/img/genshin/chars/10000043.png differ diff --git a/resources/img/genshin/material/天赋材料.png b/resources/img/genshin/material/天赋材料.png new file mode 100644 index 00000000..cfa68c10 Binary files /dev/null and b/resources/img/genshin/material/天赋材料.png differ diff --git a/resources/img/genshin/material/武器突破材料_周一周四.png b/resources/img/genshin/material/武器突破材料_周一周四.png new file mode 100644 index 00000000..5b6d99b1 Binary files /dev/null and b/resources/img/genshin/material/武器突破材料_周一周四.png differ diff --git a/resources/img/genshin/material/武器突破材料_周三周六.png b/resources/img/genshin/material/武器突破材料_周三周六.png new file mode 100644 index 00000000..493c96c3 Binary files /dev/null and b/resources/img/genshin/material/武器突破材料_周三周六.png differ diff --git a/resources/img/genshin/material/武器突破材料_周二周五.png b/resources/img/genshin/material/武器突破材料_周二周五.png new file mode 100644 index 00000000..532d3013 Binary files /dev/null and b/resources/img/genshin/material/武器突破材料_周二周五.png differ diff --git a/resources/img/genshin/material/角色天赋材料_周一周四.png b/resources/img/genshin/material/角色天赋材料_周一周四.png new file mode 100644 index 00000000..d3ad19dd Binary files /dev/null and b/resources/img/genshin/material/角色天赋材料_周一周四.png differ diff --git a/resources/img/genshin/material/角色天赋材料_周三周六.png b/resources/img/genshin/material/角色天赋材料_周三周六.png new file mode 100644 index 00000000..60e8f7d9 Binary files /dev/null and b/resources/img/genshin/material/角色天赋材料_周三周六.png differ diff --git a/resources/img/genshin/material/角色天赋材料_周二周五.png b/resources/img/genshin/material/角色天赋材料_周二周五.png new file mode 100644 index 00000000..baacbd3e Binary files /dev/null and b/resources/img/genshin/material/角色天赋材料_周二周五.png differ diff --git a/resources/img/genshin/seek_god_eye/Minimal.ttf b/resources/img/genshin/seek_god_eye/Minimal.ttf new file mode 100644 index 00000000..7a47b06a Binary files /dev/null and b/resources/img/genshin/seek_god_eye/Minimal.ttf differ diff --git a/resources/img/genshin/seek_god_eye/__init__.py b/resources/img/genshin/seek_god_eye/__init__.py new file mode 100644 index 00000000..291ca8f2 --- /dev/null +++ b/resources/img/genshin/seek_god_eye/__init__.py @@ -0,0 +1,178 @@ +from hoshino import Service +from nonebot import on_command +# from ..configs import ALLOW_PRIVATE_CHAT +import random +from .seek_god_eye import (JSON_LIST, + GOD_EYE_INFO, + GOD_EYE_CLASS_LIST, + init_uid_info, + get_random_god_eye_id, + get_god_eye_message, + get_uid_number_found, + found_god_eye, + all_god_eye_map, + delete_god_eye_info, + reset_god_eye_info) + + + + + + +sv = Service('原神神瞳信息查询') + +search_god_eye_command = [] +for eye_type in JSON_LIST: + search_god_eye_command.append(f"找{eye_type}") + +reset_god_eye_command = [] +for eye_type in JSON_LIST: + reset_god_eye_command.append(f"重置{eye_type}找到记录") + +verification_code_list = { + # 重置已找到神瞳列表时需要二次确认,这个字典用来存验证码 + # "QQ号" : 验证码 +} + + +@sv.on_prefix(search_god_eye_command) +async def search_god_eye(bot, ev): + + command_txt = ev['prefix'] + god_eye_id = ev.message.extract_plain_text().strip() + userid = str(ev['user_id']) + init_uid_info(userid) + + if not (god_eye_id in GOD_EYE_INFO): + if god_eye_id != "": + await bot.send(ev, f"找不到编号为 {god_eye_id} 的神瞳" , at_sender=True) + return + + god_eye_type = command_txt[1:] # 把指令前边的 找 字去掉 + + if god_eye_id == "": + # 如果用户没有给神瞳ID就根据属性随机一个没找到过的返回 + god_eye_id = get_random_god_eye_id(userid,god_eye_type) + + if god_eye_id == "": + # 如果随机之后还是空字符串,就表示这种神瞳已经都找完了 + await bot.send(ev, f"你已经找完这种神瞳了!", at_sender=True) + return + + mes = get_god_eye_message(god_eye_id) + + await bot.send(ev, mes, at_sender=True) + + + +@sv.on_prefix("找到神瞳了") +async def found_it(bot, ev): + god_eye_id = ev.message.extract_plain_text().strip() + userid = str(ev['user_id']) + init_uid_info(userid) + + if god_eye_id == "": + await bot.send(ev, f"你需要发送一个神瞳编号" , at_sender=True) + return + + if not (god_eye_id in GOD_EYE_INFO): + await bot.send(ev, f"找不到编号为 {god_eye_id} 的神瞳" , at_sender=True) + return + + mes = found_god_eye(userid,god_eye_id) + + await bot.send(ev, mes, at_sender=True) + + + +@sv.on_prefix("删除找到神瞳",only_to_me=True) +async def delete_god_eye_id(bot, ev): + + god_eye_id = ev.message.extract_plain_text().strip() + userid = str(ev['user_id']) + init_uid_info(userid) + + if god_eye_id == "": + await bot.send(ev, f"你需要发送一个神瞳编号" , at_sender=True) + return + + if not (god_eye_id in GOD_EYE_INFO): + await bot.send(ev, f"找不到编号为 {god_eye_id} 的神瞳" , at_sender=True) + return + + mes = delete_god_eye_info(userid,god_eye_id) + + await bot.send(ev, mes, at_sender=True) + + +@sv.on_prefix(reset_god_eye_command,only_to_me=True) +async def reset_god_eye_(bot, ev): + + verification_code = ev.message.extract_plain_text().strip() + userid = (ev['user_id']) + init_uid_info(userid) + command_txt = ev['prefix'].strip() + god_eye_type = command_txt[2:-4] + + if not (god_eye_type in JSON_LIST): + await bot.send(ev, f"没有这种神瞳" , at_sender=True) + return + + if verification_code == "": + + new_verification_code = "" + for i in range(4): + # 生成一个4位的字母验证码 + new_verification_code += str(chr(random.randint(65,90))) + + verification_code_list[userid] = new_verification_code + await bot.send(ev, f"你确定要重置已经找到的神瞳记录吗?如果确定请发送:\n{command_txt}{new_verification_code}" , at_sender=True) + return + + + if verification_code_list[userid] == verification_code: + reset_god_eye_info(userid,god_eye_type) + verification_code_list.pop(userid) + await bot.send(ev, f"已重置已经找到的{god_eye_type}记录" , at_sender=True) + return + + await bot.send(ev, f"验证码错误,请检查验证码是否正确或重新生成验证码。", at_sender=True) + + + +@sv.on_prefix("找到多少神瞳了",only_to_me=True) +async def found_god_eye_info(bot, ev): + userid = str(ev['user_id']) + init_uid_info(userid) + + mes = get_uid_number_found(userid) + + await bot.send(ev, mes, at_sender=True) + + + +@sv.on_prefix("没找到的",only_to_me=True) +async def not_found_god_eye_info(bot, ev): + userid = str(ev['user_id']) + init_uid_info(userid) + god_eye_type = ev.message.extract_plain_text().strip() + + if not (god_eye_type in JSON_LIST): + await bot.send(ev, f"没有这种神瞳" , at_sender=True) + return + + await bot.send(ev, all_god_eye_map(userid,god_eye_type,""), at_sender=True) + + + +@sv.on_prefix("所有的",only_to_me=True) +async def not_found_god_eye_info(bot, ev): + userid = str(ev['user_id']) + init_uid_info(userid) + god_eye_type = ev.message.extract_plain_text().strip() + + if not (god_eye_type in JSON_LIST): + await bot.send(ev, f"没有这种神瞳" , at_sender=True) + return + + await bot.send(ev, all_god_eye_map(userid,god_eye_type,"all"), at_sender=True) \ No newline at end of file diff --git a/resources/img/genshin/seek_god_eye/icon/map_icon.jpg b/resources/img/genshin/seek_god_eye/icon/map_icon.jpg new file mode 100644 index 00000000..a7479597 Binary files /dev/null and b/resources/img/genshin/seek_god_eye/icon/map_icon.jpg differ diff --git a/resources/img/genshin/seek_god_eye/icon/map_icon.png b/resources/img/genshin/seek_god_eye/icon/map_icon.png new file mode 100644 index 00000000..e0521d6d Binary files /dev/null and b/resources/img/genshin/seek_god_eye/icon/map_icon.png differ diff --git a/resources/img/genshin/seek_god_eye/icon/map_icon_back.jpg b/resources/img/genshin/seek_god_eye/icon/map_icon_back.jpg new file mode 100644 index 00000000..e0521d6d Binary files /dev/null and b/resources/img/genshin/seek_god_eye/icon/map_icon_back.jpg differ diff --git a/resources/img/genshin/seek_god_eye/icon/raw_rock_god_eye.png b/resources/img/genshin/seek_god_eye/icon/raw_rock_god_eye.png new file mode 100644 index 00000000..30f2346e Binary files /dev/null and b/resources/img/genshin/seek_god_eye/icon/raw_rock_god_eye.png differ diff --git a/resources/img/genshin/seek_god_eye/icon/raw_wind_god_eye.png b/resources/img/genshin/seek_god_eye/icon/raw_wind_god_eye.png new file mode 100644 index 00000000..858faccd Binary files /dev/null and b/resources/img/genshin/seek_god_eye/icon/raw_wind_god_eye.png differ diff --git a/resources/img/genshin/seek_god_eye/icon/岩神瞳.png b/resources/img/genshin/seek_god_eye/icon/岩神瞳.png new file mode 100644 index 00000000..bc7c42a3 Binary files /dev/null and b/resources/img/genshin/seek_god_eye/icon/岩神瞳.png differ diff --git a/resources/img/genshin/seek_god_eye/icon/风神瞳.png b/resources/img/genshin/seek_god_eye/icon/风神瞳.png new file mode 100644 index 00000000..e95de89f Binary files /dev/null and b/resources/img/genshin/seek_god_eye/icon/风神瞳.png differ diff --git a/resources/img/genshin/seek_god_eye/seek_god_eye.py b/resources/img/genshin/seek_god_eye/seek_god_eye.py new file mode 100644 index 00000000..66bee40a --- /dev/null +++ b/resources/img/genshin/seek_god_eye/seek_god_eye.py @@ -0,0 +1,346 @@ + +from PIL import Image,ImageDraw,ImageFont +from io import BytesIO + +import os +import json +import random +import base64 + +FILE_PATH = os.path.dirname(__file__) + +JSON_LIST = ["风神瞳","岩神瞳"] + + + +GOD_EYE_TOTAL = { + # 每种神瞳有多少个,这个字典会在导入神瞳的json时初始化 + # "风神瞳" : 100 +} + +GOD_EYE_INFO = { + # 所有神瞳的信息 + # "56": { + # "属性": "风神瞳", + # "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/21/76373921/cbd63e9fbb00160b045dafc424c1657f_1299454333660281584.gif", + # "备注": "", + # "x_pos": 1922.0018670150284, + # "y_pos": 683.9995073891628 + # } +} + +GOD_EYE_CLASS_LIST = { + # 每种神瞳的编号列表 + # "风神瞳":["1","2","3"], + # "岩神瞳":["4","5","6"] + +} + + +MAP_IMAGE = Image.open(os.path.join(FILE_PATH,"icon","map_icon.jpg")) +MAP_SIZE = MAP_IMAGE.size + + +# 风神瞳.json里记录的坐标是相对坐标,是以蒙德城的大雕像为中心的,所以图片合成时需要转换坐标 +CENTER = (3505,1907) + +# 神瞳位置图的裁切尺寸,默认是1000,表示图片长宽都是1000 +CROP_SIZE = 1000 + +uid_info = { + # 这个字典记录用户已经找到的神瞳编号 + # "12345":{ + # "风神瞳":[], + # "岩神瞳":[] + # } +} + + + +for json_name in JSON_LIST: + # 导入神瞳的.json文件 + with open(os.path.join(FILE_PATH, f"{json_name}.json"), 'r', encoding='UTF-8') as f: + data = json.load(f) + GOD_EYE_TOTAL[json_name] = len(data) + GOD_EYE_INFO.update(data) + GOD_EYE_CLASS_LIST.setdefault(json_name,list(data.keys())) + + + + +def save_uid_info(): + with open(os.path.join(FILE_PATH,'uid_info.json'),'w',encoding='UTF-8') as f: + json.dump(uid_info,f,ensure_ascii=False,indent=4) + + +# 检查uid_info.json是否存在,没有创建空的 +if not os.path.exists(os.path.join(FILE_PATH,'uid_info.json')): + save_uid_info() + +# 读取uid_info.json的信息 +with open(os.path.join(FILE_PATH,'uid_info.json'),'r',encoding='UTF-8') as f: + uid_info = json.load(f) + + + + + +class God_eye_position_image(object): + # 获取神瞳的位置图像 + # 传入的参数是神瞳的编号,实例化后直接调用get_cq_code即可返回图片的CQ码,使用base64发送 + def __init__(self,god_eye_id): + self.id = str(god_eye_id) + + # ID对应的png文件名 + self.png_name = GOD_EYE_INFO[self.id]["属性"] + '.png' + + # 复制一份地图文件 + self.map_image = MAP_IMAGE.copy() + + # 神瞳的坐标 + self.x,self.y = self.transform_position() + + # 神瞳图片在paste时的偏移量 + self.offset = [50,120] + + def transform_position(self): + # 风神瞳.json里记录的坐标是相对坐标,需要转换一下 + x = GOD_EYE_INFO[self.id]["x_pos"] + CENTER[0] + y = GOD_EYE_INFO[self.id]["y_pos"] + CENTER[1] + return [int(x),int(y)] + + def get_crop_pos(self): + # 返回地图的裁切尺寸,检查裁切点是否越界 + x = max(self.x - CROP_SIZE/2,0) + y = max(self.y - CROP_SIZE/2,0) + r = min(self.x + CROP_SIZE/2,MAP_SIZE[0]) + l = min(self.y + CROP_SIZE/2,MAP_SIZE[1]) + return [x,y,r,l] + + def paste(self): + # 把神瞳的图贴到地图上,然后以神瞳为中心裁切地图 + god_eye_image = Image.open(os.path.join(FILE_PATH, "icon", self.png_name)) + self.map_image.paste(god_eye_image,(self.x - self.offset[0],self.y - self.offset[1]),god_eye_image) + self.map_image = self.map_image.crop(self.get_crop_pos()) + + def get_cq_code(self): + self.paste() + bio = BytesIO() + self.map_image.save(bio, format='JPEG') + base64_str = 'base64://' + base64.b64encode(bio.getvalue()).decode() + + return f"[CQ:image,file={base64_str}]" + + + +class God_eye_map(object): + + def __init__(self,_resource_name,_uid,_mode = ""): + self.resource_name = _resource_name + self.uid = _uid + self.mode = _mode + + # 地图要要裁切的左上角和右下角坐标 + # 这里初始化为地图的大小 + self.x_start = MAP_SIZE[0] + self.y_start = MAP_SIZE[1] + self.x_end = 0 + self.y_end = 0 + + self.map_image = MAP_IMAGE.copy() + + self.resource_icon = Image.open(os.path.join(FILE_PATH,"icon",f"{self.resource_name}.png")) + #self.resource_icon = self.resource_icon.resize((int(150*zoom),int(150*zoom))) + + + self.resource_id_list = self.get_resource_point_list() + + + def get_resource_point_list(self): + + temp_list = GOD_EYE_CLASS_LIST[self.resource_name].copy() + + if self.mode == "all": + return temp_list + + for id in set(uid_info[self.uid][self.resource_name]): + temp_list.remove(id) + + return temp_list + + + def paste(self): + for id in self.resource_id_list: + # 把资源图片贴到地图上 + x = int(GOD_EYE_INFO[id]["x_pos"] + CENTER[0]) + y = int(GOD_EYE_INFO[id]["y_pos"] + CENTER[1]) + + + + self.map_image.paste(self.resource_icon,(x - 50 , y - 120),self.resource_icon) + + draw = ImageDraw.Draw(self.map_image) + setfont = ImageFont.truetype(FILE_PATH + '/Minimal.ttf', size=50) + + draw.text((x + 40, y - 60), str(id), fill="#000000", font=setfont) + + # 找出4个方向最远的坐标,用于后边裁切 + self.x_start = min(x,self.x_start) + self.y_start = min(y,self.y_start) + self.x_end = max(x,self.x_end) + self.y_end = max(y,self.y_end) + + + def crop(self): + + # 先把4个方向扩展150像素防止把资源图标裁掉 + self.x_start -= 150 + self.y_start -= 150 + self.x_end += 150 + self.y_end += 150 + + # 如果图片裁切的太小会看不出资源的位置在哪,检查图片裁切的长和宽看够不够1000,不到1000的按1000裁切 + if (self.x_end - self.x_start)<1000: + center = int((self.x_end + self.x_start) / 2) + self.x_start = center - 500 + self.x_end = center +500 + if (self.y_end - self.y_start)<1000: + center = int((self.y_end + self.y_start) / 2) + self.y_start = center - 500 + self.y_end = center +500 + + self.map_image = self.map_image.crop((self.x_start,self.y_start,self.x_end,self.y_end)) + + def get_cq_cod(self): + + if not self.resource_id_list: + return "没有这个资源的信息" + + self.paste() + + self.crop() + + bio = BytesIO() + self.map_image.save(bio, format='JPEG') + base64_str = 'base64://' + base64.b64encode(bio.getvalue()).decode() + + return f"[CQ:image,file={base64_str}]" + + def get_resource_count(self): + return len(self.resource_id_list) + + + +def get_uid_number_found(uid:str): + mes = "你找到的神瞳信息如下:\n" + for eye_type in JSON_LIST: + number = len(uid_info[uid][eye_type]) + mes += f"你已经找到了 {number} 个 {eye_type} ,该神瞳一共有 {GOD_EYE_TOTAL[eye_type]} 个!\n" + return mes + + +def get_eye_gif_path(eye_id): + # 获取gif的路径,找不到会返回空字符串 + eye_type = GOD_EYE_INFO[eye_id]["属性"] + gif_path = os.path.join(FILE_PATH,"icon",eye_type,str(eye_id) + ".gif") + if os.path.exists(gif_path): + return gif_path + else: + return "" + + +def get_eye_gif_cq_code(eye_id): + # 获取gif的CQ码,找不到gif文件会返回空字符串 + gif_path = get_eye_gif_path(eye_id) + if gif_path == "": + return "" + + gif_path = gif_path.replace("\\","/") + cq_code = f'[CQ:image,file=file://{gif_path}]' + return cq_code + +def get_eye_remarks(eye_id): + # 获取神瞳的备注,注意有的神瞳备注是空字符串 + return GOD_EYE_INFO[eye_id]["备注"] + +def add_god_eye_info(uid,eye_id): + eye_type = GOD_EYE_INFO[eye_id]["属性"] + uid_info[uid][eye_type].append(eye_id) + uid_info[uid][eye_type] = list(set(uid_info[uid][eye_type])) + save_uid_info() + +def init_uid_info(uid): + # 初始化用户的信息 + if not (uid in uid_info): + uid_info.setdefault(uid, {}) + for eye_type in JSON_LIST: + if not (eye_type in uid_info[uid]): + uid_info[uid].setdefault(eye_type, []) + +def get_random_god_eye_id(uid,eye_type): + # 获取一个随机没找到过的神瞳ID,返回随机到的神瞳ID,如果返回空字符串表示这种神瞳已经全部找到了 + if len(uid_info[uid][eye_type]) == GOD_EYE_TOTAL[eye_type]: + return "" + # 找出没找到过的神瞳列表 + temp_list = GOD_EYE_CLASS_LIST[eye_type].copy() + + for id in uid_info[uid][eye_type]: + temp_list.remove(id) + + # eyes_never_found = set(GOD_EYE_CLASS_LIST[eye_type]).difference(set(uid_info[uid][eye_type])) + # r = random.choice(list(eyes_never_found)) + r = random.choice(temp_list) + return str(r) + +def delete_god_eye_info(uid,eye_id): + eye_type = GOD_EYE_INFO[eye_id]["属性"] + if not (eye_id in uid_info[uid][eye_type]): + return "你还没有找到这个神瞳!" + + uid_info[uid][eye_type].remove(eye_id) + save_uid_info() + return f"已经在你的记录列表删除编号为 {eye_id} 的神瞳" + +def reset_god_eye_info(uid,eye_type): + # 重置某一种神瞳的已找到列表 + uid_info[uid][eye_type].clear() + save_uid_info() + return "已重置已找到这种神瞳的列表" + +def get_god_eye_message(eye_id): + message = f"当前神瞳编号 {eye_id} \n" + message += God_eye_position_image(eye_id).get_cq_code() # 获取神瞳位置图 + message += "\n" + + gif_cq_code = get_eye_gif_cq_code(eye_id) # 获取找神瞳的动图,没有找到这就是个空字符串 + if gif_cq_code: + message += gif_cq_code + message += "\n" + + remarks_txt = get_eye_remarks(eye_id) # 获取神瞳的备注信息 + if remarks_txt: + message += "备注:" + message += remarks_txt + message += "\n" + + message += "\n※ 如果你找到了神瞳或者你确定这个神瞳已经找过了,可以发送 找到神瞳了 神瞳编号\n" + message += "※ 机器人记录你找到这个神瞳之后将不再给你发送这个神瞳位置\n" + message += "※ 图片及数据来源于原神观测枢wiki\n" + message += "※ 神瞳位置有可能有细微误差,具体以游戏里为准" + + return message + +def found_god_eye(uid,eye_id): + add_god_eye_info(uid,eye_id) + save_uid_info() + return f"已添加编号为 {eye_id} 的神瞳找到记录!" + + + +def all_god_eye_map(uid,eye_type,mode = ""): + mes = "神之眼信息如下:\n" + + mes += God_eye_map(eye_type,uid,mode).get_cq_cod() + + return mes + diff --git a/resources/img/genshin/seek_god_eye/岩神瞳.json b/resources/img/genshin/seek_god_eye/岩神瞳.json new file mode 100644 index 00000000..96c0e09b --- /dev/null +++ b/resources/img/genshin/seek_god_eye/岩神瞳.json @@ -0,0 +1,919 @@ +{ + "2110": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/24/15363053/bfb00fa168d8684d7487fce07f5b543a_4424026387832946167.gif", + "备注": "", + "x_pos": -2407.5, + "y_pos": 1602.5 + }, + "2042": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/10/14/76373921/122c9fcb50d48c4c61d25e1c0a8cf96a_2764643910865172456.gif", + "备注": "", + "x_pos": -0.5, + "y_pos": 2664 + }, + "1865": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/25/6142363/1923190da67768eb52de24d62e1937be_2494748305899061128.gif", + "备注": "", + "x_pos": -2178.5, + "y_pos": 2167.6726049978897 + }, + "1747": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/10/14/76373921/76441984ff1d830d6b6b8018c1c7bfde_8520420476823328876.gif", + "备注": "从山上滑翔过去就能拿到了", + "x_pos": -2438, + "y_pos": 1607.6449953037095 + }, + "1744": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/22/4839652/101fce2c902850371c4c26c5192a2bf8_7299553878110113351.gif", + "备注": "神瞳在大木桩中央,但是需从旁边高处飞过去才能捡到,大木桩下面怎么跳也够不着的(别问我怎么知道的", + "x_pos": -1205, + "y_pos": 489 + }, + "1734": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/24/15363053/681afc5fbe538cb62494b5f0aeb91296_17354936688802550.gif", + "备注": "", + "x_pos": -2388.5495293809718, + "y_pos": 1226.270843798893 + }, + "1720": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/24/15363053/46b07f1e7ec0633e0d8a93456de53042_1319508688072624084.gif", + "备注": "", + "x_pos": 368.50021848898723, + "y_pos": 2696.000602283162 + }, + "1716": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/25/6142363/35b7c22e8c0c820eaee0a146271f8ff7_7014348581897273900.gif", + "备注": "", + "x_pos": -1082.4994537775328, + "y_pos": 2196.001204566325 + }, + "1714": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/25/6142363/dda98a1af8a91130de916760159c7c22_3702109991219548578.gif", + "备注": "在矿洞中", + "x_pos": -619.9987983105725, + "y_pos": 1446.0013250229576 + }, + "1692": { + "属性": "岩神瞳", + "gif_url": "", + "备注": "", + "x_pos": 9.001092444933875, + "y_pos": 1926.4993977168378 + }, + "1675": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/25/6142363/774bbecb02e6b0b4e6709a1f43c3de6e_2872670206992713583.gif", + "备注": "", + "x_pos": -1230.5002184889868, + "y_pos": 1867.4991568035725 + }, + "1674": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/24/15363053/8cc6328607f8e026e98be7fd1e1d4f3e_1568835659620315348.gif", + "备注": "", + "x_pos": -2494.4995630220265, + "y_pos": 1357.0002409132649 + }, + "1673": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/24/15363053/072762f0094569036595d0cbe9ab0518_3145564383828401599.gif", + "备注": "", + "x_pos": -2399.4995630220265, + "y_pos": 1371.5001204566324 + }, + "1672": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/22/4839652/93d513e5eccaa8668a5c7b790c7fd791_3605844902050387078.gif", + "备注": "神瞳在NPC冒险家丹迪旁边的老歪脖子树上。(不是吊死崇祯那颗啦!", + "x_pos": -1373.069958101236, + "y_pos": 368.26120726829276 + }, + "286": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/24/4839652/326213c5e0b5433d9a5c2ea6979eff5a_2139784998682881218.gif", + "备注": "神瞳在水车旁边高层塔楼的屋顶上。(我也是爬了半天悬崖才看见的( ̄﹏ ̄;)", + "x_pos": -1340.6024352857153, + "y_pos": 617.403184152372 + }, + "284": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/22/4839652/311834efa3e815663ef3b8403e1e0111_3944235440707971506.gif", + "备注": "神瞳在坑上方的空中。", + "x_pos": -1198.8504157425355, + "y_pos": 846.8043551015844 + }, + "283": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/22/4839652/20585c32a9164fcca9222b42daaaa305_3617152667042309742.gif", + "备注": "", + "x_pos": -1268.4995709468053, + "y_pos": 650.500798676363 + }, + "281": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/24/4839652/77075947eb779fa655b916e8e754a4d1_6363599850565816084.gif", + "备注": "神瞳在房檐下面,注意别飞过了。", + "x_pos": -1283.9306425450695, + "y_pos": 531.9160212744209 + }, + "280": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/22/4839652/9a4e5bcda1025328397c2cd2782b8584_3011514102623077634.gif", + "备注": "神瞳在高空中,需要先爬树再到房顶才能飞过去捡到。(真麻烦╭(╯^╰)╮)", + "x_pos": -1429.972403722703, + "y_pos": 552.4269365180517 + }, + "278": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/21/4839652/8c60960615eee3c3b5905126d93bdb98_3197582560415631799.gif", + "备注": "", + "x_pos": -1502.9143385236644, + "y_pos": 621.409365638061 + }, + "277": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/10/14/76373921/a4b7cf88ed796ff724ba4432cf37f074_7889730050607266460.gif", + "备注": "放个荒星就好了", + "x_pos": -1172.841548643175, + "y_pos": 647.7660186361509 + }, + "276": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/22/4839652/7d845562bafec2b33526a5cece8df423_1936290300520583862.gif", + "备注": "", + "x_pos": -1452.844981068734, + "y_pos": 479.83896441065644 + }, + "275": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/22/4839652/920b10fb304010e4bb1ded92dc40a707_4273448204704312890.gif", + "备注": "", + "x_pos": -1330.8781611824702, + "y_pos": 817.8336399015684 + }, + "274": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/22/4839652/5e4380aacc9d83c3bc53cd0eae3d6f98_8783309690886067650.gif", + "备注": "神瞳在庙屋顶上,可以爬后面的岩壁上去捡。", + "x_pos": -1622.0027234818067, + "y_pos": 578.914690147149 + }, + "273": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/22/4839652/e1041f1b4de72f6e078a934d9152f08f_7753023967918108067.gif", + "备注": "", + "x_pos": -1637.9529533112022, + "y_pos": 712.9580848962164 + }, + "272": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/22/4839652/3ff088aad84bbf6b29c48ab00c156c13_8209708308707735294.gif", + "备注": "神瞳在瀑布坑里的小洞,要仔细一点找哦~", + "x_pos": -1578.9985698226837, + "y_pos": 446.00425960727034 + }, + "271": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/22/4839652/a0cc053115cd320238c073a6d0f80292_3460622677525059934.gif", + "备注": "神瞳在竹子顶上,耐心的爬哦~(我要一步一步往上爬~♫ 咦我怎么唱起来了)", + "x_pos": -1496.9998569822683, + "y_pos": 801.0018635781807 + }, + "270": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/22/4839652/8955a467a8ed09df9e42c0e831c60805_8828823783563834949.gif", + "备注": "", + "x_pos": -1532.9183430201501, + "y_pos": 817.4652729834852 + }, + "269": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/22/4839652/113f5ae8217c8ea07bbe1adf57b41e38_7820847643669684849.gif", + "备注": "神瞳在瀑布旁边的大洞穴里面,遗迹守卫旁边岩壁往上爬就可以看到了。(我还以为它会突然起来打我)", + "x_pos": -1626.905048516015, + "y_pos": 373.90339097062133 + }, + "268": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/22/4839652/06cce7738ee0d1bfd1ba945150ad9e7a_318743286187121433.gif", + "备注": "神瞳在宝箱上方,爬树可以直接捡了飞跑,如果你不想被打的话。(等等,我怎么感觉我还是要被打┭┮﹏┭┮)", + "x_pos": -1345.9982837872203, + "y_pos": 736.0063894109057 + }, + "267": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/24/15363053/2a4b50143f952e432f5b018b20d9fc0d_5571795988927030483.gif", + "备注": "", + "x_pos": -1486.0005720709264, + "y_pos": 161.00851921454068 + }, + "265": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/22/4839652/1e6cfa25cbefd47f531e9ea3e67b246e_287668464508994588.gif", + "备注": "", + "x_pos": -1366.8858841399779, + "y_pos": 869.8576001924648 + }, + "264": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/10/14/76373921/1d2312d3d9fe9bc396f453c454bb3f21_3563484467109557283.gif", + "备注": "在丘丘人营地的屋顶上", + "x_pos": -1100.9994279290736, + "y_pos": 1101.0079867636318 + }, + "263": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/23/4839652/8e0236299764076ba25c5b2c348fa7a5_4505073313672454428.gif", + "备注": "", + "x_pos": -1117.8286770473292, + "y_pos": 887.8336399015684 + }, + "262": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/23/4839652/5571691d5c81615261f28dbac8b3d13b_1116984694150301308.gif", + "备注": "神瞳在半空中,需要到远处的一块石头上利用风元素激活风车产生风场飞过去才能捡到。", + "x_pos": -1191.9979977517573, + "y_pos": 1030.0063894109057 + }, + "261": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/23/4839652/013498519baea0f756c7f6ac1b26c157_447724792811709310.gif", + "备注": "在圆坑宝箱的上方。(顺便一提宝箱开启方法是用岩元素攻击圆坑中地上的阵哦~)", + "x_pos": -1213.8561364518005, + "y_pos": 911.8464187233799 + }, + "260": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/24/4839652/de08a10c8a11aaabcd44900fc7823bcc_1708027969562824562.gif", + "备注": "神瞳在石墩上较高的位置,用岩主砸个荒星当垫脚就能够到了。(像我这样憨跳是没有结果的┭┮﹏┭┮)", + "x_pos": -1049.9299336013173, + "y_pos": 957.9007287160775 + }, + "259": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/23/4839652/7a01b229bd3110675b5da4fa1ea8277c_3563199774348189887.gif", + "备注": "在山坡顶端的树上。", + "x_pos": -1170.9994279290736, + "y_pos": 1254.0037271563615 + }, + "257": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/22/4839652/234e44af005d0ff1c8ff1bf90c9da952_4891759829643618237.gif", + "备注": "找完屋顶的神瞳后,从屋顶找到大树黄叶子的方位往外跳,落下去的时候调整角度就可以看到神瞳在拐角桥底下(注意控制下落速度哦~)", + "x_pos": -1122.5, + "y_pos": 1433.0037271563615 + }, + "256": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/22/4839652/96542d31133c0b2e71fb2a947a0e4e2a_9009663536041532691.gif", + "备注": "神瞳在客栈屋顶上,通过客栈传送点旁边的大树可爬到屋顶。", + "x_pos": -1085.5004290531947, + "y_pos": 1433.5031947054526 + }, + "255": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/10/14/76373921/fbbcbc244bfacc3a07b3515b0e6b9237_5029872380655701823.gif", + "备注": "", + "x_pos": -1693, + "y_pos": 987.5 + }, + "254": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/10/14/76373921/57a8ddf17d98291d799a0a4495ab329e_2564133905221417090.gif", + "备注": "", + "x_pos": -1791, + "y_pos": 916 + }, + "253": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/24/15363053/72496f97addf4d9d60f91964cfdd9625_6295784218623893117.gif", + "备注": "", + "x_pos": -1895, + "y_pos": 732 + }, + "252": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/24/15363053/54febda9ea1207ec7a2d5ec54d76d991_2009195493168024515.gif", + "备注": "", + "x_pos": -2051.5, + "y_pos": 889.5 + }, + "251": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/24/15363053/4435bb4a7089055764f50bbf9e45ab0b_8952950108931868056.gif", + "备注": "", + "x_pos": -1479.0706135681962, + "y_pos": 2222.7820462657164 + }, + "250": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/24/15363053/f87cc4140a63d3ce829856bd710d1180_1039695060986393236.gif", + "备注": "", + "x_pos": -1991, + "y_pos": 942 + }, + "249": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/24/15363053/185bd072e14fe1b68e60fa19f5d2a84c_9081089639178637983.gif", + "备注": "", + "x_pos": -1657, + "y_pos": 1167 + }, + "248": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/24/15363053/745fe60555ea00397a7601976a76c5e5_9018417527542931034.gif", + "备注": "", + "x_pos": -1400, + "y_pos": 1500 + }, + "247": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/24/15363053/9ad571f6bb3f662295ac1fdb05a26876_3120868171121670107.gif", + "备注": "", + "x_pos": -1702, + "y_pos": 1549 + }, + "246": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/25/6142363/19d4454a4043b5f5b54966d66f4479f8_8043083059829183162.gif", + "备注": "", + "x_pos": -1641.580773306082, + "y_pos": 2477.2780711968435 + }, + "245": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/25/6142363/c78cfab542b64795d474fa18f2e17b61_4504037929925149836.gif", + "备注": "在山上的位置,可以利用风元素激活机关利用风场获得,也可以从更高的山上自高而下获取。", + "x_pos": -1213.0754203259057, + "y_pos": 2543.258557222377 + }, + "244": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/25/6142363/139b983785817eddee3074367e57a644_4117257246987464572.gif", + "备注": "天衡山的半山腰,进入山洞后从内部爬到制高点飞下来获取。", + "x_pos": -1365.5620924977115, + "y_pos": 2843.7763848039885 + }, + "243": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/25/6142363/d033e656dcb40da4930160301c31642d_5582272038780795632.gif", + "备注": "在一尊石像的正前方,跳下隐藏的坑道获取。", + "x_pos": -1260.575311081412, + "y_pos": 3075.2766257172534 + }, + "241": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/24/15363053/e530bf5bb47e8d58ff946fd71b6d032f_270147925109447429.gif", + "备注": "", + "x_pos": -1952, + "y_pos": 1303.5 + }, + "239": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/24/15363053/20812d40cd8c620b5b47f436778ed1ea_3953539578528078557.gif", + "备注": "", + "x_pos": -2064, + "y_pos": 1351 + }, + "234": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/25/6142363/11ca281c49160a765540aa1887cba43d_5461665652443691007.gif", + "备注": "想办法解开这里的秘密,获取封印在里面的岩神瞳。", + "x_pos": -1689.0703950792094, + "y_pos": 2494.7822871789813 + }, + "233": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/24/15363053/85e6bfa4dd51daccecc509ba3d868d86_3226381862921063078.gif", + "备注": "", + "x_pos": -1957, + "y_pos": 1398 + }, + "231": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/25/6142363/f2694c1f3147eb83a8ecba3488f7308f_2340210256149830404.gif", + "备注": "", + "x_pos": -1785.0410083104869, + "y_pos": 2483.2746984111336 + }, + "230": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/10/14/76373921/af444f8474d91c89b6e7c8515fb18db8_2038267040722511085.gif", + "备注": "", + "x_pos": -2037, + "y_pos": 1592 + }, + "228": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/25/6142363/961cea37862271dd31b5eb62b316b776_8281991535622649793.gif", + "备注": "", + "x_pos": -1988.5528067157732, + "y_pos": 2574.2830099187768 + }, + "227": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/24/15363053/96d9f8f6109df03b47f7a1e7740bce62_1954288530748010308.gif", + "备注": "", + "x_pos": -1965, + "y_pos": 1591 + }, + "225": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/10/14/76373921/af976a5c1e2d292e795eea8157dc24e4_4103645056210980394.gif", + "备注": "", + "x_pos": -1889.077277482293, + "y_pos": 2667.7905986866244 + }, + "224": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/10/14/76373921/c36dfdbb8f846d61caba8694bc3e61b4_2494813006484203754.gif", + "备注": "", + "x_pos": -2058, + "y_pos": 1561 + }, + "222": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/24/15363053/7f8d47727966f1e5c64ad1872c55ca41_5375743215916018392.gif", + "备注": "", + "x_pos": -2174, + "y_pos": 1493 + }, + "221": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/25/6142363/efed9717f6360aa5d8481dccc768667c_5669949726399085061.gif", + "备注": "", + "x_pos": -2032.070832057183, + "y_pos": 2841.2774689136813 + }, + "220": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/25/6142363/9f36786b07cd60e2e70ef77d57a1fe4d_8252897460680296460.gif", + "备注": "", + "x_pos": -2022.0319410175352, + "y_pos": 2979.79565786519 + }, + "219": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/24/15363053/44732d11a05c8084cad774f6cdee5412_4766101376373994746.gif", + "备注": "", + "x_pos": -2293, + "y_pos": 1439 + }, + "218": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/24/15363053/699a9419c8ff90a4ea471c77b01cd6b3_3665858705999641065.gif", + "备注": "", + "x_pos": -2357, + "y_pos": 1416 + }, + "217": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/25/6142363/49790871e4472593a878cc3fd63a9db1_6376197462342305513.gif", + "备注": "", + "x_pos": -1628.1128911871392, + "y_pos": 2820.270241515731 + }, + "216": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/24/15363053/7b35a1060f7961079dcb86110911c906_4578560071566404473.gif", + "备注": "", + "x_pos": -2372, + "y_pos": 1358.5 + }, + "215": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/25/6142363/600715fe2ea0fe748b529fc83e70ffde_8538213771536996277.gif", + "备注": "", + "x_pos": -1840.0785884162137, + "y_pos": 2870.2760234340913 + }, + "213": { + "属性": "岩神瞳", + "gif_url": "", + "备注": "", + "x_pos": -2024, + "y_pos": 1109 + }, + "212": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/25/6142363/248416e4fd9905ab79bdc3006053a084_4247108571851178371.gif", + "备注": "", + "x_pos": -2017.0734539250243, + "y_pos": 3198.28987594683 + }, + "211": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/24/15363053/6119ac8bfba3bdd7620bf1c5b28e2c30_6827682258836613594.gif", + "备注": "", + "x_pos": -2327, + "y_pos": 1094 + }, + "209": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/25/6142363/53ef4e77435978678cad49deba9f0673_2206200901886480498.gif", + "备注": "", + "x_pos": -1685.0439579118083, + "y_pos": 3161.7778302835786 + }, + "206": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/25/6142363/1b2442005095bca2b224e7f5d2f0ac6c_8463665409900924715.gif", + "备注": "", + "x_pos": -1530.5528067157734, + "y_pos": 3164.787346357547 + }, + "205": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/24/15363053/42de276fdbc9d6540b9fc21b4c65162d_6646310003246211582.gif", + "备注": "", + "x_pos": -2502.5, + "y_pos": 1580.5 + }, + "204": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/25/6142363/835d002c876155b66b460be040a1a1cf_5488112487273325804.gif", + "备注": "半山腰的石梯旁,进入不显眼山洞中获取。", + "x_pos": -1296.0726892135708, + "y_pos": 3007.768796036141 + }, + "202": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/24/15363053/e3f9bce83540de4610cfa8845ac1342c_634898536492956369.gif", + "备注": "", + "x_pos": -2554.5, + "y_pos": 1657.5 + }, + "201": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/25/6142363/e2069f78c0bd6b99f09c776e31ebee9e_2893864038704858742.gif", + "备注": "从一个制高点飞下来获取。", + "x_pos": -1445.6428241783287, + "y_pos": 2908.2703619723634 + }, + "200": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/24/15363053/ef1e07cc2c38a6e4ffbc660626fb845b_1517944109194517082.gif", + "备注": "", + "x_pos": -2593, + "y_pos": 1549.5 + }, + "198": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/26/6142363/1b6fe9f1df7519671ac51063a3df85fe_4888526966067712178.gif", + "备注": "从这座遗迹的楼顶进入内部获取岩神瞳。", + "x_pos": -1386.5665715219407, + "y_pos": 2755.775662064194 + }, + "197": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/24/15363053/d5246e49ca57101dff7104a9bf7fa811_6906477258596576472.gif", + "备注": "", + "x_pos": -2592, + "y_pos": 1672 + }, + "196": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/26/6142363/01f9590dfa5d16bdb3d3cbded50b0d04_7683001418661662742.gif", + "备注": "必须使用「荒星」(旅行者-岩)等类似技能才能获取。", + "x_pos": -1336.544176400795, + "y_pos": 2736.2726506483814 + }, + "195": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/25/6142363/b51af121fb6bf592227a4944ce0a49f5_8560203252075976300.gif", + "备注": "", + "x_pos": -995, + "y_pos": 2454 + }, + "193": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/25/6142363/03844827f6e29a50716ce1f88e8897a8_3547450626444842851.gif", + "备注": "", + "x_pos": -817, + "y_pos": 1782 + }, + "192": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/22/4839652/6992c5b2183e16fee5986a4f41dcb297_7454094125350444875.gif", + "备注": "", + "x_pos": -292, + "y_pos": 1655 + }, + "189": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/25/6142363/db4d00e8e2ee1e3511e85c84cf5cb7ed_5276418955432135382.gif", + "备注": "在山的顶端,使用火元素触发机关后利用风场起飞。", + "x_pos": -1086.5733446805311, + "y_pos": 2503.2760234340913 + }, + "188": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/22/4839652/f952dd7c54745342134bf45df64367d1_7571055893715095062.gif", + "备注": "神瞳在空中,需用风属性攻击风车产生风场才能捡到(e都e歪来,别骂了别骂了", + "x_pos": -666, + "y_pos": 1579.5 + }, + "187": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/21/4839652/12194a5ba7a0ac8929b4a872db0eac93_3768692455753349989.gif", + "备注": "", + "x_pos": -458.5, + "y_pos": 1586.5 + }, + "186": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/25/6142363/61f15f1b4ef775c99937a671bff1399b_5938135536381073318.gif", + "备注": "", + "x_pos": -717, + "y_pos": 2391 + }, + "183": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/24/15363053/2ce76b55dcf94f66735aa116fff5c33a_8845561111445684473.gif", + "备注": "", + "x_pos": 270.5, + "y_pos": 2537 + }, + "181": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/24/15363053/6cf4fd5db774ac8c2664d307f771224f_7327564672374274530.gif", + "备注": "", + "x_pos": -2135, + "y_pos": 1694 + }, + "180": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/24/15363053/69f4a1b4c9aee51eea4ee0c869c496a1_7647815399867701538.gif", + "备注": "", + "x_pos": -2001, + "y_pos": 1676 + }, + "179": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/24/15363053/92b274ed6819294c6e0498ede849aab3_4183482075727968921.gif", + "备注": "", + "x_pos": -1920, + "y_pos": 1761 + }, + "178": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/24/15363053/bc957329c93b2a9c26cd140f35a7e620_907051812852491627.gif", + "备注": "", + "x_pos": -1828, + "y_pos": 1703 + }, + "176": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/25/6142363/b9eb11e485e8224f69de4c49ba150bef_7166808008913459783.gif", + "备注": "", + "x_pos": -2183, + "y_pos": 2033 + }, + "175": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/24/15363053/b2ef8dddfccec6abf90df453afe45112_8341540754372647063.gif", + "备注": "", + "x_pos": -1637, + "y_pos": 1676 + }, + "174": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/10/14/76373921/ba299233468314ff869aa12255589d8c_956654482019651306.gif", + "备注": "", + "x_pos": -1413, + "y_pos": 1582 + }, + "173": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/26/6142363/8df4323f56862c8752d9348b603128a7_3924467011530438781.gif", + "备注": "", + "x_pos": -968, + "y_pos": 2289 + }, + "172": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/25/6142363/d06f90be30288c4f974baf22b86a7072_2681671454633752228.gif", + "备注": "", + "x_pos": -320, + "y_pos": 1860.5 + }, + "171": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/25/6142363/497d02a38cdce1306f5eb5b9765c9f11_8688165451316173668.gif", + "备注": "", + "x_pos": -286.5, + "y_pos": 1846.5 + }, + "170": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/25/6142363/d14fd84d817f693171f491cc5b7ef90f_7101805020475141960.gif", + "备注": "", + "x_pos": -527.5, + "y_pos": 1756 + }, + "168": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/21/4839652/e79826e96e945b1d4cb2d6f0a3356b7b_683988355454225141.gif", + "备注": "对准悬崖边的的草堆方向跳然后滑翔一会,可以看到神瞳在一个突出小岩石上", + "x_pos": -471, + "y_pos": 1729 + }, + "167": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/21/4839652/cd6c5f04c599137ab3eeb94eeaee864f_5337502825101761146.gif", + "备注": "", + "x_pos": -767, + "y_pos": 1670.5 + }, + "166": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/24/15363053/c222b675bd51e6c2772b23d2fe7046f9_2636542149190493706.gif", + "备注": "", + "x_pos": 152.5, + "y_pos": 2430.5 + }, + "158": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/24/15363053/d5f408d35d40b5a960e807da9f071141_5277418228530076285.gif", + "备注": "", + "x_pos": -1560, + "y_pos": 1918 + }, + "157": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/24/15363053/87e1d8618516e8a115d5fe1d293976d4_8413870914419726597.gif", + "备注": "", + "x_pos": -1473.0634034316322, + "y_pos": 1982.2633754876779 + }, + "156": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/25/6142363/3b138b7dae3c73a6b5800dc264fb8abb_3184230967842273348.gif", + "备注": "", + "x_pos": -962.5, + "y_pos": 1992 + }, + "155": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/25/6142363/984fec5b1d954f8e9c6e764f5f1472b0_3053009522588116077.gif", + "备注": "", + "x_pos": -551.5, + "y_pos": 1960.5 + }, + "154": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/25/6142363/28f799532eb4adad7d78ac8678060040_2338800999151887859.gif", + "备注": "", + "x_pos": -637.5, + "y_pos": 2052.5 + }, + "153": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/24/15363053/880e4c2af98d5e9a5dbbad0fad564668_5803930787453812284.gif", + "备注": "", + "x_pos": -175, + "y_pos": 2462 + }, + "152": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/25/6142363/0cf5d32e553834600e009973ad6cb85c_6640937310525308677.gif", + "备注": "在船上较高的位置,需要使用可以垫高角色的「荒星」(旅行者-岩)技能进行辅助攀爬,以及其他类似的技能以帮助角色达到。", + "x_pos": -636.0585966739231, + "y_pos": 2970.277107543784 + }, + "151": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/25/6142363/6584ccefa5b7483fc1170646db63fd5d_2850961042148796944.gif", + "备注": "需消灭入口的遗迹守卫,进入地下室", + "x_pos": -955.5, + "y_pos": 2048.5 + }, + "150": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/25/6142363/8a9e50275412419d1fb9f15879c01637_8432328208543305954.gif", + "备注": "", + "x_pos": -885, + "y_pos": 2087 + }, + "149": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/25/6142363/c706c742cc0c826c8daf5f56f189afed_4468459482056504433.gif", + "备注": "", + "x_pos": -624, + "y_pos": 2300 + }, + "148": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/10/14/76373921/403b0ed9cadf15f5572e0ae573a1a912_657689235043951204.gif", + "备注": "", + "x_pos": -510.5, + "y_pos": 1480.5 + }, + "147": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/24/15363053/7eba1aca68204b694032138f7a0c3d02_1250081311439252867.gif", + "备注": "", + "x_pos": -1269, + "y_pos": 1559 + }, + "146": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/10/14/76373921/4f510248b47d8bfa3bbba2a0c2c974f8_6951344005046235577.gif", + "备注": "", + "x_pos": -910.8770108957115, + "y_pos": 1378.3856715726192 + }, + "145": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/25/6142363/19388f6a8e9cd149e18e7f94e5df93c2_2560322040730289663.gif", + "备注": "", + "x_pos": -1022.9090468675945, + "y_pos": 1504.4527603871284 + }, + "144": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/22/4839652/4151ab56981ef469aadef48edc6bccab_7736619160476278206.gif", + "备注": "", + "x_pos": -242, + "y_pos": 1705 + }, + "143": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/25/6142363/8609c25ce039413d85a5f57b82440284_7591286282868156570.gif", + "备注": "", + "x_pos": -504.5, + "y_pos": 1375.5 + }, + "142": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/24/15363053/37ad1be5a090dc521b6ff003b1c03ee5_3954024625757420747.gif", + "备注": "", + "x_pos": -612.8501235621661, + "y_pos": 1110.7743893326801 + }, + "141": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/22/4839652/dbe8166689f5a574cff2e6a4822785b7_4050422453528787652.gif", + "备注": "神瞳在一块小岩石上,你可以像我一样飞过来,潇洒地落地,也可以直接爬石头。", + "x_pos": -1394.8938931329485, + "y_pos": 965.9087154797094 + }, + "140": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/22/4839652/75c1c781d4e9847a519d8380992a22b2_7705519360302196642.gif", + "备注": "", + "x_pos": -1322.9004719486034, + "y_pos": 1189.8607948979175 + }, + "139": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/25/6142363/15a6583ab2c1e9a5126ba5002418979f_2760622410182714499.gif", + "备注": "", + "x_pos": -665, + "y_pos": 1494.5 + }, + "138": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/24/15363053/680b145ce53b686547b80fdaf294faa8_3934738963438389761.gif", + "备注": "", + "x_pos": -1299, + "y_pos": 1412 + }, + "137": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/24/4839652/86b45907e056e28861e981a7a8d56da7_5966454234679688902.gif", + "备注": "在空心树桩上方。", + "x_pos": -943.7963550399827, + "y_pos": 1046.8378995088387 + }, + "136": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/22/4839652/c54cf025500e1b5a83ba20ca3c79fdca_5319557142256667902.gif", + "备注": "", + "x_pos": -1117.788918117938, + "y_pos": 781.7303444252611 + }, + "135": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/18/76373921/5f36f03b756a30e7d62cf370ea9c0665_3915499219172823185.gif", + "备注": "", + "x_pos": -938.8734354524208, + "y_pos": 740.8806132889858 + }, + "102": { + "属性": "岩神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/25/6142363/687bd1e53491186b59d3ef36367891b5_5790248486939030006.gif", + "备注": "", + "x_pos": -1212, + "y_pos": 2046.5 + } +} \ No newline at end of file diff --git a/resources/img/genshin/seek_god_eye/风神瞳.json b/resources/img/genshin/seek_god_eye/风神瞳.json new file mode 100644 index 00000000..42d8bbde --- /dev/null +++ b/resources/img/genshin/seek_god_eye/风神瞳.json @@ -0,0 +1,457 @@ +{ + "1743": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/22/21665168/599becc1b8938b69ad12cf3064c19361_2841686593498054236.gif", + "备注": "", + "x_pos": -1069.5, + "y_pos": -262.5 + }, + "858": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/21/76373921/0e2edd0fd05bdcea0bf55f6199ca895a_5603430889581911175.gif", + "备注": "", + "x_pos": 625.0006223383425, + "y_pos": 595.5019704433498 + }, + "839": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/21/76373921/6ddbe1809b8f13b696937f009ae7ba31_3494102935990581234.gif", + "备注": "收集三颗风种子或者使用风元素激活风种子产生风场,利用风场收集神瞳。", + "x_pos": 637.2934871754605, + "y_pos": 795.0310176454741 + }, + "165": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/22/21665168/5b5f0eb24c0bb9093f839ee753e86873_5281396088957363427.gif", + "备注": "", + "x_pos": -931, + "y_pos": -404.29632719353094 + }, + "164": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/22/21665168/560816ff86230c4752cde8c18adc38da_2799127768479756543.gif", + "备注": "", + "x_pos": -834, + "y_pos": -537.7670703263034 + }, + "163": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/22/21665168/cbebf705e1212987f86022935a63d94b_2962405899946701809.gif", + "备注": "", + "x_pos": -731.5, + "y_pos": -490.1717979637931 + }, + "162": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/22/21665168/6a8e6f7a9e3358d9b4aadb34f10a56db_2752851540887832021.gif", + "备注": "", + "x_pos": -385.5, + "y_pos": -196.51876204291034 + }, + "161": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/22/21665168/142ed9e15c78f4e64bc0ed686cc12bdc_3420108624570441481.gif", + "备注": "", + "x_pos": -302, + "y_pos": -230.3330858215861 + }, + "160": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/22/21665168/ffa29f79aed9dab17a0fdb5b42181f87_5627909948763941450.gif", + "备注": "藏在树叶里,一定要望清楚。", + "x_pos": -308, + "y_pos": -163.2175587048414 + }, + "134": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/10/14/76373921/10534b259531987fd0b6222c4f9455f9_1915937069589438328.gif", + "备注": "", + "x_pos": 443.5, + "y_pos": -449 + }, + "133": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/19/76373921/9ac65d5357e06034cf30417aab5ef1d7_6067053597102730250.gif", + "备注": "在悬崖上,需要跳下去捡。", + "x_pos": 1062, + "y_pos": -629.5 + }, + "132": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/21/76373921/35fa153f0e5aa5c7d2f141239ebc9406_1325897500051831636.gif", + "备注": "", + "x_pos": 209, + "y_pos": 394 + }, + "131": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/21/76373921/66c955e54c0c4dbac55c47dd818ba9a7_9114948938439204761.gif", + "备注": "使用风元素激活风种子产生风场,利用风场收集神瞳。", + "x_pos": 102, + "y_pos": 391 + }, + "130": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/21/76373921/d3f671518f8f785b5091ebe6243ca800_4538580540662507879.gif", + "备注": "", + "x_pos": 286.05730802390826, + "y_pos": 555.5060495334828 + }, + "129": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/21/76373921/e2433140fa8cde64cd44b5e90f185118_3061927369379320315.gif", + "备注": "", + "x_pos": 362.50382763372636, + "y_pos": 590.0141716833114 + }, + "128": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/22/21665168/7133b878a1b60055d6b018b7ec9708ec_6197320491016987686.gif", + "备注": "在悬崖边下面,建议飞下去", + "x_pos": -319, + "y_pos": 131 + }, + "127": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/22/21665168/8b3277d9187169d76a9b4f5037dce401_6706491041681976451.gif", + "备注": "藏在悬崖下面。", + "x_pos": -203, + "y_pos": 330 + }, + "126": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/22/21665168/6b36162fdcf659955f1b29b7f50dad7f_6994973593330281318.gif", + "备注": "需要正确顺序收集种子开启风场", + "x_pos": -308.5, + "y_pos": -7.908486158744836 + }, + "124": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/22/21665168/9283ebe824b4d41ecf85b0e6253bac77_538202390249227488.gif", + "备注": "", + "x_pos": -1132.5, + "y_pos": -229.69130254194488 + }, + "123": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/21/76373921/58ea498a2df8d3a929e63bba0ae695f3_7991661368514890561.gif", + "备注": "", + "x_pos": -881, + "y_pos": -330.70330535926905 + }, + "122": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/22/21665168/779e8789320a4af99f7c4d7f79ed7890_6517193530064431571.gif", + "备注": "", + "x_pos": -933.5, + "y_pos": -361.7273109939172 + }, + "121": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/22/21665168/fdfec3d2a6be7ed82c88f949bd6366a1_522173916302655695.gif", + "备注": "藏在树里。", + "x_pos": -242, + "y_pos": 65.87846383375177 + }, + "120": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/19/76373921/ca4f5085aa3f38d9d1181ecbf3cdee8b_4641106841585232557.gif", + "备注": "", + "x_pos": 814, + "y_pos": 79.5 + }, + "117": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/19/76373921/8e3cbbfe0de89a3e00697e1a21f28071_4175826072546034072.gif", + "备注": "", + "x_pos": 1023, + "y_pos": -17.5 + }, + "115": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/10/14/76373921/be1a0d2b6fb990157c55eca3e825662a_7866939288638921788.gif", + "备注": "", + "x_pos": 511.22063137116857, + "y_pos": 437.94524316855086 + }, + "114": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/19/76373921/b5017e7de9953b1c87324665999d35bf_4145393686446844445.gif", + "备注": "", + "x_pos": 478.6085467210878, + "y_pos": 494.4307550093972 + }, + "113": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/21/76373921/51daf4cdb9200f3c319d3b24dc88b56b_3742468746138299880.gif", + "备注": "", + "x_pos": 603.1671509809876, + "y_pos": 463.4204376839393 + }, + "112": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/19/76373921/dabde510570eb7ce9320e227cd8095c8_8421697441205627271.gif", + "备注": "", + "x_pos": 516.5, + "y_pos": 13 + }, + "99": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/21/76373921/992f2108d9b19472a8d368b7babbe5ae_4168731665053840805.gif", + "备注": "收集三颗风种子或者使用风元素激活风种子产生风场,利用风场收集神瞳", + "x_pos": 376.50186701502844, + "y_pos": 640.4980295566502 + }, + "95": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/21/76373921/5d8f5d605beeeced438e4f682b976163_3987533745357986584.gif", + "备注": "", + "x_pos": 438.6482567114026, + "y_pos": 755.9138521570512 + }, + "93": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/21/76373921/ec8d9c4d73227a91a3dd4742147e7485_4353719059385670811.gif", + "备注": "", + "x_pos": 852.5012446766859, + "y_pos": 845.5004926108377 + }, + "91": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/21/76373921/9fd6847f719940ee503a0819bd312ee1_5406786667169067497.gif", + "备注": "收集该神瞳需要解锁剑冢的三层封印,详情请参考世界任务——探索剑冢封印", + "x_pos": 821.9993776616575, + "y_pos": 948.9985221674879 + }, + "90": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/21/76373921/48a384d24c8f435e651aaaf1b9e273d8_6518040070865002555.gif", + "备注": "神瞳在悬崖下方", + "x_pos": 1172.2702688590616, + "y_pos": 830.5409528259893 + }, + "89": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/10/14/76373921/357bf357786845db042159bc781515ac_7427367320019615865.gif", + "备注": "", + "x_pos": 840.5, + "y_pos": -484 + }, + "88": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/19/76373921/486908479267a050e5fcb8e8acea3692_466608666518060779.gif", + "备注": "", + "x_pos": 892, + "y_pos": -181 + }, + "87": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/19/76373921/8dcefeb7c777e6ca711ba53d5fb55d9e_976993417096589983.gif", + "备注": "", + "x_pos": 519.7085379916562, + "y_pos": 349.49801271936576 + }, + "86": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/21/76373921/c92ec8dff3ee18d1a731feb300c174ab_5604801784480104215.gif", + "备注": "", + "x_pos": 361.0947739370349, + "y_pos": 400.93123061017695 + }, + "85": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/22/21665168/59563dfb7d697abbcfc1835f1e7c102b_7821659766969342499.gif", + "备注": "", + "x_pos": -20, + "y_pos": 244 + }, + "84": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/22/21665168/c247034a91b6d7d9289ccb2f2e12116f_8875494114136382303.gif", + "备注": "收集三个种子开启风场并且解锁风碑开启加速环即可√", + "x_pos": -306, + "y_pos": 707 + }, + "83": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/29/21665168/901d3fb29e69377455d130156570bdd5_8637882940862091530.gif", + "备注": "难点在于如何想办法爬到卢老爷房顶上...荒星的一百种用法(", + "x_pos": -338.5, + "y_pos": 561 + }, + "82": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/10/14/76373921/f3433d8d8031ffa147a681998df79d7a_5218887315681682261.gif", + "备注": "只要爬上去就能拿到了。", + "x_pos": -283, + "y_pos": 238 + }, + "81": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/22/21665168/07ea7a4da5d8bbbf0d3c557c02d1147e_3176842945635427509.gif", + "备注": "", + "x_pos": -1006, + "y_pos": -142.8653433931447 + }, + "80": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/22/21665168/e7060f05d871461a75a95b60ba721e7d_2089841828398520281.gif", + "备注": "找准位置利用风场和加速圈轻松获取。", + "x_pos": -266, + "y_pos": -317.2550675089792 + }, + "79": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/22/21665168/71866e7ad6e5a05b23fd60428f85cd10_7823192415336553234.gif", + "备注": "", + "x_pos": -373, + "y_pos": -323.65154320955844 + }, + "78": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/22/21665168/39f430abbe7752eada6dc15def179673_4999401363991100229.gif", + "备注": "依旧藏在石头后面。", + "x_pos": -365.5, + "y_pos": -372.799327897862 + }, + "77": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/22/21665168/0abed4019490b4d62ee8c9ab95081e62_1473567454678905132.gif", + "备注": "在悬崖下面的柱子里面。", + "x_pos": -718, + "y_pos": -603.5033757923725 + }, + "76": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/21/76373921/bbfc98b30998c376635f2a650e932a5c_2878748680097205899.gif", + "备注": "", + "x_pos": -1051, + "y_pos": -550.8450886389103 + }, + "75": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/22/21665168/f3b1c42035332aece6c2d8e0fc52ac8c_4590034539054074685.gif", + "备注": "藏在蜿蜒曲折的缝隙里", + "x_pos": -988, + "y_pos": -383.715308176593 + }, + "74": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/22/21665168/b741824da2cc7f48ac03aeb0b162932f_716139821476978575.gif", + "备注": "藏在岩石后面打碎就可以了。ps:用大剑更快", + "x_pos": -436.5, + "y_pos": -56.40435254944828 + }, + "73": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/22/21665168/40dcfa29e6a95032669980ddf431f429_3066257973500691506.gif", + "备注": "", + "x_pos": -680.5, + "y_pos": 3.9137221096414123 + }, + "72": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/22/21665168/0a8113bc80edfb9df12d6c52af5adc72_8276835375016036277.gif", + "备注": "需要上我们的凯亚帮忙造一下冰面。", + "x_pos": -468, + "y_pos": 661 + }, + "71": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/21/76373921/fea71fe3a9a065ea04a8b3dedb98fbc3_344345432348298655.gif", + "备注": "", + "x_pos": 944.6556222741219, + "y_pos": 985.8949736466393 + }, + "70": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/21/76373921/7daea163f3a01639e2e174205b601d41_1009418490777707416.gif", + "备注": "", + "x_pos": 707, + "y_pos": 1110 + }, + "68": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/21/76373921/eae317417f4f8f41f5e0761154dff2c3_1051702848344068202.gif", + "备注": "", + "x_pos": 676.7465709616163, + "y_pos": 691.9680729950956 + }, + "67": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/19/76373921/c11468205f7e8f2683b6786fd5374e4d_6411278277336054186.gif", + "备注": "", + "x_pos": 652.6421721161123, + "y_pos": 317.02097672776245 + }, + "66": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/19/76373921/953d887f091578a372338dd52b17864c_8645806874444553189.gif", + "备注": "", + "x_pos": 516, + "y_pos": 256.5 + }, + "65": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/22/21665168/0e562f909aac898137df61b1edaab709_4557505565462303841.gif", + "备注": "开启风场就可以飞上去 了~", + "x_pos": -59, + "y_pos": 471 + }, + "64": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/22/21665168/0a6d434b69945b3164024d33b78bdde0_5832839350587041734.gif", + "备注": "虽然风瞳在最上面但是要到最下面激活风碑飞上去。", + "x_pos": -559, + "y_pos": -332.7168085287585 + }, + "63": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/22/21665168/49de0265432412ea9d39c0f7cc2fa5c1_2206156493334154654.gif", + "备注": "", + "x_pos": -771.5, + "y_pos": 124.5 + }, + "62": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/22/21665168/c85777858ff14bf01e2561609ee8093f_23517194600674915.gif", + "备注": "就在草丛中间√", + "x_pos": -559, + "y_pos": -125.34358828674476 + }, + "61": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/22/21665168/f1ff4286ba10bf3de8bfdfc667118ddf_6175207438281676259.gif", + "备注": "激活风系尖碑开启风场获取,也可以顺便把相邻下方的风神瞳一并获取。", + "x_pos": -74.5, + "y_pos": -340 + }, + "60": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/22/21665168/9299ae1982dc3cc9a1086b2c11086184_8578846124513791350.gif", + "备注": "", + "x_pos": -23.5, + "y_pos": -243.5 + }, + "59": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/10/14/76373921/e1c8e427dec9c27113767a97789f2c5d_4665036776404972414.gif", + "备注": "", + "x_pos": 356, + "y_pos": -585.5 + }, + "58": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/21/76373921/452d016e62949afc1c717c35eb7bf170_7767005666218883453.gif", + "备注": "", + "x_pos": 1438, + "y_pos": -334 + }, + "56": { + "属性": "风神瞳", + "gif_url": "https://uploadstatic.mihoyo.com/ys-obc/2020/09/21/76373921/cbd63e9fbb00160b045dafc424c1657f_1299454333660281584.gif", + "备注": "", + "x_pos": 1922.0018670150284, + "y_pos": 683.9995073891628 + } +} \ No newline at end of file diff --git a/resources/img/genshin/texture2d/UI_EmotionIcon5.png b/resources/img/genshin/texture2d/UI_EmotionIcon5.png new file mode 100644 index 00000000..cefe8925 Binary files /dev/null and b/resources/img/genshin/texture2d/UI_EmotionIcon5.png differ diff --git a/resources/img/genshin/texture2d/ba.png b/resources/img/genshin/texture2d/ba.png new file mode 100644 index 00000000..4167908b Binary files /dev/null and b/resources/img/genshin/texture2d/ba.png differ diff --git a/resources/img/genshin/texture2d/bar.png b/resources/img/genshin/texture2d/bar.png new file mode 100644 index 00000000..6a18255b Binary files /dev/null and b/resources/img/genshin/texture2d/bar.png differ diff --git a/resources/img/genshin/texture2d/bg_1.jpg b/resources/img/genshin/texture2d/bg_1.jpg new file mode 100644 index 00000000..d74a58b7 Binary files /dev/null and b/resources/img/genshin/texture2d/bg_1.jpg differ diff --git a/resources/img/genshin/texture2d/cover.png b/resources/img/genshin/texture2d/cover.png new file mode 100644 index 00000000..63638182 Binary files /dev/null and b/resources/img/genshin/texture2d/cover.png differ diff --git a/resources/img/genshin/texture2d/default_ava.png b/resources/img/genshin/texture2d/default_ava.png new file mode 100644 index 00000000..dd30e1fe Binary files /dev/null and b/resources/img/genshin/texture2d/default_ava.png differ diff --git a/resources/img/genshin/texture2d/earth.png b/resources/img/genshin/texture2d/earth.png new file mode 100644 index 00000000..bec1f3ca Binary files /dev/null and b/resources/img/genshin/texture2d/earth.png differ diff --git a/resources/img/genshin/texture2d/h.png b/resources/img/genshin/texture2d/h.png new file mode 100644 index 00000000..c68e2a64 Binary files /dev/null and b/resources/img/genshin/texture2d/h.png differ diff --git a/resources/img/genshin/texture2d/l.png b/resources/img/genshin/texture2d/l.png new file mode 100644 index 00000000..92492a60 Binary files /dev/null and b/resources/img/genshin/texture2d/l.png differ diff --git a/resources/img/genshin/texture2d/level.png b/resources/img/genshin/texture2d/level.png new file mode 100644 index 00000000..15561957 Binary files /dev/null and b/resources/img/genshin/texture2d/level.png differ diff --git a/resources/img/genshin/texture2d/level2.png b/resources/img/genshin/texture2d/level2.png new file mode 100644 index 00000000..9bc7dbd9 Binary files /dev/null and b/resources/img/genshin/texture2d/level2.png differ diff --git a/resources/img/genshin/texture2d/luoxuan.png b/resources/img/genshin/texture2d/luoxuan.png new file mode 100644 index 00000000..5ec57368 Binary files /dev/null and b/resources/img/genshin/texture2d/luoxuan.png differ diff --git a/resources/img/genshin/texture2d/p1.png b/resources/img/genshin/texture2d/p1.png new file mode 100644 index 00000000..913593f7 Binary files /dev/null and b/resources/img/genshin/texture2d/p1.png differ diff --git a/resources/img/genshin/texture2d/staron.png b/resources/img/genshin/texture2d/staron.png new file mode 100644 index 00000000..96a2f449 Binary files /dev/null and b/resources/img/genshin/texture2d/staron.png differ diff --git a/resources/img/genshin/texture2d/wind.png b/resources/img/genshin/texture2d/wind.png new file mode 100644 index 00000000..402fc9ed Binary files /dev/null and b/resources/img/genshin/texture2d/wind.png differ diff --git a/resources/img/genshin/texture2d/wlevel.png b/resources/img/genshin/texture2d/wlevel.png new file mode 100644 index 00000000..fb3e4391 Binary files /dev/null and b/resources/img/genshin/texture2d/wlevel.png differ diff --git a/resources/img/other/laopo.jpg b/resources/img/other/laopo.jpg new file mode 100644 index 00000000..163aa951 Binary files /dev/null and b/resources/img/other/laopo.jpg differ diff --git a/resources/img/other/luxun.jpg b/resources/img/other/luxun.jpg new file mode 100644 index 00000000..8b10eaf6 Binary files /dev/null and b/resources/img/other/luxun.jpg differ diff --git a/resources/img/other/shop.png b/resources/img/other/shop.png new file mode 100644 index 00000000..d7597426 Binary files /dev/null and b/resources/img/other/shop.png differ diff --git a/resources/img/zhenxun.jpg b/resources/img/zhenxun.jpg new file mode 100644 index 00000000..cccd123c Binary files /dev/null and b/resources/img/zhenxun.jpg differ diff --git a/resources/ttf/msyh.ttf b/resources/ttf/msyh.ttf new file mode 100644 index 00000000..aa23ae1f Binary files /dev/null and b/resources/ttf/msyh.ttf differ diff --git a/resources/ttf/wq.ttf b/resources/ttf/wq.ttf new file mode 100644 index 00000000..f15cfefc Binary files /dev/null and b/resources/ttf/wq.ttf differ diff --git a/resources/ttf/yz.ttf b/resources/ttf/yz.ttf new file mode 100644 index 00000000..d150b537 Binary files /dev/null and b/resources/ttf/yz.ttf differ diff --git a/resources/ttf/yzz.ttc b/resources/ttf/yzz.ttc new file mode 100644 index 00000000..d150b537 Binary files /dev/null and b/resources/ttf/yzz.ttc differ diff --git a/resources/txt/cookie/buff.txt b/resources/txt/cookie/buff.txt new file mode 100644 index 00000000..d19596a5 --- /dev/null +++ b/resources/txt/cookie/buff.txt @@ -0,0 +1 @@ +1-k1y3pbawuKxciXrC8YLuBp9k9H44PTYBxhxQKLifSx-C2046478249 \ No newline at end of file diff --git a/resources/txt/yulu.txt b/resources/txt/yulu.txt new file mode 100644 index 00000000..81b4973c --- /dev/null +++ b/resources/txt/yulu.txt @@ -0,0 +1,563 @@ +人生就是一列开往坟墓的列车,路途上会有很多站,很难有人可以至始至终陪着走完。 + 我也很没用,但是两个人一起的话,就会变得很坚强。 + 你给不了我想要的东西,活在自己的世界里的付出没意义。 + 我喜欢雨,因为它带来天空的味道。 + 如果你是魔女,我只要化身为魔王就可以了。 + 或许前路永夜,即便如此我也要前进,因为星光即使微弱也会为我照亮前途。 + 曾经发生过的事情不可能忘记,只不过是想不起而已。 + 永远也不要忘记能够笑的坚强 =) + 看吧,星星只有在夜里才璀璨夺目啊。 + 错的不是我 错的是这个世界。 + 虽然迷茫与痛苦过,但也曾天真的笑过。 + 无法舍弃两个方中的任何一方,那不是温柔,那不过是软弱罢了。 + 被大家所依赖的人,在自己受伤的时候往往只能独自面对痛苦。 + 这个世界从来不曾对任何人温柔,与其诅咒黑暗,不如燃起蜡烛。 + 我不知道离别的滋味是这样凄凉,我不知道说声再见要这么坚强。 + 痛苦,是保持清醒的最好方式。 + 我只能送你到这里了,剩下的路你要自己走,不要回头。 + 自己来选择,不会后悔的路,——利威尔。 + 人老的唯一好处就是,少了的东西越来越少了。 + 能原谅女人谎言的才是真正的男人。 + 你原本打算吃掉我,所以就算被我吃掉,也没资格抱怨吧。 + 远的不是距离,而是次元啊。 + 我回来了,从轮回的尽头。 + 没有期待就没有失望,没有羁绊就不会受伤。 + 失败的人只有一种,就是在抵达成功之前放弃的人。 + 你说你会爱我一辈子,我真傻,居然忘了问“是这辈子还是下辈子” + 木叶飞舞之处,火亦生生不息。 + 对不起,我对活一千年没有兴趣,我只要今天能活着就好。 + 时间不会冲淡痛苦,时间只会让人习惯痛苦。 + 我们仰望着同一片天空却看着不同的地方。 + “转瞬即逝的相逢与离别,每一个瞬间,我都想要珍惜, + 世上所有的不公平 都是因为当事者的能力不足造成的。 + 一如既往,孤独相伴,万千纷扰,与我何干。 + 曾经发生过的事不可能忘记,只是想不起来了。 + 很奇怪,我忘记了我自己的名字,但是千寻的名字我却一直都记得。 + 我很好奇,阎王爷的生死簿上可有他自己的名字! + 立誓今生尊你为王,用我热血为你封疆。 + 我情愿在你的记忆里淡忘,也不愿你为我受伤。 + 没有第二把刀的人,是没有资格成为杀手的。 + 王来承认,王来允许,王来背负整个世界。 + 比起不做而后悔,不如做了再后悔。 + 你的愿望,我确实听到了,一岐日和, 汝为有缘人。 + 弱者,连死的方式都无从选择。 + -烦恼着迷惑着痛苦着,而最后得到的答案却简单到让我不禁想笑出来。 + 即便再悲伤也要勇敢活下去,这是人类的诅咒,但一定,也是一种祝福。 + 天若无能制裁邪恶,我等将会于黑暗之中给予消逝----- + 没必要的事就不做,必要的事就尽快做。 + 与其伤害别人,我宁愿被伤害。 + 如果结果不如你所愿 就在尘埃落定前奋力一搏。 + 做不到的事情就不要轻易答应人。 + 我不是天生的王者 但我骨子里流动着不让我低头的血液。 + 人正是因为度过了一段阴暗岁月,才会更渴求黎明的曙光。 + 自己来选择,不会后悔的道路。 + 你没听过这句伟大的名言么?“肚子饿了就要吃!。 + 只要有你想要保护的东西,那就拔剑好了。 + 事情总是突然的,而理由总是事后面加上去的。 + 不知所措,才是人生。 + 一举一动,都是承诺,会被另一个人看在眼里,记在心上的。 + 一悲一喜一枉然,一草一木一红颜。 + Yes,my lord. + 干燥的空气,尘埃的味道,我在其中…踏上旅途。 + 迷茫时,坚定地对自己说,当时的梦想,我还记得。 + 只要有你在,我就无所不能。 + 我是一个经常笑的人,可我不是经常开心的人。 + 不相信自己的人 连努力的价值都没有。 + 一点都不可怕的对手其实才是最恐怖的敌人。 + 回忆这东西毫无意义,我不是已经证明了吗。 + 就算是对我抱有敌意的人,也是被某个人深爱着而降生在这个世界上的。 + 无常索命,厉鬼勾魂。 + 我再也不要看见她哭的样子了,就算我从此从她心目中消失。 + 生命可以随心所欲,但不能随波逐流。 + 他喜欢她,无关爱情,她幸福了,于是他也幸福了。 + 温柔正确的人总是难以生存,因为这世界既不温柔,也不正确。 + 奇迹不是免费的,如果你祈求了希望,也会散播出同等的绝望。 + 时间能冲淡痛苦,但是,我并不想用时间来治愈一切。 + 你驻足于春色中,于那独一无二的春色之中。 + 那些口口声声为了别人的家伙,基本上其实都是为了自己。 + 每次我最痛苦的时候你总是能看透我的心,虽然很不甘心,但是我好高兴。 + 世上并没有绝对的善与恶,差别只在于强者和无法分清事实的弱者。 + 这世上所有的不利状况,都是当事者能力不足导致的。 + 解开它,试试的话也许能行,但是,不尝试的话就绝对办不到。 +“如果下雨了,你愿意留下吗?”,“即使不下雨,我也在这里啊, + 孤独的人不会伤害别人,只会不断地伤害自己罢了。 + 没有光明是不幸的吗?需要光明才是真正的不幸。 + 我的愿望是,将一位少女拥入怀中,而拯救世界,只不过是顺带罢了。 + 没有被杀的觉悟,就没有杀戮的资格。 + 世界这么大,人生这么长,总会有这么一个人,让你想要温柔的对待。 + 人永远不知道,谁哪次不经意的跟你说了再见之后,就真的不会再见了。 + 这个世界里没有什么规则,就算有,那也是由我创造的。 + 其实美丽的故事都是没有结局的,只因为它没有结局所以才会美丽。 + 喜欢你,因为我喜欢你,比世界上的任何一个人都喜欢你。 + 一旦拒绝了信仰,就不能再踏入神的大门。 + 在我感到艰辛痛苦的时候,给予我支持的,是大量的虚构故事。 + 我们仰望著同一片天空却看著不同的地方。 + 不胜,则亡,但,不战,就不会胜利。 + I do not know go where,but I have been on the road.,我不知道将去何方,但我已在路上。 + 无论你期望或者不期望,清晨依旧来临。 + 我是什么人没必要告诉你,正如我从来没问过你是什么人。 + 有些烦恼,丢掉了,才有云淡风轻的机会。 + 要让一群人团结起来,需要的不是英明的领导,而是共同的敌人。 +有些事,记得不如忘了好。《白蛇·缘起》 +大声的笑出来,就不害怕了。《龙猫》 +荣耀之路,是没有止境的。《全职高手》 +红姬啼鸣孰解意,蛇尾惊风虎吼疾。《死神》 +喝他喝过的酒,受他受给伤。《魔道祖师》 +别人的梦想,你少给我插手!《银河奥特曼》 +常如风起,人生不可弃。《起风了》 +光再美,怎如初见。《未闻花名》 +要代表月亮,消灭你们!《美少女战士》 +崇拜,是距离理解最远的感情。《死神》 +我们的征途是星辰大海。《银河英雄传说》 +能收拾那个女孩的,只有我!《银魂》 +艾伦,有你,我什么都能。《进击的巨人》 +你特别好,我喜欢你。《魔道祖师》 +美丽,然而却令人有些不安。《择天记》 +我绝不会让你再死一次了。《镇魂街》 +什么都没有了,连病都没有了。《择天记》 +熊大熊二,光头强又来砍树了。《熊出没》 +繁叶散尽,重融泥土,生生不息。《K》 +大家都是奇怪而普通的。《意外的幸运签》 +想要确定,想要相连,其实很害怕吧。《K》 +手握神杖的不是神明,是教宗。《择天记》 +光头强,我的木头呢。《熊出没》 +别太逞强,别忘了你还有我。《足球小将》 +清醒地活着,或者清醒地死去。《择天记》 +若合我意,一切皆好。《文豪野犬》 +我只是在练习,跟你说再见。《死神》 +燃烧吧,小宇宙!《圣斗士星矢》 +会努力就是最棒的才能啊!《元气囝仔》 +我马上就去,跑着去。《穿越时空的少女》 +转世重生,今生定不负你!《妖神记》 +鱼。你看,又闪了一下。《龙猫》 +是非在己,毁誉由人。《魔道祖师》 +心在哭泣,眼睛却流不出泪水。《寄生兽》 +这次我绝不逃避,直面一切给你瞧瞧。《K》 +呔,好你个妖精。《葫芦娃》 +不知所措,才是人生。《海贼王》 +树木和人类曾经是很好的朋友。《龙猫》 +尊的赤,是最美丽的,赤。《K》 +我早就忘了,该如何开心的笑了。《黑执事》 +这个世界上,没有什么是理所当然的!《K》 +不可能,爱就是责任。《镇魂街》 +起风了,唯有努力生存。《起风了》 +谢谢你来过我的世界。《萤火之森》 +我不要变成你的包袱!《侧耳倾听》 +看的开一点,伤得就会少一点。《龙猫》 +那些言语中的,复杂思考。《死神》 +接受别人的爱,有时确实很沉重。《银魂》 +吾王礼司,剑统万宗。《K》 +有情若无情,相见不如不见。《择天记》 +到了最后,只有相信自己。《网球王子》 +勿因未候日光暖,擅自轻言世间寒。《K》 +爱上他,不如先习惯他!《红猪》 +邪魔,现形吧!《十二生肖守护神》 +未待旭日,不可语寒。《K》 +爱不是一句话,只是一个动作。《千与千寻》 +现实是给那些缺乏想象力的人的。《龙猫》 +安啦,安啦,船到桥头自然直。《K》 +生不由己,不如不生。《镇魂街》 +你将来愿意嫁给我吗?《侧耳倾听》 +远行之路,有朋相伴,便无畏惧。《K》 +千言万语,不当一默。《择天记》 +我在未来等你,且行且珍惜。《千与千寻》 +心存善意,定能途遇天使。《龙猫》 +系君千里行,心系君之名。《你的名字》 +起风了,我们还要努力活下去。《起风了》 +以剑制剑,我等大义无霾。《K》 +我变强了,也秃了。《一拳超人》 +小学生真是太棒了!《萝球社》 +错的不是我,是这个世界!《反叛的鲁鲁修》 +金属易断,人心亦然。《文豪野犬》 +凡是战斗的人,才能取得胜利。《武庚纪》 +宁欺千金裘,莫惹下三流。《少年歌行》 +喜欢,但是无限接近于爱。《橙路》 +我,很努力的在这边活过了。《刀剑神域》 +有目标,才能向着目标前进。《择天记》 +生命是黑暗中闪烁的光。娜乌西卡《风之谷》 +我果然是个天才!《灌篮高手》 +人各有命,上天注定。《镇魂街》 +来到这世上真是太好了。《悬崖上的金鱼姬》 +努力是不会背叛自己的,虽然梦想会背叛。 +努力不一定能实现梦想,但是曾经努力过的事实却足以安慰自己。 +现实中,有人幸福,就必定有人被抛弃,有人光鲜,就必须有人满身泥泞。 +“努力”是这个世界上最虚伪的东西之一,是成功者的借口,是失败者的安慰。然而不幸的是,努力却又是必须的,是即使明知会血本无归也不得不付出的投资。 +所谓孤零零指的不是周围的人口密度,而是指个人的精神层面了。就算别人离你再近,要是不能感觉和自己是同一种生物,那么干涸的心也得不到满足。 +要变得坚强。如果很软弱的话,终有一日会连悲鸣都无法发出,活得像行尸走肉一般。 +当对自己抱有信心的时候,不该轻易说出期待,期待是放弃后才能说的话,只得如此,别无他法,如果没有这种无奈只显得矫情。 +有才能的人如果对自己的才能毫无自觉的话,那么会让没有才能的人觉得无比讽刺。 +对自己有自信时,不能对人说「期待」。所谓的「期待」是放弃时的托词,因为别无选择。若缺少这种无奈感,说这个词就太虚伪了。 +有一天,你到了人类的世界,不要去爱上一个人, 因为,爱上一个人, 会让你真正变成孤单一人。 +送走人间种种别离,送走世间种种变迁,逝者如斯,时光永远不会止步,所以,我们会再度与人萍水相逢,相识相知,一同织下我们的人生。 +只要在这里,你就不是孤身一人。昔日织会记下,那些漠然被岁月消磨的记忆,那些不得不别过的人儿,也会在昔日织里,与你执手相看泪眼。 +是你教会了我:悲痛的事,温柔以对; 难过的事,坚强以对。 +从失败中吸取教训就是这样的,但是大多数人只把它挂在嘴边,根本就不学,以此为借口忘掉失败。 +无论栖于清流,还是栖于浊流,只要向前游终究可以成为美丽的鱼。 +眼泪,有时候是一种无法言说的幸福。微笑,有时候是一种没有说出口的伤痛。 总会有一次流泪,让我们瞬间长大。 +“喜欢就像是风吹过大海的声音.” +“如果你愿意听,每一句都是我爱你.” + “想要循环你的心跳,也想回放你的傻笑.” +“记得她在信纸上为我写的每个字,却再也没有见过她一次.” +生命可以随心所欲,但不能随波逐流。——森田宏幸《猫的报恩》 +我不知将去何方,但我已经在路上。——宫崎骏《千与千寻》 +我们仰望同一片天空,却看着不同的地方。——新海诚《秒速五厘米》 +时间带着明显的恶意,在我身上缓缓流逝。——新海诚《秒速五厘米》 +有思念你的人在的地方,就是你的归处。——《火影忍者》 +不要停止奔跑,不要回顾来路,来路无可眷恋,值得期待的只有前方。——《马男波杰克》 +如果结果并非所愿,那就在尘埃落定前奋力一搏。(夏目贵志《夏目友人帐》) +我们终会相知,在那悠远的苍穹。 +马上,春天就要来了,与你相遇的春天,一个没有你的春天。——《四月是你的谎言》 +我觉得你很幸运,因为你可以选择爱我或不爱我,而我只能选择爱你或更爱你。——《日在校园》 +如果能在六十亿分之一的概率下与你相遇,即使你那时候你还是身体无法动弹,我也会和你结婚。 —— 《Angel Beats》 +早苗阿姨说过,能哭的地方只有厕所和爸爸的怀里。——《CLANNAD》 +秒速五厘米,那是樱花飘落的速度,那么怎样的速度才能走完我与你之间的距离?——《秒速五厘米》 +愿你有一天能和你最重要的人再次相遇!——《可塑性记忆》 +我愿为你带上罪恶之冠,即使背负.上所有的罪恶和孤独,也绝不让你受伤。——《罪恶王冠》 + 明明想要杀死某种生物,自己却没有做好被杀死的准备,你不觉得这种想法很奇怪么?——时崎狂三《约会大作战》 + 我们每天度过的称之为日常的生活,其实是一个个奇迹的连续也说不定。《日常》 + 与其有闲琢磨如何漂亮死去,还不如漂亮的活到最后一刻。《银魂》 + 我是要成为海贼王的男人啊ヽ(`Д´)ノ~路飞《海贼王》 +拥有被杀的觉悟,才有开枪的权利。」——鲁鲁修《反叛的鲁鲁修》 +朱雀,你要成为英雄,从世界的敌人皇帝鲁路修·V·不列颠尼亚手中拯救世界的救世主,成为 Zero。这也是对你的惩罚,你必须作为正义的使者戴着面具活下去,不用在作为枢木朱雀,也必须为世界牺牲承认该有的幸福,永远-----《叛逆的鲁鲁修》 +这是你若不能理解的,人类感情的极致,比希望更热烈,比绝望更深邃的——爱啊!——晓美焰《魔法少女小圆—叛逆的物语》 +我们只是活着就已经竭尽全力了。《银魂》 + 我们终会相知,在那悠远的苍穹。by《缘之空》 + 零食就是正义!——紫原敦《黑子的篮球》 + 来吧!颤抖吧!惊叹吧!绝望吧!放声大哭吧!我的艺术就是——————爆炸!———《火影忍者》迪达拉 + 我觉得你很幸运,因为你可以选择爱我或不爱我,而我只能选择爱你或更爱你。——桂言叶《日在校园》 + 我终于明白了,你并不是因为命令或者身为 Servant 来保护我,而是出于自身意志,保护了我啊———伊莉亚《Fate stay night》 + 把已经失去的东西重新变得有意义的职业只有两个,作家和侦探。只有作家才能在梦想中将其复活,只有侦探才能将其从坟墓中挖掘出来还原成信息。---爱丽丝《神的记事本》 +「不抵抗就不会死,为什么你就是不明白!」——卡缪·维丹《机动战士 Z 高达》 +「没有什么大不了」这句话,只有当事者才有资格说——《悠久之翼》 +「我——撒了一个谎,宫园薰,喜欢渡亮太的,这样的一个谎。这个谎把你——有马公生君,命运般地带到了我的面前。」马上,春天就要来了,与你相遇的春天,一个没有你的春天.《四月是你的谎言》 + 如果这是你的希望的话, 我就随你到天涯海角吧. 即使王座崩坏, 金光闪闪的王冠腐朽, 数之不尽的尸体堆积如山, 我会留在静静横卧的, 小小的王的身边, 直到将军的声音响起, 之时.《黑执事》 +"谢谢你们! 比谢谢更加的谢谢!"--真白《樱花庄的宠物女孩》 +"悲伤也是会有的, 倒不如说尽是这样的事, 可正是如此我们才更需要前进, 令人唾弃的事由我们来做, 剩下的就去改变世界吧! 塔兹米! 用你炽热的灵魂呐喊吧!"--布兰德《斩赤红之瞳》 + 能哭的地方,只有厕所,和爸爸的怀里。—《clannad》 + 谁都无法相信未来,谁都无法接受未来。——晓美焰《魔法少女小圆》 + 隐约雷鸣,阴霾天空,但盼风雨来,能留你在此。《言叶之庭》 + 要得到幸福的话,就需要与之相应的努力,也就是代价。不是经常说人生是正负和零么!有好事也有痛苦的事,有痛苦的事也有好事。不过这是错的。为了变得幸福,作为代价,必须背负与其同等的不幸。也就是说为了好事情,必须要忍受坏事情。所谓有痛苦的事就有好事什么的,并不是含有乐观意味的话。反过来说,在高的地位上的话,对工作就有相应的高要求对吧。要是不能满足这种高要求就是不诚实的人。再进一步反过来说,要把自己置于不幸中的话,自己就必须放弃一定程度的努力。——壹原侑子《xxxHolic》 + 这样被诅咒的人生,怎么能接受呢。ー仲村由理《angelbeats》 + 人类这种生物,有时候是连短短的十分钟也等不起的!———仲村由理《Angel Beats!》 + 惟愿, 你与你所处的这个世界, 今后也如此幸福。——黑桐干也《空之境界》 + 你要是没有胜算的话,就由我来创造胜算,尝试一切可能的方法。---Saber《Fate stay night》 + 面麻最喜欢仁太了…对仁太的喜欢…是想成为仁太新娘的那种喜欢~《未闻花名》 +有树叶飞舞的地方,就会有火在燃烧,火的意志照耀着村子,就会有更多的树叶发芽,他们会承载着火的意志,把信念带向远方。——《火影忍者》 +雪,只要落下便已是此生的尽头,唯有融化消失,然而,即使飞舞着上升,最后仍不忘落下的那颗种子。虽然有些虚幻,却比什么都坚强。我啊-----虽然 绝对算不上什么优秀,但至少,希望能像雪一般,变得坚强起来。----《至少像雪那样》 +所谓的觉悟、就是在黑暗的荒野中开辟前行的道路—乔鲁诺乔班纳《JOJO 的奇妙冒险》 +即使这份感情是虚假的,这也是我唯一的真实。楪祈《罪恶王冠》 +因为我是天才嘛!——樱木花道《灌篮高手》 +教练,我想打篮球。三井寿《灌篮高手》 +没有痛苦相伴的教训是毫无意义的,因为、人倘若不牺牲些什么,就什么也不可能得到。但是,当直面这些痛苦、克服它们的时候,人将获得不输给任何事物的坚韧的心。没错,钢铁一般的心。——爱德华《钢之炼金术师》 + 雪为什么是白色的?因为它们忘记了自己本身的颜色……C.C《反叛的鲁路修》 + 你的所言所行,全都闪烁着光芒,太过刺目,于是我闭上双眼,但内心还是无法停止对你的憧憬。——《四月是你的谎言》 +「何等失态,罪该万死」———提耶利亚《高达 OO》 + 那个……其实啊,我想说的是,就算我死了,你也要努力活下去。活下去,看着这个世界直到最后,请帮我找出创造这个世界的意义,像我这样的胆小鬼来到这个世界的意义,还有我跟你相遇所代表的意义。——幸《刀剑神域》 + 一个人才会混乱的吧,即使是在黑暗中,只要有个人和自己一起走的话,就会安心很多,也一定会找到答案的。——《TrueTears》 + 我错了,善良没有任何意义 渣滓必须受到歧视 我... 要成为王——樱满集《罪恶王冠》 + 如果每个人都能为自己所爱的事情付诸努力,那崭新的地方定是梦想的终点---《LOVE LIVE》 +-莫扎特曾经说过大胆地踏上旅途吧,我不知道路途的前方究竟有什么,但是,我们还是迈出了步伐,我们仍在旅途之中。——有马公生《四月是你的谎言》 + 我可是货真价实的萝莉控,我对女性的好球带是 7 岁到 12 岁 也就是说。。。我只把小学女生当成异性 虽然有时年龄会往下修正,可是绝对不会往上调整 真是的,小学生真是太棒了!---安藤寿来《日常系的异能战斗》 + 萝莉控不是病,是人生态度啊!安藤寿来《日常系的异能战斗》 + 我不能喝酒,请给我一杯橙汁。户愚吕弟《幽游白书》 + 所谓的王者,就是要活的比任何人都要耀眼,成为万民敬仰的存在。伊斯坎达尔《Fate Zero》 + 如果能在六十亿分之一的概率下次与你相遇,即使你那时候你还是身体无法动弹,我也会和你结婚。」——日向秀树《AngelBeats!》 + 我想知道,为何世界如此扭曲,这份扭曲又从何产生。为何人类要支配被支配,又是为何人类要如此悲哀的活着.《高达》 + 瞬间的犹豫可是会丧命的,所以我决不会犹豫。——夏尔《黑执事》 + 1000 减 7 等于多少?---金木研《东京喰种》 + 总有一天我会让这里座无虚席!——高坂穗乃果《LoveLive!》 + 大家的背后,由我来守护!--西谷夕《排球少年》 + 我讨厌温柔的女孩子。温柔的女孩子其实对所有人都温柔,我却会误以为只对我温柔,然后就沾沾自喜得意忘形,最后闹得不欢而散,双方都受到伤害。——所以我才讨厌温柔的女孩子。《我的青春恋爱物语果然有问题》 + 我们总是在意错过了多少,却不注意自己拥有多少。——《未闻花名》 + 没有未来的未来不是我想要的未来!----神原秋人《境界的彼方》 + 人没有牺牲就没有获得, 如果要获得什么就必须付出同等的代价, 那就是炼金术的等价交换的原则。《钢之炼金术师》 + 男人变态有什么错!---前原圭一《寒蝉鸣啼之时》 + 苦难算什么,我本来就喜欢走在修罗之路上--索隆《海贼王》 + 只要是活着的,就是神也杀给你看––两仪式《空之境界》 + 你不是一个人,我们是共犯。如果你是魔女的话,我只要成为魔王就可以了吧。《叛逆的鲁鲁修》 + 大家回答我 为什么要低头,重复一遍 为什么要低头,我们是弱者!现在如此 过去也如此!是的 不是什么都没有改变吗!强者模仿弱者夺来的武器 是无法发挥出其真正的力量的,要说为什么的话 我们的武器本质在于,那弱小到悲屈的软弱啊!我在此强调,我们是弱者!我们宣誓作为弱者活下去,像弱者一样战斗然后已弱者的方式消灭强者!就像过去一样 今后也会贯彻到底!承认吧 我们是最弱的种族!正因为我们天生什么都没有,所以才能驾驭一切的,最弱的种族!----空《no game no life》 +"是我太愚蠢了,虽然只有一瞬间,我竟然想和你厮守一生。"---桔梗《犬夜叉》 + 不能逃避,不能逃避,不能逃避。—碇真嗣《EVA》 + 人类最强的武器就是刀和叉-《美食的俘虏》 + 初见幽灵现真身,始知其为枯芒草。《冰菓》 + 你不是牺牲了自己的一切,养育我到今天了吗?为了我这样没出息的儿子,耗费了自己的一生。已经足够了!---冈崎朋也《CLANNAD》 + 关于自己的生活,我和你都不是读者,而是作者。至少结局,还是能自己说了算的。――银桑《银魂》 + 即使交不到 100 个朋友也没有关系,只要交到一个比 100 个朋友更重要的朋友。——《我的朋友很少》 + 无论发生了什么,也不要后悔与我相遇。《CLANNAD AFTER STORY》 +前路永夜,即便如此我也要前进,因为星光即使微弱也会为我照亮前途。《四月是你的谎言》 + 能原谅女人谎话的————才是男人!香吉士《海贼王》 + 有个器官比我的心脏还重要,虽然我看不见它,但是它确实在我的体内,因为有它我才能站的直,就算步履蹒跚也能笔直往前走。如果我不去的话,它可是会拦腰折断的,我的灵魂它会拦腰折断的。比起心脏停止跳动,我更重视它。坂田银时《银魂》 + 群聚的都是弱者。弱小的草食动物才喜欢群聚。《家庭教师》 + 遥远的不是距离,而是次元啊!---安艺伦也《路人女主的养成方法》 + 亚丝娜,我的命是你的——桐谷和人《刀剑神域》 +「即使是走过无数次的路,也能走到从未踏足过的地方,正因为是走过无数次的路,景色才会变幻万千,光是这样还不足够吗?因为只是这样,所以才不足够吗?」——函南优一《空中杀手》 + 错的不是我,而是这个世界。《東京喰种》 + 时间可以冲淡一切,但,我並不想用时间来磨平伤口。《黑执事》 + 爱德:「等价交换,我的人生给你一半,所以你的人生也给我一半。」温迪:「哈.. 你是笨蛋啊?」爱德:「你说什么?」温迪:「别说一半,全部都给你呀!」——《钢之炼金术师 FA》 + 不要哀求,学会争取若是如此,终有所获。——阿德洛克•萨斯顿《交响诗篇》 + 秒速 5 厘米,那是樱花飘落的速度,那么怎样的速度,才能走完我与你之间的距离?——《秒速五厘米》 + 一切都是 Steins Gate 的选择!《命运石之门》 + 可能会有迷茫的時候,也可能会有因为不如意而觉得烦躁的时候。无论是谁都会遇到低谷,但只有跨越低谷的人才能得到大家的认可。《花开物语》 + 剑本凶器,剑术是杀人术,这是无法用语言掩饰的。为了断这之间的宿命,正是这把逆刃剑的使命——不杀之誓《浪客剑心》 + 明明感觉距离很近 但伸手却又抓不到 即使这样 即使望尘莫及 亦有留在心中的东西 曾身处同一时间层 曾仰望过同一样东西 只要记着这些 就算相互远离 也依然可以相信我们还是同在 现在要不停蹦跑 只要目标远大 总有一天 会赶上那目标《fate/stay night》 + 把绫波,还给我! 我变成怎么样无所谓,世界变成怎样也无所谓,但是绫波,至少她一个人,我一定要救出来!——碇真嗣《eva:破》 + 没必要的事不做,必要的事尽快做。---折木奉太郎《冰菓》 + 招待不周——《食戟之灵》 + 就算悲伤难抑,遍体鳞伤的处于谷底,也不能停下演奏,只有这样我们才是真正活着的。-你真的可以忘记么?-----《四月是你的谎言》 + 这个世界上没有偶然,有的只是必然」——壹原侑子《xxxholic》 + 苦恼着,歇斯底里着,痛苦着,不断挣扎的数月时间,这一切会在未来的某一瞬间得到回报。我们或许就是被那个瞬间迷住的,一种无可救药的生物吧。——《四月是你的谎言》 + 艾伦,只要有你在,我就无所不能。——三笠《进击的巨人》 + 把手伸向不属于人类领域的愚者啊……天上天下只有一人有资格欣赏你的破灭,除了我吉尔伽美什别无他人。耀眼而虚幻的人啊,投入我的怀抱吧。这就是我的决定。——吉尔伽美什《fate stay night》 + 人类的赞歌就是勇气的赞歌!——《jojo 的奇妙冒险》 + 藏好了吗?----《未闻花名》 + 我喜欢你。对君之爱,胜于世上万千,思君之意,亙古如斯,唯有这份心意不输给任何人。纵使此身魂去魄散,消失离散于世间,若有来生,我心依旧。---五更琉璃《我的妹妹不可能那么可爱》 +什么也无法舍弃的人,就什么也无法改变。埃尔文斯密斯《进击的巨人》 +恐惧不是犯罪,它能让人感觉到自己的弱小,认识到弱小之后,人才能变得温柔和坚强。——《妖精的尾巴》 +宫园薰:“你会忘记吗?和你一起在学校探险的女孩,和你一起帮助迷路小孩的女孩,从医院跑出来,等在那里的女孩,你会忘记吗?”——《四月是你的谎言》 +黎明前的天是最黑暗的,不过千万别闭眼,因为不敢直视黑暗的人,也看不到明天的第一缕光明。——《银魂》 +这世界上所有的失败都是由于当事者能力不足造成的。——《东京食尸鬼》 +就算颠覆整个宇宙,我也要把你找回来。——《凉宫春日的消失》 +有在了解了自己的无能以后,才能踏上成为高手的道路。——《灌篮高手》 +己喜欢的人未必喜欢自己,人的感情并不是相对的,这才是有趣之处。——《你的名字》 +有人会嘲笑竭尽全力的人。——《家庭教师》 +相信自己的人,连努力的价值都没有。——《火影忍者》 +我一直在想,没有结果的恋爱是否有意义,消逝了的事物和从没有存在过的事物是否相同。现在我明白了,是有意义的,确实有啊,能喜欢上你,真的太好了。——《蜂蜜与四叶草》 +温柔正确的人总是难以生存,因为这个世界既不温柔也不正确。——《我的青春恋爱物语果然有问题》 +虽然不知道是不是适合,但我觉得现在就好,即使发生了很多讨厌的事情,但活在当下就好。——《意外的幸运签》 +人永远不知道,谁哪次不经意的跟你说了再见之后,就真的不会再见了。——《千与千寻》 +正义是用来维持善与恶平衡的东西,若是朝向恶的一方就应该止步并寻找善的道路,这种寻找的行为才是正义,正因如此,神才把智慧赋予了人类。——《龙珠》 +即使再怎么勉强,再怎么不自量力,再怎么厚颜无耻,也要用自己的双手,保护最珍惜的东西。——《魔法禁书录》 +那些来者不拒,去者不追的人,该是有多孤独啊。——《人渣的本愿》 +生活在战斗中的人只有两条路可以选,不是变强就是死亡,当他选择苟延残喘度过余生这条道路的时候,他就已经死了。——《幽游白书》 +起风了,唯有努力生存。——《起风了》 +解救自己软弱的,一定不是眼泪,而是打破现实的决心。——《网球王子》 +反正担心和不担心结果都是一样的,既然这样,光担心的话不是很吃亏吗?——《樱桃小丸子》 +人的眼睛之所以要长在前面,是为了要向前看。——《哆啦A梦》 +不论是我或是其他任何人,都不是为了死亡而存在,而是为了活下去而活着。——《刀剑神域》 +坚强不是面对悲伤不流一滴泪,而是擦干眼泪后微笑着面对以后的生活。——《风之谷》 +这世界上也许有人喜欢孤独,但没有人可以承受孤独。——《妖精的尾巴》 +所谓的朋友就是,不管是误入歧途还是犯了罪过都要一起走下去一起背负,这才是真正的朋友啊!——《男子高中生的日常》 +除去不可能的因素,留下的不管多么的不合情理,那也一定就是事实的真相。——《名侦探柯南》 +命运的红线一旦断了,就再也接不上了。——《犬夜叉》 +只要你的心是善良的,对错都是别人的事。——《大鱼海棠》 +为什么重要的东西总是在察觉到的时候就已经失去了。——《无头骑士异闻录》 +努力只是完成结果的过程,如果以结果本身为荣的话,就本末倒置了。——《笨蛋测试召唤兽》 +当你无法在拥有的时候,你唯一能做的就是不要忘记。——《龙猫》 +真正重要的东西,总是没有的人比拥有的人更清楚。——《银魂》 +什么都无法舍弃的人,就什么都改变不了。——《进击的巨人》 +真正痛苦的事不是不能向人求助,而是没有一个可以求助的人吧。——《寒蝉鸣泣之时》 +除了死亡,所有的离开都是背叛。——《黑执事》 +只要有想见的人,就不再是孤身一人了。——《夏目友人帐》 +其实美丽的故事都是没有结局的,但因为它没有结局才会美丽。——《萤火之森》 +或许存在本身,就毫无意义可言。——《死亡笔记》 +一个人的死,对于这个世界来说不过是多了一座坟墓,但对于相依为命的人来说,却是整个世界都被坟墓掩埋。——《海贼王》 +要么变强改变世界,要么一直做被伤害的人。——《东京食尸鬼》 +看清一个人何必去揭穿,讨厌一个人又何必翻脸,活着,总有看不惯的人,就如别人看不惯我们。——《NANA》 +人类之所以会失败,是因为有“羞耻”之心。——《JOJO奇妙冒险》 + 为了爱,人类能够非常温柔,也能非常坚强!不杀一只小虫,不折一枝花,这样度过一生的人实在没有。人不是神,所以不管是那么善良的人也会无意间做点坏事。这就是生活。为了生活只能这么做。——《圣斗士星矢》 +世界上没有所谓永恒的东西。——《数码宝贝》 +思念的人所在的地方,就是你的归宿。——《火影忍者》 +隐约雷鸣,阴霾天空,即使天无雨,我亦留此地。——《言叶之庭》 +大部分人不想长大,只是没办法继续当一个小孩子。——《小林家的龙女仆》 + 虚伪的眼泪会伤害别人,虚伪的笑会伤害自己。——《叛逆的鲁路修》 +有时候你不吃点苦头,就永远看不***相。——《恶童》 +万物有界,爱恨无由。——《狐妖小红娘》 +真相如果是残酷的话,那么谎言,一定就是温柔的了,所以那份温柔,便是谎言 ——大老师 我的青春恋爱物语果然有问题 +也许我没有什么天赋,唯有斗志,我绝不会输给任何人。 ——艾伦·耶格尔 进击的巨人 +自己来选择,不会后悔的道路。 ——利威尔·阿克曼 进击的巨人 +你死后的星空依旧耀眼, 可我却觉得黯淡无光。 ——斩·赤红之瞳 +无限接近于零,却又不等于零的可能性。 ——游戏人生 +正因为生来什么都没有,因此我们能拥有一切。 ——游戏人生 +究竟要怎样 ,才能将这份爱意铭刻在你心上? ——DEAREST DROP 末日时在做什么?有没有空?可以来拯救吗? +只要那一抹笑容尚存,我便心无旁骛。 ——声之形 +以声之色,塑以花之形 。 ——声之形 +想看看大海, 想爱上一个人, 即使是怪兽, 也有心啊。 ——声之形 +我从小就有疑问,为什么我会是我而不是别人呢? ——乙坂有宇 charlotte +这个世界上,有很多事是可以靠时间冲淡的,虽然也有一些连时间也无可奈何。——麻枝准 charlotte +谁都无法制裁一件没有发生过的事。 ——绫小路清隆 欢迎来到实力至上主义的教室 +如果全世界都否定你的话,那么我就要超过他们更加的肯定你! ——五河士道 约会大作战 +会站起来的,为了你的话,即使千百次也会站起来。 ——时崎狂三 约会大作战 +不要让我们共度的美好时光成为我独自一人的回忆。 ——Re:从零开始的异世界生活 +我记得他的样子,我不知道他的名字。 ——椿 大鱼·海棠 +美丽的并非这个世界,而是接受了这个世界的你的眼睛。 ——吸血鬼骑士 +请和我一起去寻找那看不见的东西吧。 ——声之形 +或许前路永夜,即便如此我也要前进,因为星光即使微弱也会为我照亮前路。 ——宫园薰 四月是你的谎言 +你驻足于春色中,于那独一无二的春色之中 ——有马公生 四月是你的谎言 +这世上所有的不公平都是因为当事人能力的不足。 ——石田スイ 东京食尸鬼 +如果我闭上了双眼,看到的是黑暗的话,那么当我睁开眼睛去看这个世界的时候,是否会是一片光明? ——金木研 东京食尸鬼 +命运就像一条长河,而我们众生皆是水里的鱼。也许强大的人可以轻易改变一条鱼,乃至一群鱼的命运,但你记住,无论是谁,都改变不了这条河的流向。 ——wlop 鬼刀 +黑白圣堂血天使,天剑鬼刀阿修罗 ——wlop 鬼刀 +这个世界也许充满丑恶,贪婪,愚昧,自私,但也请坚信,无论在你多落寞的时候,也总会有一个天使,在你身后! ——wlop 鬼刀 +描线一笔接着一笔,白色的素描本上渐渐萌生黑意,即便如此,还是无法照准记忆中的风景。 ——你的名字 +一只狮子率领的羊群,可以打败一只羊率领的狮群。 ——游戏人生 +即使走投无路,没有任何希望,只要还能嘶声力竭地呐喊,就可以不靠别的,只凭纯粹的信念走下去,那么,这不就是所谓的“梦想”吗? ——我的青春恋爱物语果然有问题 + 灯光一点点亮起来,为我照亮前行的方向,若是能照亮我未来的方向就好了,不是现在的这个自己,而是指引我找到更优秀的自己。 ———花开伊吕波 +即使在再怎么勉强,再怎么不自量力,再怎么厚颜无耻,也要用自己的双手,保护最珍惜的东西。 ——魔法禁书目录 +仿佛快要像消殒般孱弱,却拼命发着光,咚咚,咚咚,如同心跳一般,这是,生命之光。 ――――四月是你的谎言 +谁都不可能和谁在一起一辈子,人就是这样,必须去习惯失去。――――秒速五厘米 +聚拢,成形,捻转回绕,时而返回,暂歇,再联接,这就是组纽,这就是时间,这就是结。 ――――你的名字 +什么都无法舍弃的人,什么都无法改变。 ――――进击的巨人 +温柔、正确的人总是难以生存,因为这世界既不温柔也不正确。 ――――我的青春恋爱物语果然有问题 +真正的危机不是机器人像人一样思考,而是人想机器一样思考。 ――――凉宫春日的忧郁 +你觉得被圈养的鸟儿为什么无法自由地翱翔天际?是因为鸟笼不是属于它的东西。 ――――东京喰种 +人之所以会照顾其他生物,是因为人类会感到空虚,之所以会想保护环境,是因为人类不想被环境毁灭。 ――――寄生兽 +没有未来的未来不是我想要的未来。《境界的彼方》 +如果真爱有颜色,那么一定是蓝色。《RE:从零开始的异世界生活》 +你指尖跃动的电光,是我此生不灭的信仰。《某科学的超电磁炮》 +愿你有一天能和重要的人重逢。《可塑性记忆》 +为王的诞生献上礼炮。《罪恶王冠》 +以声之名,塑花之形,将你之名,刻于我心。《声之形》 +立于浮华之世,奏响天籁之音。《Angel Beats!》 +万剑穿心终不悔,相视一笑轻王权。《狐妖小红娘》 +或许前路永夜,即便如此我也要前进,因为星光即使微弱也会为我照亮前路/此生无悔入四月,来世愿做友人A。《四月是你的谎言》 +这一切都是命运石之门的选择。《命运石之门》 +末将于禁,愿为曹家世代赴汤蹈火!《镇魂街》 +今天的风儿有些喧嚣啊。《男子高中生的日常》 +我大德意志的科学技术世界第一。《JOJO》 +错的不是我,错的是世界。《反叛的鲁鲁修》 +都是时臣的错。《Fate/Zero》 +一本正经地胡说八道。《约会大作战》 +我不需要什么伙伴,玩游戏的是我本人,有棋子的话就够了。——夏尔(黑执事) +真相永远只有一个!——江户川柯南\工藤新一 (名侦探柯南) +错的不是我 错的是这个世界。——金木研 (东京喰种) +世界上有些事,还是让它永远成为谜比较好。——黑羽快斗 (名侦探柯南) +梦想是否无聊并不是别人来决定的,不管是什么样的梦想,自己拼命努力去追寻才是最重要的!——日奈森亚梦 (守护甜心) +如果说我比别人看得更远些,那是因为我站在了巨人的肩膀上。——利威尔 (进击的巨人) +就算是对我抱有敌意的人,也是被某个人深爱着而降生在这个世界上的。——樱满集 (罪恶王冠) +希望和失望总是牵着手来到你面前,如果你害怕,失望就会变得巨大,最后吞噬了希望,如果你勇赶面对, 就能改变困境。每个人的内心都有一颗星星,无论什么时侯都要让内心的星星放出光芒。 ——月野兔 (美少女战士) +幻觉,有幻觉。幻觉中潜伏着有幻觉,有幻觉中孕育而生的幻觉。真实中包含着谎言,谎言中潜藏着真实,这就是雾。——六道骸 (家庭教师) +我不是英雄,我只做我想做的事,保护我想要保护的人而已。——路飞 (海贼王) +将过去和羁绊全部丢弃,不要吝惜那为了梦想流下的泪水。——路飞 (海贼王) +只要有你在,我就无所不能。——三笠·阿克曼 (进击的巨人) +天才的字典里,没有不可能这三个字。——樱木花道 (灌篮高手) +我不管你是谁,只要打扰我睡觉,绝不原谅! ——流川枫 (灌篮高手) +命运的红线一旦断了,就再也接不上了。——桔梗 (犬夜叉) +我永远也不会忘记那个忘记我的存在的人。——桔梗 (犬夜叉) +你的命是我的,我绝对不会把你的命交给别人的。 ——桔梗 (犬夜叉) +总躲在自己的角落里 是什么都改变不了的。——《火影忍者》 +痛苦的时候要是不能在一起,那还能叫伙伴吗!——乌索普《海贼王》 +人的梦想是永远不会结束的!——黑胡子《海贼王》 +此时此刻,我竟不知究竟是悲伤,还是快乐。——端木蓉《秦时明月》 +虚弱的笑声是康复的标志。——樱桃小丸子《樱桃小丸子》 +不要害怕遭到欺骗,因为这世界就建筑在欺骗之上。——日番谷冬狮郎《死神》 +“连接遥远的过去与未来,我们为此而存在……”——进藤光《棋魂》 +痛苦可以成为两人间的某种牵绊。——草灯《LOVELESS》 +不幸的人总是在创造比自己更不幸的人。——露西·哈特菲利亚《妖精的尾巴》 +人的怨恨是无止尽的。——阎魔爱《地狱少女》 +对别人抱有期待,只能让自己受伤。——松前绪花《花开伊吕波》 +不能了解到彼此的痛楚,就无法亲身感受。——塞巴斯蒂安·米卡利斯《黑执事》 +能原谅女人的谎话的,才是男人。——山治《海贼王》 +要是喜欢一个人,就要连那个人脏的地方一起喜欢。——坂田银时《银魂》 +如果爱,请深爱,千万不要松手;若不爱,请放开,千万不要回头。——市丸银《死神》 +一定要保护自己的梦想,即使牺牲一切。——大崎娜娜《NANA》 +不相信自己的人,连努力的价值都没有。——凯《火影忍者》 +要想成为强者,就不要回避心里的恐惧!——葛聂《秦时明月》 +追逐梦想的人比抓住梦想的人更能发挥实力啊!——冲田总悟《银魂》 +我一直都想证明:努力是能够超越天才的!——李洛克《火影忍者》 +活下去的意志是最强的力量!——绯村剑心《浪客剑心》 +想哭的时候能哭出来,也是一种坚强。——法伊·D·佛罗莱特《翼·年代记》 +我可是不到最后不轻言放弃的男人。——三井寿《灌篮高手》 +我,不能再次同样的失败了……——C.C.《反叛的鲁路修》 +不管夜晚多么黑暗,黎明总是会到来。——夏莉·菲内特《反叛的鲁路修》 +我不管这个世上的人怎么说我,我只想依照我的信念做事,绝不后悔,不管现在将来都一样!——罗罗亚·索隆《海贼王》 +梦想是否无聊并不是别人来决定的,不管是什么样的梦想,自己拼命努力去追寻才是最重要的!——日奈森亚梦—《守护甜心》 +这个宇宙整体的真理就是无常,没有所谓的完全的正义与完全的邪恶。——沙加《圣斗士星矢》 +因为失去,所以明白。——旗木卡卡西《火影忍者》 +世界上有些事,还是让它永远成为谜比较好。——黑羽快斗《名侦探柯南》 +在这个世界里(地狱),只要灵魂不灭,就不会死。所以,只要心不认输,就不会输。——麻仓叶《通灵王》 +什么都无所谓只想在你身边,什么都无所谓只想和你说话,什么都无所谓所以请你不要逃避。——风早翔太《好想告诉你》 +如果爱,请深爱,千万不要松手; 若不爱,请放开,千万不要回头。——市丸银《死神》 +因为有亲情的牵绊,一旦失去就会痛。——佐助《火影忍者》 +人在了解了什么是爱的时候,也就同时背负上了憎恨。——佐助《火影忍者》 +人,都是依靠自己的感知和认知来认识这个世界,但也被之束缚的生活着的,那就叫做现实,可是感知和认知是暧昧不清的东西,现实也许也只是镜花水月,人都是活在自己的自我意识中的,你不这么认为吗?——鼬《火影忍者》 +时间能冲淡痛苦,但我并不指望时间的慰疗。——夏尔(黑执事) +在这个世界,能受到诅咒的种族,就只有人类了。——科穆伊《驱魔少年》 +如果抛弃了怨恨的话,那天之后的我就不存在了。——夏尔(黑执事) +是努力还是放弃,只有一种选择,人类能选择的,无论何时都只有这两条路,只有诚实地说出自己的心情,接下来就要看对方的决定了,是努力还是放弃,这时就轮到他们选择了。——花本修司《蜂蜜与四叶草》 +自己的伤自己承受,只要依然活着,伤总有一天还是会好的。——李娜莉《驱魔少年》 +一旦失去的东西,就再也拿不回来了。——夏尔(黑执事) +生命只有一个,也是只有一次的东西,你不觉得因此,生命才是无法动摇,闪耀而尊贵的东西吗? ——天秤座童虎《圣斗士星矢》 +当你想做一件事,却无能为力的时候,是最痛苦的。——基拉·大和《高达SEED》 +能哭的地方除了厕所还有爸爸的怀里。——冈崎汐《CLANNAD》 +身不动,能否退去黑暗,花与水。——冲田总司《新撰组异闻录》 +谁都…无法成为谁的替代。所以心痛,总是伴随着离别的人。——玖兰枢《吸血鬼骑士》 +不要害怕遭到欺骗,因为这世界就建筑在欺骗之上。——日番谷冬狮郎《死神》 +有些事情,可以理解但无法接受!——阿斯兰·萨拉《机动战士高达Seed》 +人像花这样的娇弱而不坚强,即使可以保持着外表躲避风雨,但仍然恋着阳光,暴风雨来临时,无论多么华丽的外表都无法遮挡。——灰原哀 +无论身边围着多少人,我永远都是那么孤独。——鸣海步《推理之绊》 +闭上眼睛想象世界,我能看到什么?——亚连·沃克《驱魔少年》 +迷茫不仅会害了自己,甚至会害了自己想要守护的人。——”相泽虹一《隐之王》 +我觉得你比我幸福,因为你可以选择爱我或不爱我,而我只能选择爱你或更爱你。——《schooldays》 +女孩也好男孩也好外貌也好,人类最重要的不是内在吗?——藤冈春绯《樱兰高校男公关部》 +要是眼睁睁的看着重要的同伴死去,就算是死,我也不能瞑目。——泽田纲吉《家庭教师HitmanReborn》 +人究竟什么时候会死,是心脏被枪打中的时候?不对。得到不治之症吗?也不对。喝了剧毒蘑菇汤之后吗?当然不是。而是被世人遗忘的时候。就算我消失了,我的梦想还是会实现的,那个梦想一定能拯救这个国家人们的心病。——希鲁鲁克《海贼王》 +哪里有你的地方,哪里就是我的家。——克罗诺《圣枪修女》 +人是不能阻止时间流逝的,如果硬是要逆天而行的话,就会收到惩罚。——灰原哀 +我早就闭上了双眼,我的目的只在于黑暗之中。——宇智波佐助《火影忍者》 +我,不能再次同样的失败了……——C.C.《反叛的鲁路修》 +即使是坠入绝望的深渊,只要有能往上爬的蜘蛛丝就不会放弃紧紧抓住,人类拥有这份坚强。——夏尔(黑执事) +我想成为一个温柔的人,因为曾被温柔的人那样对待,深深了解那种被温柔相待的感觉。——绿川幸《夏目友人帐》 +“转瞬即逝的相逢与离别,每一个瞬间,我都想要珍惜。”——夏目贵志《夏目友人帐》 +可是只要一旦被谁爱上了的话,或者一度爱过谁的话,就再也忘不了了啊。——露神《夏目友人帐》 +彼方为谁,无我有问 +九月露湿,待君之前 +——新海诚《你的名字》 +假如我们相遇,肯定一眼就能认出彼此。——宫水三叶《你的名字》 +或许前路永夜,即便如此我也要前进,因为星光即使微弱也会为我照亮前路。——宫园薰《四月是你的谎言》 +你驻足于春色中,于那独一无二的春色之中。——有马公生《四月是你的谎言》 +知识不能替代友谊,比起失去你,我宁愿做个白痴 。——派大星《海绵宝宝》 +只要我还能再看到你一次,我就能跟你说我有多爱你。——海绵宝宝《海绵宝宝》 +如果时光可以倒流 我还是会选择认识你 虽然会伤痕累累 但是心中的温暖记忆是谁都无法给与的 谢谢你来过我的世界。——绿川幸《萤火之森》 +一定,有段时间,无法再盼望夏天了,心若刀绞,泪水夺眶而出。 +然而,留在手中的温暖与夏日的回忆,都将永远伴随我。——萤《萤火之森》 +梦想是一个天真的词,实现梦想是一个残酷的词。——藤子·F·不二雄《哆啦A梦》 +“我想一直在你身边,直到你不需要我的时候。”——《哆啦A梦》 +他的眼里有星辰大海,是骑士触不可及的光芒。——安迷修《凹凸世界》 +你说大海是世界上最美丽的蓝,那是你没有见过他的眼睛。——《凹凸世界》 +人就是这样 越是没有实力越爱说大话 世界上只有没有实力的人 才整天希望别人赞赏。—— 卡卡西《火影忍者》 +“活着本来没有什么意义 但是只要活着 就可以找到 有趣的事情。就像你发现了花 我又发现了你一样”。——大蛇丸《火影忍者》 +人因为有难忘的记忆而变得坚强,这就是所谓的成长吧。——纲手《火影忍者》 +为了爱,人类能够非常温柔,也能非常坚强!不杀一只小虫,不折一枝花,这样度过一生的人实在没有。人不是神,所以不管是那么善良的人也会无意间做点坏事。这就是生活。为了生活只能这么做。——雅典娜《圣斗士星矢》 +伤痕,是男子汉的勋章。——车田正美《圣斗士星矢》 +护吾之人,显其名。——夏目贵志《夏目友人帐》 +我们的孤独就像天空中漂浮的城市,仿佛是一个秘密,却无从述说。——宫崎骏《天空之城》 +越是试着忘记,越是记得深刻。——宫崎骏《天空之城》 +如谷之歌,扎根土里。与风共存,与种子越冬,与鸟歌颂。——宫崎骏《天空之城》 +很多事情都是命中注定的,就好像你会遇到什么样的人,经历什么样的伤痛,最终如何离开这个世界,没什么能改变命运。——宫崎骏《天空之城》 +有时候,坚持了你最不想干的事情之后,便可得到你最想要的东西。——宫崎骏《天空之城》 +我爱你是因为你比我更像我自己。——宫崎骏《天空之城》 +我忽然有些恍惚,恍惚到自己也忘却了和她在一起发生过什么,似乎那些已经被时光所淹没的过去,只不过是一场打了麻药的手术,虽然有一丝丝痛楚,却并不那么真实。——宫崎骏《天空之城》 +我的孤独就像天空中飘浮的城市 仿佛是一个秘密 却无从述说。——宫崎骏《天空之城》 +不管前方的路有多苦,只要走的方向正确,不管多么崎岖不平,都比站在原地更接近幸福。——宫崎骏《千与千寻》 +我不知道离别的滋味是这样凄凉,我不知道说声再见要这么坚强。——宫崎骏 《千与千寻》 +人永远不知道,谁哪次不经意的跟你说了再见之后,就真的不会再见了。——宫崎骏《千与千寻》 +曾经发生过的事情不可能忘记,只不过是想不起而已。——宫崎骏《千与千寻》 +已经走到尽头的东西,重生也不过是再一次的消亡。就像所有的开始,其实都只是一个写好了的结局。——宫崎骏《千与千寻》 +人们常常会欺骗你,是为了让你明白,有时候,你唯一应该相信的人就是你自己。——宫崎骏《千与千寻》 +一条路不能回头,就是一生要走许多路,有成长之路。很多事情不能自己掌控,即使再孤单再寂寞,仍要继续走下去,不许停也不能回头。——宫崎骏《千与千寻》 +这个世界真的很现实,每个人都在为着同一个目的,不惜一切代价努力着,心甘情愿的成为金钱的奴隶,死心蹋地的付出。——宫崎骏《千与千寻》 +你不会遇到第二个我、友情也好、爱情也罢。——宫崎骏《千与千寻》 +不要吃太胖噢,会被杀掉的!——宫崎骏《千与千寻》 +我只能送你到这儿了,剩下的路你要自己走,不要回头。——宫崎骏《千与千寻》 +生活坏到一定程度就会好起来,因为它无法更坏。努力过后,才知道许多事情,坚持坚持,就过来了。——宫崎骏《龙猫》 +有些烦恼,丢掉了,才有云淡风轻的机会。——宫崎骏《龙猫》 +什么时候我们开始无法像孩子一样肆意地大呼小叫了?心里的小情绪堆积得像山一样高,直到溢出来。 与其如此,不如永远像孩子一样。——宫崎骏《龙猫》 +如果把童年再放映一遍,我们一定会先大笑,然后放声痛哭,最后挂着泪,微笑着睡去。——宫崎骏《龙猫》 +有时我沉默,不是不快乐,只是想把心净空。有时候你需要退开一点,清醒一下,然后提醒自己,我是谁,要去哪里。——宫崎骏《龙猫》 +当一个胖纸没有什么不好,最起码可以温暖其他的人。——宫崎骏《龙猫》 +人生的某些障碍,你是逃不掉的。与其费尽周折绕过去,不如勇敢的地攀越,或许这会铸就你人生的高点。——宫崎骏《龙猫》 +不要害怕孤独。因为这个世界上,肯定有一个人,正努力的走向你。——宫崎骏《龙猫》 +当你无法在拥有的时候,你唯一能做的就是不要忘记。——宫崎骏《龙猫》 +也许生存在世间的人们都只是在等待一种偶遇,一种适时的相遇,时间对了,你们便会遇上。——宫崎骏《龙猫》 +不管你曾经被伤害得有多深,总会有一个人的出现,让你原谅之前生活对你所有的刁难。——宫崎骏《幽灵公主》 +到不了的地方都叫做远方,回不去的世界都叫做家乡,我一直向往的却是比远方更远的地方。——宫崎骏《幽灵公主》 +命运是任何人也无法改变的,但他可以决定是等死还是面对。——宫崎骏《幽灵公主》 +你说你会爱我一辈子,我真傻,居然忘记了问是这辈子还是下辈子。——宫崎骏《幽灵公主》 +我们的生命太短,来不及见证那些遥远到令人恍惚的词语,比如,天长地久。——宫崎骏《幽灵公主》 +世界这么大,人生这么长,总会有这么一个人,让你想要温柔地对待。——宫崎骏《哈尔的移动城堡》 +对不起,你一直在等我,但是我却现在才来。——宫崎骏《哈尔的移动城堡》 +在茫茫人海中相遇相知相守无论谁都不会一帆风顺,只有一颗舍得付出懂得感恩的心才能拥有一生的爱和幸福。——宫崎骏《哈尔的移动城堡》 +爱,不是寻找一个完美的人,而是学会用完美的眼光,欣赏那个并不完美的人。 +因为爱你,只要你一个肯定,我就足够勇敢。——宫崎骏《哈尔的移动城堡》 +以后我给你造个移动的房子好不好?上面挂满气球,可以飞到天涯海角。房子可以很小,但足够住下你和我。——宫崎骏《哈尔的移动城堡》 +由比滨结衣是个温柔的女孩,我如此擅自地贴上了标签。 —— 大老师 diff --git a/resources/voice/dinggong/01_你这家伙,找块豆腐一头撞死算了!_.mp3 b/resources/voice/dinggong/01_你这家伙,找块豆腐一头撞死算了!_.mp3 new file mode 100644 index 00000000..f25790e7 Binary files /dev/null and b/resources/voice/dinggong/01_你这家伙,找块豆腐一头撞死算了!_.mp3 differ diff --git a/resources/voice/dinggong/02_你还是老老实实定个闹钟起床啊!干吗每次都非要我来叫醒你嘛。_.mp3 b/resources/voice/dinggong/02_你还是老老实实定个闹钟起床啊!干吗每次都非要我来叫醒你嘛。_.mp3 new file mode 100644 index 00000000..18954677 Binary files /dev/null and b/resources/voice/dinggong/02_你还是老老实实定个闹钟起床啊!干吗每次都非要我来叫醒你嘛。_.mp3 differ diff --git a/resources/voice/dinggong/03_吵死了吵死了吵死了!真是吵死了!_.mp3 b/resources/voice/dinggong/03_吵死了吵死了吵死了!真是吵死了!_.mp3 new file mode 100644 index 00000000..6d29f656 Binary files /dev/null and b/resources/voice/dinggong/03_吵死了吵死了吵死了!真是吵死了!_.mp3 differ diff --git a/resources/voice/dinggong/04_ 是我选的你,你可别以为是你给了我机会哦!_.mp3 b/resources/voice/dinggong/04_ 是我选的你,你可别以为是你给了我机会哦!_.mp3 new file mode 100644 index 00000000..afb7a487 Binary files /dev/null and b/resources/voice/dinggong/04_ 是我选的你,你可别以为是你给了我机会哦!_.mp3 differ diff --git a/resources/voice/dinggong/05_什么“早安”,应该说“您早上好”才对!_.mp3 b/resources/voice/dinggong/05_什么“早安”,应该说“您早上好”才对!_.mp3 new file mode 100644 index 00000000..0b09ba71 Binary files /dev/null and b/resources/voice/dinggong/05_什么“早安”,应该说“您早上好”才对!_.mp3 differ diff --git a/resources/voice/dinggong/06_你可别胡思乱想_.mp3 b/resources/voice/dinggong/06_你可别胡思乱想_.mp3 new file mode 100644 index 00000000..29bc6d0b Binary files /dev/null and b/resources/voice/dinggong/06_你可别胡思乱想_.mp3 differ diff --git a/resources/voice/dinggong/07_我才不是特地为你做的。_.mp3 b/resources/voice/dinggong/07_我才不是特地为你做的。_.mp3 new file mode 100644 index 00000000..07e96425 Binary files /dev/null and b/resources/voice/dinggong/07_我才不是特地为你做的。_.mp3 differ diff --git a/resources/voice/dinggong/08_ 接、接吻什么的,你还早了100年呢!_.mp3 b/resources/voice/dinggong/08_ 接、接吻什么的,你还早了100年呢!_.mp3 new file mode 100644 index 00000000..35f02f54 Binary files /dev/null and b/resources/voice/dinggong/08_ 接、接吻什么的,你还早了100年呢!_.mp3 differ diff --git a/resources/voice/dinggong/09_… 哭…我的胸部…_.mp3 b/resources/voice/dinggong/09_… 哭…我的胸部…_.mp3 new file mode 100644 index 00000000..24aa0d92 Binary files /dev/null and b/resources/voice/dinggong/09_… 哭…我的胸部…_.mp3 differ diff --git a/resources/voice/dinggong/10_要是你受伤的话,岂不是会让我很头疼。_.mp3 b/resources/voice/dinggong/10_要是你受伤的话,岂不是会让我很头疼。_.mp3 new file mode 100644 index 00000000..2d06a4fc Binary files /dev/null and b/resources/voice/dinggong/10_要是你受伤的话,岂不是会让我很头疼。_.mp3 differ diff --git a/resources/voice/dinggong/11_你这个笨蛋!_.mp3 b/resources/voice/dinggong/11_你这个笨蛋!_.mp3 new file mode 100644 index 00000000..af73364a Binary files /dev/null and b/resources/voice/dinggong/11_你这个笨蛋!_.mp3 differ diff --git a/resources/voice/dinggong/12_再见之类的话,我才懒得对你说…_.mp3 b/resources/voice/dinggong/12_再见之类的话,我才懒得对你说…_.mp3 new file mode 100644 index 00000000..af12b9b2 Binary files /dev/null and b/resources/voice/dinggong/12_再见之类的话,我才懒得对你说…_.mp3 differ diff --git a/resources/voice/dinggong/13_我才没有为你担心!_.mp3 b/resources/voice/dinggong/13_我才没有为你担心!_.mp3 new file mode 100644 index 00000000..b0875626 Binary files /dev/null and b/resources/voice/dinggong/13_我才没有为你担心!_.mp3 differ diff --git a/resources/voice/dinggong/14_我、我可不是因为自己喜欢才打扮成这样…只有在你面前罢了…_.mp3 b/resources/voice/dinggong/14_我、我可不是因为自己喜欢才打扮成这样…只有在你面前罢了…_.mp3 new file mode 100644 index 00000000..352243e8 Binary files /dev/null and b/resources/voice/dinggong/14_我、我可不是因为自己喜欢才打扮成这样…只有在你面前罢了…_.mp3 differ diff --git a/resources/voice/dinggong/15_真是的…笨蛋…_.mp3 b/resources/voice/dinggong/15_真是的…笨蛋…_.mp3 new file mode 100644 index 00000000..b1ac6645 Binary files /dev/null and b/resources/voice/dinggong/15_真是的…笨蛋…_.mp3 differ diff --git a/resources/voice/dinggong/16_尽管放马过来吧!让我打你个落花流水!_.mp3 b/resources/voice/dinggong/16_尽管放马过来吧!让我打你个落花流水!_.mp3 new file mode 100644 index 00000000..3a99930e Binary files /dev/null and b/resources/voice/dinggong/16_尽管放马过来吧!让我打你个落花流水!_.mp3 differ diff --git a/resources/voice/dinggong/17_留在我身边!一辈子!没异议吧!_.mp3 b/resources/voice/dinggong/17_留在我身边!一辈子!没异议吧!_.mp3 new file mode 100644 index 00000000..91e89e86 Binary files /dev/null and b/resources/voice/dinggong/17_留在我身边!一辈子!没异议吧!_.mp3 differ diff --git a/resources/voice/dinggong/18_生日礼物这种东西,我想没有其他人会送给你了吧…_.mp3 b/resources/voice/dinggong/18_生日礼物这种东西,我想没有其他人会送给你了吧…_.mp3 new file mode 100644 index 00000000..cb6286aa Binary files /dev/null and b/resources/voice/dinggong/18_生日礼物这种东西,我想没有其他人会送给你了吧…_.mp3 differ diff --git a/resources/voice/dinggong/19_ hi~_.mp3 b/resources/voice/dinggong/19_ hi~_.mp3 new file mode 100644 index 00000000..1aa14684 Binary files /dev/null and b/resources/voice/dinggong/19_ hi~_.mp3 differ diff --git a/resources/voice/dinggong/20_这个送给你……_.mp3 b/resources/voice/dinggong/20_这个送给你……_.mp3 new file mode 100644 index 00000000..1328bd2d Binary files /dev/null and b/resources/voice/dinggong/20_这个送给你……_.mp3 differ diff --git a/resources/voice/dinggong/21_给我等一下!你这个木头人!_.mp3 b/resources/voice/dinggong/21_给我等一下!你这个木头人!_.mp3 new file mode 100644 index 00000000..27dddc54 Binary files /dev/null and b/resources/voice/dinggong/21_给我等一下!你这个木头人!_.mp3 differ diff --git a/resources/voice/dinggong/22_为什么…_.mp3 b/resources/voice/dinggong/22_为什么…_.mp3 new file mode 100644 index 00000000..5ab7ce85 Binary files /dev/null and b/resources/voice/dinggong/22_为什么…_.mp3 differ diff --git a/resources/voice/dinggong/23_为什么你就是注意不到嘛!_.mp3 b/resources/voice/dinggong/23_为什么你就是注意不到嘛!_.mp3 new file mode 100644 index 00000000..b793ce9a Binary files /dev/null and b/resources/voice/dinggong/23_为什么你就是注意不到嘛!_.mp3 differ diff --git a/resources/voice/dinggong/24_正好顺便,我也邀请一下你吧。_.mp3 b/resources/voice/dinggong/24_正好顺便,我也邀请一下你吧。_.mp3 new file mode 100644 index 00000000..82e28bde Binary files /dev/null and b/resources/voice/dinggong/24_正好顺便,我也邀请一下你吧。_.mp3 differ diff --git a/resources/voice/dinggong/25_就算你不打电话给我,我也没什么寂寞的…_.mp3 b/resources/voice/dinggong/25_就算你不打电话给我,我也没什么寂寞的…_.mp3 new file mode 100644 index 00000000..49efe1ee Binary files /dev/null and b/resources/voice/dinggong/25_就算你不打电话给我,我也没什么寂寞的…_.mp3 differ diff --git a/resources/voice/dinggong/26_别离我这么近…丢死人了…_.mp3 b/resources/voice/dinggong/26_别离我这么近…丢死人了…_.mp3 new file mode 100644 index 00000000..31fb93ac Binary files /dev/null and b/resources/voice/dinggong/26_别离我这么近…丢死人了…_.mp3 differ diff --git a/resources/voice/dinggong/27_那、那家伙干什么嘛!_.mp3 b/resources/voice/dinggong/27_那、那家伙干什么嘛!_.mp3 new file mode 100644 index 00000000..40ee4d75 Binary files /dev/null and b/resources/voice/dinggong/27_那、那家伙干什么嘛!_.mp3 differ diff --git a/resources/voice/dinggong/28_明明已经有我了的说!呜呜…_.mp3 b/resources/voice/dinggong/28_明明已经有我了的说!呜呜…_.mp3 new file mode 100644 index 00000000..01674bcf Binary files /dev/null and b/resources/voice/dinggong/28_明明已经有我了的说!呜呜…_.mp3 differ diff --git a/resources/voice/dinggong/29_别逃,至少听我把话说完!_.mp3 b/resources/voice/dinggong/29_别逃,至少听我把话说完!_.mp3 new file mode 100644 index 00000000..3a848398 Binary files /dev/null and b/resources/voice/dinggong/29_别逃,至少听我把话说完!_.mp3 differ diff --git a/resources/voice/dinggong/30_ 真是的,不管啦笨蛋!!你让人家怎么说嘛!!_.mp3 b/resources/voice/dinggong/30_ 真是的,不管啦笨蛋!!你让人家怎么说嘛!!_.mp3 new file mode 100644 index 00000000..d3908649 Binary files /dev/null and b/resources/voice/dinggong/30_ 真是的,不管啦笨蛋!!你让人家怎么说嘛!!_.mp3 differ diff --git a/resources/voice/dinggong/31_你睡糊涂了吧,干什么呐!_.mp3 b/resources/voice/dinggong/31_你睡糊涂了吧,干什么呐!_.mp3 new file mode 100644 index 00000000..9ddb9f9b Binary files /dev/null and b/resources/voice/dinggong/31_你睡糊涂了吧,干什么呐!_.mp3 differ diff --git a/resources/voice/dinggong/32_你可不许对我说“No”哦_.mp3 b/resources/voice/dinggong/32_你可不许对我说“No”哦_.mp3 new file mode 100644 index 00000000..a1b8b816 Binary files /dev/null and b/resources/voice/dinggong/32_你可不许对我说“No”哦_.mp3 differ diff --git a/resources/voice/dinggong/33_虽然很丢人,让、让、让你牵牵手还是可以容忍…来吧…_.mp3 b/resources/voice/dinggong/33_虽然很丢人,让、让、让你牵牵手还是可以容忍…来吧…_.mp3 new file mode 100644 index 00000000..bd797127 Binary files /dev/null and b/resources/voice/dinggong/33_虽然很丢人,让、让、让你牵牵手还是可以容忍…来吧…_.mp3 differ diff --git a/resources/voice/dinggong/34_睡、睡…睡在我的腿上!?只、只能睡1分钟哦!_.mp3 b/resources/voice/dinggong/34_睡、睡…睡在我的腿上!?只、只能睡1分钟哦!_.mp3 new file mode 100644 index 00000000..4e142a02 Binary files /dev/null and b/resources/voice/dinggong/34_睡、睡…睡在我的腿上!?只、只能睡1分钟哦!_.mp3 differ diff --git a/resources/voice/dinggong/35_唔,今天只有我们两个人的话…_.mp3 b/resources/voice/dinggong/35_唔,今天只有我们两个人的话…_.mp3 new file mode 100644 index 00000000..3bcc8350 Binary files /dev/null and b/resources/voice/dinggong/35_唔,今天只有我们两个人的话…_.mp3 differ diff --git a/resources/voice/dinggong/36_真是拿你没办法呢…_.mp3 b/resources/voice/dinggong/36_真是拿你没办法呢…_.mp3 new file mode 100644 index 00000000..9a76b75a Binary files /dev/null and b/resources/voice/dinggong/36_真是拿你没办法呢…_.mp3 differ diff --git a/resources/voice/dinggong/37_变态、变态、变态、变态、变态笨蛋大变态!!!_.mp3 b/resources/voice/dinggong/37_变态、变态、变态、变态、变态笨蛋大变态!!!_.mp3 new file mode 100644 index 00000000..984b2b22 Binary files /dev/null and b/resources/voice/dinggong/37_变态、变态、变态、变态、变态笨蛋大变态!!!_.mp3 differ diff --git a/resources/voice/dinggong/38_真是的,不管了啦…_.mp3 b/resources/voice/dinggong/38_真是的,不管了啦…_.mp3 new file mode 100644 index 00000000..1c3eddce Binary files /dev/null and b/resources/voice/dinggong/38_真是的,不管了啦…_.mp3 differ diff --git a/resources/voice/dinggong/39_别在那装傻了啦!!真是的_.mp3 b/resources/voice/dinggong/39_别在那装傻了啦!!真是的_.mp3 new file mode 100644 index 00000000..485be4a2 Binary files /dev/null and b/resources/voice/dinggong/39_别在那装傻了啦!!真是的_.mp3 differ diff --git a/resources/voice/dinggong/40_小心我一脚踢飞你!_.mp3 b/resources/voice/dinggong/40_小心我一脚踢飞你!_.mp3 new file mode 100644 index 00000000..eeec9dc3 Binary files /dev/null and b/resources/voice/dinggong/40_小心我一脚踢飞你!_.mp3 differ diff --git a/resources/voice/dinggong/41_啊…也好,既然你坚持要带着…_.mp3 b/resources/voice/dinggong/41_啊…也好,既然你坚持要带着…_.mp3 new file mode 100644 index 00000000..026da2a2 Binary files /dev/null and b/resources/voice/dinggong/41_啊…也好,既然你坚持要带着…_.mp3 differ diff --git a/resources/voice/dinggong/42_我也没办法了呢…_.mp3 b/resources/voice/dinggong/42_我也没办法了呢…_.mp3 new file mode 100644 index 00000000..4be7d90b Binary files /dev/null and b/resources/voice/dinggong/42_我也没办法了呢…_.mp3 differ diff --git a/resources/voice/dinggong/43_所以说我不想给别人看到啊!_.mp3 b/resources/voice/dinggong/43_所以说我不想给别人看到啊!_.mp3 new file mode 100644 index 00000000..08625518 Binary files /dev/null and b/resources/voice/dinggong/43_所以说我不想给别人看到啊!_.mp3 differ diff --git a/resources/voice/dinggong/44_只想给你一个人…_.mp3 b/resources/voice/dinggong/44_只想给你一个人…_.mp3 new file mode 100644 index 00000000..01abb82b Binary files /dev/null and b/resources/voice/dinggong/44_只想给你一个人…_.mp3 differ diff --git a/resources/voice/dinggong/45_不准无视我!快给我道歉!_.mp3 b/resources/voice/dinggong/45_不准无视我!快给我道歉!_.mp3 new file mode 100644 index 00000000..dee1ed9b Binary files /dev/null and b/resources/voice/dinggong/45_不准无视我!快给我道歉!_.mp3 differ diff --git a/resources/voice/dinggong/46_所以说只是从眼睛里流出来的汗啦!_.mp3 b/resources/voice/dinggong/46_所以说只是从眼睛里流出来的汗啦!_.mp3 new file mode 100644 index 00000000..4b5de351 Binary files /dev/null and b/resources/voice/dinggong/46_所以说只是从眼睛里流出来的汗啦!_.mp3 differ diff --git a/resources/voice/dinggong/47_才~不~是眼泪呢!_.mp3 b/resources/voice/dinggong/47_才~不~是眼泪呢!_.mp3 new file mode 100644 index 00000000..c6b21564 Binary files /dev/null and b/resources/voice/dinggong/47_才~不~是眼泪呢!_.mp3 differ diff --git a/resources/voice/dinggong/48_真是的~笨蛋、笨蛋、笨蛋!!_.mp3 b/resources/voice/dinggong/48_真是的~笨蛋、笨蛋、笨蛋!!_.mp3 new file mode 100644 index 00000000..34b91951 Binary files /dev/null and b/resources/voice/dinggong/48_真是的~笨蛋、笨蛋、笨蛋!!_.mp3 differ diff --git a/resources/voice/dinggong/49_不知道、不知道、不知道!_.mp3 b/resources/voice/dinggong/49_不知道、不知道、不知道!_.mp3 new file mode 100644 index 00000000..b446f1fb Binary files /dev/null and b/resources/voice/dinggong/49_不知道、不知道、不知道!_.mp3 differ diff --git a/resources/voice/dinggong/50_才没有吃醋呢,你在说什么傻话啊!_.mp3 b/resources/voice/dinggong/50_才没有吃醋呢,你在说什么傻话啊!_.mp3 new file mode 100644 index 00000000..cc5e8f8e Binary files /dev/null and b/resources/voice/dinggong/50_才没有吃醋呢,你在说什么傻话啊!_.mp3 differ diff --git a/resources/voice/dinggong/51_所以说我最讨厌优柔寡断的家伙了!_.mp3 b/resources/voice/dinggong/51_所以说我最讨厌优柔寡断的家伙了!_.mp3 new file mode 100644 index 00000000..5cdaf551 Binary files /dev/null and b/resources/voice/dinggong/51_所以说我最讨厌优柔寡断的家伙了!_.mp3 differ diff --git a/resources/voice/dinggong/52_才不好呢。_.mp3 b/resources/voice/dinggong/52_才不好呢。_.mp3 new file mode 100644 index 00000000..296af41d Binary files /dev/null and b/resources/voice/dinggong/52_才不好呢。_.mp3 differ diff --git a/resources/voice/dinggong/53_只、只准你看着我哦!_.mp3 b/resources/voice/dinggong/53_只、只准你看着我哦!_.mp3 new file mode 100644 index 00000000..2902c7e2 Binary files /dev/null and b/resources/voice/dinggong/53_只、只准你看着我哦!_.mp3 differ diff --git a/resources/voice/dinggong/54_所以说别做些不正经的事了…对好不容易才和你在一起的我…_.mp3 b/resources/voice/dinggong/54_所以说别做些不正经的事了…对好不容易才和你在一起的我…_.mp3 new file mode 100644 index 00000000..fd0a0c24 Binary files /dev/null and b/resources/voice/dinggong/54_所以说别做些不正经的事了…对好不容易才和你在一起的我…_.mp3 differ diff --git a/resources/voice/dinggong/55_对你说我喜欢你还是不讨厌你什么的_.mp3 b/resources/voice/dinggong/55_对你说我喜欢你还是不讨厌你什么的_.mp3 new file mode 100644 index 00000000..8ae13cf2 Binary files /dev/null and b/resources/voice/dinggong/55_对你说我喜欢你还是不讨厌你什么的_.mp3 differ diff --git a/resources/voice/dinggong/56_拉面都泡糟了啦!快点吃掉啦!_.mp3 b/resources/voice/dinggong/56_拉面都泡糟了啦!快点吃掉啦!_.mp3 new file mode 100644 index 00000000..cbd38279 Binary files /dev/null and b/resources/voice/dinggong/56_拉面都泡糟了啦!快点吃掉啦!_.mp3 differ diff --git a/resources/voice/dinggong/57_诶,让我帮你吹吹?笨蛋啊你~_.mp3 b/resources/voice/dinggong/57_诶,让我帮你吹吹?笨蛋啊你~_.mp3 new file mode 100644 index 00000000..d2bf4353 Binary files /dev/null and b/resources/voice/dinggong/57_诶,让我帮你吹吹?笨蛋啊你~_.mp3 differ diff --git a/resources/voice/dinggong/58_我才没有觉得你很有用呢…_.mp3 b/resources/voice/dinggong/58_我才没有觉得你很有用呢…_.mp3 new file mode 100644 index 00000000..02c09cd0 Binary files /dev/null and b/resources/voice/dinggong/58_我才没有觉得你很有用呢…_.mp3 differ diff --git a/resources/voice/dinggong/59_我才没有很开心呢!_.mp3 b/resources/voice/dinggong/59_我才没有很开心呢!_.mp3 new file mode 100644 index 00000000..6c3a7ba3 Binary files /dev/null and b/resources/voice/dinggong/59_我才没有很开心呢!_.mp3 differ diff --git a/resources/voice/dinggong/60_要多多的和我联系!不然我会担心你的…_.mp3 b/resources/voice/dinggong/60_要多多的和我联系!不然我会担心你的…_.mp3 new file mode 100644 index 00000000..e27d74d8 Binary files /dev/null and b/resources/voice/dinggong/60_要多多的和我联系!不然我会担心你的…_.mp3 differ diff --git a/resources/voice/temp/bd_yysb.wav b/resources/voice/temp/bd_yysb.wav new file mode 100644 index 00000000..53ed2a20 Binary files /dev/null and b/resources/voice/temp/bd_yysb.wav differ diff --git a/services/__pycache__/db_context.cpython-38.pyc b/services/__pycache__/db_context.cpython-38.pyc new file mode 100644 index 00000000..97605bd1 Binary files /dev/null and b/services/__pycache__/db_context.cpython-38.pyc differ diff --git a/services/__pycache__/db_context.cpython-39.pyc b/services/__pycache__/db_context.cpython-39.pyc new file mode 100644 index 00000000..a943fde5 Binary files /dev/null and b/services/__pycache__/db_context.cpython-39.pyc differ diff --git a/services/__pycache__/init_config.cpython-39.pyc b/services/__pycache__/init_config.cpython-39.pyc new file mode 100644 index 00000000..fd1e46bc Binary files /dev/null and b/services/__pycache__/init_config.cpython-39.pyc differ diff --git a/services/__pycache__/log.cpython-38.pyc b/services/__pycache__/log.cpython-38.pyc new file mode 100644 index 00000000..e06a2209 Binary files /dev/null and b/services/__pycache__/log.cpython-38.pyc differ diff --git a/services/__pycache__/log.cpython-39.pyc b/services/__pycache__/log.cpython-39.pyc new file mode 100644 index 00000000..83c2d096 Binary files /dev/null and b/services/__pycache__/log.cpython-39.pyc differ diff --git a/services/db_context.py b/services/db_context.py new file mode 100644 index 00000000..3cf46b2e --- /dev/null +++ b/services/db_context.py @@ -0,0 +1,27 @@ + + +from gino import Gino +from .log import logger +from configs.config import bind, sql_name, user, password, address, port, database + + +# 全局数据库连接对象 +db = Gino() + + +async def init(): + i_bind = bind + if not bind: + i_bind = f"{sql_name}://{user}:{password}@{address}:{port}/{database}" + # print(i_bind) + try: + await db.set_bind(i_bind) + await db.gino.create_all() + logger.info(f'Database loaded successfully!') + except Exception as e: + raise Exception(f'数据库连接错误.... e: {e}') + + +async def disconnect(): + await db.pop_bind().close() + diff --git a/services/init_config.py b/services/init_config.py new file mode 100644 index 00000000..55c6b1f9 --- /dev/null +++ b/services/init_config.py @@ -0,0 +1,159 @@ +# import nonebot +from pathlib import Path +try: + import ujson as json +except ModuleNotFoundError: + import json + +# driver: nonebot.Driver = nonebot.get_driver() + +base_config = Path() / 'config.json' +plugins_cmd_config = Path() / 'configs' / 'plugins2cmd_config.json' +other_config = Path() / 'configs' / 'other_config.json' + + +def init_config(): + if not base_config.exists(): + base_config.parent.mkdir(parents=True, exist_ok=True) + config_dict = { + 'apikey': { + 'LOLICON_KEY': '', + 'TL_KEY': [], + }, + 'sql': { + 'bind': '', + 'sql_name': '', + 'user': '', + 'password': '', + 'address': '', + 'port': '', + 'database': '', + }, + 'path': { + 'IMAGE_PATH': '', + 'VOICE_PATH': '', + 'TXT_PATH': '', + 'LOG_PATH': '', + 'DATA_PATH': '', + 'DRAW_PATH': '', + 'TEMP_PATH': '', + }, + 'proxy': { + 'system_proxy': '', + 'buff_proxy': '' + }, + 'rsshub': { + 'RSSHUBAPP': 'https://docs.rsshub.app/', + }, + 'level': { + 'DELETE_IMG_LEVEL': 7, + 'MOVE_IMG_LEVEL': 7, + 'UPLOAD_LEVEL': 6, + 'BAN_LEVEL': 5, + 'OC_LEVEL': 2, + 'MUTE_LEVEL': 5, + }, + } + with open(base_config, 'w', encoding='utf8') as f: + json.dump(config_dict, f, indent=4, ensure_ascii=False) + if not plugins_cmd_config.exists(): + plugins_cmd_config.parent.mkdir(parents=True, exist_ok=True) + config_dict = { + 'base_config': { + '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': ['原神资源查询', '原神资源列表'], + } + } + with open(plugins_cmd_config, 'w', encoding='utf8') as f: + json.dump(config_dict, f, indent=4, ensure_ascii=False) + if not other_config.exists(): + other_config.parent.mkdir(parents=True, exist_ok=True) + config_dict = { + 'base': { + 'IMAGE_DIR_LIST': ["色图", "美图", "萝莉", "壁纸"], + 'BAN_RESULT': "才不会给你发消息.", + }, + 'bool': { + 'AUTO_ADD_FRIEND': True, + 'DOWNLOAD_SETU': True, + }, + 'probability': { + 'INITIAL_SETU_PROBABILITY': 0.7, + 'FUDU_PROBABILITY': 0.7, + }, + 'max_count': { + 'MAXINFO_REIMU': 7, + 'COUNT_PER_DAY_REIMU': 5, + 'MAXINFO_BT': 10, + 'MAXINFO_PRIVATE_ANIME': 20, + 'MAXINFO_GROUP_ANIME': 5, + 'MAX_FIND_IMG_COUNT': 3, + 'MAX_SIGN_GOLD': 200, + }, + 'malicious_ban': { + 'MALICIOUS_BAN_TIME': 30, + 'MALICIOUS_BAN_COUNT': 4, + 'MALICIOUS_CHECK_TIME': 5, + }, + 'open_case': { + 'INITIAL_OPEN_CASE_COUNT': 20, + }, + 'mute': { + 'MUTE_DEFAULT_COUNT': 10, + 'MUTE_DEFAULT_TIME': 7, + 'MUTE_DEFAULT_DURATION': 10, + }, + 'other': { + 'UPDATE_GOCQ_GROUP': [], + 'ADMIN_DEFAULT_AUTH': 5, + }, + 'auth': { + 'admin_plugins_auth': { + "admin_bot_manage": 2, + "ban": 5, + "delete_img": 7, + "move_img": 7, + "upload_img": 6, + "admin_help": 1, + "mute": 5 + } + }, + } + with open(other_config, 'w', encoding='utf8') as f: + json.dump(config_dict, f, indent=4, ensure_ascii=False) + + + diff --git a/services/log.py b/services/log.py new file mode 100644 index 00000000..9de3fc6d --- /dev/null +++ b/services/log.py @@ -0,0 +1,30 @@ +import logging +from datetime import datetime +from configs.path_config import LOG_PATH + +# CRITICAL 50 +# ERROR 40 +# WARNING 30 +# INFO 20 +# DEBUG 10 +# NOTSET 0 + +# _handler = logging.StreamHandler(sys.stdout) +# _handler.setFormatter( +# logging.Formatter('[%(asctime)s %(name)s] %(levelname)s: %(message)s') +# ) +logger = logging.getLogger('hibiki') +logger.setLevel(level=logging.DEBUG) + +formatter = logging.Formatter('[%(asctime)s] - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s') +# print(LOG_PATH) +file_handler = logging.FileHandler(LOG_PATH + str((datetime.now()).date()) + '.log', mode='a', encoding='utf-8') +file_handler.setLevel(level=logging.INFO) +file_handler.setFormatter(formatter) + +stream_handler = logging.StreamHandler() +stream_handler.setLevel(logging.INFO) +stream_handler.setFormatter(formatter) + +logger.addHandler(file_handler) +logger.addHandler(stream_handler) diff --git a/util/__pycache__/img_utils.cpython-38.pyc b/util/__pycache__/img_utils.cpython-38.pyc new file mode 100644 index 00000000..b8b278af Binary files /dev/null and b/util/__pycache__/img_utils.cpython-38.pyc differ diff --git a/util/__pycache__/img_utils.cpython-39.pyc b/util/__pycache__/img_utils.cpython-39.pyc new file mode 100644 index 00000000..72badc06 Binary files /dev/null and b/util/__pycache__/img_utils.cpython-39.pyc differ diff --git a/util/__pycache__/init_result.cpython-38.pyc b/util/__pycache__/init_result.cpython-38.pyc new file mode 100644 index 00000000..0728e3b7 Binary files /dev/null and b/util/__pycache__/init_result.cpython-38.pyc differ diff --git a/util/__pycache__/init_result.cpython-39.pyc b/util/__pycache__/init_result.cpython-39.pyc new file mode 100644 index 00000000..0836531c Binary files /dev/null and b/util/__pycache__/init_result.cpython-39.pyc differ diff --git a/util/__pycache__/langconv.cpython-38.pyc b/util/__pycache__/langconv.cpython-38.pyc new file mode 100644 index 00000000..94b49227 Binary files /dev/null and b/util/__pycache__/langconv.cpython-38.pyc differ diff --git a/util/__pycache__/langconv.cpython-39.pyc b/util/__pycache__/langconv.cpython-39.pyc new file mode 100644 index 00000000..49ba2e1b Binary files /dev/null and b/util/__pycache__/langconv.cpython-39.pyc differ diff --git a/util/__pycache__/user_agent.cpython-38.pyc b/util/__pycache__/user_agent.cpython-38.pyc new file mode 100644 index 00000000..8295ff47 Binary files /dev/null and b/util/__pycache__/user_agent.cpython-38.pyc differ diff --git a/util/__pycache__/user_agent.cpython-39.pyc b/util/__pycache__/user_agent.cpython-39.pyc new file mode 100644 index 00000000..b7a1ed25 Binary files /dev/null and b/util/__pycache__/user_agent.cpython-39.pyc differ diff --git a/util/__pycache__/utils.cpython-38.pyc b/util/__pycache__/utils.cpython-38.pyc new file mode 100644 index 00000000..64a42e01 Binary files /dev/null and b/util/__pycache__/utils.cpython-38.pyc differ diff --git a/util/__pycache__/utils.cpython-39.pyc b/util/__pycache__/utils.cpython-39.pyc new file mode 100644 index 00000000..8c6e7bd8 Binary files /dev/null and b/util/__pycache__/utils.cpython-39.pyc differ diff --git a/util/__pycache__/zh_wiki.cpython-38.pyc b/util/__pycache__/zh_wiki.cpython-38.pyc new file mode 100644 index 00000000..79955b22 Binary files /dev/null and b/util/__pycache__/zh_wiki.cpython-38.pyc differ diff --git a/util/__pycache__/zh_wiki.cpython-39.pyc b/util/__pycache__/zh_wiki.cpython-39.pyc new file mode 100644 index 00000000..0f8ca89d Binary files /dev/null and b/util/__pycache__/zh_wiki.cpython-39.pyc differ diff --git a/util/get_bilibili_img.py b/util/get_bilibili_img.py new file mode 100644 index 00000000..19348e0b --- /dev/null +++ b/util/get_bilibili_img.py @@ -0,0 +1,140 @@ +import requests +from util.user_agent import get_user_agent +from bs4 import BeautifulSoup +from time import sleep +import threading +import os +from configs.path_config import IMAGE_PATH + +lock = threading.Lock() + +url = "https://search.bilibili.com/article" +# path = IMAGE_PATH + "setu/" + +index = 1 +THREAD_SUM_REMAINDER = 2 # 越小线程越多 + + +class bilibiliThread (threading.Thread): + def __init__(self, threadId, url_list, path, nolist): + threading.Thread.__init__(self) + self.threadId = threadId + self.url_list = url_list + self.path = path + self.nolist = nolist + def run(self): + print("开始线程<><><><><><><><><> " + self.threadId) + thread_get_url(self.threadId, self.url_list, self.path, self.nolist) + + +def get_bilibili_img(name, path, nolist=None): + global index + index = get_dirfile_len(path) + print("index===", index) + threadId = 1 + params = { + 'keyword': name, + 'page': '1' + } + res = requests.get(url, headers=get_user_agent(), params=params) + sleep(8) + soup = BeautifulSoup(res.text, 'html.parser') + # print(soup.text) + try: + total_page = soup.find_all('button', {'class': 'pagination-btn'})[-1].text.strip() + print("1 try") + except: + try: + total_page = soup.find_all('button', {'class': 'pagination-btn num-btn'})[-1].text.strip() + print("2 try") + except: + total_page = 1 + print("3 except") + print(total_page) + url_list = [] + for page in range(1, int(total_page)+1): + url_r = "https://search.bilibili.com/article?keyword=" + name + "&page=" + str(page) + url_list.append(url_r) + if page % THREAD_SUM_REMAINDER == 0: + print('-----> ' + str(page) + " =======>", url_list) + # _thread.start_new_thread(thread_get_url, (url_list, path,)) + bilibiliThread(str(threadId), url_list, path, nolist).start() + threadId += 1 + sleep(0.5) + url_list = [] + if url_list: + print("=========================最后一个线程启动========================= url数量: ", len(url_list)) + bilibiliThread(str(threadId), url_list, path, nolist).start() + + +def thread_get_url(threadId, url_list, path, nolist): + for url in url_list: + res = requests.get(url, headers=get_user_agent()) + sleep(2) + soup = BeautifulSoup(res.text, 'lxml') + alist = soup.find_all('a', {'class': 'poster'}) + img_content_page = [] + # print(alist) + for a in alist: + if nolist != None: + if a.get('href') not in nolist: + img_content_page.append("https://" + a.get('href')[2:]) + else: + img_content_page.append("https://" + a.get('href')[2:]) + pic_url = [] + for img_content in img_content_page: + print("开始获取---------->", img_content) + res = requests.get(img_content, headers=get_user_agent()) + sleep(2) + soup = BeautifulSoup(res.text, 'lxml') + figure_ls = soup.body.find_all('figure') + # print(figure_ls) + for figure in figure_ls: + try: + _ = figure.img.attrs['class'] + except: + data_src = figure.img.attrs['data-src'] + pic_url.append('https:' + data_src) + print("线程 " + threadId + " 获取完毕------> 开始存储") + for url in pic_url: + print("线程 " + threadId + "正在存储---------------->", url) + res = requests.get(url, headers=get_user_agent()) + save_img(res.content, path, threadId) + pic_url = [] + print("线程 " + threadId + " ---------------->执行完毕") + + +def save_img(img, path, threadId): + global index + try: + lock.acquire() + img_index = index + finally: + lock.release() + try: + with open(path + str(img_index) + ".jpg", 'wb') as f: + f.write(img) + lock.acquire() + index += 1 + except: + print("线程 " + threadId + "存储失败-------->" + str(img_index) + ".jpg") + finally: + lock.release() + + +def get_dirfile_len(path): + return len(os.listdir(path)) + + +if __name__ == '__main__': + # url = "https://search.bilibili.com" \ + # "/article?keyword=%23%E4%BB%8A%E6%97%A5%E4%BB%BD%E7%9A%84%E5%8F%AF%E7%88%B1%" \ + # "E5%B0%8F%E8%90%9D%E8%8E%89%EF%BC%8C%E8%BF%9B%E6%9D%A5%E7%9C%8B%E7%9C%8B%EF%BC%8C%E" \ + # "6%8F%90%E7%A5%9E%E9%86%92%E8%84%91%EF%BC%81" + # res = requests.get(url, headers=get_user_agent()) + # sleep(2) + # soup = BeautifulSoup(res.text, 'lxml') + # alist = soup.find_all('button', {'class': 'pagination-btn num-btn'}) + # total_page = soup.find_all('button', {'class': 'pagination-btn num-btn'})[-1].text.strip() + # print(total_page) + get_bilibili_img("精选动漫壁纸手机电脑壁纸&动漫游戏专题", IMAGE_PATH + "bizhi/") \ No newline at end of file diff --git a/util/img_utils.py b/util/img_utils.py new file mode 100644 index 00000000..5e4528bd --- /dev/null +++ b/util/img_utils.py @@ -0,0 +1,296 @@ +import os +from configs.path_config import IMAGE_PATH, TXT_PATH, TTF_PATH +from PIL import Image, ImageFile, ImageDraw, ImageFont +import cv2 +import imagehash +import base64 +from io import BytesIO +from matplotlib import pyplot as plt + + +# 扫描图库id是否连贯 +def scan_img(path): + path = IMAGE_PATH + path + nolist = [] + length = len(os.listdir(path)) + print(length) + for i in range(length): + if i in nolist: + continue + img_path = path + "{}.jpg".format(i) + if not os.path.exists(img_path): + print("不存在=== " + str(length) + ".jpg -------> " + str(i) + ".jpg") + os.rename(path + "{}.jpg".format(length - 1), img_path) + nolist.append(length) + length -= 1 + + +# 比较hash值 +def compare_image_with_hash(image_file1, image_file2, max_dif=1.5): + """ + max_dif: 允许最大hash差值, 越小越精确,最小为0 + 推荐使用 + """ + ImageFile.LOAD_TRUNCATED_IMAGES = True + hash_1 = None + hash_2 = None + hash_1 = get_img_hash(image_file1) + hash_2 = get_img_hash(image_file2) + dif = hash_1 - hash_2 + if dif < 0: + dif = -dif + if dif <= max_dif: + return True + else: + return False + + +# 比较图片与hash值 +def compare_one_img_hash(image_file, hash_2, max_dif=1.5): + hash_1 = get_img_hash(image_file) + dif = hash_1 - hash_2 + if dif < 0: + dif = -dif + if dif <= max_dif: + return True + else: + return False + + +def get_img_hash(image_file): + with open(image_file, 'rb') as fp: + hash_value = imagehash.average_hash(Image.open(fp)) + return hash_value + + +# 压缩图片 +def rar_imgs(inpath, outpath, ratio=0.9, start=0, end=0, lens=0, maxsize=0.0, in_file_name='', out_file_name='', + itype='jpg'): + in_path = IMAGE_PATH + inpath + '/' + out_path = IMAGE_PATH + outpath + '/' + # scan_img(inpath) + l = [] + if in_file_name != '' and out_file_name != '': + filein = in_path + in_file_name + "." + itype + fileout = out_path + out_file_name + "." + itype + h, w, d = cv2.imread(filein).shape + width = int(w * ratio) + height = int(h * ratio) + ResizeImage(filein, fileout, width, height) + else: + if lens == 0: + lens = len(os.listdir(in_path)) + if end == 0: + end = lens + for i in range(start, end): + if i in l: + continue + if maxsize != 0: + if os.path.getsize(in_path + str(i) + ".jpg") > maxsize: + print("压缩----->", i, ".jpg") + filein = in_path + str(i) + ".jpg" + fileout = out_path + str(i) + ".jpg" + h, w, d = cv2.imread(filein).shape + width = int(w * ratio) + height = int(h * ratio) + ResizeImage(filein, fileout, width, height) + else: + continue + else: + print("压缩----->", i, ".jpg") + filein = in_path + str(i) + ".jpg" + fileout = out_path + str(i) + ".jpg" + h, w, d = cv2.imread(filein).shape + width = int(w * ratio) + height = int(h * ratio) + ResizeImage(filein, fileout, width, height) + + +# 压缩 +def ResizeImage(filein, fileout, width, height): + img = cv2.resize(cv2.imread(filein), (int(width), int(height))) + cv2.imwrite(fileout, img) + + +# 保存图片压缩后的hash值 +def save_img_hash(path, name): + for file in os.listdir(IMAGE_PATH + path): + if os.path.getsize(IMAGE_PATH + path + file) > 1024 * 1024 * 1.5: + compare_img_hash_in_txt(IMAGE_PATH + 'rar/' + file, name) + else: + compare_img_hash_in_txt(IMAGE_PATH + path + file, name) + + +# 比较色图hash值 +def compare_img_hash_in_txt(file, name, mode=1): + with open(TXT_PATH + name + ".txt", 'a+') as txtfile: + txtfile.seek(0) + hash_list = txtfile.read()[:-1].strip(",") + txtfile.seek(2) + with open(file, 'rb') as fp: + img_hash = str(imagehash.average_hash(Image.open(fp))) + if img_hash not in hash_list: + if mode == 1: + txtfile.write(img_hash + ",") + return False + return True + + +# 透明背景 -> 白色 +def alphabg2white_PIL(img): + img = img.convert('RGBA') + sp = img.size + width = sp[0] + height = sp[1] + for yh in range(height): + for xw in range(width): + dot = (xw, yh) + color_d = img.getpixel(dot) + if color_d[3] == 0: + color_d = (255, 255, 255, 255) + img.putpixel(dot, color_d) + return img + + +def pic2b64(pic: Image) -> str: + buf = BytesIO() + pic.save(buf, format='PNG') + base64_str = base64.b64encode(buf.getvalue()).decode() + return 'base64://' + base64_str + + +def fig2b64(plt: plt) -> str: + buf = BytesIO() + plt.savefig(buf, format='PNG', dpi=100) + base64_str = base64.b64encode(buf.getvalue()).decode() + return 'base64://' + base64_str + + +class CreateImg: + def __init__(self, + w, + h, + img_w=0, + img_h=0, + color='white', + image_type='RGBA', + font_size=10, + background='', + ttf='yz.ttf', + divisor=1): + self.w = int(w) + self.h = int(h) + self.img_w = int(img_w) + self.img_h = int(img_h) + self.current_w = 0 + self.current_h = 0 + self.ttfont = ImageFont.truetype(TTF_PATH + ttf, int(font_size)) + if not background: + self.markImg = Image.new(image_type, (self.w, self.h), color) + else: + if w == 0 and h == 0: + self.markImg = Image.open(background) + w, h = self.markImg.size + if divisor: + self.w = int(divisor * w) + self.h = int(divisor * h) + self.markImg = self.markImg.resize((self.w, self.h), Image.ANTIALIAS) + else: + self.w = w + self.h = h + else: + self.markImg = Image.open(background).resize((self.w, self.h), Image.ANTIALIAS) + self.draw = ImageDraw.Draw(self.markImg) + self.size = self.w, self.h + + # 贴图 + def paste(self, img, pos=None, alpha=False): + if isinstance(img, CreateImg): + img = img.markImg + if self.current_w == self.w: + self.current_w = 0 + self.current_h += self.img_h + if not pos: + pos = (self.current_w, self.current_h) + if alpha: + try: + self.markImg.paste(img, pos, img) + except ValueError: + img = img.convert("RGBA") + self.markImg.paste(img, pos, img) + else: + self.markImg.paste(img, pos) + self.current_w += self.img_w + return self.markImg + + # 获取文字大小 + def getsize(self, msg): + return self.ttfont.getsize(msg) + + # 写字 + def text(self, pos, text, fill=(0, 0, 0)): + self.draw.text(pos, text, fill=fill, font=self.ttfont) + return self.markImg + + # 饼图 + def pieslice(self): + self.draw.pieslice((350, 50, 500, 200), -150, -30, 'pink', 'crimson') + return self.markImg + + # 保存 + def save(self, path): + self.markImg.save(path) + + # 显示 + def show(self): + self.markImg.show(self.markImg) + + # 压缩 + def resize(self, ratio): + self.markImg = self.markImg.resize((int(self.w * ratio), int(self.h * ratio)), Image.ANTIALIAS) + self.w, self.h = self.markImg.size + self.size = self.w, self.h + self.draw = ImageDraw.Draw(self.markImg) + + # 检查字体大小 + def check_font_size(self, word): + return self.ttfont.getsize(word)[0] > self.w + + # 透明化 + def transparent(self, n=0): + self.markImg = self.markImg.convert('RGBA') # 修改颜色通道为RGBA + x, y = self.markImg.size # 获得长和宽 + # 设置每个像素点颜色的透明度 + for i in range(n, x - n): + for k in range(n, y - n): + color = self.markImg.getpixel((i, k)) + color = color[:-1] + (100, ) + self.markImg.putpixel((i, k), color) + return self.markImg + + # 转bs4: + def pic2bs4(self): + buf = BytesIO() + self.markImg.save(buf, format='PNG') + base64_str = base64.b64encode(buf.getvalue()).decode() + return 'base64://' + base64_str + + # + def convert(self, itype): + self.markImg = self.markImg.convert(itype) + + +if __name__ == '__main__': + pass + + + + + + + + + + + + diff --git a/util/init_result.py b/util/init_result.py new file mode 100644 index 00000000..3b369ddf --- /dev/null +++ b/util/init_result.py @@ -0,0 +1,86 @@ +from configs.path_config import IMAGE_PATH, VOICE_PATH +from nonebot.adapters.cqhttp.message import MessageSegment +import os +from services.log import logger + + +def image(img_name: str = None, path: str = '', abspath: str = None, b64: str = None): + if abspath: + if os.path.exists(abspath): + return MessageSegment.image("file:///" + abspath) + else: + return '' + elif b64: + if b64.find('base64://') != -1: + return MessageSegment.image(b64) + else: + return MessageSegment.image('base64://' + b64) + else: + img_name = str(img_name) + if img_name.find('http') == -1: + if len(img_name.split('.')) == 1: + img_name += '.jpg' + if os.path.exists(IMAGE_PATH + path + '/' + img_name): + return MessageSegment.image("file:///" + IMAGE_PATH + path + '/' + img_name) + else: + logger.warning(f"图片 {path}/{img_name}缺失.") + return '' + else: + return MessageSegment.image(img_name) + + +def at(qq): + return MessageSegment.at(qq) + + +def record(voice_name='', path=''): + if len(voice_name.split('.')) == 1: + voice_name += '.mp3' + if path == "": + name = VOICE_PATH + "{}.".format(voice_name) + else: + name = VOICE_PATH + "{}/{}".format(path, voice_name) + if voice_name.find('http') == -1: + if os.path.exists(name): + result = MessageSegment.record("file:///" + name) + return result + else: + logger.warning(f"语音{path}/{voice_name}缺失...") + return "" + else: + return MessageSegment.record(voice_name) + + +def text(msg): + return MessageSegment.text(msg) + + +def contact_user(qq): + return MessageSegment.contact_user(qq) + + +def share(url, title, content='', image_url=''): + return MessageSegment.share(url, title, content, image_url) + + +def xml(data): + return MessageSegment.xml(data) + + +def json(data): + return MessageSegment.json(data) + + +def face(id_): + return MessageSegment.face(id_) + + +def poke(qq): + return MessageSegment('poke', {"qq": qq}) + + +def forward(): + return MessageSegment.forward() + +# if __name__ == '__main__': +# print(get_record_result("dadada", "", type="amr")) diff --git a/util/langconv.py b/util/langconv.py new file mode 100644 index 00000000..4977161b --- /dev/null +++ b/util/langconv.py @@ -0,0 +1,274 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from copy import deepcopy +import re + +try: + import psyco + psyco.full() +except: + pass + +from .zh_wiki import zh2Hant, zh2Hans + +import sys +py3k = sys.version_info >= (3, 0, 0) + +if py3k: + UEMPTY = '' +else: + _zh2Hant, _zh2Hans = {}, {} + for old, new in ((zh2Hant, _zh2Hant), (zh2Hans, _zh2Hans)): + for k, v in old.items(): + new[k.decode('utf8')] = v.decode('utf8') + zh2Hant = _zh2Hant + zh2Hans = _zh2Hans + UEMPTY = ''.decode('utf8') + +# states +(START, END, FAIL, WAIT_TAIL) = list(range(4)) +# conditions +(TAIL, ERROR, MATCHED_SWITCH, UNMATCHED_SWITCH, CONNECTOR) = list(range(5)) + +MAPS = {} + +class Node(object): + def __init__(self, from_word, to_word=None, is_tail=True, + have_child=False): + self.from_word = from_word + if to_word is None: + self.to_word = from_word + self.data = (is_tail, have_child, from_word) + self.is_original = True + else: + self.to_word = to_word or from_word + self.data = (is_tail, have_child, to_word) + self.is_original = False + self.is_tail = is_tail + self.have_child = have_child + + def is_original_long_word(self): + return self.is_original and len(self.from_word)>1 + + def is_follow(self, chars): + return chars != self.from_word[:-1] + + def __str__(self): + return '' % (repr(self.from_word), + repr(self.to_word), self.is_tail, self.have_child) + + __repr__ = __str__ + +class ConvertMap(object): + def __init__(self, name, mapping=None): + self.name = name + self._map = {} + if mapping: + self.set_convert_map(mapping) + + def set_convert_map(self, mapping): + convert_map = {} + have_child = {} + max_key_length = 0 + for key in sorted(mapping.keys()): + if len(key)>1: + for i in range(1, len(key)): + parent_key = key[:i] + have_child[parent_key] = True + have_child[key] = False + max_key_length = max(max_key_length, len(key)) + for key in sorted(have_child.keys()): + convert_map[key] = (key in mapping, have_child[key], + mapping.get(key, UEMPTY)) + self._map = convert_map + self.max_key_length = max_key_length + + def __getitem__(self, k): + try: + is_tail, have_child, to_word = self._map[k] + return Node(k, to_word, is_tail, have_child) + except: + return Node(k) + + def __contains__(self, k): + return k in self._map + + def __len__(self): + return len(self._map) + +class StatesMachineException(Exception): pass + +class StatesMachine(object): + def __init__(self): + self.state = START + self.final = UEMPTY + self.len = 0 + self.pool = UEMPTY + + def clone(self, pool): + new = deepcopy(self) + new.state = WAIT_TAIL + new.pool = pool + return new + + def feed(self, char, map): + node = map[self.pool+char] + + if node.have_child: + if node.is_tail: + if node.is_original: + cond = UNMATCHED_SWITCH + else: + cond = MATCHED_SWITCH + else: + cond = CONNECTOR + else: + if node.is_tail: + cond = TAIL + else: + cond = ERROR + + new = None + if cond == ERROR: + self.state = FAIL + elif cond == TAIL: + if self.state == WAIT_TAIL and node.is_original_long_word(): + self.state = FAIL + else: + self.final += node.to_word + self.len += 1 + self.pool = UEMPTY + self.state = END + elif self.state == START or self.state == WAIT_TAIL: + if cond == MATCHED_SWITCH: + new = self.clone(node.from_word) + self.final += node.to_word + self.len += 1 + self.state = END + self.pool = UEMPTY + elif cond == UNMATCHED_SWITCH or cond == CONNECTOR: + if self.state == START: + new = self.clone(node.from_word) + self.final += node.to_word + self.len += 1 + self.state = END + else: + if node.is_follow(self.pool): + self.state = FAIL + else: + self.pool = node.from_word + elif self.state == END: + # END is a new START + self.state = START + new = self.feed(char, map) + elif self.state == FAIL: + raise StatesMachineException('Translate States Machine ' + 'have error with input data %s' % node) + return new + + def __len__(self): + return self.len + 1 + + def __str__(self): + return '' % ( + id(self), self.pool, self.state, self.final) + __repr__ = __str__ + +class Converter(object): + def __init__(self, to_encoding): + self.to_encoding = to_encoding + self.map = MAPS[to_encoding] + self.start() + + def feed(self, char): + branches = [] + for fsm in self.machines: + new = fsm.feed(char, self.map) + if new: + branches.append(new) + if branches: + self.machines.extend(branches) + self.machines = [fsm for fsm in self.machines if fsm.state != FAIL] + all_ok = True + for fsm in self.machines: + if fsm.state != END: + all_ok = False + if all_ok: + self._clean() + return self.get_result() + + def _clean(self): + if len(self.machines): + self.machines.sort(key=lambda x: len(x)) + # self.machines.sort(cmp=lambda x,y: cmp(len(x), len(y))) + self.final += self.machines[0].final + self.machines = [StatesMachine()] + + def start(self): + self.machines = [StatesMachine()] + self.final = UEMPTY + + def end(self): + self.machines = [fsm for fsm in self.machines + if fsm.state == FAIL or fsm.state == END] + self._clean() + + def convert(self, string): + self.start() + for char in string: + self.feed(char) + self.end() + return self.get_result() + + def get_result(self): + return self.final + + +def registery(name, mapping): + global MAPS + MAPS[name] = ConvertMap(name, mapping) + +registery('zh-hant', zh2Hant) +registery('zh-hans', zh2Hans) +del zh2Hant, zh2Hans + + +def run(): + import sys + from optparse import OptionParser + parser = OptionParser() + parser.add_option('-e', type='string', dest='encoding', + help='encoding') + parser.add_option('-f', type='string', dest='file_in', + help='input file (- for stdin)') + parser.add_option('-t', type='string', dest='file_out', + help='output file') + (options, args) = parser.parse_args() + if not options.encoding: + parser.error('encoding must be set') + if options.file_in: + if options.file_in == '-': + file_in = sys.stdin + else: + file_in = open(options.file_in) + else: + file_in = sys.stdin + if options.file_out: + if options.file_out == '-': + file_out = sys.stdout + else: + file_out = open(options.file_out, 'wb') + else: + file_out = sys.stdout + + c = Converter(options.encoding) + for line in file_in: + # print >> file_out, c.convert(line.rstrip('\n').decode( + file_out.write(c.convert(line.rstrip('\n').decode( + 'utf8')).encode('utf8')) + + +if __name__ == '__main__': + run() + diff --git a/util/user_agent.py b/util/user_agent.py new file mode 100644 index 00000000..8cf7d94f --- /dev/null +++ b/util/user_agent.py @@ -0,0 +1,47 @@ +import random + + +user_agent = [ + "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50", + "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50", + "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0", + "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729; InfoPath.3; rv:11.0) like Gecko", + "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)", + "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)", + "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)", + "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)", + "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0.1) Gecko/20100101 Firefox/4.0.1", + "Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1", + "Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; en) Presto/2.8.131 Version/11.11", + "Opera/9.80 (Windows NT 6.1; U; en) Presto/2.8.131 Version/11.11", + "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_0) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11", + "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Maxthon 2.0)", + "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; TencentTraveler 4.0)", + "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)", + "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; The World)", + "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; SE 2.X MetaSr 1.0; SE 2.X MetaSr 1.0; .NET CLR 2.0.50727; SE 2.X MetaSr 1.0)", + "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; 360SE)", + "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Avant Browser)", + "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)", + "Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_3_3 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8J2 Safari/6533.18.5", + "Mozilla/5.0 (iPod; U; CPU iPhone OS 4_3_3 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8J2 Safari/6533.18.5", + "Mozilla/5.0 (iPad; U; CPU OS 4_3_3 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8J2 Safari/6533.18.5", + "Mozilla/5.0 (Linux; U; Android 2.3.7; en-us; Nexus One Build/FRF91) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1", + "MQQBrowser/26 Mozilla/5.0 (Linux; U; Android 2.3.7; zh-cn; MB200 Build/GRJ22; CyanogenMod-7) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1", + "Opera/9.80 (Android 2.3.4; Linux; Opera Mobi/build-1107180945; U; en-GB) Presto/2.8.149 Version/11.10", + "Mozilla/5.0 (Linux; U; Android 3.0; en-us; Xoom Build/HRI39) AppleWebKit/534.13 (KHTML, like Gecko) Version/4.0 Safari/534.13", + "Mozilla/5.0 (BlackBerry; U; BlackBerry 9800; en) AppleWebKit/534.1+ (KHTML, like Gecko) Version/6.0.0.337 Mobile Safari/534.1+", + "Mozilla/5.0 (hp-tablet; Linux; hpwOS/3.0.0; U; en-US) AppleWebKit/534.6 (KHTML, like Gecko) wOSBrowser/233.70 Safari/534.6 TouchPad/1.0", + "Mozilla/5.0 (SymbianOS/9.4; Series60/5.0 NokiaN97-1/20.0.019; Profile/MIDP-2.1 Configuration/CLDC-1.1) AppleWebKit/525 (KHTML, like Gecko) BrowserNG/7.1.18124", + "Mozilla/5.0 (compatible; MSIE 9.0; Windows Phone OS 7.5; Trident/5.0; IEMobile/9.0; HTC; Titan)", + "UCWEB7.0.2.37/28/999", + "NOKIA5700/ UCWEB7.0.2.37/28/999", + "Openwave/ UCWEB7.0.2.37/28/999", + "Mozilla/4.0 (compatible; MSIE 6.0; ) Opera/UCWEB7.0.2.37/28/999", + # iPhone 6: + "Mozilla/6.0 (iPhone; CPU iPhone OS 8_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/8.0 Mobile/10A5376e Safari/8536.25" +] + + +def get_user_agent(): + return {'User-Agent': random.choice(user_agent)} diff --git a/util/utils.py b/util/utils.py new file mode 100644 index 00000000..491762f3 --- /dev/null +++ b/util/utils.py @@ -0,0 +1,263 @@ +import time +from datetime import datetime, timedelta +from collections import defaultdict +from nonebot import require +import nonebot +import json +import pytz +from configs.path_config import TXT_PATH +from configs.config import system_proxy +import pypinyin + + +scheduler = require('nonebot_plugin_apscheduler').scheduler + + +# 次数检测 +class CountLimiter: + def __init__(self, max): + self.count = defaultdict(int) + self.max = max + + def add(self, key): + self.count[key] += 1 + + def check(self, key) -> bool: + if self.count[key] >= self.max: + self.count[key] = 0 + return True + return False + + +# 用户正在执行此命令 +class UserExistLimiter: + def __init__(self): + self.mbool = defaultdict(bool) + self.time = time.time() + + def set_True(self, key): + self.time = time.time() + self.mbool[key] = True + + def set_False(self, key): + self.mbool[key] = False + + def check(self, key): + if time.time() - self.time > 30: + self.set_False(key) + return False + return self.mbool[key] + + +# 命令cd +class FreqLimiter: + def __init__(self, default_cd_seconds): + self.next_time = defaultdict(float) + self.default_cd = default_cd_seconds + + def check(self, key) -> bool: + return time.time() >= self.next_time[key] + + def start_cd(self, key, cd_time=0): + self.next_time[key] = time.time() + (cd_time if cd_time > 0 else self.default_cd) + + def left_time(self, key) -> float: + return self.next_time[key] - time.time() + + +static_flmt = FreqLimiter(15) + + +# 恶意触发命令检测 +class BanCheckLimiter: + def __init__(self, default_check_time: float = 5, default_count: int = 4): + self.mint = defaultdict(int) + self.mtime = defaultdict(float) + self.default_check_time = default_check_time + self.default_count = default_count + + def add(self, key): + if self.mint[key] == 1: + self.mtime[key] = time.time() + self.mint[key] += 1 + + def check(self, key) -> bool: + # print(self.mint[key]) + # print(time.time() - self.mtime[key]) + if time.time() - self.mtime[key] > self.default_check_time: + self.mtime[key] = time.time() + self.mint[key] = 0 + return False + if self.mint[key] >= self.default_count and time.time() - self.mtime[key] < self.default_check_time: + self.mtime[key] = time.time() + self.mint[key] = 0 + return True + return False + + +# 每日次数 +class DailyNumberLimiter: + tz = pytz.timezone('Asia/Shanghai') + + def __init__(self, max_num): + self.today = -1 + self.count = defaultdict(int) + self.max = max_num + + def check(self, key) -> bool: + now = datetime.now(self.tz) + day = (now - timedelta(hours=5)).day + if day != self.today: + self.today = day + self.count.clear() + return bool(self.count[key] < self.max) + + def get_num(self, key): + return self.count[key] + + def increase(self, key, num=1): + self.count[key] += num + + def reset(self, key): + self.count[key] = 0 + + +def is_number(s) -> bool: + try: + float(s) + return True + except ValueError: + pass + try: + import unicodedata + unicodedata.numeric(s) + return True + except (TypeError, ValueError): + pass + return False + + +def get_lines(path: str, start: int = 0, end: int = 0) -> list: + l = [] + with open(path, 'r', errors='ignore', encoding="UTF-8") as f: + lines = f.readlines() + for line in lines: + if line != "\n" and line != "": + if end == 0: + l.append(line[start:]) + else: + l.append(line[start: end]) + return l + + +# 获取bot +def get_bot(): + return list(nonebot.get_bots().values())[0] + + +def get_message_at(data: str) -> list: + qq_list = [] + data = json.loads(data) + try: + for msg in data['message']: + if msg['type'] == 'at': + qq_list.append(int(msg['data']['qq'])) + return qq_list + except Exception: + return [] + + +def get_message_imgs(data: str) -> list: + img_list = [] + data = json.loads(data) + try: + for msg in data['message']: + if msg['type'] == 'image': + img_list.append(msg['data']['url']) + return img_list + except Exception: + return [] + + +def get_message_text(data: str) -> str: + data = json.loads(data) + result = '' + try: + for msg in data['message']: + if msg['type'] == 'text': + result += msg['data']['text'].strip() + ' ' + return result.strip() + except Exception: + return '' + + +def get_message_type(data: str) -> str: + return json.loads(data)['message_type'] + + +def get_message_record(data: str) -> str: + data = json.loads(data) + try: + for msg in data['message']: + if msg['type'] == 'record': + return msg['data']['url'] + return '' + except Exception: + return '' + + +def get_message_json(data: str) -> dict: + data = json.loads(data) + try: + for msg in data['message']: + if msg['type'] == 'json': + return msg['data'] + return {} + except Exception: + return {} + + +def add_to_16(value): + while len(value) % 16 != 0: + value += '\0' + return str.encode(value) + + +# 获取文本加密后的cookie +def get_cookie_text(cookie_name: str) -> str: + with open(TXT_PATH + "cookie/" + cookie_name + ".txt", 'r') as f: + return f.read() + + +# 获取本地http代理 +def get_local_proxy(): + # from urllib.request import getproxies + # import platform + # proxy = getproxies()['http'] + # if platform.system() != 'Windows': + # proxy = 'http://' + proxy + return system_proxy if system_proxy else None + + +# 判断是否为中文 +def is_Chinese(word): + for ch in word: + if '\u4e00' <= ch <= '\u9fff': + return True + return False + + +def user_avatar(qq): + return f'http://q1.qlogo.cn/g?b=qq&nk={qq}&s=160' + + +def group_avatar(group_id): + return f'http://p.qlogo.cn/gh/{group_id}/{group_id}/640/' + + +def cn2py(word) -> str: + temp = "" + for i in pypinyin.pinyin(word, style=pypinyin.NORMAL): + temp += ''.join(i) + return temp + diff --git a/util/zh_wiki.py b/util/zh_wiki.py new file mode 100644 index 00000000..4f5720f7 --- /dev/null +++ b/util/zh_wiki.py @@ -0,0 +1,8275 @@ +# -*- coding: utf-8 -*- +# copy fom wikipedia + +zh2Hant = { +'呆': '獃', +"打印机": "印表機", +'帮助文件': '說明檔案', +"画": "畫", +"龙": "竜", +"板": "板", +"表": "表", +"才": "才", +"丑": "醜", +"出": "出", +"淀": "澱", +"冬": "冬", +"范": "範", +"丰": "豐", +"刮": "刮", +"后": "後", +"胡": "胡", +"回": "回", +"伙": "夥", +"姜": "薑", +"借": "借", +"克": "克", +"困": "困", +"漓": "漓", +"里": "里", +"帘": "簾", +"霉": "霉", +"面": "面", +"蔑": "蔑", +"千": "千", +"秋": "秋", +"松": "松", +"咸": "咸", +"向": "向", +"余": "餘", +"郁": "鬱", +"御": "御", +"愿": "願", +"云": "雲", +"芸": "芸", +"沄": "沄", +"致": "致", +"制": "制", +"朱": "朱", +"筑": "築", +"准": "準", +"厂": "廠", +"广": "廣", +"辟": "闢", +"别": "別", +"卜": "卜", +"沈": "沈", +"冲": "沖", +"种": "種", +"虫": "蟲", +"担": "擔", +"党": "黨", +"斗": "鬥", +"儿": "兒", +"干": "乾", +"谷": "谷", +"柜": "櫃", +"合": "合", +"划": "劃", +"坏": "壞", +"几": "幾", +"系": "系", +"家": "家", +"价": "價", +"据": "據", +"卷": "捲", +"适": "適", +"蜡": "蠟", +"腊": "臘", +"了": "了", +"累": "累", +"么": "麽", +"蒙": "蒙", +"万": "萬", +"宁": "寧", +"朴": "樸", +"苹": "蘋", +"仆": "僕", +"曲": "曲", +"确": "確", +"舍": "舍", +"胜": "勝", +"术": "術", +"台": "台", +"体": "體", +"涂": "塗", +"叶": "葉", +"吁": "吁", +"旋": "旋", +"佣": "傭", +"与": "與", +"折": "折", +"征": "徵", +"症": "症", +"恶": "惡", +"发": "發", +"复": "復", +"汇": "匯", +"获": "獲", +"饥": "飢", +"尽": "盡", +"历": "歷", +"卤": "滷", +"弥": "彌", +"签": "簽", +"纤": "纖", +"苏": "蘇", +"坛": "壇", +"团": "團", +"须": "須", +"脏": "臟", +"只": "只", +"钟": "鐘", +"药": "藥", +"同": "同", +"志": "志", +"杯": "杯", +"岳": "岳", +"布": "布", +"当": "當", +"吊": "弔", +"仇": "仇", +"蕴": "蘊", +"线": "線", +"为": "為", +"产": "產", +"众": "眾", +"伪": "偽", +"凫": "鳧", +"厕": "廁", +"启": "啟", +"墙": "牆", +"壳": "殼", +"奖": "獎", +"妫": "媯", +"并": "並", +"录": "錄", +"悫": "愨", +"极": "極", +"沩": "溈", +"瘘": "瘺", +"硷": "鹼", +"竖": "豎", +"绝": "絕", +"绣": "繡", +"绦": "絛", +"绱": "緔", +"绷": "綳", +"绿": "綠", +"缰": "韁", +"苧": "苎", +"莼": "蒓", +"说": "說", +"谣": "謠", +"谫": "譾", +"赃": "贓", +"赍": "齎", +"赝": "贗", +"酝": "醞", +"采": "採", +"钩": "鉤", +"钵": "缽", +"锈": "銹", +"锐": "銳", +"锨": "杴", +"镌": "鐫", +"镢": "钁", +"阅": "閱", +"颓": "頹", +"颜": "顏", +"骂": "罵", +"鲇": "鯰", +"鲞": "鯗", +"鳄": "鱷", +"鸡": "雞", +"鹚": "鶿", +"荡": "盪", +"锤": "錘", +"㟆": "㠏", +"㛟": "𡞵", +"专": "專", +"业": "業", +"丛": "叢", +"东": "東", +"丝": "絲", +"丢": "丟", +"两": "兩", +"严": "嚴", +"丧": "喪", +"个": "個", +"临": "臨", +"丽": "麗", +"举": "舉", +"义": "義", +"乌": "烏", +"乐": "樂", +"乔": "喬", +"习": "習", +"乡": "鄉", +"书": "書", +"买": "買", +"乱": "亂", +"争": "爭", +"于": "於", +"亏": "虧", +"亚": "亞", +"亩": "畝", +"亲": "親", +"亵": "褻", +"亸": "嚲", +"亿": "億", +"仅": "僅", +"从": "從", +"仑": "侖", +"仓": "倉", +"仪": "儀", +"们": "們", +"优": "優", +"会": "會", +"伛": "傴", +"伞": "傘", +"伟": "偉", +"传": "傳", +"伣": "俔", +"伤": "傷", +"伥": "倀", +"伦": "倫", +"伧": "傖", +"伫": "佇", +"佥": "僉", +"侠": "俠", +"侣": "侶", +"侥": "僥", +"侦": "偵", +"侧": "側", +"侨": "僑", +"侩": "儈", +"侪": "儕", +"侬": "儂", +"俣": "俁", +"俦": "儔", +"俨": "儼", +"俩": "倆", +"俪": "儷", +"俫": "倈", +"俭": "儉", +"债": "債", +"倾": "傾", +"偬": "傯", +"偻": "僂", +"偾": "僨", +"偿": "償", +"傥": "儻", +"傧": "儐", +"储": "儲", +"傩": "儺", +"㑩": "儸", +"兑": "兌", +"兖": "兗", +"兰": "蘭", +"关": "關", +"兴": "興", +"兹": "茲", +"养": "養", +"兽": "獸", +"冁": "囅", +"内": "內", +"冈": "岡", +"册": "冊", +"写": "寫", +"军": "軍", +"农": "農", +"冯": "馮", +"决": "決", +"况": "況", +"冻": "凍", +"净": "凈", +"凉": "涼", +"减": "減", +"凑": "湊", +"凛": "凜", +"凤": "鳳", +"凭": "憑", +"凯": "凱", +"击": "擊", +"凿": "鑿", +"刍": "芻", +"刘": "劉", +"则": "則", +"刚": "剛", +"创": "創", +"删": "刪", +"刬": "剗", +"刭": "剄", +"刹": "剎", +"刽": "劊", +"刿": "劌", +"剀": "剴", +"剂": "劑", +"剐": "剮", +"剑": "劍", +"剥": "剝", +"剧": "劇", +"㓥": "劏", +"㔉": "劚", +"劝": "勸", +"办": "辦", +"务": "務", +"劢": "勱", +"动": "動", +"励": "勵", +"劲": "勁", +"劳": "勞", +"势": "勢", +"勋": "勛", +"勚": "勩", +"匀": "勻", +"匦": "匭", +"匮": "匱", +"区": "區", +"医": "醫", +"华": "華", +"协": "協", +"单": "單", +"卖": "賣", +"卢": "盧", +"卫": "衛", +"却": "卻", +"厅": "廳", +"厉": "厲", +"压": "壓", +"厌": "厭", +"厍": "厙", +"厐": "龎", +"厘": "釐", +"厢": "廂", +"厣": "厴", +"厦": "廈", +"厨": "廚", +"厩": "廄", +"厮": "廝", +"县": "縣", +"叁": "叄", +"参": "參", +"双": "雙", +"变": "變", +"叙": "敘", +"叠": "疊", +"号": "號", +"叹": "嘆", +"叽": "嘰", +"吓": "嚇", +"吕": "呂", +"吗": "嗎", +"吣": "唚", +"吨": "噸", +"听": "聽", +"吴": "吳", +"呐": "吶", +"呒": "嘸", +"呓": "囈", +"呕": "嘔", +"呖": "嚦", +"呗": "唄", +"员": "員", +"呙": "咼", +"呛": "嗆", +"呜": "嗚", +"咏": "詠", +"咙": "嚨", +"咛": "嚀", +"咝": "噝", +"响": "響", +"哑": "啞", +"哒": "噠", +"哓": "嘵", +"哔": "嗶", +"哕": "噦", +"哗": "嘩", +"哙": "噲", +"哜": "嚌", +"哝": "噥", +"哟": "喲", +"唛": "嘜", +"唝": "嗊", +"唠": "嘮", +"唡": "啢", +"唢": "嗩", +"唤": "喚", +"啧": "嘖", +"啬": "嗇", +"啭": "囀", +"啮": "嚙", +"啴": "嘽", +"啸": "嘯", +"㖞": "喎", +"喷": "噴", +"喽": "嘍", +"喾": "嚳", +"嗫": "囁", +"嗳": "噯", +"嘘": "噓", +"嘤": "嚶", +"嘱": "囑", +"㖊": "噚", +"噜": "嚕", +"嚣": "囂", +"园": "園", +"囱": "囪", +"围": "圍", +"囵": "圇", +"国": "國", +"图": "圖", +"圆": "圓", +"圣": "聖", +"圹": "壙", +"场": "場", +"坂": "阪", +"块": "塊", +"坚": "堅", +"坜": "壢", +"坝": "壩", +"坞": "塢", +"坟": "墳", +"坠": "墜", +"垄": "壟", +"垅": "壠", +"垆": "壚", +"垒": "壘", +"垦": "墾", +"垩": "堊", +"垫": "墊", +"垭": "埡", +"垱": "壋", +"垲": "塏", +"垴": "堖", +"埘": "塒", +"埙": "塤", +"埚": "堝", +"埯": "垵", +"堑": "塹", +"堕": "墮", +"𡒄": "壈", +"壮": "壯", +"声": "聲", +"壶": "壺", +"壸": "壼", +"处": "處", +"备": "備", +"够": "夠", +"头": "頭", +"夸": "誇", +"夹": "夾", +"夺": "奪", +"奁": "奩", +"奂": "奐", +"奋": "奮", +"奥": "奧", +"奸": "姦", +"妆": "妝", +"妇": "婦", +"妈": "媽", +"妩": "嫵", +"妪": "嫗", +"姗": "姍", +"姹": "奼", +"娄": "婁", +"娅": "婭", +"娆": "嬈", +"娇": "嬌", +"娈": "孌", +"娱": "娛", +"娲": "媧", +"娴": "嫻", +"婳": "嫿", +"婴": "嬰", +"婵": "嬋", +"婶": "嬸", +"媪": "媼", +"嫒": "嬡", +"嫔": "嬪", +"嫱": "嬙", +"嬷": "嬤", +"孙": "孫", +"学": "學", +"孪": "孿", +"宝": "寶", +"实": "實", +"宠": "寵", +"审": "審", +"宪": "憲", +"宫": "宮", +"宽": "寬", +"宾": "賓", +"寝": "寢", +"对": "對", +"寻": "尋", +"导": "導", +"寿": "壽", +"将": "將", +"尔": "爾", +"尘": "塵", +"尝": "嘗", +"尧": "堯", +"尴": "尷", +"尸": "屍", +"层": "層", +"屃": "屓", +"屉": "屜", +"届": "屆", +"属": "屬", +"屡": "屢", +"屦": "屨", +"屿": "嶼", +"岁": "歲", +"岂": "豈", +"岖": "嶇", +"岗": "崗", +"岘": "峴", +"岙": "嶴", +"岚": "嵐", +"岛": "島", +"岭": "嶺", +"岽": "崬", +"岿": "巋", +"峄": "嶧", +"峡": "峽", +"峣": "嶢", +"峤": "嶠", +"峥": "崢", +"峦": "巒", +"崂": "嶗", +"崃": "崍", +"崄": "嶮", +"崭": "嶄", +"嵘": "嶸", +"嵚": "嶔", +"嵝": "嶁", +"巅": "巔", +"巩": "鞏", +"巯": "巰", +"币": "幣", +"帅": "帥", +"师": "師", +"帏": "幃", +"帐": "帳", +"帜": "幟", +"带": "帶", +"帧": "幀", +"帮": "幫", +"帱": "幬", +"帻": "幘", +"帼": "幗", +"幂": "冪", +"庄": "莊", +"庆": "慶", +"庐": "廬", +"庑": "廡", +"库": "庫", +"应": "應", +"庙": "廟", +"庞": "龐", +"废": "廢", +"廪": "廩", +"开": "開", +"异": "異", +"弃": "棄", +"弑": "弒", +"张": "張", +"弪": "弳", +"弯": "彎", +"弹": "彈", +"强": "強", +"归": "歸", +"彝": "彞", +"彦": "彥", +"彻": "徹", +"径": "徑", +"徕": "徠", +"忆": "憶", +"忏": "懺", +"忧": "憂", +"忾": "愾", +"怀": "懷", +"态": "態", +"怂": "慫", +"怃": "憮", +"怄": "慪", +"怅": "悵", +"怆": "愴", +"怜": "憐", +"总": "總", +"怼": "懟", +"怿": "懌", +"恋": "戀", +"恒": "恆", +"恳": "懇", +"恸": "慟", +"恹": "懨", +"恺": "愷", +"恻": "惻", +"恼": "惱", +"恽": "惲", +"悦": "悅", +"悬": "懸", +"悭": "慳", +"悮": "悞", +"悯": "憫", +"惊": "驚", +"惧": "懼", +"惨": "慘", +"惩": "懲", +"惫": "憊", +"惬": "愜", +"惭": "慚", +"惮": "憚", +"惯": "慣", +"愠": "慍", +"愤": "憤", +"愦": "憒", +"慑": "懾", +"懑": "懣", +"懒": "懶", +"懔": "懍", +"戆": "戇", +"戋": "戔", +"戏": "戲", +"戗": "戧", +"战": "戰", +"戬": "戩", +"戯": "戱", +"户": "戶", +"扑": "撲", +"执": "執", +"扩": "擴", +"扪": "捫", +"扫": "掃", +"扬": "揚", +"扰": "擾", +"抚": "撫", +"抛": "拋", +"抟": "摶", +"抠": "摳", +"抡": "掄", +"抢": "搶", +"护": "護", +"报": "報", +"拟": "擬", +"拢": "攏", +"拣": "揀", +"拥": "擁", +"拦": "攔", +"拧": "擰", +"拨": "撥", +"择": "擇", +"挂": "掛", +"挚": "摯", +"挛": "攣", +"挜": "掗", +"挝": "撾", +"挞": "撻", +"挟": "挾", +"挠": "撓", +"挡": "擋", +"挢": "撟", +"挣": "掙", +"挤": "擠", +"挥": "揮", +"挦": "撏", +"挽": "輓", +"捝": "挩", +"捞": "撈", +"损": "損", +"捡": "撿", +"换": "換", +"捣": "搗", +"掳": "擄", +"掴": "摑", +"掷": "擲", +"掸": "撣", +"掺": "摻", +"掼": "摜", +"揽": "攬", +"揾": "搵", +"揿": "撳", +"搀": "攙", +"搁": "擱", +"搂": "摟", +"搅": "攪", +"携": "攜", +"摄": "攝", +"摅": "攄", +"摆": "擺", +"摇": "搖", +"摈": "擯", +"摊": "攤", +"撄": "攖", +"撑": "撐", +"㧑": "撝", +"撵": "攆", +"撷": "擷", +"撸": "擼", +"撺": "攛", +"㧟": "擓", +"擞": "擻", +"攒": "攢", +"敌": "敵", +"敛": "斂", +"数": "數", +"斋": "齋", +"斓": "斕", +"斩": "斬", +"断": "斷", +"无": "無", +"旧": "舊", +"时": "時", +"旷": "曠", +"旸": "暘", +"昙": "曇", +"昼": "晝", +"昽": "曨", +"显": "顯", +"晋": "晉", +"晒": "曬", +"晓": "曉", +"晔": "曄", +"晕": "暈", +"晖": "暉", +"暂": "暫", +"暧": "曖", +"机": "機", +"杀": "殺", +"杂": "雜", +"权": "權", +"杆": "桿", +"条": "條", +"来": "來", +"杨": "楊", +"杩": "榪", +"杰": "傑", +"构": "構", +"枞": "樅", +"枢": "樞", +"枣": "棗", +"枥": "櫪", +"枧": "梘", +"枨": "棖", +"枪": "槍", +"枫": "楓", +"枭": "梟", +"柠": "檸", +"柽": "檉", +"栀": "梔", +"栅": "柵", +"标": "標", +"栈": "棧", +"栉": "櫛", +"栊": "櫳", +"栋": "棟", +"栌": "櫨", +"栎": "櫟", +"栏": "欄", +"树": "樹", +"栖": "棲", +"栗": "慄", +"样": "樣", +"栾": "欒", +"桠": "椏", +"桡": "橈", +"桢": "楨", +"档": "檔", +"桤": "榿", +"桥": "橋", +"桦": "樺", +"桧": "檜", +"桨": "槳", +"桩": "樁", +"梦": "夢", +"梼": "檮", +"梾": "棶", +"梿": "槤", +"检": "檢", +"棁": "梲", +"棂": "欞", +"椁": "槨", +"椟": "櫝", +"椠": "槧", +"椤": "欏", +"椭": "橢", +"楼": "樓", +"榄": "欖", +"榅": "榲", +"榇": "櫬", +"榈": "櫚", +"榉": "櫸", +"槚": "檟", +"槛": "檻", +"槟": "檳", +"槠": "櫧", +"横": "橫", +"樯": "檣", +"樱": "櫻", +"橥": "櫫", +"橱": "櫥", +"橹": "櫓", +"橼": "櫞", +"檩": "檁", +"欢": "歡", +"欤": "歟", +"欧": "歐", +"歼": "殲", +"殁": "歿", +"殇": "殤", +"残": "殘", +"殒": "殞", +"殓": "殮", +"殚": "殫", +"殡": "殯", +"㱮": "殨", +"㱩": "殰", +"殴": "毆", +"毁": "毀", +"毂": "轂", +"毕": "畢", +"毙": "斃", +"毡": "氈", +"毵": "毿", +"氇": "氌", +"气": "氣", +"氢": "氫", +"氩": "氬", +"氲": "氳", +"汉": "漢", +"汤": "湯", +"汹": "洶", +"沟": "溝", +"没": "沒", +"沣": "灃", +"沤": "漚", +"沥": "瀝", +"沦": "淪", +"沧": "滄", +"沪": "滬", +"泞": "濘", +"注": "註", +"泪": "淚", +"泶": "澩", +"泷": "瀧", +"泸": "瀘", +"泺": "濼", +"泻": "瀉", +"泼": "潑", +"泽": "澤", +"泾": "涇", +"洁": "潔", +"洒": "灑", +"洼": "窪", +"浃": "浹", +"浅": "淺", +"浆": "漿", +"浇": "澆", +"浈": "湞", +"浊": "濁", +"测": "測", +"浍": "澮", +"济": "濟", +"浏": "瀏", +"浐": "滻", +"浑": "渾", +"浒": "滸", +"浓": "濃", +"浔": "潯", +"涛": "濤", +"涝": "澇", +"涞": "淶", +"涟": "漣", +"涠": "潿", +"涡": "渦", +"涣": "渙", +"涤": "滌", +"润": "潤", +"涧": "澗", +"涨": "漲", +"涩": "澀", +"渊": "淵", +"渌": "淥", +"渍": "漬", +"渎": "瀆", +"渐": "漸", +"渑": "澠", +"渔": "漁", +"渖": "瀋", +"渗": "滲", +"温": "溫", +"湾": "灣", +"湿": "濕", +"溃": "潰", +"溅": "濺", +"溆": "漵", +"滗": "潷", +"滚": "滾", +"滞": "滯", +"滟": "灧", +"滠": "灄", +"满": "滿", +"滢": "瀅", +"滤": "濾", +"滥": "濫", +"滦": "灤", +"滨": "濱", +"滩": "灘", +"滪": "澦", +"漤": "灠", +"潆": "瀠", +"潇": "瀟", +"潋": "瀲", +"潍": "濰", +"潜": "潛", +"潴": "瀦", +"澜": "瀾", +"濑": "瀨", +"濒": "瀕", +"㲿": "瀇", +"灏": "灝", +"灭": "滅", +"灯": "燈", +"灵": "靈", +"灶": "竈", +"灾": "災", +"灿": "燦", +"炀": "煬", +"炉": "爐", +"炖": "燉", +"炜": "煒", +"炝": "熗", +"点": "點", +"炼": "煉", +"炽": "熾", +"烁": "爍", +"烂": "爛", +"烃": "烴", +"烛": "燭", +"烟": "煙", +"烦": "煩", +"烧": "燒", +"烨": "燁", +"烩": "燴", +"烫": "燙", +"烬": "燼", +"热": "熱", +"焕": "煥", +"焖": "燜", +"焘": "燾", +"㶽": "煱", +"煴": "熅", +"㶶": "燶", +"爱": "愛", +"爷": "爺", +"牍": "牘", +"牦": "氂", +"牵": "牽", +"牺": "犧", +"犊": "犢", +"状": "狀", +"犷": "獷", +"犸": "獁", +"犹": "猶", +"狈": "狽", +"狝": "獮", +"狞": "獰", +"独": "獨", +"狭": "狹", +"狮": "獅", +"狯": "獪", +"狰": "猙", +"狱": "獄", +"狲": "猻", +"猃": "獫", +"猎": "獵", +"猕": "獼", +"猡": "玀", +"猪": "豬", +"猫": "貓", +"猬": "蝟", +"献": "獻", +"獭": "獺", +"㺍": "獱", +"玑": "璣", +"玚": "瑒", +"玛": "瑪", +"玮": "瑋", +"环": "環", +"现": "現", +"玱": "瑲", +"玺": "璽", +"珐": "琺", +"珑": "瓏", +"珰": "璫", +"珲": "琿", +"琏": "璉", +"琐": "瑣", +"琼": "瓊", +"瑶": "瑤", +"瑷": "璦", +"璎": "瓔", +"瓒": "瓚", +"瓯": "甌", +"电": "電", +"画": "畫", +"畅": "暢", +"畴": "疇", +"疖": "癤", +"疗": "療", +"疟": "瘧", +"疠": "癘", +"疡": "瘍", +"疬": "癧", +"疭": "瘲", +"疮": "瘡", +"疯": "瘋", +"疱": "皰", +"疴": "痾", +"痈": "癰", +"痉": "痙", +"痒": "癢", +"痖": "瘂", +"痨": "癆", +"痪": "瘓", +"痫": "癇", +"瘅": "癉", +"瘆": "瘮", +"瘗": "瘞", +"瘪": "癟", +"瘫": "癱", +"瘾": "癮", +"瘿": "癭", +"癞": "癩", +"癣": "癬", +"癫": "癲", +"皑": "皚", +"皱": "皺", +"皲": "皸", +"盏": "盞", +"盐": "鹽", +"监": "監", +"盖": "蓋", +"盗": "盜", +"盘": "盤", +"眍": "瞘", +"眦": "眥", +"眬": "矓", +"睁": "睜", +"睐": "睞", +"睑": "瞼", +"瞆": "瞶", +"瞒": "瞞", +"䁖": "瞜", +"瞩": "矚", +"矫": "矯", +"矶": "磯", +"矾": "礬", +"矿": "礦", +"砀": "碭", +"码": "碼", +"砖": "磚", +"砗": "硨", +"砚": "硯", +"砜": "碸", +"砺": "礪", +"砻": "礱", +"砾": "礫", +"础": "礎", +"硁": "硜", +"硕": "碩", +"硖": "硤", +"硗": "磽", +"硙": "磑", +"碍": "礙", +"碛": "磧", +"碜": "磣", +"碱": "鹼", +"礼": "禮", +"祃": "禡", +"祎": "禕", +"祢": "禰", +"祯": "禎", +"祷": "禱", +"祸": "禍", +"禀": "稟", +"禄": "祿", +"禅": "禪", +"离": "離", +"秃": "禿", +"秆": "稈", +"积": "積", +"称": "稱", +"秽": "穢", +"秾": "穠", +"稆": "穭", +"税": "稅", +"䅉": "稏", +"稣": "穌", +"稳": "穩", +"穑": "穡", +"穷": "窮", +"窃": "竊", +"窍": "竅", +"窎": "窵", +"窑": "窯", +"窜": "竄", +"窝": "窩", +"窥": "窺", +"窦": "竇", +"窭": "窶", +"竞": "競", +"笃": "篤", +"笋": "筍", +"笔": "筆", +"笕": "筧", +"笺": "箋", +"笼": "籠", +"笾": "籩", +"筚": "篳", +"筛": "篩", +"筜": "簹", +"筝": "箏", +"䇲": "筴", +"筹": "籌", +"筼": "篔", +"简": "簡", +"箓": "籙", +"箦": "簀", +"箧": "篋", +"箨": "籜", +"箩": "籮", +"箪": "簞", +"箫": "簫", +"篑": "簣", +"篓": "簍", +"篮": "籃", +"篱": "籬", +"簖": "籪", +"籁": "籟", +"籴": "糴", +"类": "類", +"籼": "秈", +"粜": "糶", +"粝": "糲", +"粤": "粵", +"粪": "糞", +"粮": "糧", +"糁": "糝", +"糇": "餱", +"紧": "緊", +"䌷": "紬", +"䌹": "絅", +"絷": "縶", +"䌼": "綐", +"䌽": "綵", +"䌸": "縳", +"䍁": "繸", +"䍀": "繿", +"纟": "糹", +"纠": "糾", +"纡": "紆", +"红": "紅", +"纣": "紂", +"纥": "紇", +"约": "約", +"级": "級", +"纨": "紈", +"纩": "纊", +"纪": "紀", +"纫": "紉", +"纬": "緯", +"纭": "紜", +"纮": "紘", +"纯": "純", +"纰": "紕", +"纱": "紗", +"纲": "綱", +"纳": "納", +"纴": "紝", +"纵": "縱", +"纶": "綸", +"纷": "紛", +"纸": "紙", +"纹": "紋", +"纺": "紡", +"纻": "紵", +"纼": "紖", +"纽": "紐", +"纾": "紓", +"绀": "紺", +"绁": "紲", +"绂": "紱", +"练": "練", +"组": "組", +"绅": "紳", +"细": "細", +"织": "織", +"终": "終", +"绉": "縐", +"绊": "絆", +"绋": "紼", +"绌": "絀", +"绍": "紹", +"绎": "繹", +"经": "經", +"绐": "紿", +"绑": "綁", +"绒": "絨", +"结": "結", +"绔": "絝", +"绕": "繞", +"绖": "絰", +"绗": "絎", +"绘": "繪", +"给": "給", +"绚": "絢", +"绛": "絳", +"络": "絡", +"绞": "絞", +"统": "統", +"绠": "綆", +"绡": "綃", +"绢": "絹", +"绤": "綌", +"绥": "綏", +"继": "繼", +"绨": "綈", +"绩": "績", +"绪": "緒", +"绫": "綾", +"绬": "緓", +"续": "續", +"绮": "綺", +"绯": "緋", +"绰": "綽", +"绲": "緄", +"绳": "繩", +"维": "維", +"绵": "綿", +"绶": "綬", +"绸": "綢", +"绹": "綯", +"绺": "綹", +"绻": "綣", +"综": "綜", +"绽": "綻", +"绾": "綰", +"缀": "綴", +"缁": "緇", +"缂": "緙", +"缃": "緗", +"缄": "緘", +"缅": "緬", +"缆": "纜", +"缇": "緹", +"缈": "緲", +"缉": "緝", +"缊": "縕", +"缋": "繢", +"缌": "緦", +"缍": "綞", +"缎": "緞", +"缏": "緶", +"缑": "緱", +"缒": "縋", +"缓": "緩", +"缔": "締", +"缕": "縷", +"编": "編", +"缗": "緡", +"缘": "緣", +"缙": "縉", +"缚": "縛", +"缛": "縟", +"缜": "縝", +"缝": "縫", +"缞": "縗", +"缟": "縞", +"缠": "纏", +"缡": "縭", +"缢": "縊", +"缣": "縑", +"缤": "繽", +"缥": "縹", +"缦": "縵", +"缧": "縲", +"缨": "纓", +"缩": "縮", +"缪": "繆", +"缫": "繅", +"缬": "纈", +"缭": "繚", +"缮": "繕", +"缯": "繒", +"缱": "繾", +"缲": "繰", +"缳": "繯", +"缴": "繳", +"缵": "纘", +"罂": "罌", +"网": "網", +"罗": "羅", +"罚": "罰", +"罢": "罷", +"罴": "羆", +"羁": "羈", +"羟": "羥", +"翘": "翹", +"耢": "耮", +"耧": "耬", +"耸": "聳", +"耻": "恥", +"聂": "聶", +"聋": "聾", +"职": "職", +"聍": "聹", +"联": "聯", +"聩": "聵", +"聪": "聰", +"肃": "肅", +"肠": "腸", +"肤": "膚", +"肮": "骯", +"肴": "餚", +"肾": "腎", +"肿": "腫", +"胀": "脹", +"胁": "脅", +"胆": "膽", +"胧": "朧", +"胨": "腖", +"胪": "臚", +"胫": "脛", +"胶": "膠", +"脉": "脈", +"脍": "膾", +"脐": "臍", +"脑": "腦", +"脓": "膿", +"脔": "臠", +"脚": "腳", +"脱": "脫", +"脶": "腡", +"脸": "臉", +"腭": "齶", +"腻": "膩", +"腼": "靦", +"腽": "膃", +"腾": "騰", +"膑": "臏", +"臜": "臢", +"舆": "輿", +"舣": "艤", +"舰": "艦", +"舱": "艙", +"舻": "艫", +"艰": "艱", +"艳": "艷", +"艺": "藝", +"节": "節", +"芈": "羋", +"芗": "薌", +"芜": "蕪", +"芦": "蘆", +"苁": "蓯", +"苇": "葦", +"苈": "藶", +"苋": "莧", +"苌": "萇", +"苍": "蒼", +"苎": "苧", +"茎": "莖", +"茏": "蘢", +"茑": "蔦", +"茔": "塋", +"茕": "煢", +"茧": "繭", +"荆": "荊", +"荐": "薦", +"荙": "薘", +"荚": "莢", +"荛": "蕘", +"荜": "蓽", +"荞": "蕎", +"荟": "薈", +"荠": "薺", +"荣": "榮", +"荤": "葷", +"荥": "滎", +"荦": "犖", +"荧": "熒", +"荨": "蕁", +"荩": "藎", +"荪": "蓀", +"荫": "蔭", +"荬": "蕒", +"荭": "葒", +"荮": "葤", +"莅": "蒞", +"莱": "萊", +"莲": "蓮", +"莳": "蒔", +"莴": "萵", +"莶": "薟", +"莸": "蕕", +"莹": "瑩", +"莺": "鶯", +"萝": "蘿", +"萤": "螢", +"营": "營", +"萦": "縈", +"萧": "蕭", +"萨": "薩", +"葱": "蔥", +"蒇": "蕆", +"蒉": "蕢", +"蒋": "蔣", +"蒌": "蔞", +"蓝": "藍", +"蓟": "薊", +"蓠": "蘺", +"蓣": "蕷", +"蓥": "鎣", +"蓦": "驀", +"蔂": "虆", +"蔷": "薔", +"蔹": "蘞", +"蔺": "藺", +"蔼": "藹", +"蕰": "薀", +"蕲": "蘄", +"薮": "藪", +"䓕": "薳", +"藓": "蘚", +"蘖": "櫱", +"虏": "虜", +"虑": "慮", +"虚": "虛", +"虬": "虯", +"虮": "蟣", +"虽": "雖", +"虾": "蝦", +"虿": "蠆", +"蚀": "蝕", +"蚁": "蟻", +"蚂": "螞", +"蚕": "蠶", +"蚬": "蜆", +"蛊": "蠱", +"蛎": "蠣", +"蛏": "蟶", +"蛮": "蠻", +"蛰": "蟄", +"蛱": "蛺", +"蛲": "蟯", +"蛳": "螄", +"蛴": "蠐", +"蜕": "蛻", +"蜗": "蝸", +"蝇": "蠅", +"蝈": "蟈", +"蝉": "蟬", +"蝼": "螻", +"蝾": "蠑", +"螀": "螿", +"螨": "蟎", +"䗖": "螮", +"蟏": "蠨", +"衅": "釁", +"衔": "銜", +"补": "補", +"衬": "襯", +"衮": "袞", +"袄": "襖", +"袅": "裊", +"袆": "褘", +"袜": "襪", +"袭": "襲", +"袯": "襏", +"装": "裝", +"裆": "襠", +"裈": "褌", +"裢": "褳", +"裣": "襝", +"裤": "褲", +"裥": "襇", +"褛": "褸", +"褴": "襤", +"䙓": "襬", +"见": "見", +"观": "觀", +"觃": "覎", +"规": "規", +"觅": "覓", +"视": "視", +"觇": "覘", +"览": "覽", +"觉": "覺", +"觊": "覬", +"觋": "覡", +"觌": "覿", +"觍": "覥", +"觎": "覦", +"觏": "覯", +"觐": "覲", +"觑": "覷", +"觞": "觴", +"触": "觸", +"觯": "觶", +"訚": "誾", +"䜣": "訢", +"誉": "譽", +"誊": "謄", +"䜧": "譅", +"讠": "訁", +"计": "計", +"订": "訂", +"讣": "訃", +"认": "認", +"讥": "譏", +"讦": "訐", +"讧": "訌", +"讨": "討", +"让": "讓", +"讪": "訕", +"讫": "訖", +"讬": "託", +"训": "訓", +"议": "議", +"讯": "訊", +"记": "記", +"讱": "訒", +"讲": "講", +"讳": "諱", +"讴": "謳", +"讵": "詎", +"讶": "訝", +"讷": "訥", +"许": "許", +"讹": "訛", +"论": "論", +"讻": "訩", +"讼": "訟", +"讽": "諷", +"设": "設", +"访": "訪", +"诀": "訣", +"证": "證", +"诂": "詁", +"诃": "訶", +"评": "評", +"诅": "詛", +"识": "識", +"诇": "詗", +"诈": "詐", +"诉": "訴", +"诊": "診", +"诋": "詆", +"诌": "謅", +"词": "詞", +"诎": "詘", +"诏": "詔", +"诐": "詖", +"译": "譯", +"诒": "詒", +"诓": "誆", +"诔": "誄", +"试": "試", +"诖": "詿", +"诗": "詩", +"诘": "詰", +"诙": "詼", +"诚": "誠", +"诛": "誅", +"诜": "詵", +"话": "話", +"诞": "誕", +"诟": "詬", +"诠": "詮", +"诡": "詭", +"询": "詢", +"诣": "詣", +"诤": "諍", +"该": "該", +"详": "詳", +"诧": "詫", +"诨": "諢", +"诩": "詡", +"诪": "譸", +"诫": "誡", +"诬": "誣", +"语": "語", +"诮": "誚", +"误": "誤", +"诰": "誥", +"诱": "誘", +"诲": "誨", +"诳": "誑", +"诵": "誦", +"诶": "誒", +"请": "請", +"诸": "諸", +"诹": "諏", +"诺": "諾", +"读": "讀", +"诼": "諑", +"诽": "誹", +"课": "課", +"诿": "諉", +"谀": "諛", +"谁": "誰", +"谂": "諗", +"调": "調", +"谄": "諂", +"谅": "諒", +"谆": "諄", +"谇": "誶", +"谈": "談", +"谊": "誼", +"谋": "謀", +"谌": "諶", +"谍": "諜", +"谎": "謊", +"谏": "諫", +"谐": "諧", +"谑": "謔", +"谒": "謁", +"谓": "謂", +"谔": "諤", +"谕": "諭", +"谖": "諼", +"谗": "讒", +"谘": "諮", +"谙": "諳", +"谚": "諺", +"谛": "諦", +"谜": "謎", +"谝": "諞", +"谞": "諝", +"谟": "謨", +"谠": "讜", +"谡": "謖", +"谢": "謝", +"谤": "謗", +"谥": "謚", +"谦": "謙", +"谧": "謐", +"谨": "謹", +"谩": "謾", +"谪": "謫", +"谬": "謬", +"谭": "譚", +"谮": "譖", +"谯": "譙", +"谰": "讕", +"谱": "譜", +"谲": "譎", +"谳": "讞", +"谴": "譴", +"谵": "譫", +"谶": "讖", +"豮": "豶", +"䝙": "貙", +"䞐": "賰", +"贝": "貝", +"贞": "貞", +"负": "負", +"贠": "貟", +"贡": "貢", +"财": "財", +"责": "責", +"贤": "賢", +"败": "敗", +"账": "賬", +"货": "貨", +"质": "質", +"贩": "販", +"贪": "貪", +"贫": "貧", +"贬": "貶", +"购": "購", +"贮": "貯", +"贯": "貫", +"贰": "貳", +"贱": "賤", +"贲": "賁", +"贳": "貰", +"贴": "貼", +"贵": "貴", +"贶": "貺", +"贷": "貸", +"贸": "貿", +"费": "費", +"贺": "賀", +"贻": "貽", +"贼": "賊", +"贽": "贄", +"贾": "賈", +"贿": "賄", +"赀": "貲", +"赁": "賃", +"赂": "賂", +"资": "資", +"赅": "賅", +"赆": "贐", +"赇": "賕", +"赈": "賑", +"赉": "賚", +"赊": "賒", +"赋": "賦", +"赌": "賭", +"赎": "贖", +"赏": "賞", +"赐": "賜", +"赑": "贔", +"赒": "賙", +"赓": "賡", +"赔": "賠", +"赕": "賧", +"赖": "賴", +"赗": "賵", +"赘": "贅", +"赙": "賻", +"赚": "賺", +"赛": "賽", +"赜": "賾", +"赞": "贊", +"赟": "贇", +"赠": "贈", +"赡": "贍", +"赢": "贏", +"赣": "贛", +"赪": "赬", +"赵": "趙", +"赶": "趕", +"趋": "趨", +"趱": "趲", +"趸": "躉", +"跃": "躍", +"跄": "蹌", +"跞": "躒", +"践": "踐", +"跶": "躂", +"跷": "蹺", +"跸": "蹕", +"跹": "躚", +"跻": "躋", +"踊": "踴", +"踌": "躊", +"踪": "蹤", +"踬": "躓", +"踯": "躑", +"蹑": "躡", +"蹒": "蹣", +"蹰": "躕", +"蹿": "躥", +"躏": "躪", +"躜": "躦", +"躯": "軀", +"车": "車", +"轧": "軋", +"轨": "軌", +"轩": "軒", +"轪": "軑", +"轫": "軔", +"转": "轉", +"轭": "軛", +"轮": "輪", +"软": "軟", +"轰": "轟", +"轱": "軲", +"轲": "軻", +"轳": "轤", +"轴": "軸", +"轵": "軹", +"轶": "軼", +"轷": "軤", +"轸": "軫", +"轹": "轢", +"轺": "軺", +"轻": "輕", +"轼": "軾", +"载": "載", +"轾": "輊", +"轿": "轎", +"辀": "輈", +"辁": "輇", +"辂": "輅", +"较": "較", +"辄": "輒", +"辅": "輔", +"辆": "輛", +"辇": "輦", +"辈": "輩", +"辉": "輝", +"辊": "輥", +"辋": "輞", +"辌": "輬", +"辍": "輟", +"辎": "輜", +"辏": "輳", +"辐": "輻", +"辑": "輯", +"辒": "轀", +"输": "輸", +"辔": "轡", +"辕": "轅", +"辖": "轄", +"辗": "輾", +"辘": "轆", +"辙": "轍", +"辚": "轔", +"辞": "辭", +"辩": "辯", +"辫": "辮", +"边": "邊", +"辽": "遼", +"达": "達", +"迁": "遷", +"过": "過", +"迈": "邁", +"运": "運", +"还": "還", +"这": "這", +"进": "進", +"远": "遠", +"违": "違", +"连": "連", +"迟": "遲", +"迩": "邇", +"迳": "逕", +"迹": "跡", +"选": "選", +"逊": "遜", +"递": "遞", +"逦": "邐", +"逻": "邏", +"遗": "遺", +"遥": "遙", +"邓": "鄧", +"邝": "鄺", +"邬": "鄔", +"邮": "郵", +"邹": "鄒", +"邺": "鄴", +"邻": "鄰", +"郏": "郟", +"郐": "鄶", +"郑": "鄭", +"郓": "鄆", +"郦": "酈", +"郧": "鄖", +"郸": "鄲", +"酂": "酇", +"酦": "醱", +"酱": "醬", +"酽": "釅", +"酾": "釃", +"酿": "釀", +"释": "釋", +"鉴": "鑒", +"銮": "鑾", +"錾": "鏨", +"𨱏": "鎝", +"钅": "釒", +"钆": "釓", +"钇": "釔", +"针": "針", +"钉": "釘", +"钊": "釗", +"钋": "釙", +"钌": "釕", +"钍": "釷", +"钎": "釺", +"钏": "釧", +"钐": "釤", +"钑": "鈒", +"钒": "釩", +"钓": "釣", +"钔": "鍆", +"钕": "釹", +"钖": "鍚", +"钗": "釵", +"钘": "鈃", +"钙": "鈣", +"钚": "鈈", +"钛": "鈦", +"钜": "鉅", +"钝": "鈍", +"钞": "鈔", +"钠": "鈉", +"钡": "鋇", +"钢": "鋼", +"钣": "鈑", +"钤": "鈐", +"钥": "鑰", +"钦": "欽", +"钧": "鈞", +"钨": "鎢", +"钪": "鈧", +"钫": "鈁", +"钬": "鈥", +"钭": "鈄", +"钮": "鈕", +"钯": "鈀", +"钰": "鈺", +"钱": "錢", +"钲": "鉦", +"钳": "鉗", +"钴": "鈷", +"钶": "鈳", +"钷": "鉕", +"钸": "鈽", +"钹": "鈸", +"钺": "鉞", +"钻": "鑽", +"钼": "鉬", +"钽": "鉭", +"钾": "鉀", +"钿": "鈿", +"铀": "鈾", +"铁": "鐵", +"铂": "鉑", +"铃": "鈴", +"铄": "鑠", +"铅": "鉛", +"铆": "鉚", +"铇": "鉋", +"铈": "鈰", +"铉": "鉉", +"铊": "鉈", +"铋": "鉍", +"铌": "鈮", +"铍": "鈹", +"铎": "鐸", +"铏": "鉶", +"铐": "銬", +"铑": "銠", +"铒": "鉺", +"铓": "鋩", +"铔": "錏", +"铕": "銪", +"铖": "鋮", +"铗": "鋏", +"铘": "鋣", +"铙": "鐃", +"铚": "銍", +"铛": "鐺", +"铜": "銅", +"铝": "鋁", +"铞": "銱", +"铟": "銦", +"铠": "鎧", +"铡": "鍘", +"铢": "銖", +"铣": "銑", +"铤": "鋌", +"铥": "銩", +"铦": "銛", +"铧": "鏵", +"铨": "銓", +"铩": "鎩", +"铪": "鉿", +"铫": "銚", +"铬": "鉻", +"铭": "銘", +"铮": "錚", +"铯": "銫", +"铰": "鉸", +"铱": "銥", +"铲": "鏟", +"铳": "銃", +"铴": "鐋", +"铵": "銨", +"银": "銀", +"铷": "銣", +"铸": "鑄", +"铹": "鐒", +"铺": "鋪", +"铻": "鋙", +"铼": "錸", +"铽": "鋱", +"链": "鏈", +"铿": "鏗", +"销": "銷", +"锁": "鎖", +"锂": "鋰", +"锃": "鋥", +"锄": "鋤", +"锅": "鍋", +"锆": "鋯", +"锇": "鋨", +"锉": "銼", +"锊": "鋝", +"锋": "鋒", +"锌": "鋅", +"锍": "鋶", +"锎": "鐦", +"锏": "鐧", +"锑": "銻", +"锒": "鋃", +"锓": "鋟", +"锔": "鋦", +"锕": "錒", +"锖": "錆", +"锗": "鍺", +"锘": "鍩", +"错": "錯", +"锚": "錨", +"锛": "錛", +"锜": "錡", +"锝": "鍀", +"锞": "錁", +"锟": "錕", +"锠": "錩", +"锡": "錫", +"锢": "錮", +"锣": "鑼", +"锥": "錐", +"锦": "錦", +"锧": "鑕", +"锩": "錈", +"锪": "鍃", +"锫": "錇", +"锬": "錟", +"锭": "錠", +"键": "鍵", +"锯": "鋸", +"锰": "錳", +"锱": "錙", +"锲": "鍥", +"锳": "鍈", +"锴": "鍇", +"锵": "鏘", +"锶": "鍶", +"锷": "鍔", +"锸": "鍤", +"锹": "鍬", +"锺": "鍾", +"锻": "鍛", +"锼": "鎪", +"锽": "鍠", +"锾": "鍰", +"锿": "鎄", +"镀": "鍍", +"镁": "鎂", +"镂": "鏤", +"镃": "鎡", +"镄": "鐨", +"镅": "鎇", +"镆": "鏌", +"镇": "鎮", +"镈": "鎛", +"镉": "鎘", +"镊": "鑷", +"镋": "鎲", +"镍": "鎳", +"镎": "鎿", +"镏": "鎦", +"镐": "鎬", +"镑": "鎊", +"镒": "鎰", +"镓": "鎵", +"镔": "鑌", +"镕": "鎔", +"镖": "鏢", +"镗": "鏜", +"镘": "鏝", +"镙": "鏍", +"镚": "鏰", +"镛": "鏞", +"镜": "鏡", +"镝": "鏑", +"镞": "鏃", +"镟": "鏇", +"镠": "鏐", +"镡": "鐔", +"镣": "鐐", +"镤": "鏷", +"镥": "鑥", +"镦": "鐓", +"镧": "鑭", +"镨": "鐠", +"镩": "鑹", +"镪": "鏹", +"镫": "鐙", +"镬": "鑊", +"镭": "鐳", +"镮": "鐶", +"镯": "鐲", +"镰": "鐮", +"镱": "鐿", +"镲": "鑔", +"镳": "鑣", +"镴": "鑞", +"镵": "鑱", +"镶": "鑲", +"长": "長", +"门": "門", +"闩": "閂", +"闪": "閃", +"闫": "閆", +"闬": "閈", +"闭": "閉", +"问": "問", +"闯": "闖", +"闰": "閏", +"闱": "闈", +"闲": "閑", +"闳": "閎", +"间": "間", +"闵": "閔", +"闶": "閌", +"闷": "悶", +"闸": "閘", +"闹": "鬧", +"闺": "閨", +"闻": "聞", +"闼": "闥", +"闽": "閩", +"闾": "閭", +"闿": "闓", +"阀": "閥", +"阁": "閣", +"阂": "閡", +"阃": "閫", +"阄": "鬮", +"阆": "閬", +"阇": "闍", +"阈": "閾", +"阉": "閹", +"阊": "閶", +"阋": "鬩", +"阌": "閿", +"阍": "閽", +"阎": "閻", +"阏": "閼", +"阐": "闡", +"阑": "闌", +"阒": "闃", +"阓": "闠", +"阔": "闊", +"阕": "闋", +"阖": "闔", +"阗": "闐", +"阘": "闒", +"阙": "闕", +"阚": "闞", +"阛": "闤", +"队": "隊", +"阳": "陽", +"阴": "陰", +"阵": "陣", +"阶": "階", +"际": "際", +"陆": "陸", +"陇": "隴", +"陈": "陳", +"陉": "陘", +"陕": "陝", +"陧": "隉", +"陨": "隕", +"险": "險", +"随": "隨", +"隐": "隱", +"隶": "隸", +"隽": "雋", +"难": "難", +"雏": "雛", +"雠": "讎", +"雳": "靂", +"雾": "霧", +"霁": "霽", +"霡": "霢", +"霭": "靄", +"靓": "靚", +"静": "靜", +"靥": "靨", +"䩄": "靦", +"鞑": "韃", +"鞒": "鞽", +"鞯": "韉", +"韦": "韋", +"韧": "韌", +"韨": "韍", +"韩": "韓", +"韪": "韙", +"韫": "韞", +"韬": "韜", +"韵": "韻", +"页": "頁", +"顶": "頂", +"顷": "頃", +"顸": "頇", +"项": "項", +"顺": "順", +"顼": "頊", +"顽": "頑", +"顾": "顧", +"顿": "頓", +"颀": "頎", +"颁": "頒", +"颂": "頌", +"颃": "頏", +"预": "預", +"颅": "顱", +"领": "領", +"颇": "頗", +"颈": "頸", +"颉": "頡", +"颊": "頰", +"颋": "頲", +"颌": "頜", +"颍": "潁", +"颎": "熲", +"颏": "頦", +"颐": "頤", +"频": "頻", +"颒": "頮", +"颔": "頷", +"颕": "頴", +"颖": "穎", +"颗": "顆", +"题": "題", +"颙": "顒", +"颚": "顎", +"颛": "顓", +"额": "額", +"颞": "顳", +"颟": "顢", +"颠": "顛", +"颡": "顙", +"颢": "顥", +"颤": "顫", +"颥": "顬", +"颦": "顰", +"颧": "顴", +"风": "風", +"飏": "颺", +"飐": "颭", +"飑": "颮", +"飒": "颯", +"飓": "颶", +"飔": "颸", +"飕": "颼", +"飖": "颻", +"飗": "飀", +"飘": "飄", +"飙": "飆", +"飚": "飈", +"飞": "飛", +"飨": "饗", +"餍": "饜", +"饣": "飠", +"饤": "飣", +"饦": "飥", +"饧": "餳", +"饨": "飩", +"饩": "餼", +"饪": "飪", +"饫": "飫", +"饬": "飭", +"饭": "飯", +"饮": "飲", +"饯": "餞", +"饰": "飾", +"饱": "飽", +"饲": "飼", +"饳": "飿", +"饴": "飴", +"饵": "餌", +"饶": "饒", +"饷": "餉", +"饸": "餄", +"饹": "餎", +"饺": "餃", +"饻": "餏", +"饼": "餅", +"饽": "餑", +"饾": "餖", +"饿": "餓", +"馀": "餘", +"馁": "餒", +"馂": "餕", +"馃": "餜", +"馄": "餛", +"馅": "餡", +"馆": "館", +"馇": "餷", +"馈": "饋", +"馉": "餶", +"馊": "餿", +"馋": "饞", +"馌": "饁", +"馍": "饃", +"馎": "餺", +"馏": "餾", +"馐": "饈", +"馑": "饉", +"馒": "饅", +"馓": "饊", +"馔": "饌", +"馕": "饢", +"䯄": "騧", +"马": "馬", +"驭": "馭", +"驮": "馱", +"驯": "馴", +"驰": "馳", +"驱": "驅", +"驲": "馹", +"驳": "駁", +"驴": "驢", +"驵": "駔", +"驶": "駛", +"驷": "駟", +"驸": "駙", +"驹": "駒", +"驺": "騶", +"驻": "駐", +"驼": "駝", +"驽": "駑", +"驾": "駕", +"驿": "驛", +"骀": "駘", +"骁": "驍", +"骃": "駰", +"骄": "驕", +"骅": "驊", +"骆": "駱", +"骇": "駭", +"骈": "駢", +"骉": "驫", +"骊": "驪", +"骋": "騁", +"验": "驗", +"骍": "騂", +"骎": "駸", +"骏": "駿", +"骐": "騏", +"骑": "騎", +"骒": "騍", +"骓": "騅", +"骔": "騌", +"骕": "驌", +"骖": "驂", +"骗": "騙", +"骘": "騭", +"骙": "騤", +"骚": "騷", +"骛": "騖", +"骜": "驁", +"骝": "騮", +"骞": "騫", +"骟": "騸", +"骠": "驃", +"骡": "騾", +"骢": "驄", +"骣": "驏", +"骤": "驟", +"骥": "驥", +"骦": "驦", +"骧": "驤", +"髅": "髏", +"髋": "髖", +"髌": "髕", +"鬓": "鬢", +"魇": "魘", +"魉": "魎", +"鱼": "魚", +"鱽": "魛", +"鱾": "魢", +"鱿": "魷", +"鲀": "魨", +"鲁": "魯", +"鲂": "魴", +"鲃": "䰾", +"鲄": "魺", +"鲅": "鮁", +"鲆": "鮃", +"鲈": "鱸", +"鲉": "鮋", +"鲊": "鮓", +"鲋": "鮒", +"鲌": "鮊", +"鲍": "鮑", +"鲎": "鱟", +"鲏": "鮍", +"鲐": "鮐", +"鲑": "鮭", +"鲒": "鮚", +"鲓": "鮳", +"鲔": "鮪", +"鲕": "鮞", +"鲖": "鮦", +"鲗": "鰂", +"鲘": "鮜", +"鲙": "鱠", +"鲚": "鱭", +"鲛": "鮫", +"鲜": "鮮", +"鲝": "鮺", +"鲟": "鱘", +"鲠": "鯁", +"鲡": "鱺", +"鲢": "鰱", +"鲣": "鰹", +"鲤": "鯉", +"鲥": "鰣", +"鲦": "鰷", +"鲧": "鯀", +"鲨": "鯊", +"鲩": "鯇", +"鲪": "鮶", +"鲫": "鯽", +"鲬": "鯒", +"鲭": "鯖", +"鲮": "鯪", +"鲯": "鯕", +"鲰": "鯫", +"鲱": "鯡", +"鲲": "鯤", +"鲳": "鯧", +"鲴": "鯝", +"鲵": "鯢", +"鲶": "鯰", +"鲷": "鯛", +"鲸": "鯨", +"鲹": "鰺", +"鲺": "鯴", +"鲻": "鯔", +"鲼": "鱝", +"鲽": "鰈", +"鲾": "鰏", +"鲿": "鱨", +"鳀": "鯷", +"鳁": "鰮", +"鳂": "鰃", +"鳃": "鰓", +"鳅": "鰍", +"鳆": "鰒", +"鳇": "鰉", +"鳈": "鰁", +"鳉": "鱂", +"鳊": "鯿", +"鳋": "鰠", +"鳌": "鰲", +"鳍": "鰭", +"鳎": "鰨", +"鳏": "鰥", +"鳐": "鰩", +"鳑": "鰟", +"鳒": "鰜", +"鳓": "鰳", +"鳔": "鰾", +"鳕": "鱈", +"鳖": "鱉", +"鳗": "鰻", +"鳘": "鰵", +"鳙": "鱅", +"鳚": "䲁", +"鳛": "鰼", +"鳜": "鱖", +"鳝": "鱔", +"鳞": "鱗", +"鳟": "鱒", +"鳠": "鱯", +"鳡": "鱤", +"鳢": "鱧", +"鳣": "鱣", +"䴓": "鳾", +"䴕": "鴷", +"䴔": "鵁", +"䴖": "鶄", +"䴗": "鶪", +"䴘": "鷈", +"䴙": "鷿", +"㶉": "鸂", +"鸟": "鳥", +"鸠": "鳩", +"鸢": "鳶", +"鸣": "鳴", +"鸤": "鳲", +"鸥": "鷗", +"鸦": "鴉", +"鸧": "鶬", +"鸨": "鴇", +"鸩": "鴆", +"鸪": "鴣", +"鸫": "鶇", +"鸬": "鸕", +"鸭": "鴨", +"鸮": "鴞", +"鸯": "鴦", +"鸰": "鴒", +"鸱": "鴟", +"鸲": "鴝", +"鸳": "鴛", +"鸴": "鷽", +"鸵": "鴕", +"鸶": "鷥", +"鸷": "鷙", +"鸸": "鴯", +"鸹": "鴰", +"鸺": "鵂", +"鸻": "鴴", +"鸼": "鵃", +"鸽": "鴿", +"鸾": "鸞", +"鸿": "鴻", +"鹀": "鵐", +"鹁": "鵓", +"鹂": "鸝", +"鹃": "鵑", +"鹄": "鵠", +"鹅": "鵝", +"鹆": "鵒", +"鹇": "鷳", +"鹈": "鵜", +"鹉": "鵡", +"鹊": "鵲", +"鹋": "鶓", +"鹌": "鵪", +"鹍": "鵾", +"鹎": "鵯", +"鹏": "鵬", +"鹐": "鵮", +"鹑": "鶉", +"鹒": "鶊", +"鹓": "鵷", +"鹔": "鷫", +"鹕": "鶘", +"鹖": "鶡", +"鹗": "鶚", +"鹘": "鶻", +"鹙": "鶖", +"鹛": "鶥", +"鹜": "鶩", +"鹝": "鷊", +"鹞": "鷂", +"鹟": "鶲", +"鹠": "鶹", +"鹡": "鶺", +"鹢": "鷁", +"鹣": "鶼", +"鹤": "鶴", +"鹥": "鷖", +"鹦": "鸚", +"鹧": "鷓", +"鹨": "鷚", +"鹩": "鷯", +"鹪": "鷦", +"鹫": "鷲", +"鹬": "鷸", +"鹭": "鷺", +"鹯": "鸇", +"鹰": "鷹", +"鹱": "鸌", +"鹲": "鸏", +"鹳": "鸛", +"鹴": "鸘", +"鹾": "鹺", +"麦": "麥", +"麸": "麩", +"黄": "黃", +"黉": "黌", +"黡": "黶", +"黩": "黷", +"黪": "黲", +"黾": "黽", +"鼋": "黿", +"鼍": "鼉", +"鼗": "鞀", +"鼹": "鼴", +"齐": "齊", +"齑": "齏", +"齿": "齒", +"龀": "齔", +"龁": "齕", +"龂": "齗", +"龃": "齟", +"龄": "齡", +"龅": "齙", +"龆": "齠", +"龇": "齜", +"龈": "齦", +"龉": "齬", +"龊": "齪", +"龋": "齲", +"龌": "齷", +"龙": "龍", +"龚": "龔", +"龛": "龕", +"龟": "龜", +"一伙": "一伙", +"一并": "一併", +"一准": "一准", +"一划": "一划", +"一地里": "一地裡", +"一干": "一干", +"一树百获": "一樹百穫", +"一台": "一臺", +"一冲": "一衝", +"一只": "一隻", +"一发千钧": "一髮千鈞", +"一出": "一齣", +"七只": "七隻", +"三元里": "三元裡", +"三国志": "三國誌", +"三复": "三複", +"三只": "三隻", +"上吊": "上吊", +"上台": "上臺", +"下不了台": "下不了臺", +"下台": "下臺", +"下面": "下麵", +"不准": "不准", +"不吊": "不吊", +"不知就里": "不知就裡", +"不知所云": "不知所云", +"不锈钢": "不鏽鋼", +"丑剧": "丑劇", +"丑旦": "丑旦", +"丑角": "丑角", +"并存着": "並存著", +"中岳": "中嶽", +"中台医专": "中臺醫專", +"丰南": "丰南", +"丰台": "丰台", +"丰姿": "丰姿", +"丰采": "丰采", +"丰韵": "丰韻", +"主干": "主幹", +"么么唱唱": "么么唱唱", +"么儿": "么兒", +"么喝": "么喝", +"么妹": "么妹", +"么弟": "么弟", +"么爷": "么爺", +"九世之雠": "九世之讎", +"九只": "九隻", +"干丝": "乾絲", +"干着急": "乾著急", +"乱发": "亂髮", +"云云": "云云", +"云尔": "云爾", +"五岳": "五嶽", +"五斗柜": "五斗櫃", +"五斗橱": "五斗櫥", +"五谷": "五穀", +"五行生克": "五行生剋", +"五只": "五隻", +"五出": "五齣", +"交卷": "交卷", +"人云亦云": "人云亦云", +"人物志": "人物誌", +"什锦面": "什錦麵", +"什么": "什麼", +"仆倒": "仆倒", +"介系词": "介係詞", +"介系词": "介繫詞", +"仿制": "仿製", +"伙伕": "伙伕", +"伙伴": "伙伴", +"伙同": "伙同", +"伙夫": "伙夫", +"伙房": "伙房", +"伙计": "伙計", +"伙食": "伙食", +"布下": "佈下", +"布告": "佈告", +"布哨": "佈哨", +"布局": "佈局", +"布岗": "佈崗", +"布施": "佈施", +"布景": "佈景", +"布满": "佈滿", +"布线": "佈線", +"布置": "佈置", +"布署": "佈署", +"布道": "佈道", +"布达": "佈達", +"布防": "佈防", +"布阵": "佈陣", +"布雷": "佈雷", +"体育锻鍊": "体育鍛鍊", +"何干": "何干", +"作准": "作准", +"佣人": "佣人", +"佣工": "佣工", +"佣金": "佣金", +"并入": "併入", +"并列": "併列", +"并到": "併到", +"并合": "併合", +"并吞": "併吞", +"并在": "併在", +"并成": "併成", +"并排": "併排", +"并拢": "併攏", +"并案": "併案", +"并为": "併為", +"并发": "併發", +"并科": "併科", +"并购": "併購", +"并进": "併進", +"来复": "來複", +"供制": "供製", +"依依不舍": "依依不捨", +"侵并": "侵併", +"便辟": "便辟", +"系数": "係數", +"系为": "係為", +"保险柜": "保險柜", +"信号台": "信號臺", +"修复": "修複", +"修胡刀": "修鬍刀", +"俯冲": "俯衝", +"个里": "個裡", +"借着": "借著", +"假发": "假髮", +"停制": "停製", +"偷鸡不着": "偷雞不著", +"家伙": "傢伙", +"家俱": "傢俱", +"家具": "傢具", +"传布": "傳佈", +"债台高筑": "債臺高築", +"傻里傻气": "傻裡傻氣", +"倾家荡产": "傾家蕩產", +"倾覆": "傾複", +"倾覆": "傾覆", +"僱佣": "僱佣", +"仪表": "儀錶", +"亿只": "億隻", +"尽尽": "儘儘", +"尽先": "儘先", +"尽其所有": "儘其所有", +"尽力": "儘力", +"尽快": "儘快", +"尽早": "儘早", +"尽是": "儘是", +"尽管": "儘管", +"尽速": "儘速", +"尽量": "儘量", +"允准": "允准", +"兄台": "兄臺", +"充饥": "充饑", +"光采": "光采", +"克里": "克裡", +"克复": "克複", +"入伙": "入伙", +"内制": "內製", +"两只": "兩隻", +"八字胡": "八字鬍", +"八只": "八隻", +"公布": "公佈", +"公干": "公幹", +"公斗": "公斗", +"公历": "公曆", +"六只": "六隻", +"六出": "六齣", +"兼并": "兼併", +"冤雠": "冤讎", +"准予": "准予", +"准假": "准假", +"准将": "准將", +"准考证": "准考證", +"准许": "准許", +"几几": "几几", +"几案": "几案", +"几丝": "几絲", +"凹洞里": "凹洞裡", +"出征": "出征", +"出锤": "出鎚", +"刀削面": "刀削麵", +"刁斗": "刁斗", +"分布": "分佈", +"切面": "切麵", +"刊布": "刊佈", +"划上": "划上", +"划下": "划下", +"划不来": "划不來", +"划了": "划了", +"划具": "划具", +"划出": "划出", +"划到": "划到", +"划动": "划動", +"划去": "划去", +"划子": "划子", +"划得来": "划得來", +"划拳": "划拳", +"划桨": "划槳", +"划水": "划水", +"划算": "划算", +"划船": "划船", +"划艇": "划艇", +"划着": "划著", +"划着走": "划著走", +"划行": "划行", +"划走": "划走", +"划起": "划起", +"划进": "划進", +"划过": "划過", +"初征": "初征", +"别致": "別緻", +"别着": "別著", +"别只": "別隻", +"利比里亚": "利比裡亞", +"刮着": "刮著", +"刮胡刀": "刮鬍刀", +"剃发": "剃髮", +"剃须": "剃鬚", +"削发": "削髮", +"克制": "剋制", +"克星": "剋星", +"克服": "剋服", +"克死": "剋死", +"克薄": "剋薄", +"前仆后继": "前仆後繼", +"前台": "前臺", +"前车之复": "前車之覆", +"刚才": "剛纔", +"剪发": "剪髮", +"割舍": "割捨", +"创制": "創製", +"加里宁": "加裡寧", +"动荡": "動蕩", +"劳力士表": "勞力士錶", +"包准": "包准", +"包谷": "包穀", +"北斗": "北斗", +"北回": "北迴", +"匡复": "匡複", +"匪干": "匪幹", +"十卷": "十卷", +"十台": "十臺", +"十只": "十隻", +"十出": "十齣", +"千丝万缕": "千絲萬縷", +"千回百折": "千迴百折", +"千回百转": "千迴百轉", +"千钧一发": "千鈞一髮", +"千只": "千隻", +"升斗小民": "升斗小民", +"半只": "半隻", +"南岳": "南嶽", +"南征": "南征", +"南台": "南臺", +"南回": "南迴", +"卡里": "卡裡", +"印制": "印製", +"卷入": "卷入", +"卷取": "卷取", +"卷土重来": "卷土重來", +"卷子": "卷子", +"卷宗": "卷宗", +"卷尺": "卷尺", +"卷层云": "卷層雲", +"卷帙": "卷帙", +"卷扬机": "卷揚機", +"卷曲": "卷曲", +"卷染": "卷染", +"卷烟": "卷煙", +"卷筒": "卷筒", +"卷纬": "卷緯", +"卷绕": "卷繞", +"卷装": "卷裝", +"卷轴": "卷軸", +"卷云": "卷雲", +"卷领": "卷領", +"卷发": "卷髮", +"卷须": "卷鬚", +"参与": "參与", +"参与者": "參与者", +"参合": "參合", +"参考价值": "參考價值", +"参与": "參與", +"参与人员": "參與人員", +"参与制": "參與制", +"参与感": "參與感", +"参与者": "參與者", +"参观团": "參觀團", +"参观团体": "參觀團體", +"参阅": "參閱", +"反冲": "反衝", +"反复": "反複", +"反复": "反覆", +"取舍": "取捨", +"口里": "口裡", +"只准": "只准", +"只冲": "只衝", +"叮当": "叮噹", +"可怜虫": "可憐虫", +"可紧可松": "可緊可鬆", +"台制": "台製", +"司令台": "司令臺", +"吃着不尽": "吃著不盡", +"吃里扒外": "吃裡扒外", +"吃里爬外": "吃裡爬外", +"各吊": "各吊", +"合伙": "合伙", +"合并": "合併", +"吊上": "吊上", +"吊下": "吊下", +"吊了": "吊了", +"吊个": "吊個", +"吊儿郎当": "吊兒郎當", +"吊到": "吊到", +"吊去": "吊去", +"吊取": "吊取", +"吊吊": "吊吊", +"吊嗓": "吊嗓", +"吊好": "吊好", +"吊子": "吊子", +"吊带": "吊帶", +"吊带裤": "吊帶褲", +"吊床": "吊床", +"吊得": "吊得", +"吊挂": "吊掛", +"吊挂着": "吊掛著", +"吊杆": "吊杆", +"吊架": "吊架", +"吊桶": "吊桶", +"吊杆": "吊桿", +"吊桥": "吊橋", +"吊死": "吊死", +"吊灯": "吊燈", +"吊环": "吊環", +"吊盘": "吊盤", +"吊索": "吊索", +"吊着": "吊著", +"吊装": "吊裝", +"吊裤": "吊褲", +"吊裤带": "吊褲帶", +"吊袜": "吊襪", +"吊走": "吊走", +"吊起": "吊起", +"吊车": "吊車", +"吊钩": "吊鉤", +"吊销": "吊銷", +"吊钟": "吊鐘", +"同伙": "同伙", +"名表": "名錶", +"后冠": "后冠", +"后土": "后土", +"后妃": "后妃", +"后座": "后座", +"后稷": "后稷", +"后羿": "后羿", +"后里": "后里", +"向着": "向著", +"吞并": "吞併", +"吹发": "吹髮", +"吕后": "呂后", +"獃里獃气": "呆裡呆氣", +"周而复始": "周而複始", +"呼吁": "呼籲", +"和面": "和麵", +"哪里": "哪裡", +"哭脏": "哭髒", +"问卷": "問卷", +"喝采": "喝采", +"单干": "單干", +"单只": "單隻", +"嘴里": "嘴裡", +"恶心": "噁心", +"当啷": "噹啷", +"当当": "噹噹", +"噜苏": "嚕囌", +"向导": "嚮導", +"向往": "嚮往", +"向应": "嚮應", +"向日": "嚮日", +"向迩": "嚮邇", +"严丝合缝": "嚴絲合縫", +"严复": "嚴複", +"四舍五入": "四捨五入", +"四只": "四隻", +"四出": "四齣", +"回丝": "回絲", +"回着": "回著", +"回荡": "回蕩", +"回复": "回覆", +"回采": "回采", +"圈子里": "圈子裡", +"圈里": "圈裡", +"国历": "國曆", +"国雠": "國讎", +"园里": "園裡", +"图里": "圖裡", +"土里": "土裡", +"土制": "土製", +"地志": "地誌", +"坍台": "坍臺", +"坑里": "坑裡", +"坦荡": "坦蕩", +"垂发": "垂髮", +"垮台": "垮臺", +"埋布": "埋佈", +"城里": "城裡", +"基干": "基幹", +"报复": "報複", +"塌台": "塌臺", +"塔台": "塔臺", +"涂着": "塗著", +"墓志": "墓誌", +"墨斗": "墨斗", +"墨索里尼": "墨索裡尼", +"垦复": "墾複", +"垄断价格": "壟斷價格", +"垄断资产": "壟斷資產", +"垄断集团": "壟斷集團", +"壶里": "壺裡", +"寿面": "壽麵", +"夏天里": "夏天裡", +"夏历": "夏曆", +"外制": "外製", +"多冲": "多衝", +"多采多姿": "多采多姿", +"多么": "多麼", +"夜光表": "夜光錶", +"夜里": "夜裡", +"梦里": "夢裡", +"大伙": "大伙", +"大卷": "大卷", +"大干": "大干", +"大干": "大幹", +"大锤": "大鎚", +"大只": "大隻", +"天后": "天后", +"天干": "天干", +"天文台": "天文臺", +"太后": "太后", +"奏折": "奏摺", +"女丑": "女丑", +"女佣": "女佣", +"好家夥": "好傢夥", +"好戏连台": "好戲連臺", +"如法泡制": "如法泡製", +"妆台": "妝臺", +"姜太公": "姜太公", +"姜子牙": "姜子牙", +"姜丝": "姜絲", +"字汇": "字彙", +"字里行间": "字裡行間", +"存折": "存摺", +"孟姜女": "孟姜女", +"宇宙志": "宇宙誌", +"定准": "定准", +"定制": "定製", +"宣布": "宣佈", +"宫里": "宮裡", +"家伙": "家伙", +"家里": "家裡", +"密布": "密佈", +"寇雠": "寇讎", +"实干": "實幹", +"写字台": "寫字檯", +"写字台": "寫字臺", +"宽松": "寬鬆", +"封面里": "封面裡", +"射干": "射干", +"对表": "對錶", +"小丑": "小丑", +"小伙": "小伙", +"小只": "小隻", +"少吊": "少吊", +"尺布斗粟": "尺布斗粟", +"尼克松": "尼克鬆", +"尼采": "尼采", +"尿斗": "尿斗", +"局里": "局裡", +"居里": "居裡", +"屋子里": "屋子裡", +"屋里": "屋裡", +"展布": "展佈", +"屡仆屡起": "屢仆屢起", +"屯里": "屯裡", +"山岳": "山嶽", +"山里": "山裡", +"峰回": "峰迴", +"巡回": "巡迴", +"巧干": "巧幹", +"巴尔干": "巴爾幹", +"巴里": "巴裡", +"巷里": "巷裡", +"市里": "市裡", +"布谷": "布穀", +"希腊": "希腊", +"帘子": "帘子", +"帘布": "帘布", +"席卷": "席卷", +"带团参加": "帶團參加", +"带发修行": "帶髮修行", +"干休": "干休", +"干系": "干係", +"干卿何事": "干卿何事", +"干将": "干將", +"干戈": "干戈", +"干挠": "干撓", +"干扰": "干擾", +"干支": "干支", +"干政": "干政", +"干时": "干時", +"干涉": "干涉", +"干犯": "干犯", +"干与": "干與", +"干着急": "干著急", +"干贝": "干貝", +"干预": "干預", +"平台": "平臺", +"年历": "年曆", +"年里": "年裡", +"干上": "幹上", +"干下去": "幹下去", +"干了": "幹了", +"干事": "幹事", +"干些": "幹些", +"干个": "幹個", +"干劲": "幹勁", +"干员": "幹員", +"干吗": "幹嗎", +"干嘛": "幹嘛", +"干坏事": "幹壞事", +"干完": "幹完", +"干得": "幹得", +"干性油": "幹性油", +"干才": "幹才", +"干掉": "幹掉", +"干校": "幹校", +"干活": "幹活", +"干流": "幹流", +"干球温度": "幹球溫度", +"干线": "幹線", +"干练": "幹練", +"干警": "幹警", +"干起来": "幹起來", +"干路": "幹路", +"干道": "幹道", +"干部": "幹部", +"干么": "幹麼", +"几丝": "幾絲", +"几只": "幾隻", +"几出": "幾齣", +"底里": "底裡", +"康采恩": "康采恩", +"庙里": "廟裡", +"建台": "建臺", +"弄脏": "弄髒", +"弔卷": "弔卷", +"弘历": "弘曆", +"别扭": "彆扭", +"别拗": "彆拗", +"别气": "彆氣", +"别脚": "彆腳", +"别着": "彆著", +"弹子台": "彈子檯", +"弹药": "彈葯", +"汇报": "彙報", +"汇整": "彙整", +"汇编": "彙編", +"汇总": "彙總", +"汇纂": "彙纂", +"汇辑": "彙輯", +"汇集": "彙集", +"形单影只": "形單影隻", +"影后": "影后", +"往里": "往裡", +"往复": "往複", +"征伐": "征伐", +"征兵": "征兵", +"征尘": "征塵", +"征夫": "征夫", +"征战": "征戰", +"征收": "征收", +"征服": "征服", +"征求": "征求", +"征发": "征發", +"征衣": "征衣", +"征讨": "征討", +"征途": "征途", +"后台": "後臺", +"从里到外": "從裡到外", +"从里向外": "從裡向外", +"复雠": "復讎", +"复辟": "復辟", +"德干高原": "德干高原", +"心愿": "心愿", +"心荡神驰": "心蕩神馳", +"心里": "心裡", +"忙里": "忙裡", +"快干": "快幹", +"快冲": "快衝", +"怎么": "怎麼", +"怎么着": "怎麼著", +"怒发冲冠": "怒髮衝冠", +"急冲而下": "急衝而下", +"怪里怪气": "怪裡怪氣", +"恩准": "恩准", +"情有所钟": "情有所鍾", +"意面": "意麵", +"慌里慌张": "慌裡慌張", +"慰借": "慰藉", +"忧郁": "憂郁", +"凭吊": "憑吊", +"凭借": "憑藉", +"凭借着": "憑藉著", +"蒙懂": "懞懂", +"怀里": "懷裡", +"怀表": "懷錶", +"悬吊": "懸吊", +"恋恋不舍": "戀戀不捨", +"戏台": "戲臺", +"戴表": "戴錶", +"戽斗": "戽斗", +"房里": "房裡", +"手不释卷": "手不釋卷", +"手卷": "手卷", +"手折": "手摺", +"手里": "手裡", +"手表": "手錶", +"手松": "手鬆", +"才干": "才幹", +"才高八斗": "才高八斗", +"打谷": "打穀", +"扞御": "扞禦", +"批准": "批准", +"批复": "批複", +"批复": "批覆", +"承制": "承製", +"抗御": "抗禦", +"折冲": "折衝", +"披复": "披覆", +"披发": "披髮", +"抱朴": "抱朴", +"抵御": "抵禦", +"拆伙": "拆伙", +"拆台": "拆臺", +"拈须": "拈鬚", +"拉纤": "拉縴", +"拉面": "拉麵", +"拖吊": "拖吊", +"拗别": "拗彆", +"拮据": "拮据", +"振荡": "振蕩", +"捍御": "捍禦", +"舍不得": "捨不得", +"舍出": "捨出", +"舍去": "捨去", +"舍命": "捨命", +"舍己从人": "捨己從人", +"舍己救人": "捨己救人", +"舍己为人": "捨己為人", +"舍己为公": "捨己為公", +"舍己为国": "捨己為國", +"舍得": "捨得", +"舍我其谁": "捨我其誰", +"舍本逐末": "捨本逐末", +"舍弃": "捨棄", +"舍死忘生": "捨死忘生", +"舍生": "捨生", +"舍短取长": "捨短取長", +"舍身": "捨身", +"舍车保帅": "捨車保帥", +"舍近求远": "捨近求遠", +"捲发": "捲髮", +"捵面": "捵麵", +"扫荡": "掃蕩", +"掌柜": "掌柜", +"排骨面": "排骨麵", +"挂帘": "掛帘", +"挂面": "掛麵", +"接着说": "接著說", +"提心吊胆": "提心吊膽", +"插图卷": "插圖卷", +"换吊": "換吊", +"换只": "換隻", +"换发": "換髮", +"摇荡": "搖蕩", +"搭伙": "搭伙", +"折合": "摺合", +"折奏": "摺奏", +"折子": "摺子", +"折尺": "摺尺", +"折扇": "摺扇", +"折梯": "摺梯", +"折椅": "摺椅", +"折叠": "摺疊", +"折痕": "摺痕", +"折篷": "摺篷", +"折纸": "摺紙", +"折裙": "摺裙", +"撒布": "撒佈", +"撚须": "撚鬚", +"撞球台": "撞球檯", +"擂台": "擂臺", +"担仔面": "擔仔麵", +"担担面": "擔擔麵", +"担着": "擔著", +"担负着": "擔負著", +"据云": "據云", +"擢发难数": "擢髮難數", +"摆布": "擺佈", +"摄制": "攝製", +"支干": "支幹", +"收获": "收穫", +"改制": "改製", +"攻克": "攻剋", +"放荡": "放蕩", +"放松": "放鬆", +"叙说着": "敘說著", +"散伙": "散伙", +"散布": "散佈", +"散荡": "散蕩", +"散发": "散髮", +"整只": "整隻", +"整出": "整齣", +"文采": "文采", +"斗六": "斗六", +"斗南": "斗南", +"斗大": "斗大", +"斗子": "斗子", +"斗室": "斗室", +"斗方": "斗方", +"斗栱": "斗栱", +"斗笠": "斗笠", +"斗箕": "斗箕", +"斗篷": "斗篷", +"斗胆": "斗膽", +"斗转参横": "斗轉參橫", +"斗量": "斗量", +"斗门": "斗門", +"料斗": "料斗", +"斯里兰卡": "斯裡蘭卡", +"新历": "新曆", +"断头台": "斷頭臺", +"方才": "方纔", +"施舍": "施捨", +"旋绕着": "旋繞著", +"旋回": "旋迴", +"族里": "族裡", +"日历": "日曆", +"日志": "日誌", +"日进斗金": "日進斗金", +"明了": "明瞭", +"明窗净几": "明窗淨几", +"明里": "明裡", +"星斗": "星斗", +"星历": "星曆", +"星移斗换": "星移斗換", +"星移斗转": "星移斗轉", +"星罗棋布": "星羅棋佈", +"星辰表": "星辰錶", +"春假里": "春假裡", +"春天里": "春天裡", +"晃荡": "晃蕩", +"景致": "景緻", +"暗地里": "暗地裡", +"暗沟里": "暗溝裡", +"暗里": "暗裡", +"历数": "曆數", +"历书": "曆書", +"历法": "曆法", +"书卷": "書卷", +"会干": "會幹", +"会里": "會裡", +"月历": "月曆", +"月台": "月臺", +"有只": "有隻", +"木制": "木製", +"本台": "本臺", +"朴子": "朴子", +"朴实": "朴實", +"朴硝": "朴硝", +"朴素": "朴素", +"朴资茅斯": "朴資茅斯", +"村里": "村裡", +"束发": "束髮", +"东岳": "東嶽", +"东征": "東征", +"松赞干布": "松贊干布", +"板着脸": "板著臉", +"板荡": "板蕩", +"枕借": "枕藉", +"林宏岳": "林宏嶽", +"枝干": "枝幹", +"枯干": "枯幹", +"某只": "某隻", +"染发": "染髮", +"柜上": "柜上", +"柜台": "柜台", +"柜子": "柜子", +"查卷": "查卷", +"查号台": "查號臺", +"校雠学": "校讎學", +"核准": "核准", +"核复": "核覆", +"格里": "格裡", +"案卷": "案卷", +"条干": "條幹", +"棉卷": "棉卷", +"棉制": "棉製", +"植发": "植髮", +"楼台": "樓臺", +"标志着": "標志著", +"标致": "標緻", +"标志": "標誌", +"模制": "模製", +"树干": "樹幹", +"横征暴敛": "橫征暴斂", +"横冲": "橫衝", +"档卷": "檔卷", +"检复": "檢覆", +"台子": "檯子", +"台布": "檯布", +"台灯": "檯燈", +"台球": "檯球", +"台面": "檯面", +"柜台": "櫃檯", +"柜台": "櫃臺", +"栏干": "欄干", +"欺蒙": "欺矇", +"歌后": "歌后", +"欧几里得": "歐幾裡得", +"正当着": "正當著", +"武后": "武后", +"武松": "武鬆", +"归并": "歸併", +"死里求生": "死裡求生", +"死里逃生": "死裡逃生", +"残卷": "殘卷", +"杀虫药": "殺虫藥", +"壳里": "殼裡", +"母后": "母后", +"每只": "每隻", +"比干": "比干", +"毛卷": "毛卷", +"毛发": "毛髮", +"毫发": "毫髮", +"气冲牛斗": "氣沖牛斗", +"气象台": "氣象臺", +"氯霉素": "氯黴素", +"水斗": "水斗", +"水里": "水裡", +"水表": "水錶", +"永历": "永曆", +"污蔑": "汙衊", +"池里": "池裡", +"污蔑": "污衊", +"沈着": "沈著", +"没事干": "沒事幹", +"没精打采": "沒精打采", +"冲着": "沖著", +"沙里淘金": "沙裡淘金", +"河里": "河裡", +"油面": "油麵", +"泡面": "泡麵", +"泰斗": "泰斗", +"洗手不干": "洗手不幹", +"洗发精": "洗髮精", +"派团参加": "派團參加", +"流荡": "流蕩", +"浩荡": "浩蕩", +"浪琴表": "浪琴錶", +"浪荡": "浪蕩", +"浮荡": "浮蕩", +"海里": "海裡", +"涂着": "涂著", +"液晶表": "液晶錶", +"凉面": "涼麵", +"淡朱": "淡硃", +"淫荡": "淫蕩", +"测验卷": "測驗卷", +"港制": "港製", +"游荡": "游蕩", +"凑合着": "湊合著", +"湖里": "湖裡", +"汤团": "湯糰", +"汤面": "湯麵", +"卤制": "滷製", +"卤面": "滷麵", +"满布": "滿佈", +"漂荡": "漂蕩", +"漏斗": "漏斗", +"演奏台": "演奏臺", +"潭里": "潭裡", +"激荡": "激蕩", +"浓郁": "濃郁", +"浓发": "濃髮", +"湿地松": "濕地鬆", +"蒙蒙": "濛濛", +"蒙雾": "濛霧", +"瀛台": "瀛臺", +"弥漫": "瀰漫", +"弥漫着": "瀰漫著", +"火并": "火併", +"灰蒙": "灰濛", +"炒面": "炒麵", +"炮制": "炮製", +"炸药": "炸葯", +"炸酱面": "炸醬麵", +"为着": "為著", +"乌干达": "烏干達", +"乌苏里江": "烏蘇裡江", +"乌发": "烏髮", +"乌龙面": "烏龍麵", +"烘制": "烘製", +"烽火台": "烽火臺", +"无干": "無干", +"无精打采": "無精打采", +"炼制": "煉製", +"烟卷儿": "煙卷兒", +"烟斗": "煙斗", +"烟斗丝": "煙斗絲", +"烟台": "煙臺", +"照准": "照准", +"熨斗": "熨斗", +"灯台": "燈臺", +"燎发": "燎髮", +"烫发": "燙髮", +"烫面": "燙麵", +"烛台": "燭臺", +"炉台": "爐臺", +"爽荡": "爽蕩", +"片言只语": "片言隻語", +"牛肉面": "牛肉麵", +"牛只": "牛隻", +"特准": "特准", +"特征": "特征", +"特里": "特裡", +"特制": "特製", +"牵系": "牽繫", +"狼借": "狼藉", +"猛冲": "猛衝", +"奖杯": "獎盃", +"获准": "獲准", +"率团参加": "率團參加", +"王侯后": "王侯后", +"王后": "王后", +"班里": "班裡", +"理发": "理髮", +"瑶台": "瑤臺", +"甚么": "甚麼", +"甜面酱": "甜麵醬", +"生力面": "生力麵", +"生锈": "生鏽", +"生发": "生髮", +"田里": "田裡", +"由馀": "由余", +"男佣": "男佣", +"男用表": "男用錶", +"留发": "留髮", +"畚斗": "畚斗", +"当着": "當著", +"疏松": "疏鬆", +"疲困": "疲睏", +"病症": "病癥", +"症候": "癥候", +"症状": "癥狀", +"症结": "癥結", +"登台": "登臺", +"发布": "發佈", +"发着": "發著", +"发面": "發麵", +"发霉": "發黴", +"白卷": "白卷", +"白干儿": "白干兒", +"白发": "白髮", +"白面": "白麵", +"百里": "百裡", +"百只": "百隻", +"皇后": "皇后", +"皇历": "皇曆", +"皓发": "皓髮", +"皮里阳秋": "皮裏陽秋", +"皮里春秋": "皮裡春秋", +"皮制": "皮製", +"皱折": "皺摺", +"盒里": "盒裡", +"监制": "監製", +"盘里": "盤裡", +"盘回": "盤迴", +"直接参与": "直接參与", +"直冲": "直衝", +"相克": "相剋", +"相干": "相干", +"相冲": "相衝", +"看台": "看臺", +"眼帘": "眼帘", +"眼眶里": "眼眶裡", +"眼里": "眼裡", +"困乏": "睏乏", +"睡着了": "睡著了", +"了如": "瞭如", +"了望": "瞭望", +"了然": "瞭然", +"了若指掌": "瞭若指掌", +"了解": "瞭解", +"蒙住": "矇住", +"蒙昧无知": "矇昧無知", +"蒙混": "矇混", +"蒙蒙": "矇矇", +"蒙眬": "矇矓", +"蒙蔽": "矇蔽", +"蒙骗": "矇騙", +"短发": "短髮", +"石英表": "石英錶", +"研制": "研製", +"砰当": "砰噹", +"砲台": "砲臺", +"朱唇皓齿": "硃唇皓齒", +"朱批": "硃批", +"朱砂": "硃砂", +"朱笔": "硃筆", +"朱红色": "硃紅色", +"朱色": "硃色", +"硬干": "硬幹", +"砚台": "硯臺", +"碑志": "碑誌", +"磁制": "磁製", +"磨制": "磨製", +"示复": "示覆", +"社里": "社裡", +"神采": "神采", +"御侮": "禦侮", +"御寇": "禦寇", +"御寒": "禦寒", +"御敌": "禦敵", +"秃发": "禿髮", +"秀发": "秀髮", +"私下里": "私下裡", +"秋天里": "秋天裡", +"秋裤": "秋褲", +"秒表": "秒錶", +"稀松": "稀鬆", +"禀复": "稟覆", +"稻谷": "稻穀", +"稽征": "稽征", +"谷仓": "穀倉", +"谷场": "穀場", +"谷子": "穀子", +"谷壳": "穀殼", +"谷物": "穀物", +"谷皮": "穀皮", +"谷神": "穀神", +"谷粒": "穀粒", +"谷舱": "穀艙", +"谷苗": "穀苗", +"谷草": "穀草", +"谷贱伤农": "穀賤傷農", +"谷道": "穀道", +"谷雨": "穀雨", +"谷类": "穀類", +"积极参与": "積极參与", +"积极参加": "積极參加", +"空荡": "空蕩", +"窗帘": "窗帘", +"窗明几净": "窗明几淨", +"窗台": "窗檯", +"窗台": "窗臺", +"窝里": "窩裡", +"窝阔台": "窩闊臺", +"穷追不舍": "窮追不捨", +"笆斗": "笆斗", +"笑里藏刀": "笑裡藏刀", +"第一卷": "第一卷", +"筋斗": "筋斗", +"答卷": "答卷", +"答复": "答複", +"答复": "答覆", +"筵几": "筵几", +"箕斗": "箕斗", +"签着": "簽著", +"吁求": "籲求", +"吁请": "籲請", +"粗制": "粗製", +"粗卤": "粗鹵", +"精干": "精幹", +"精明强干": "精明強幹", +"精致": "精緻", +"精制": "精製", +"精辟": "精辟", +"精采": "精采", +"糊里糊涂": "糊裡糊塗", +"团子": "糰子", +"系着": "系著", +"纪历": "紀曆", +"红发": "紅髮", +"红霉素": "紅黴素", +"纡回": "紆迴", +"纳采": "納采", +"素食面": "素食麵", +"素面": "素麵", +"紫微斗数": "紫微斗數", +"细致": "細緻", +"组里": "組裡", +"结发": "結髮", +"绝对参照": "絕對參照", +"丝来线去": "絲來線去", +"丝布": "絲布", +"丝板": "絲板", +"丝瓜布": "絲瓜布", +"丝绒布": "絲絨布", +"丝线": "絲線", +"丝织厂": "絲織廠", +"丝虫": "絲蟲", +"綑吊": "綑吊", +"经卷": "經卷", +"绿霉素": "綠黴素", +"维系": "維繫", +"绾发": "綰髮", +"网里": "網裡", +"紧绷": "緊繃", +"紧绷着": "緊繃著", +"紧追不舍": "緊追不捨", +"编制": "編製", +"编发": "編髮", +"缓冲": "緩衝", +"致密": "緻密", +"萦回": "縈迴", +"县里": "縣裡", +"县志": "縣誌", +"缝里": "縫裡", +"缝制": "縫製", +"纤夫": "縴夫", +"繁复": "繁複", +"绷住": "繃住", +"绷子": "繃子", +"绷带": "繃帶", +"绷紧": "繃緊", +"绷脸": "繃臉", +"绷着": "繃著", +"绷着脸": "繃著臉", +"绷着脸儿": "繃著臉兒", +"绷开": "繃開", +"绘制": "繪製", +"系上": "繫上", +"系到": "繫到", +"系囚": "繫囚", +"系心": "繫心", +"系念": "繫念", +"系怀": "繫懷", +"系数": "繫數", +"系于": "繫於", +"系系": "繫系", +"系紧": "繫緊", +"系绳": "繫繩", +"系着": "繫著", +"系辞": "繫辭", +"缴卷": "繳卷", +"累囚": "纍囚", +"累累": "纍纍", +"坛子": "罈子", +"坛坛罐罐": "罈罈罐罐", +"骂着": "罵著", +"美制": "美製", +"美发": "美髮", +"翻来覆去": "翻來覆去", +"翻云覆雨": "翻雲覆雨", +"老么": "老么", +"老板": "老闆", +"考卷": "考卷", +"耕获": "耕穫", +"聊斋志异": "聊齋誌異", +"联系": "聯係", +"联系": "聯繫", +"肉丝面": "肉絲麵", +"肉羹面": "肉羹麵", +"肉松": "肉鬆", +"肢体": "肢体", +"背向着": "背向著", +"背地里": "背地裡", +"胡里胡涂": "胡裡胡塗", +"能干": "能幹", +"脉冲": "脈衝", +"脱发": "脫髮", +"腊味": "腊味", +"腊笔": "腊筆", +"腊肉": "腊肉", +"脑子里": "腦子裡", +"腰里": "腰裡", +"胶卷": "膠卷", +"自制": "自製", +"自觉自愿": "自覺自愿", +"台上": "臺上", +"台下": "臺下", +"台中": "臺中", +"台北": "臺北", +"台南": "臺南", +"台地": "臺地", +"台塑": "臺塑", +"台大": "臺大", +"台币": "臺幣", +"台座": "臺座", +"台东": "臺東", +"台柱": "臺柱", +"台榭": "臺榭", +"台汽": "臺汽", +"台海": "臺海", +"台澎金马": "臺澎金馬", +"台湾": "臺灣", +"台灯": "臺燈", +"台球": "臺球", +"台省": "臺省", +"台端": "臺端", +"台糖": "臺糖", +"台肥": "臺肥", +"台航": "臺航", +"台视": "臺視", +"台词": "臺詞", +"台车": "臺車", +"台铁": "臺鐵", +"台阶": "臺階", +"台电": "臺電", +"台面": "臺面", +"舂谷": "舂穀", +"兴致": "興緻", +"兴高采烈": "興高采烈", +"旧历": "舊曆", +"舒卷": "舒卷", +"舞台": "舞臺", +"航海历": "航海曆", +"船只": "船隻", +"舰只": "艦隻", +"芬郁": "芬郁", +"花卷": "花卷", +"花盆里": "花盆裡", +"花采": "花采", +"苑里": "苑裡", +"若干": "若干", +"苦干": "苦幹", +"苦里": "苦裏", +"苦卤": "苦鹵", +"范仲淹": "范仲淹", +"范蠡": "范蠡", +"范阳": "范陽", +"茅台": "茅臺", +"茶几": "茶几", +"草丛里": "草叢裡", +"庄里": "莊裡", +"茎干": "莖幹", +"莽荡": "莽蕩", +"菌丝体": "菌絲体", +"菌丝体": "菌絲體", +"华里": "華裡", +"华发": "華髮", +"万卷": "萬卷", +"万历": "萬曆", +"万只": "萬隻", +"落发": "落髮", +"着儿": "著兒", +"着书立说": "著書立說", +"着色软体": "著色軟體", +"着重指出": "著重指出", +"着录": "著錄", +"着录规则": "著錄規則", +"蓄发": "蓄髮", +"蓄须": "蓄鬚", +"蓬发": "蓬髮", +"蓬松": "蓬鬆", +"莲台": "蓮臺", +"荡来荡去": "蕩來蕩去", +"荡女": "蕩女", +"荡妇": "蕩婦", +"荡寇": "蕩寇", +"荡平": "蕩平", +"荡涤": "蕩滌", +"荡漾": "蕩漾", +"荡然": "蕩然", +"荡舟": "蕩舟", +"荡船": "蕩船", +"荡荡": "蕩蕩", +"薑丝": "薑絲", +"薙发": "薙髮", +"借以": "藉以", +"借口": "藉口", +"借故": "藉故", +"借机": "藉機", +"借此": "藉此", +"借由": "藉由", +"借端": "藉端", +"借着": "藉著", +"借借": "藉藉", +"借词": "藉詞", +"借资": "藉資", +"借酒浇愁": "藉酒澆愁", +"藤制": "藤製", +"蕴含着": "蘊含著", +"蕴涵着": "蘊涵著", +"蕴借": "蘊藉", +"萝卜": "蘿蔔", +"虎须": "虎鬚", +"号志": "號誌", +"蜂后": "蜂后", +"蛮干": "蠻幹", +"行事历": "行事曆", +"胡同": "衚衕", +"冲上": "衝上", +"冲下": "衝下", +"冲来": "衝來", +"冲倒": "衝倒", +"冲出": "衝出", +"冲到": "衝到", +"冲刺": "衝刺", +"冲克": "衝剋", +"冲力": "衝力", +"冲劲": "衝勁", +"冲动": "衝動", +"冲去": "衝去", +"冲口": "衝口", +"冲垮": "衝垮", +"冲堂": "衝堂", +"冲压": "衝壓", +"冲天": "衝天", +"冲掉": "衝掉", +"冲撞": "衝撞", +"冲击": "衝擊", +"冲散": "衝散", +"冲决": "衝決", +"冲浪": "衝浪", +"冲激": "衝激", +"冲破": "衝破", +"冲程": "衝程", +"冲突": "衝突", +"冲线": "衝線", +"冲着": "衝著", +"冲冲": "衝衝", +"冲要": "衝要", +"冲起": "衝起", +"冲进": "衝進", +"冲过": "衝過", +"冲锋": "衝鋒", +"表里": "表裡", +"袖里": "袖裡", +"被里": "被裡", +"被复": "被複", +"被复": "被覆", +"被复着": "被覆著", +"被发": "被髮", +"裁并": "裁併", +"裁制": "裁製", +"里面": "裏面", +"里人": "裡人", +"里加": "裡加", +"里外": "裡外", +"里子": "裡子", +"里屋": "裡屋", +"里层": "裡層", +"里布": "裡布", +"里带": "裡帶", +"里弦": "裡弦", +"里应外合": "裡應外合", +"里拉": "裡拉", +"里斯": "裡斯", +"里海": "裡海", +"里脊": "裡脊", +"里衣": "裡衣", +"里里": "裡裡", +"里通外国": "裡通外國", +"里通外敌": "裡通外敵", +"里边": "裡邊", +"里间": "裡間", +"里面": "裡面", +"里头": "裡頭", +"制件": "製件", +"制作": "製作", +"制做": "製做", +"制备": "製備", +"制冰": "製冰", +"制冷": "製冷", +"制剂": "製劑", +"制品": "製品", +"制图": "製圖", +"制成": "製成", +"制法": "製法", +"制为": "製為", +"制片": "製片", +"制版": "製版", +"制程": "製程", +"制糖": "製糖", +"制纸": "製紙", +"制药": "製藥", +"制表": "製表", +"制裁": "製裁", +"制造": "製造", +"制革": "製革", +"制鞋": "製鞋", +"制盐": "製鹽", +"复仞年如": "複仞年如", +"复以百万": "複以百萬", +"复位": "複位", +"复信": "複信", +"复分数": "複分數", +"复列": "複列", +"复利": "複利", +"复印": "複印", +"复原": "複原", +"复句": "複句", +"复合": "複合", +"复名": "複名", +"复员": "複員", +"复壁": "複壁", +"复壮": "複壯", +"复姓": "複姓", +"复字键": "複字鍵", +"复审": "複審", +"复写": "複寫", +"复式": "複式", +"复复": "複復", +"复数": "複數", +"复本": "複本", +"复查": "複查", +"复核": "複核", +"复检": "複檢", +"复次": "複次", +"复比": "複比", +"复决": "複決", +"复活": "複活", +"复测": "複測", +"复亩珍": "複畝珍", +"复发": "複發", +"复目": "複目", +"复眼": "複眼", +"复种": "複種", +"复线": "複線", +"复习": "複習", +"复兴社": "複興社", +"复旧": "複舊", +"复色": "複色", +"复叶": "複葉", +"复盖": "複蓋", +"复苏": "複蘇", +"复制": "複製", +"复诊": "複診", +"复词": "複詞", +"复试": "複試", +"复课": "複課", +"复议": "複議", +"复变函数": "複變函數", +"复赛": "複賽", +"复述": "複述", +"复选": "複選", +"复钱": "複錢", +"复杂": "複雜", +"复电": "複電", +"复音": "複音", +"复韵": "複韻", +"衬里": "襯裡", +"西岳": "西嶽", +"西征": "西征", +"西历": "西曆", +"要冲": "要衝", +"要么": "要麼", +"复上": "覆上", +"复亡": "覆亡", +"复住": "覆住", +"复信": "覆信", +"复命": "覆命", +"复在": "覆在", +"复审": "覆審", +"复成": "覆成", +"复败": "覆敗", +"复文": "覆文", +"复校": "覆校", +"复核": "覆核", +"覆水难收": "覆水難收", +"复没": "覆沒", +"复灭": "覆滅", +"复盆": "覆盆", +"复舟": "覆舟", +"复着": "覆著", +"复盖": "覆蓋", +"复盖着": "覆蓋著", +"复试": "覆試", +"复议": "覆議", +"复车": "覆車", +"复载": "覆載", +"复辙": "覆轍", +"复电": "覆電", +"见复": "見覆", +"亲征": "親征", +"观众台": "觀眾臺", +"观台": "觀臺", +"观象台": "觀象臺", +"角落里": "角落裡", +"觔斗": "觔斗", +"触须": "觸鬚", +"订制": "訂製", +"诉说着": "訴說著", +"词汇": "詞彙", +"试卷": "試卷", +"诗卷": "詩卷", +"话里有话": "話裡有話", +"志哀": "誌哀", +"志喜": "誌喜", +"志庆": "誌慶", +"语云": "語云", +"语汇": "語彙", +"诬蔑": "誣衊", +"诵经台": "誦經臺", +"说着": "說著", +"课征": "課征", +"调制": "調製", +"调频台": "調頻臺", +"请参阅": "請參閱", +"讲台": "講臺", +"谢绝参观": "謝絕參觀", +"护发": "護髮", +"雠隙": "讎隙", +"豆腐干": "豆腐干", +"竖着": "豎著", +"丰富多采": "豐富多采", +"丰滨": "豐濱", +"丰滨乡": "豐濱鄉", +"丰采": "豐采", +"象征着": "象徵著", +"贵干": "貴幹", +"贾后": "賈后", +"赈饥": "賑饑", +"贤后": "賢后", +"质朴": "質朴", +"赌台": "賭檯", +"购并": "購併", +"赤松": "赤鬆", +"起吊": "起吊", +"起复": "起複", +"赶制": "趕製", +"跌荡": "跌蕩", +"跟斗": "跟斗", +"跳荡": "跳蕩", +"跳表": "跳錶", +"踬仆": "躓仆", +"躯干": "軀幹", +"车库里": "車庫裡", +"车站里": "車站裡", +"车里": "車裡", +"轻松": "輕鬆", +"轮回": "輪迴", +"转台": "轉檯", +"辛丑": "辛丑", +"辟邪": "辟邪", +"办伙": "辦伙", +"办公台": "辦公檯", +"辞汇": "辭彙", +"农历": "農曆", +"迂回": "迂迴", +"近日里": "近日裡", +"迥然回异": "迥然迴異", +"回光返照": "迴光返照", +"回向": "迴向", +"回圈": "迴圈", +"回廊": "迴廊", +"回形夹": "迴形夾", +"回文": "迴文", +"回旋": "迴旋", +"回流": "迴流", +"回环": "迴環", +"回荡": "迴盪", +"回纹针": "迴紋針", +"回绕": "迴繞", +"回肠": "迴腸", +"回荡": "迴蕩", +"回诵": "迴誦", +"回路": "迴路", +"回转": "迴轉", +"回递性": "迴遞性", +"回避": "迴避", +"回响": "迴響", +"回风": "迴風", +"回首": "迴首", +"迷蒙": "迷濛", +"退伙": "退伙", +"这么着": "這么著", +"这里": "這裏", +"这里": "這裡", +"这只": "這隻", +"这么": "這麼", +"这么着": "這麼著", +"通心面": "通心麵", +"速食面": "速食麵", +"连系": "連繫", +"连台好戏": "連臺好戲", +"游荡": "遊蕩", +"遍布": "遍佈", +"递回": "遞迴", +"远征": "遠征", +"适才": "適纔", +"遮复": "遮覆", +"还冲": "還衝", +"邋里邋遢": "邋裡邋遢", +"那里": "那裡", +"那只": "那隻", +"那么": "那麼", +"那么着": "那麼著", +"邪辟": "邪辟", +"郁烈": "郁烈", +"郁穆": "郁穆", +"郁郁": "郁郁", +"郁闭": "郁閉", +"郁馥": "郁馥", +"乡愿": "鄉愿", +"乡里": "鄉裡", +"邻里": "鄰裡", +"配合着": "配合著", +"配制": "配製", +"酒杯": "酒盃", +"酒坛": "酒罈", +"酥松": "酥鬆", +"醋坛": "醋罈", +"酝借": "醞藉", +"酝酿着": "醞釀著", +"医药": "醫葯", +"醲郁": "醲郁", +"酿制": "釀製", +"采地": "采地", +"采女": "采女", +"采声": "采聲", +"采色": "采色", +"采邑": "采邑", +"里程表": "里程錶", +"重折": "重摺", +"重复": "重複", +"重复": "重覆", +"重锤": "重鎚", +"野台戏": "野臺戲", +"金斗": "金斗", +"金表": "金錶", +"金发": "金髮", +"金霉素": "金黴素", +"钉锤": "釘鎚", +"银朱": "銀硃", +"银发": "銀髮", +"铜制": "銅製", +"铝制": "鋁製", +"钢制": "鋼製", +"录着": "錄著", +"录制": "錄製", +"表带": "錶帶", +"表店": "錶店", +"表厂": "錶廠", +"表壳": "錶殼", +"表链": "錶鏈", +"表面": "錶面", +"锅台": "鍋臺", +"锻鍊出": "鍛鍊出", +"锻鍊身体": "鍛鍊身体", +"锲而不舍": "鍥而不捨", +"锤儿": "鎚兒", +"锤子": "鎚子", +"锤头": "鎚頭", +"链霉素": "鏈黴素", +"镜台": "鏡臺", +"锈病": "鏽病", +"锈菌": "鏽菌", +"锈蚀": "鏽蝕", +"钟表": "鐘錶", +"铁锤": "鐵鎚", +"铁锈": "鐵鏽", +"长征": "長征", +"长发": "長髮", +"长须鲸": "長鬚鯨", +"门帘": "門帘", +"门斗": "門斗", +"门里": "門裡", +"开伙": "開伙", +"开卷": "開卷", +"开诚布公": "開誠佈公", +"开采": "開采", +"閒情逸致": "閒情逸緻", +"閒荡": "閒蕩", +"间不容发": "間不容髮", +"闵采尔": "閔采爾", +"阅卷": "閱卷", +"阑干": "闌干", +"关系": "關係", +"关系着": "關係著", +"防御": "防禦", +"防锈": "防鏽", +"防台": "防颱", +"阿斗": "阿斗", +"阿里": "阿裡", +"除旧布新": "除舊佈新", +"阴干": "陰干", +"阴历": "陰曆", +"阴郁": "陰郁", +"陆征祥": "陸征祥", +"阳春面": "陽春麵", +"阳历": "陽曆", +"阳台": "陽臺", +"只字": "隻字", +"只影": "隻影", +"只手遮天": "隻手遮天", +"只眼": "隻眼", +"只言片语": "隻言片語", +"只身": "隻身", +"雅致": "雅緻", +"雇佣": "雇佣", +"双折": "雙摺", +"杂志": "雜誌", +"鸡丝": "雞絲", +"鸡丝面": "雞絲麵", +"鸡腿面": "雞腿麵", +"鸡只": "雞隻", +"难舍": "難捨", +"雪里": "雪裡", +"云须": "雲鬚", +"电子表": "電子錶", +"电台": "電臺", +"电冲": "電衝", +"电复": "電覆", +"电视台": "電視臺", +"电表": "電錶", +"震荡": "震蕩", +"雾里": "霧裡", +"露台": "露臺", +"灵台": "靈臺", +"青瓦台": "青瓦臺", +"青霉": "青黴", +"面朝着": "面朝著", +"面临着": "面臨著", +"鞋里": "鞋裡", +"鞣制": "鞣製", +"秋千": "鞦韆", +"鞭辟入里": "鞭辟入裡", +"韩国制": "韓國製", +"韩制": "韓製", +"预制": "預製", +"颁布": "頒佈", +"头里": "頭裡", +"头发": "頭髮", +"颊须": "頰鬚", +"颠仆": "顛仆", +"颠复": "顛複", +"颠复": "顛覆", +"显着标志": "顯著標志", +"风土志": "風土誌", +"风斗": "風斗", +"风物志": "風物誌", +"风里": "風裡", +"风采": "風采", +"台风": "颱風", +"刮了": "颳了", +"刮倒": "颳倒", +"刮去": "颳去", +"刮得": "颳得", +"刮着": "颳著", +"刮走": "颳走", +"刮起": "颳起", +"刮风": "颳風", +"飘荡": "飄蕩", +"饭团": "飯糰", +"饼干": "餅干", +"馄饨面": "餛飩麵", +"饥不择食": "饑不擇食", +"饥寒": "饑寒", +"饥民": "饑民", +"饥渴": "饑渴", +"饥溺": "饑溺", +"饥荒": "饑荒", +"饥饱": "饑飽", +"饥饿": "饑餓", +"饥馑": "饑饉", +"首当其冲": "首當其衝", +"香郁": "香郁", +"馥郁": "馥郁", +"马里": "馬裡", +"马表": "馬錶", +"骀荡": "駘蕩", +"腾冲": "騰衝", +"骨子里": "骨子裡", +"骨干": "骨幹", +"骨灰坛": "骨灰罈", +"肮脏": "骯髒", +"脏乱": "髒亂", +"脏兮兮": "髒兮兮", +"脏字": "髒字", +"脏得": "髒得", +"脏东西": "髒東西", +"脏水": "髒水", +"脏的": "髒的", +"脏话": "髒話", +"脏钱": "髒錢", +"高干": "高幹", +"高台": "高臺", +"髭须": "髭鬚", +"发型": "髮型", +"发夹": "髮夾", +"发妻": "髮妻", +"发姐": "髮姐", +"发带": "髮帶", +"发廊": "髮廊", +"发式": "髮式", +"发指": "髮指", +"发捲": "髮捲", +"发根": "髮根", +"发毛": "髮毛", +"发油": "髮油", +"发状": "髮狀", +"发短心长": "髮短心長", +"发端": "髮端", +"发结": "髮結", +"发丝": "髮絲", +"发网": "髮網", +"发肤": "髮膚", +"发胶": "髮膠", +"发菜": "髮菜", +"发蜡": "髮蠟", +"发辫": "髮辮", +"发针": "髮針", +"发长": "髮長", +"发际": "髮際", +"发霜": "髮霜", +"发髻": "髮髻", +"发鬓": "髮鬢", +"鬅松": "鬅鬆", +"松了": "鬆了", +"松些": "鬆些", +"松劲": "鬆勁", +"松动": "鬆動", +"松口": "鬆口", +"松土": "鬆土", +"松弛": "鬆弛", +"松快": "鬆快", +"松懈": "鬆懈", +"松手": "鬆手", +"松散": "鬆散", +"松林": "鬆林", +"松柔": "鬆柔", +"松毛虫": "鬆毛蟲", +"松浮": "鬆浮", +"松涛": "鬆濤", +"松科": "鬆科", +"松节油": "鬆節油", +"松绑": "鬆綁", +"松紧": "鬆緊", +"松缓": "鬆緩", +"松脆": "鬆脆", +"松脱": "鬆脫", +"松起": "鬆起", +"松软": "鬆軟", +"松通": "鬆通", +"松开": "鬆開", +"松饼": "鬆餅", +"松松": "鬆鬆", +"鬈发": "鬈髮", +"胡子": "鬍子", +"胡梢": "鬍梢", +"胡渣": "鬍渣", +"胡髭": "鬍髭", +"胡须": "鬍鬚", +"须根": "鬚根", +"须毛": "鬚毛", +"须生": "鬚生", +"须眉": "鬚眉", +"须发": "鬚髮", +"须须": "鬚鬚", +"鬓发": "鬢髮", +"斗着": "鬥著", +"闹着玩儿": "鬧著玩儿", +"闹着玩儿": "鬧著玩兒", +"郁郁": "鬱郁", +"鱼松": "魚鬆", +"鲸须": "鯨鬚", +"鲇鱼": "鯰魚", +"鹤发": "鶴髮", +"卤化": "鹵化", +"卤味": "鹵味", +"卤族": "鹵族", +"卤水": "鹵水", +"卤汁": "鹵汁", +"卤簿": "鹵簿", +"卤素": "鹵素", +"卤莽": "鹵莽", +"卤钝": "鹵鈍", +"咸味": "鹹味", +"咸土": "鹹土", +"咸度": "鹹度", +"咸得": "鹹得", +"咸水": "鹹水", +"咸海": "鹹海", +"咸淡": "鹹淡", +"咸湖": "鹹湖", +"咸汤": "鹹湯", +"咸的": "鹹的", +"咸肉": "鹹肉", +"咸菜": "鹹菜", +"咸蛋": "鹹蛋", +"咸猪肉": "鹹豬肉", +"咸类": "鹹類", +"咸鱼": "鹹魚", +"咸鸭蛋": "鹹鴨蛋", +"咸卤": "鹹鹵", +"咸咸": "鹹鹹", +"盐卤": "鹽鹵", +"面价": "麵價", +"面包": "麵包", +"面团": "麵團", +"面店": "麵店", +"面厂": "麵廠", +"面杖": "麵杖", +"面条": "麵條", +"面灰": "麵灰", +"面皮": "麵皮", +"面筋": "麵筋", +"面粉": "麵粉", +"面糊": "麵糊", +"面线": "麵線", +"面茶": "麵茶", +"面食": "麵食", +"面饺": "麵餃", +"面饼": "麵餅", +"麻酱面": "麻醬麵", +"黄历": "黃曆", +"黄发垂髫": "黃髮垂髫", +"黑发": "黑髮", +"黑松": "黑鬆", +"霉毒": "黴毒", +"霉菌": "黴菌", +"鼓里": "鼓裡", +"冬冬": "鼕鼕", +"龙卷": "龍卷", +"龙须": "龍鬚", +} + +zh2Hans = { +'顯著': '显著', +'土著': '土著', +'印表機': '打印机', +'說明檔案': '帮助文件', +"瀋": "沈", +"畫": "划", +"鍾": "钟", +"靦": "腼", +"餘": "余", +"鯰": "鲇", +"鹼": "碱", +"㠏": "㟆", +"𡞵": "㛟", +"万": "万", +"与": "与", +"丑": "丑", +"丟": "丢", +"並": "并", +"丰": "丰", +"么": "么", +"乾": "干", +"乾坤": "乾坤", +"乾隆": "乾隆", +"亂": "乱", +"云": "云", +"亙": "亘", +"亞": "亚", +"仆": "仆", +"价": "价", +"伙": "伙", +"佇": "伫", +"佈": "布", +"体": "体", +"余": "余", +"佣": "佣", +"併": "并", +"來": "来", +"侖": "仑", +"侶": "侣", +"俁": "俣", +"係": "系", +"俔": "伣", +"俠": "侠", +"倀": "伥", +"倆": "俩", +"倈": "俫", +"倉": "仓", +"個": "个", +"們": "们", +"倫": "伦", +"偉": "伟", +"側": "侧", +"偵": "侦", +"偽": "伪", +"傑": "杰", +"傖": "伧", +"傘": "伞", +"備": "备", +"傢": "家", +"傭": "佣", +"傯": "偬", +"傳": "传", +"傴": "伛", +"債": "债", +"傷": "伤", +"傾": "倾", +"僂": "偻", +"僅": "仅", +"僉": "佥", +"僑": "侨", +"僕": "仆", +"僞": "伪", +"僥": "侥", +"僨": "偾", +"價": "价", +"儀": "仪", +"儂": "侬", +"億": "亿", +"儈": "侩", +"儉": "俭", +"儐": "傧", +"儔": "俦", +"儕": "侪", +"儘": "尽", +"償": "偿", +"優": "优", +"儲": "储", +"儷": "俪", +"儸": "㑩", +"儺": "傩", +"儻": "傥", +"儼": "俨", +"儿": "儿", +"兇": "凶", +"兌": "兑", +"兒": "儿", +"兗": "兖", +"党": "党", +"內": "内", +"兩": "两", +"冊": "册", +"冪": "幂", +"准": "准", +"凈": "净", +"凍": "冻", +"凜": "凛", +"几": "几", +"凱": "凯", +"划": "划", +"別": "别", +"刪": "删", +"剄": "刭", +"則": "则", +"剋": "克", +"剎": "刹", +"剗": "刬", +"剛": "刚", +"剝": "剥", +"剮": "剐", +"剴": "剀", +"創": "创", +"劃": "划", +"劇": "剧", +"劉": "刘", +"劊": "刽", +"劌": "刿", +"劍": "剑", +"劏": "㓥", +"劑": "剂", +"劚": "㔉", +"勁": "劲", +"動": "动", +"務": "务", +"勛": "勋", +"勝": "胜", +"勞": "劳", +"勢": "势", +"勩": "勚", +"勱": "劢", +"勵": "励", +"勸": "劝", +"勻": "匀", +"匭": "匦", +"匯": "汇", +"匱": "匮", +"區": "区", +"協": "协", +"卷": "卷", +"卻": "却", +"厂": "厂", +"厙": "厍", +"厠": "厕", +"厭": "厌", +"厲": "厉", +"厴": "厣", +"參": "参", +"叄": "叁", +"叢": "丛", +"台": "台", +"叶": "叶", +"吊": "吊", +"后": "后", +"吳": "吴", +"吶": "呐", +"呂": "吕", +"獃": "呆", +"咼": "呙", +"員": "员", +"唄": "呗", +"唚": "吣", +"問": "问", +"啓": "启", +"啞": "哑", +"啟": "启", +"啢": "唡", +"喎": "㖞", +"喚": "唤", +"喪": "丧", +"喬": "乔", +"單": "单", +"喲": "哟", +"嗆": "呛", +"嗇": "啬", +"嗊": "唝", +"嗎": "吗", +"嗚": "呜", +"嗩": "唢", +"嗶": "哔", +"嘆": "叹", +"嘍": "喽", +"嘔": "呕", +"嘖": "啧", +"嘗": "尝", +"嘜": "唛", +"嘩": "哗", +"嘮": "唠", +"嘯": "啸", +"嘰": "叽", +"嘵": "哓", +"嘸": "呒", +"嘽": "啴", +"噁": "恶", +"噓": "嘘", +"噚": "㖊", +"噝": "咝", +"噠": "哒", +"噥": "哝", +"噦": "哕", +"噯": "嗳", +"噲": "哙", +"噴": "喷", +"噸": "吨", +"噹": "当", +"嚀": "咛", +"嚇": "吓", +"嚌": "哜", +"嚕": "噜", +"嚙": "啮", +"嚥": "咽", +"嚦": "呖", +"嚨": "咙", +"嚮": "向", +"嚲": "亸", +"嚳": "喾", +"嚴": "严", +"嚶": "嘤", +"囀": "啭", +"囁": "嗫", +"囂": "嚣", +"囅": "冁", +"囈": "呓", +"囌": "苏", +"囑": "嘱", +"囪": "囱", +"圇": "囵", +"國": "国", +"圍": "围", +"園": "园", +"圓": "圆", +"圖": "图", +"團": "团", +"坏": "坏", +"垵": "埯", +"埡": "垭", +"埰": "采", +"執": "执", +"堅": "坚", +"堊": "垩", +"堖": "垴", +"堝": "埚", +"堯": "尧", +"報": "报", +"場": "场", +"塊": "块", +"塋": "茔", +"塏": "垲", +"塒": "埘", +"塗": "涂", +"塚": "冢", +"塢": "坞", +"塤": "埙", +"塵": "尘", +"塹": "堑", +"墊": "垫", +"墜": "坠", +"墮": "堕", +"墳": "坟", +"墻": "墙", +"墾": "垦", +"壇": "坛", +"壈": "𡒄", +"壋": "垱", +"壓": "压", +"壘": "垒", +"壙": "圹", +"壚": "垆", +"壞": "坏", +"壟": "垄", +"壠": "垅", +"壢": "坜", +"壩": "坝", +"壯": "壮", +"壺": "壶", +"壼": "壸", +"壽": "寿", +"夠": "够", +"夢": "梦", +"夾": "夹", +"奐": "奂", +"奧": "奥", +"奩": "奁", +"奪": "夺", +"奬": "奖", +"奮": "奋", +"奼": "姹", +"妝": "妆", +"姍": "姗", +"姜": "姜", +"姦": "奸", +"娛": "娱", +"婁": "娄", +"婦": "妇", +"婭": "娅", +"媧": "娲", +"媯": "妫", +"媼": "媪", +"媽": "妈", +"嫗": "妪", +"嫵": "妩", +"嫻": "娴", +"嫿": "婳", +"嬀": "妫", +"嬈": "娆", +"嬋": "婵", +"嬌": "娇", +"嬙": "嫱", +"嬡": "嫒", +"嬤": "嬷", +"嬪": "嫔", +"嬰": "婴", +"嬸": "婶", +"孌": "娈", +"孫": "孙", +"學": "学", +"孿": "孪", +"宁": "宁", +"宮": "宫", +"寢": "寝", +"實": "实", +"寧": "宁", +"審": "审", +"寫": "写", +"寬": "宽", +"寵": "宠", +"寶": "宝", +"將": "将", +"專": "专", +"尋": "寻", +"對": "对", +"導": "导", +"尷": "尴", +"屆": "届", +"屍": "尸", +"屓": "屃", +"屜": "屉", +"屢": "屡", +"層": "层", +"屨": "屦", +"屬": "属", +"岡": "冈", +"峴": "岘", +"島": "岛", +"峽": "峡", +"崍": "崃", +"崗": "岗", +"崢": "峥", +"崬": "岽", +"嵐": "岚", +"嶁": "嵝", +"嶄": "崭", +"嶇": "岖", +"嶔": "嵚", +"嶗": "崂", +"嶠": "峤", +"嶢": "峣", +"嶧": "峄", +"嶮": "崄", +"嶴": "岙", +"嶸": "嵘", +"嶺": "岭", +"嶼": "屿", +"嶽": "岳", +"巋": "岿", +"巒": "峦", +"巔": "巅", +"巰": "巯", +"帘": "帘", +"帥": "帅", +"師": "师", +"帳": "帐", +"帶": "带", +"幀": "帧", +"幃": "帏", +"幗": "帼", +"幘": "帻", +"幟": "帜", +"幣": "币", +"幫": "帮", +"幬": "帱", +"幹": "干", +"幺": "么", +"幾": "几", +"广": "广", +"庫": "库", +"廁": "厕", +"廂": "厢", +"廄": "厩", +"廈": "厦", +"廚": "厨", +"廝": "厮", +"廟": "庙", +"廠": "厂", +"廡": "庑", +"廢": "废", +"廣": "广", +"廩": "廪", +"廬": "庐", +"廳": "厅", +"弒": "弑", +"弳": "弪", +"張": "张", +"強": "强", +"彆": "别", +"彈": "弹", +"彌": "弥", +"彎": "弯", +"彙": "汇", +"彞": "彝", +"彥": "彦", +"征": "征", +"後": "后", +"徑": "径", +"從": "从", +"徠": "徕", +"復": "复", +"徵": "征", +"徹": "彻", +"志": "志", +"恆": "恒", +"恥": "耻", +"悅": "悦", +"悞": "悮", +"悵": "怅", +"悶": "闷", +"惡": "恶", +"惱": "恼", +"惲": "恽", +"惻": "恻", +"愛": "爱", +"愜": "惬", +"愨": "悫", +"愴": "怆", +"愷": "恺", +"愾": "忾", +"愿": "愿", +"慄": "栗", +"態": "态", +"慍": "愠", +"慘": "惨", +"慚": "惭", +"慟": "恸", +"慣": "惯", +"慤": "悫", +"慪": "怄", +"慫": "怂", +"慮": "虑", +"慳": "悭", +"慶": "庆", +"憂": "忧", +"憊": "惫", +"憐": "怜", +"憑": "凭", +"憒": "愦", +"憚": "惮", +"憤": "愤", +"憫": "悯", +"憮": "怃", +"憲": "宪", +"憶": "忆", +"懇": "恳", +"應": "应", +"懌": "怿", +"懍": "懔", +"懞": "蒙", +"懟": "怼", +"懣": "懑", +"懨": "恹", +"懲": "惩", +"懶": "懒", +"懷": "怀", +"懸": "悬", +"懺": "忏", +"懼": "惧", +"懾": "慑", +"戀": "恋", +"戇": "戆", +"戔": "戋", +"戧": "戗", +"戩": "戬", +"戰": "战", +"戱": "戯", +"戲": "戏", +"戶": "户", +"担": "担", +"拋": "抛", +"挩": "捝", +"挾": "挟", +"捨": "舍", +"捫": "扪", +"据": "据", +"掃": "扫", +"掄": "抡", +"掗": "挜", +"掙": "挣", +"掛": "挂", +"採": "采", +"揀": "拣", +"揚": "扬", +"換": "换", +"揮": "挥", +"損": "损", +"搖": "摇", +"搗": "捣", +"搵": "揾", +"搶": "抢", +"摑": "掴", +"摜": "掼", +"摟": "搂", +"摯": "挚", +"摳": "抠", +"摶": "抟", +"摺": "折", +"摻": "掺", +"撈": "捞", +"撏": "挦", +"撐": "撑", +"撓": "挠", +"撝": "㧑", +"撟": "挢", +"撣": "掸", +"撥": "拨", +"撫": "抚", +"撲": "扑", +"撳": "揿", +"撻": "挞", +"撾": "挝", +"撿": "捡", +"擁": "拥", +"擄": "掳", +"擇": "择", +"擊": "击", +"擋": "挡", +"擓": "㧟", +"擔": "担", +"據": "据", +"擠": "挤", +"擬": "拟", +"擯": "摈", +"擰": "拧", +"擱": "搁", +"擲": "掷", +"擴": "扩", +"擷": "撷", +"擺": "摆", +"擻": "擞", +"擼": "撸", +"擾": "扰", +"攄": "摅", +"攆": "撵", +"攏": "拢", +"攔": "拦", +"攖": "撄", +"攙": "搀", +"攛": "撺", +"攜": "携", +"攝": "摄", +"攢": "攒", +"攣": "挛", +"攤": "摊", +"攪": "搅", +"攬": "揽", +"敗": "败", +"敘": "叙", +"敵": "敌", +"數": "数", +"斂": "敛", +"斃": "毙", +"斕": "斓", +"斗": "斗", +"斬": "斩", +"斷": "断", +"於": "于", +"時": "时", +"晉": "晋", +"晝": "昼", +"暈": "晕", +"暉": "晖", +"暘": "旸", +"暢": "畅", +"暫": "暂", +"曄": "晔", +"曆": "历", +"曇": "昙", +"曉": "晓", +"曏": "向", +"曖": "暧", +"曠": "旷", +"曨": "昽", +"曬": "晒", +"書": "书", +"會": "会", +"朧": "胧", +"朮": "术", +"术": "术", +"朴": "朴", +"東": "东", +"杴": "锨", +"极": "极", +"柜": "柜", +"柵": "栅", +"桿": "杆", +"梔": "栀", +"梘": "枧", +"條": "条", +"梟": "枭", +"梲": "棁", +"棄": "弃", +"棖": "枨", +"棗": "枣", +"棟": "栋", +"棧": "栈", +"棲": "栖", +"棶": "梾", +"椏": "桠", +"楊": "杨", +"楓": "枫", +"楨": "桢", +"業": "业", +"極": "极", +"榪": "杩", +"榮": "荣", +"榲": "榅", +"榿": "桤", +"構": "构", +"槍": "枪", +"槤": "梿", +"槧": "椠", +"槨": "椁", +"槳": "桨", +"樁": "桩", +"樂": "乐", +"樅": "枞", +"樓": "楼", +"標": "标", +"樞": "枢", +"樣": "样", +"樸": "朴", +"樹": "树", +"樺": "桦", +"橈": "桡", +"橋": "桥", +"機": "机", +"橢": "椭", +"橫": "横", +"檁": "檩", +"檉": "柽", +"檔": "档", +"檜": "桧", +"檟": "槚", +"檢": "检", +"檣": "樯", +"檮": "梼", +"檯": "台", +"檳": "槟", +"檸": "柠", +"檻": "槛", +"櫃": "柜", +"櫓": "橹", +"櫚": "榈", +"櫛": "栉", +"櫝": "椟", +"櫞": "橼", +"櫟": "栎", +"櫥": "橱", +"櫧": "槠", +"櫨": "栌", +"櫪": "枥", +"櫫": "橥", +"櫬": "榇", +"櫱": "蘖", +"櫳": "栊", +"櫸": "榉", +"櫻": "樱", +"欄": "栏", +"權": "权", +"欏": "椤", +"欒": "栾", +"欖": "榄", +"欞": "棂", +"欽": "钦", +"歐": "欧", +"歟": "欤", +"歡": "欢", +"歲": "岁", +"歷": "历", +"歸": "归", +"歿": "殁", +"殘": "残", +"殞": "殒", +"殤": "殇", +"殨": "㱮", +"殫": "殚", +"殮": "殓", +"殯": "殡", +"殰": "㱩", +"殲": "歼", +"殺": "杀", +"殻": "壳", +"殼": "壳", +"毀": "毁", +"毆": "殴", +"毿": "毵", +"氂": "牦", +"氈": "毡", +"氌": "氇", +"氣": "气", +"氫": "氢", +"氬": "氩", +"氳": "氲", +"汙": "污", +"決": "决", +"沒": "没", +"沖": "冲", +"況": "况", +"洶": "汹", +"浹": "浃", +"涂": "涂", +"涇": "泾", +"涼": "凉", +"淀": "淀", +"淒": "凄", +"淚": "泪", +"淥": "渌", +"淨": "净", +"淩": "凌", +"淪": "沦", +"淵": "渊", +"淶": "涞", +"淺": "浅", +"渙": "涣", +"減": "减", +"渦": "涡", +"測": "测", +"渾": "浑", +"湊": "凑", +"湞": "浈", +"湯": "汤", +"溈": "沩", +"準": "准", +"溝": "沟", +"溫": "温", +"滄": "沧", +"滅": "灭", +"滌": "涤", +"滎": "荥", +"滬": "沪", +"滯": "滞", +"滲": "渗", +"滷": "卤", +"滸": "浒", +"滻": "浐", +"滾": "滚", +"滿": "满", +"漁": "渔", +"漚": "沤", +"漢": "汉", +"漣": "涟", +"漬": "渍", +"漲": "涨", +"漵": "溆", +"漸": "渐", +"漿": "浆", +"潁": "颍", +"潑": "泼", +"潔": "洁", +"潙": "沩", +"潛": "潜", +"潤": "润", +"潯": "浔", +"潰": "溃", +"潷": "滗", +"潿": "涠", +"澀": "涩", +"澆": "浇", +"澇": "涝", +"澐": "沄", +"澗": "涧", +"澠": "渑", +"澤": "泽", +"澦": "滪", +"澩": "泶", +"澮": "浍", +"澱": "淀", +"濁": "浊", +"濃": "浓", +"濕": "湿", +"濘": "泞", +"濛": "蒙", +"濟": "济", +"濤": "涛", +"濫": "滥", +"濰": "潍", +"濱": "滨", +"濺": "溅", +"濼": "泺", +"濾": "滤", +"瀅": "滢", +"瀆": "渎", +"瀇": "㲿", +"瀉": "泻", +"瀋": "沈", +"瀏": "浏", +"瀕": "濒", +"瀘": "泸", +"瀝": "沥", +"瀟": "潇", +"瀠": "潆", +"瀦": "潴", +"瀧": "泷", +"瀨": "濑", +"瀰": "弥", +"瀲": "潋", +"瀾": "澜", +"灃": "沣", +"灄": "滠", +"灑": "洒", +"灕": "漓", +"灘": "滩", +"灝": "灏", +"灠": "漤", +"灣": "湾", +"灤": "滦", +"灧": "滟", +"災": "灾", +"為": "为", +"烏": "乌", +"烴": "烃", +"無": "无", +"煉": "炼", +"煒": "炜", +"煙": "烟", +"煢": "茕", +"煥": "焕", +"煩": "烦", +"煬": "炀", +"煱": "㶽", +"熅": "煴", +"熒": "荧", +"熗": "炝", +"熱": "热", +"熲": "颎", +"熾": "炽", +"燁": "烨", +"燈": "灯", +"燉": "炖", +"燒": "烧", +"燙": "烫", +"燜": "焖", +"營": "营", +"燦": "灿", +"燭": "烛", +"燴": "烩", +"燶": "㶶", +"燼": "烬", +"燾": "焘", +"爍": "烁", +"爐": "炉", +"爛": "烂", +"爭": "争", +"爲": "为", +"爺": "爷", +"爾": "尔", +"牆": "墙", +"牘": "牍", +"牽": "牵", +"犖": "荦", +"犢": "犊", +"犧": "牺", +"狀": "状", +"狹": "狭", +"狽": "狈", +"猙": "狰", +"猶": "犹", +"猻": "狲", +"獁": "犸", +"獄": "狱", +"獅": "狮", +"獎": "奖", +"獨": "独", +"獪": "狯", +"獫": "猃", +"獮": "狝", +"獰": "狞", +"獱": "㺍", +"獲": "获", +"獵": "猎", +"獷": "犷", +"獸": "兽", +"獺": "獭", +"獻": "献", +"獼": "猕", +"玀": "猡", +"現": "现", +"琺": "珐", +"琿": "珲", +"瑋": "玮", +"瑒": "玚", +"瑣": "琐", +"瑤": "瑶", +"瑩": "莹", +"瑪": "玛", +"瑲": "玱", +"璉": "琏", +"璣": "玑", +"璦": "瑷", +"璫": "珰", +"環": "环", +"璽": "玺", +"瓊": "琼", +"瓏": "珑", +"瓔": "璎", +"瓚": "瓒", +"甌": "瓯", +"產": "产", +"産": "产", +"畝": "亩", +"畢": "毕", +"異": "异", +"畵": "画", +"當": "当", +"疇": "畴", +"疊": "叠", +"痙": "痉", +"痾": "疴", +"瘂": "痖", +"瘋": "疯", +"瘍": "疡", +"瘓": "痪", +"瘞": "瘗", +"瘡": "疮", +"瘧": "疟", +"瘮": "瘆", +"瘲": "疭", +"瘺": "瘘", +"瘻": "瘘", +"療": "疗", +"癆": "痨", +"癇": "痫", +"癉": "瘅", +"癘": "疠", +"癟": "瘪", +"癢": "痒", +"癤": "疖", +"癥": "症", +"癧": "疬", +"癩": "癞", +"癬": "癣", +"癭": "瘿", +"癮": "瘾", +"癰": "痈", +"癱": "瘫", +"癲": "癫", +"發": "发", +"皚": "皑", +"皰": "疱", +"皸": "皲", +"皺": "皱", +"盃": "杯", +"盜": "盗", +"盞": "盏", +"盡": "尽", +"監": "监", +"盤": "盘", +"盧": "卢", +"盪": "荡", +"眥": "眦", +"眾": "众", +"睏": "困", +"睜": "睁", +"睞": "睐", +"瞘": "眍", +"瞜": "䁖", +"瞞": "瞒", +"瞭": "了", +"瞶": "瞆", +"瞼": "睑", +"矇": "蒙", +"矓": "眬", +"矚": "瞩", +"矯": "矫", +"硃": "朱", +"硜": "硁", +"硤": "硖", +"硨": "砗", +"确": "确", +"硯": "砚", +"碩": "硕", +"碭": "砀", +"碸": "砜", +"確": "确", +"碼": "码", +"磑": "硙", +"磚": "砖", +"磣": "碜", +"磧": "碛", +"磯": "矶", +"磽": "硗", +"礆": "硷", +"礎": "础", +"礙": "碍", +"礦": "矿", +"礪": "砺", +"礫": "砾", +"礬": "矾", +"礱": "砻", +"祿": "禄", +"禍": "祸", +"禎": "祯", +"禕": "祎", +"禡": "祃", +"禦": "御", +"禪": "禅", +"禮": "礼", +"禰": "祢", +"禱": "祷", +"禿": "秃", +"秈": "籼", +"种": "种", +"稅": "税", +"稈": "秆", +"稏": "䅉", +"稟": "禀", +"種": "种", +"稱": "称", +"穀": "谷", +"穌": "稣", +"積": "积", +"穎": "颖", +"穠": "秾", +"穡": "穑", +"穢": "秽", +"穩": "稳", +"穫": "获", +"穭": "稆", +"窩": "窝", +"窪": "洼", +"窮": "穷", +"窯": "窑", +"窵": "窎", +"窶": "窭", +"窺": "窥", +"竄": "窜", +"竅": "窍", +"竇": "窦", +"竈": "灶", +"竊": "窃", +"竪": "竖", +"競": "竞", +"筆": "笔", +"筍": "笋", +"筑": "筑", +"筧": "笕", +"筴": "䇲", +"箋": "笺", +"箏": "筝", +"節": "节", +"範": "范", +"築": "筑", +"篋": "箧", +"篔": "筼", +"篤": "笃", +"篩": "筛", +"篳": "筚", +"簀": "箦", +"簍": "篓", +"簞": "箪", +"簡": "简", +"簣": "篑", +"簫": "箫", +"簹": "筜", +"簽": "签", +"簾": "帘", +"籃": "篮", +"籌": "筹", +"籖": "签", +"籙": "箓", +"籜": "箨", +"籟": "籁", +"籠": "笼", +"籩": "笾", +"籪": "簖", +"籬": "篱", +"籮": "箩", +"籲": "吁", +"粵": "粤", +"糝": "糁", +"糞": "粪", +"糧": "粮", +"糰": "团", +"糲": "粝", +"糴": "籴", +"糶": "粜", +"糹": "纟", +"糾": "纠", +"紀": "纪", +"紂": "纣", +"約": "约", +"紅": "红", +"紆": "纡", +"紇": "纥", +"紈": "纨", +"紉": "纫", +"紋": "纹", +"納": "纳", +"紐": "纽", +"紓": "纾", +"純": "纯", +"紕": "纰", +"紖": "纼", +"紗": "纱", +"紘": "纮", +"紙": "纸", +"級": "级", +"紛": "纷", +"紜": "纭", +"紝": "纴", +"紡": "纺", +"紬": "䌷", +"細": "细", +"紱": "绂", +"紲": "绁", +"紳": "绅", +"紵": "纻", +"紹": "绍", +"紺": "绀", +"紼": "绋", +"紿": "绐", +"絀": "绌", +"終": "终", +"組": "组", +"絅": "䌹", +"絆": "绊", +"絎": "绗", +"結": "结", +"絕": "绝", +"絛": "绦", +"絝": "绔", +"絞": "绞", +"絡": "络", +"絢": "绚", +"給": "给", +"絨": "绒", +"絰": "绖", +"統": "统", +"絲": "丝", +"絳": "绛", +"絶": "绝", +"絹": "绢", +"綁": "绑", +"綃": "绡", +"綆": "绠", +"綈": "绨", +"綉": "绣", +"綌": "绤", +"綏": "绥", +"綐": "䌼", +"經": "经", +"綜": "综", +"綞": "缍", +"綠": "绿", +"綢": "绸", +"綣": "绻", +"綫": "线", +"綬": "绶", +"維": "维", +"綯": "绹", +"綰": "绾", +"綱": "纲", +"網": "网", +"綳": "绷", +"綴": "缀", +"綵": "䌽", +"綸": "纶", +"綹": "绺", +"綺": "绮", +"綻": "绽", +"綽": "绰", +"綾": "绫", +"綿": "绵", +"緄": "绲", +"緇": "缁", +"緊": "紧", +"緋": "绯", +"緑": "绿", +"緒": "绪", +"緓": "绬", +"緔": "绱", +"緗": "缃", +"緘": "缄", +"緙": "缂", +"線": "线", +"緝": "缉", +"緞": "缎", +"締": "缔", +"緡": "缗", +"緣": "缘", +"緦": "缌", +"編": "编", +"緩": "缓", +"緬": "缅", +"緯": "纬", +"緱": "缑", +"緲": "缈", +"練": "练", +"緶": "缏", +"緹": "缇", +"緻": "致", +"縈": "萦", +"縉": "缙", +"縊": "缢", +"縋": "缒", +"縐": "绉", +"縑": "缣", +"縕": "缊", +"縗": "缞", +"縛": "缚", +"縝": "缜", +"縞": "缟", +"縟": "缛", +"縣": "县", +"縧": "绦", +"縫": "缝", +"縭": "缡", +"縮": "缩", +"縱": "纵", +"縲": "缧", +"縳": "䌸", +"縴": "纤", +"縵": "缦", +"縶": "絷", +"縷": "缕", +"縹": "缥", +"總": "总", +"績": "绩", +"繃": "绷", +"繅": "缫", +"繆": "缪", +"繒": "缯", +"織": "织", +"繕": "缮", +"繚": "缭", +"繞": "绕", +"繡": "绣", +"繢": "缋", +"繩": "绳", +"繪": "绘", +"繫": "系", +"繭": "茧", +"繮": "缰", +"繯": "缳", +"繰": "缲", +"繳": "缴", +"繸": "䍁", +"繹": "绎", +"繼": "继", +"繽": "缤", +"繾": "缱", +"繿": "䍀", +"纈": "缬", +"纊": "纩", +"續": "续", +"纍": "累", +"纏": "缠", +"纓": "缨", +"纔": "才", +"纖": "纤", +"纘": "缵", +"纜": "缆", +"缽": "钵", +"罈": "坛", +"罌": "罂", +"罰": "罚", +"罵": "骂", +"罷": "罢", +"羅": "罗", +"羆": "罴", +"羈": "羁", +"羋": "芈", +"羥": "羟", +"義": "义", +"習": "习", +"翹": "翘", +"耬": "耧", +"耮": "耢", +"聖": "圣", +"聞": "闻", +"聯": "联", +"聰": "聪", +"聲": "声", +"聳": "耸", +"聵": "聩", +"聶": "聂", +"職": "职", +"聹": "聍", +"聽": "听", +"聾": "聋", +"肅": "肃", +"胜": "胜", +"脅": "胁", +"脈": "脉", +"脛": "胫", +"脫": "脱", +"脹": "胀", +"腊": "腊", +"腎": "肾", +"腖": "胨", +"腡": "脶", +"腦": "脑", +"腫": "肿", +"腳": "脚", +"腸": "肠", +"膃": "腽", +"膚": "肤", +"膠": "胶", +"膩": "腻", +"膽": "胆", +"膾": "脍", +"膿": "脓", +"臉": "脸", +"臍": "脐", +"臏": "膑", +"臘": "腊", +"臚": "胪", +"臟": "脏", +"臠": "脔", +"臢": "臜", +"臥": "卧", +"臨": "临", +"臺": "台", +"與": "与", +"興": "兴", +"舉": "举", +"舊": "旧", +"艙": "舱", +"艤": "舣", +"艦": "舰", +"艫": "舻", +"艱": "艰", +"艷": "艳", +"芻": "刍", +"苧": "苎", +"苹": "苹", +"范": "范", +"茲": "兹", +"荊": "荆", +"莊": "庄", +"莖": "茎", +"莢": "荚", +"莧": "苋", +"華": "华", +"萇": "苌", +"萊": "莱", +"萬": "万", +"萵": "莴", +"葉": "叶", +"葒": "荭", +"著名": "著名", +"葤": "荮", +"葦": "苇", +"葯": "药", +"葷": "荤", +"蒓": "莼", +"蒔": "莳", +"蒞": "莅", +"蒼": "苍", +"蓀": "荪", +"蓋": "盖", +"蓮": "莲", +"蓯": "苁", +"蓴": "莼", +"蓽": "荜", +"蔔": "卜", +"蔞": "蒌", +"蔣": "蒋", +"蔥": "葱", +"蔦": "茑", +"蔭": "荫", +"蕁": "荨", +"蕆": "蒇", +"蕎": "荞", +"蕒": "荬", +"蕓": "芸", +"蕕": "莸", +"蕘": "荛", +"蕢": "蒉", +"蕩": "荡", +"蕪": "芜", +"蕭": "萧", +"蕷": "蓣", +"薀": "蕰", +"薈": "荟", +"薊": "蓟", +"薌": "芗", +"薔": "蔷", +"薘": "荙", +"薟": "莶", +"薦": "荐", +"薩": "萨", +"薳": "䓕", +"薴": "苧", +"薺": "荠", +"藉": "借", +"藍": "蓝", +"藎": "荩", +"藝": "艺", +"藥": "药", +"藪": "薮", +"藴": "蕴", +"藶": "苈", +"藹": "蔼", +"藺": "蔺", +"蘄": "蕲", +"蘆": "芦", +"蘇": "苏", +"蘊": "蕴", +"蘋": "苹", +"蘚": "藓", +"蘞": "蔹", +"蘢": "茏", +"蘭": "兰", +"蘺": "蓠", +"蘿": "萝", +"虆": "蔂", +"處": "处", +"虛": "虚", +"虜": "虏", +"號": "号", +"虧": "亏", +"虫": "虫", +"虯": "虬", +"蛺": "蛱", +"蛻": "蜕", +"蜆": "蚬", +"蜡": "蜡", +"蝕": "蚀", +"蝟": "猬", +"蝦": "虾", +"蝸": "蜗", +"螄": "蛳", +"螞": "蚂", +"螢": "萤", +"螮": "䗖", +"螻": "蝼", +"螿": "螀", +"蟄": "蛰", +"蟈": "蝈", +"蟎": "螨", +"蟣": "虮", +"蟬": "蝉", +"蟯": "蛲", +"蟲": "虫", +"蟶": "蛏", +"蟻": "蚁", +"蠅": "蝇", +"蠆": "虿", +"蠐": "蛴", +"蠑": "蝾", +"蠟": "蜡", +"蠣": "蛎", +"蠨": "蟏", +"蠱": "蛊", +"蠶": "蚕", +"蠻": "蛮", +"衆": "众", +"衊": "蔑", +"術": "术", +"衕": "同", +"衚": "胡", +"衛": "卫", +"衝": "冲", +"衹": "只", +"袞": "衮", +"裊": "袅", +"裏": "里", +"補": "补", +"裝": "装", +"裡": "里", +"製": "制", +"複": "复", +"褌": "裈", +"褘": "袆", +"褲": "裤", +"褳": "裢", +"褸": "褛", +"褻": "亵", +"襇": "裥", +"襏": "袯", +"襖": "袄", +"襝": "裣", +"襠": "裆", +"襤": "褴", +"襪": "袜", +"襬": "䙓", +"襯": "衬", +"襲": "袭", +"覆蓋": "覆盖", +"翻來覆去": "翻来覆去", +"見": "见", +"覎": "觃", +"規": "规", +"覓": "觅", +"視": "视", +"覘": "觇", +"覡": "觋", +"覥": "觍", +"覦": "觎", +"親": "亲", +"覬": "觊", +"覯": "觏", +"覲": "觐", +"覷": "觑", +"覺": "觉", +"覽": "览", +"覿": "觌", +"觀": "观", +"觴": "觞", +"觶": "觯", +"觸": "触", +"訁": "讠", +"訂": "订", +"訃": "讣", +"計": "计", +"訊": "讯", +"訌": "讧", +"討": "讨", +"訐": "讦", +"訒": "讱", +"訓": "训", +"訕": "讪", +"訖": "讫", +"託": "讬", +"記": "记", +"訛": "讹", +"訝": "讶", +"訟": "讼", +"訢": "䜣", +"訣": "诀", +"訥": "讷", +"訩": "讻", +"訪": "访", +"設": "设", +"許": "许", +"訴": "诉", +"訶": "诃", +"診": "诊", +"註": "注", +"詁": "诂", +"詆": "诋", +"詎": "讵", +"詐": "诈", +"詒": "诒", +"詔": "诏", +"評": "评", +"詖": "诐", +"詗": "诇", +"詘": "诎", +"詛": "诅", +"詞": "词", +"詠": "咏", +"詡": "诩", +"詢": "询", +"詣": "诣", +"試": "试", +"詩": "诗", +"詫": "诧", +"詬": "诟", +"詭": "诡", +"詮": "诠", +"詰": "诘", +"話": "话", +"該": "该", +"詳": "详", +"詵": "诜", +"詼": "诙", +"詿": "诖", +"誄": "诔", +"誅": "诛", +"誆": "诓", +"誇": "夸", +"誌": "志", +"認": "认", +"誑": "诳", +"誒": "诶", +"誕": "诞", +"誘": "诱", +"誚": "诮", +"語": "语", +"誠": "诚", +"誡": "诫", +"誣": "诬", +"誤": "误", +"誥": "诰", +"誦": "诵", +"誨": "诲", +"說": "说", +"説": "说", +"誰": "谁", +"課": "课", +"誶": "谇", +"誹": "诽", +"誼": "谊", +"誾": "訚", +"調": "调", +"諂": "谄", +"諄": "谆", +"談": "谈", +"諉": "诿", +"請": "请", +"諍": "诤", +"諏": "诹", +"諑": "诼", +"諒": "谅", +"論": "论", +"諗": "谂", +"諛": "谀", +"諜": "谍", +"諝": "谞", +"諞": "谝", +"諢": "诨", +"諤": "谔", +"諦": "谛", +"諧": "谐", +"諫": "谏", +"諭": "谕", +"諮": "谘", +"諱": "讳", +"諳": "谙", +"諶": "谌", +"諷": "讽", +"諸": "诸", +"諺": "谚", +"諼": "谖", +"諾": "诺", +"謀": "谋", +"謁": "谒", +"謂": "谓", +"謄": "誊", +"謅": "诌", +"謊": "谎", +"謎": "谜", +"謐": "谧", +"謔": "谑", +"謖": "谡", +"謗": "谤", +"謙": "谦", +"謚": "谥", +"講": "讲", +"謝": "谢", +"謠": "谣", +"謡": "谣", +"謨": "谟", +"謫": "谪", +"謬": "谬", +"謭": "谫", +"謳": "讴", +"謹": "谨", +"謾": "谩", +"譅": "䜧", +"證": "证", +"譎": "谲", +"譏": "讥", +"譖": "谮", +"識": "识", +"譙": "谯", +"譚": "谭", +"譜": "谱", +"譫": "谵", +"譯": "译", +"議": "议", +"譴": "谴", +"護": "护", +"譸": "诪", +"譽": "誉", +"譾": "谫", +"讀": "读", +"變": "变", +"讎": "仇", +"讎": "雠", +"讒": "谗", +"讓": "让", +"讕": "谰", +"讖": "谶", +"讜": "谠", +"讞": "谳", +"豈": "岂", +"豎": "竖", +"豐": "丰", +"豬": "猪", +"豶": "豮", +"貓": "猫", +"貙": "䝙", +"貝": "贝", +"貞": "贞", +"貟": "贠", +"負": "负", +"財": "财", +"貢": "贡", +"貧": "贫", +"貨": "货", +"販": "贩", +"貪": "贪", +"貫": "贯", +"責": "责", +"貯": "贮", +"貰": "贳", +"貲": "赀", +"貳": "贰", +"貴": "贵", +"貶": "贬", +"買": "买", +"貸": "贷", +"貺": "贶", +"費": "费", +"貼": "贴", +"貽": "贻", +"貿": "贸", +"賀": "贺", +"賁": "贲", +"賂": "赂", +"賃": "赁", +"賄": "贿", +"賅": "赅", +"資": "资", +"賈": "贾", +"賊": "贼", +"賑": "赈", +"賒": "赊", +"賓": "宾", +"賕": "赇", +"賙": "赒", +"賚": "赉", +"賜": "赐", +"賞": "赏", +"賠": "赔", +"賡": "赓", +"賢": "贤", +"賣": "卖", +"賤": "贱", +"賦": "赋", +"賧": "赕", +"質": "质", +"賫": "赍", +"賬": "账", +"賭": "赌", +"賰": "䞐", +"賴": "赖", +"賵": "赗", +"賺": "赚", +"賻": "赙", +"購": "购", +"賽": "赛", +"賾": "赜", +"贄": "贽", +"贅": "赘", +"贇": "赟", +"贈": "赠", +"贊": "赞", +"贋": "赝", +"贍": "赡", +"贏": "赢", +"贐": "赆", +"贓": "赃", +"贔": "赑", +"贖": "赎", +"贗": "赝", +"贛": "赣", +"贜": "赃", +"赬": "赪", +"趕": "赶", +"趙": "赵", +"趨": "趋", +"趲": "趱", +"跡": "迹", +"踐": "践", +"踴": "踊", +"蹌": "跄", +"蹕": "跸", +"蹣": "蹒", +"蹤": "踪", +"蹺": "跷", +"躂": "跶", +"躉": "趸", +"躊": "踌", +"躋": "跻", +"躍": "跃", +"躑": "踯", +"躒": "跞", +"躓": "踬", +"躕": "蹰", +"躚": "跹", +"躡": "蹑", +"躥": "蹿", +"躦": "躜", +"躪": "躏", +"軀": "躯", +"車": "车", +"軋": "轧", +"軌": "轨", +"軍": "军", +"軑": "轪", +"軒": "轩", +"軔": "轫", +"軛": "轭", +"軟": "软", +"軤": "轷", +"軫": "轸", +"軲": "轱", +"軸": "轴", +"軹": "轵", +"軺": "轺", +"軻": "轲", +"軼": "轶", +"軾": "轼", +"較": "较", +"輅": "辂", +"輇": "辁", +"輈": "辀", +"載": "载", +"輊": "轾", +"輒": "辄", +"輓": "挽", +"輔": "辅", +"輕": "轻", +"輛": "辆", +"輜": "辎", +"輝": "辉", +"輞": "辋", +"輟": "辍", +"輥": "辊", +"輦": "辇", +"輩": "辈", +"輪": "轮", +"輬": "辌", +"輯": "辑", +"輳": "辏", +"輸": "输", +"輻": "辐", +"輾": "辗", +"輿": "舆", +"轀": "辒", +"轂": "毂", +"轄": "辖", +"轅": "辕", +"轆": "辘", +"轉": "转", +"轍": "辙", +"轎": "轿", +"轔": "辚", +"轟": "轰", +"轡": "辔", +"轢": "轹", +"轤": "轳", +"辟": "辟", +"辦": "办", +"辭": "辞", +"辮": "辫", +"辯": "辩", +"農": "农", +"迴": "回", +"适": "适", +"逕": "迳", +"這": "这", +"連": "连", +"週": "周", +"進": "进", +"遊": "游", +"運": "运", +"過": "过", +"達": "达", +"違": "违", +"遙": "遥", +"遜": "逊", +"遞": "递", +"遠": "远", +"適": "适", +"遲": "迟", +"遷": "迁", +"選": "选", +"遺": "遗", +"遼": "辽", +"邁": "迈", +"還": "还", +"邇": "迩", +"邊": "边", +"邏": "逻", +"邐": "逦", +"郁": "郁", +"郟": "郏", +"郵": "邮", +"鄆": "郓", +"鄉": "乡", +"鄒": "邹", +"鄔": "邬", +"鄖": "郧", +"鄧": "邓", +"鄭": "郑", +"鄰": "邻", +"鄲": "郸", +"鄴": "邺", +"鄶": "郐", +"鄺": "邝", +"酇": "酂", +"酈": "郦", +"醖": "酝", +"醜": "丑", +"醞": "酝", +"醫": "医", +"醬": "酱", +"醱": "酦", +"釀": "酿", +"釁": "衅", +"釃": "酾", +"釅": "酽", +"采": "采", +"釋": "释", +"釐": "厘", +"釒": "钅", +"釓": "钆", +"釔": "钇", +"釕": "钌", +"釗": "钊", +"釘": "钉", +"釙": "钋", +"針": "针", +"釣": "钓", +"釤": "钐", +"釧": "钏", +"釩": "钒", +"釵": "钗", +"釷": "钍", +"釹": "钕", +"釺": "钎", +"鈀": "钯", +"鈁": "钫", +"鈃": "钘", +"鈄": "钭", +"鈈": "钚", +"鈉": "钠", +"鈍": "钝", +"鈎": "钩", +"鈐": "钤", +"鈑": "钣", +"鈒": "钑", +"鈔": "钞", +"鈕": "钮", +"鈞": "钧", +"鈣": "钙", +"鈥": "钬", +"鈦": "钛", +"鈧": "钪", +"鈮": "铌", +"鈰": "铈", +"鈳": "钶", +"鈴": "铃", +"鈷": "钴", +"鈸": "钹", +"鈹": "铍", +"鈺": "钰", +"鈽": "钸", +"鈾": "铀", +"鈿": "钿", +"鉀": "钾", +"鉅": "钜", +"鉈": "铊", +"鉉": "铉", +"鉋": "铇", +"鉍": "铋", +"鉑": "铂", +"鉕": "钷", +"鉗": "钳", +"鉚": "铆", +"鉛": "铅", +"鉞": "钺", +"鉢": "钵", +"鉤": "钩", +"鉦": "钲", +"鉬": "钼", +"鉭": "钽", +"鉶": "铏", +"鉸": "铰", +"鉺": "铒", +"鉻": "铬", +"鉿": "铪", +"銀": "银", +"銃": "铳", +"銅": "铜", +"銍": "铚", +"銑": "铣", +"銓": "铨", +"銖": "铢", +"銘": "铭", +"銚": "铫", +"銛": "铦", +"銜": "衔", +"銠": "铑", +"銣": "铷", +"銥": "铱", +"銦": "铟", +"銨": "铵", +"銩": "铥", +"銪": "铕", +"銫": "铯", +"銬": "铐", +"銱": "铞", +"銳": "锐", +"銷": "销", +"銹": "锈", +"銻": "锑", +"銼": "锉", +"鋁": "铝", +"鋃": "锒", +"鋅": "锌", +"鋇": "钡", +"鋌": "铤", +"鋏": "铗", +"鋒": "锋", +"鋙": "铻", +"鋝": "锊", +"鋟": "锓", +"鋣": "铘", +"鋤": "锄", +"鋥": "锃", +"鋦": "锔", +"鋨": "锇", +"鋩": "铓", +"鋪": "铺", +"鋭": "锐", +"鋮": "铖", +"鋯": "锆", +"鋰": "锂", +"鋱": "铽", +"鋶": "锍", +"鋸": "锯", +"鋼": "钢", +"錁": "锞", +"錄": "录", +"錆": "锖", +"錇": "锫", +"錈": "锩", +"錏": "铔", +"錐": "锥", +"錒": "锕", +"錕": "锟", +"錘": "锤", +"錙": "锱", +"錚": "铮", +"錛": "锛", +"錟": "锬", +"錠": "锭", +"錡": "锜", +"錢": "钱", +"錦": "锦", +"錨": "锚", +"錩": "锠", +"錫": "锡", +"錮": "锢", +"錯": "错", +"録": "录", +"錳": "锰", +"錶": "表", +"錸": "铼", +"鍀": "锝", +"鍁": "锨", +"鍃": "锪", +"鍆": "钔", +"鍇": "锴", +"鍈": "锳", +"鍋": "锅", +"鍍": "镀", +"鍔": "锷", +"鍘": "铡", +"鍚": "钖", +"鍛": "锻", +"鍠": "锽", +"鍤": "锸", +"鍥": "锲", +"鍩": "锘", +"鍬": "锹", +"鍰": "锾", +"鍵": "键", +"鍶": "锶", +"鍺": "锗", +"鍾": "钟", +"鎂": "镁", +"鎄": "锿", +"鎇": "镅", +"鎊": "镑", +"鎔": "镕", +"鎖": "锁", +"鎘": "镉", +"鎚": "锤", +"鎛": "镈", +"鎝": "𨱏", +"鎡": "镃", +"鎢": "钨", +"鎣": "蓥", +"鎦": "镏", +"鎧": "铠", +"鎩": "铩", +"鎪": "锼", +"鎬": "镐", +"鎮": "镇", +"鎰": "镒", +"鎲": "镋", +"鎳": "镍", +"鎵": "镓", +"鎸": "镌", +"鎿": "镎", +"鏃": "镞", +"鏇": "镟", +"鏈": "链", +"鏌": "镆", +"鏍": "镙", +"鏐": "镠", +"鏑": "镝", +"鏗": "铿", +"鏘": "锵", +"鏜": "镗", +"鏝": "镘", +"鏞": "镛", +"鏟": "铲", +"鏡": "镜", +"鏢": "镖", +"鏤": "镂", +"鏨": "錾", +"鏰": "镚", +"鏵": "铧", +"鏷": "镤", +"鏹": "镪", +"鏽": "锈", +"鐃": "铙", +"鐋": "铴", +"鐐": "镣", +"鐒": "铹", +"鐓": "镦", +"鐔": "镡", +"鐘": "钟", +"鐙": "镫", +"鐝": "镢", +"鐠": "镨", +"鐦": "锎", +"鐧": "锏", +"鐨": "镄", +"鐫": "镌", +"鐮": "镰", +"鐲": "镯", +"鐳": "镭", +"鐵": "铁", +"鐶": "镮", +"鐸": "铎", +"鐺": "铛", +"鐿": "镱", +"鑄": "铸", +"鑊": "镬", +"鑌": "镔", +"鑒": "鉴", +"鑔": "镲", +"鑕": "锧", +"鑞": "镴", +"鑠": "铄", +"鑣": "镳", +"鑥": "镥", +"鑭": "镧", +"鑰": "钥", +"鑱": "镵", +"鑲": "镶", +"鑷": "镊", +"鑹": "镩", +"鑼": "锣", +"鑽": "钻", +"鑾": "銮", +"鑿": "凿", +"钁": "镢", +"镟": "旋", +"長": "长", +"門": "门", +"閂": "闩", +"閃": "闪", +"閆": "闫", +"閈": "闬", +"閉": "闭", +"開": "开", +"閌": "闶", +"閎": "闳", +"閏": "闰", +"閑": "闲", +"間": "间", +"閔": "闵", +"閘": "闸", +"閡": "阂", +"閣": "阁", +"閤": "合", +"閥": "阀", +"閨": "闺", +"閩": "闽", +"閫": "阃", +"閬": "阆", +"閭": "闾", +"閱": "阅", +"閲": "阅", +"閶": "阊", +"閹": "阉", +"閻": "阎", +"閼": "阏", +"閽": "阍", +"閾": "阈", +"閿": "阌", +"闃": "阒", +"闆": "板", +"闈": "闱", +"闊": "阔", +"闋": "阕", +"闌": "阑", +"闍": "阇", +"闐": "阗", +"闒": "阘", +"闓": "闿", +"闔": "阖", +"闕": "阙", +"闖": "闯", +"關": "关", +"闞": "阚", +"闠": "阓", +"闡": "阐", +"闤": "阛", +"闥": "闼", +"阪": "坂", +"陘": "陉", +"陝": "陕", +"陣": "阵", +"陰": "阴", +"陳": "陈", +"陸": "陆", +"陽": "阳", +"隉": "陧", +"隊": "队", +"階": "阶", +"隕": "陨", +"際": "际", +"隨": "随", +"險": "险", +"隱": "隐", +"隴": "陇", +"隸": "隶", +"隻": "只", +"雋": "隽", +"雖": "虽", +"雙": "双", +"雛": "雏", +"雜": "杂", +"雞": "鸡", +"離": "离", +"難": "难", +"雲": "云", +"電": "电", +"霢": "霡", +"霧": "雾", +"霽": "霁", +"靂": "雳", +"靄": "霭", +"靈": "灵", +"靚": "靓", +"靜": "静", +"靨": "靥", +"鞀": "鼗", +"鞏": "巩", +"鞝": "绱", +"鞦": "秋", +"鞽": "鞒", +"韁": "缰", +"韃": "鞑", +"韆": "千", +"韉": "鞯", +"韋": "韦", +"韌": "韧", +"韍": "韨", +"韓": "韩", +"韙": "韪", +"韜": "韬", +"韞": "韫", +"韻": "韵", +"響": "响", +"頁": "页", +"頂": "顶", +"頃": "顷", +"項": "项", +"順": "顺", +"頇": "顸", +"須": "须", +"頊": "顼", +"頌": "颂", +"頎": "颀", +"頏": "颃", +"預": "预", +"頑": "顽", +"頒": "颁", +"頓": "顿", +"頗": "颇", +"領": "领", +"頜": "颌", +"頡": "颉", +"頤": "颐", +"頦": "颏", +"頭": "头", +"頮": "颒", +"頰": "颊", +"頲": "颋", +"頴": "颕", +"頷": "颔", +"頸": "颈", +"頹": "颓", +"頻": "频", +"頽": "颓", +"顆": "颗", +"題": "题", +"額": "额", +"顎": "颚", +"顏": "颜", +"顒": "颙", +"顓": "颛", +"顔": "颜", +"願": "愿", +"顙": "颡", +"顛": "颠", +"類": "类", +"顢": "颟", +"顥": "颢", +"顧": "顾", +"顫": "颤", +"顬": "颥", +"顯": "显", +"顰": "颦", +"顱": "颅", +"顳": "颞", +"顴": "颧", +"風": "风", +"颭": "飐", +"颮": "飑", +"颯": "飒", +"颱": "台", +"颳": "刮", +"颶": "飓", +"颸": "飔", +"颺": "飏", +"颻": "飖", +"颼": "飕", +"飀": "飗", +"飄": "飘", +"飆": "飙", +"飈": "飚", +"飛": "飞", +"飠": "饣", +"飢": "饥", +"飣": "饤", +"飥": "饦", +"飩": "饨", +"飪": "饪", +"飫": "饫", +"飭": "饬", +"飯": "饭", +"飲": "饮", +"飴": "饴", +"飼": "饲", +"飽": "饱", +"飾": "饰", +"飿": "饳", +"餃": "饺", +"餄": "饸", +"餅": "饼", +"餉": "饷", +"養": "养", +"餌": "饵", +"餎": "饹", +"餏": "饻", +"餑": "饽", +"餒": "馁", +"餓": "饿", +"餕": "馂", +"餖": "饾", +"餚": "肴", +"餛": "馄", +"餜": "馃", +"餞": "饯", +"餡": "馅", +"館": "馆", +"餱": "糇", +"餳": "饧", +"餶": "馉", +"餷": "馇", +"餺": "馎", +"餼": "饩", +"餾": "馏", +"餿": "馊", +"饁": "馌", +"饃": "馍", +"饅": "馒", +"饈": "馐", +"饉": "馑", +"饊": "馓", +"饋": "馈", +"饌": "馔", +"饑": "饥", +"饒": "饶", +"饗": "飨", +"饜": "餍", +"饞": "馋", +"饢": "馕", +"馬": "马", +"馭": "驭", +"馮": "冯", +"馱": "驮", +"馳": "驰", +"馴": "驯", +"馹": "驲", +"駁": "驳", +"駐": "驻", +"駑": "驽", +"駒": "驹", +"駔": "驵", +"駕": "驾", +"駘": "骀", +"駙": "驸", +"駛": "驶", +"駝": "驼", +"駟": "驷", +"駡": "骂", +"駢": "骈", +"駭": "骇", +"駰": "骃", +"駱": "骆", +"駸": "骎", +"駿": "骏", +"騁": "骋", +"騂": "骍", +"騅": "骓", +"騌": "骔", +"騍": "骒", +"騎": "骑", +"騏": "骐", +"騖": "骛", +"騙": "骗", +"騤": "骙", +"騧": "䯄", +"騫": "骞", +"騭": "骘", +"騮": "骝", +"騰": "腾", +"騶": "驺", +"騷": "骚", +"騸": "骟", +"騾": "骡", +"驀": "蓦", +"驁": "骜", +"驂": "骖", +"驃": "骠", +"驄": "骢", +"驅": "驱", +"驊": "骅", +"驌": "骕", +"驍": "骁", +"驏": "骣", +"驕": "骄", +"驗": "验", +"驚": "惊", +"驛": "驿", +"驟": "骤", +"驢": "驴", +"驤": "骧", +"驥": "骥", +"驦": "骦", +"驪": "骊", +"驫": "骉", +"骯": "肮", +"髏": "髅", +"髒": "脏", +"體": "体", +"髕": "髌", +"髖": "髋", +"髮": "发", +"鬆": "松", +"鬍": "胡", +"鬚": "须", +"鬢": "鬓", +"鬥": "斗", +"鬧": "闹", +"鬩": "阋", +"鬮": "阄", +"鬱": "郁", +"魎": "魉", +"魘": "魇", +"魚": "鱼", +"魛": "鱽", +"魢": "鱾", +"魨": "鲀", +"魯": "鲁", +"魴": "鲂", +"魷": "鱿", +"魺": "鲄", +"鮁": "鲅", +"鮃": "鲆", +"鮊": "鲌", +"鮋": "鲉", +"鮍": "鲏", +"鮎": "鲇", +"鮐": "鲐", +"鮑": "鲍", +"鮒": "鲋", +"鮓": "鲊", +"鮚": "鲒", +"鮜": "鲘", +"鮝": "鲞", +"鮞": "鲕", +"鮦": "鲖", +"鮪": "鲔", +"鮫": "鲛", +"鮭": "鲑", +"鮮": "鲜", +"鮳": "鲓", +"鮶": "鲪", +"鮺": "鲝", +"鯀": "鲧", +"鯁": "鲠", +"鯇": "鲩", +"鯉": "鲤", +"鯊": "鲨", +"鯒": "鲬", +"鯔": "鲻", +"鯕": "鲯", +"鯖": "鲭", +"鯗": "鲞", +"鯛": "鲷", +"鯝": "鲴", +"鯡": "鲱", +"鯢": "鲵", +"鯤": "鲲", +"鯧": "鲳", +"鯨": "鲸", +"鯪": "鲮", +"鯫": "鲰", +"鯴": "鲺", +"鯷": "鳀", +"鯽": "鲫", +"鯿": "鳊", +"鰁": "鳈", +"鰂": "鲗", +"鰃": "鳂", +"鰈": "鲽", +"鰉": "鳇", +"鰍": "鳅", +"鰏": "鲾", +"鰐": "鳄", +"鰒": "鳆", +"鰓": "鳃", +"鰜": "鳒", +"鰟": "鳑", +"鰠": "鳋", +"鰣": "鲥", +"鰥": "鳏", +"鰨": "鳎", +"鰩": "鳐", +"鰭": "鳍", +"鰮": "鳁", +"鰱": "鲢", +"鰲": "鳌", +"鰳": "鳓", +"鰵": "鳘", +"鰷": "鲦", +"鰹": "鲣", +"鰺": "鲹", +"鰻": "鳗", +"鰼": "鳛", +"鰾": "鳔", +"鱂": "鳉", +"鱅": "鳙", +"鱈": "鳕", +"鱉": "鳖", +"鱒": "鳟", +"鱔": "鳝", +"鱖": "鳜", +"鱗": "鳞", +"鱘": "鲟", +"鱝": "鲼", +"鱟": "鲎", +"鱠": "鲙", +"鱣": "鳣", +"鱤": "鳡", +"鱧": "鳢", +"鱨": "鲿", +"鱭": "鲚", +"鱯": "鳠", +"鱷": "鳄", +"鱸": "鲈", +"鱺": "鲡", +"䰾": "鲃", +"䲁": "鳚", +"鳥": "鸟", +"鳧": "凫", +"鳩": "鸠", +"鳬": "凫", +"鳲": "鸤", +"鳳": "凤", +"鳴": "鸣", +"鳶": "鸢", +"鳾": "䴓", +"鴆": "鸩", +"鴇": "鸨", +"鴉": "鸦", +"鴒": "鸰", +"鴕": "鸵", +"鴛": "鸳", +"鴝": "鸲", +"鴞": "鸮", +"鴟": "鸱", +"鴣": "鸪", +"鴦": "鸯", +"鴨": "鸭", +"鴯": "鸸", +"鴰": "鸹", +"鴴": "鸻", +"鴷": "䴕", +"鴻": "鸿", +"鴿": "鸽", +"鵁": "䴔", +"鵂": "鸺", +"鵃": "鸼", +"鵐": "鹀", +"鵑": "鹃", +"鵒": "鹆", +"鵓": "鹁", +"鵜": "鹈", +"鵝": "鹅", +"鵠": "鹄", +"鵡": "鹉", +"鵪": "鹌", +"鵬": "鹏", +"鵮": "鹐", +"鵯": "鹎", +"鵲": "鹊", +"鵷": "鹓", +"鵾": "鹍", +"鶄": "䴖", +"鶇": "鸫", +"鶉": "鹑", +"鶊": "鹒", +"鶓": "鹋", +"鶖": "鹙", +"鶘": "鹕", +"鶚": "鹗", +"鶡": "鹖", +"鶥": "鹛", +"鶩": "鹜", +"鶪": "䴗", +"鶬": "鸧", +"鶯": "莺", +"鶲": "鹟", +"鶴": "鹤", +"鶹": "鹠", +"鶺": "鹡", +"鶻": "鹘", +"鶼": "鹣", +"鶿": "鹚", +"鷀": "鹚", +"鷁": "鹢", +"鷂": "鹞", +"鷄": "鸡", +"鷈": "䴘", +"鷊": "鹝", +"鷓": "鹧", +"鷖": "鹥", +"鷗": "鸥", +"鷙": "鸷", +"鷚": "鹨", +"鷥": "鸶", +"鷦": "鹪", +"鷫": "鹔", +"鷯": "鹩", +"鷲": "鹫", +"鷳": "鹇", +"鷸": "鹬", +"鷹": "鹰", +"鷺": "鹭", +"鷽": "鸴", +"鷿": "䴙", +"鸂": "㶉", +"鸇": "鹯", +"鸌": "鹱", +"鸏": "鹲", +"鸕": "鸬", +"鸘": "鹴", +"鸚": "鹦", +"鸛": "鹳", +"鸝": "鹂", +"鸞": "鸾", +"鹵": "卤", +"鹹": "咸", +"鹺": "鹾", +"鹽": "盐", +"麗": "丽", +"麥": "麦", +"麩": "麸", +"麯": "曲", +"麵": "面", +"麼": "么", +"麽": "么", +"黃": "黄", +"黌": "黉", +"點": "点", +"黨": "党", +"黲": "黪", +"黴": "霉", +"黶": "黡", +"黷": "黩", +"黽": "黾", +"黿": "鼋", +"鼉": "鼍", +"鼕": "冬", +"鼴": "鼹", +"齊": "齐", +"齋": "斋", +"齎": "赍", +"齏": "齑", +"齒": "齿", +"齔": "龀", +"齕": "龁", +"齗": "龂", +"齙": "龅", +"齜": "龇", +"齟": "龃", +"齠": "龆", +"齡": "龄", +"齣": "出", +"齦": "龈", +"齪": "龊", +"齬": "龉", +"齲": "龋", +"齶": "腭", +"齷": "龌", +"龍": "龙", +"龎": "厐", +"龐": "庞", +"龔": "龚", +"龕": "龛", +"龜": "龟", + +"幾畫": "几画", +"賣畫": "卖画", +"滷鹼": "卤碱", +"原畫": "原画", +"口鹼": "口碱", +"古畫": "古画", +"名畫": "名画", +"奇畫": "奇画", +"如畫": "如画", +"弱鹼": "弱碱", +"彩畫": "彩画", +"所畫": "所画", +"扉畫": "扉画", +"教畫": "教画", +"水鹼": "水碱", +"洋鹼": "洋碱", +"炭畫": "炭画", +"畫一": "画一", +"畫上": "画上", +"畫下": "画下", +"畫中": "画中", +"畫供": "画供", +"畫兒": "画儿", +"畫具": "画具", +"畫出": "画出", +"畫史": "画史", +"畫品": "画品", +"畫商": "画商", +"畫圈": "画圈", +"畫境": "画境", +"畫工": "画工", +"畫帖": "画帖", +"畫幅": "画幅", +"畫意": "画意", +"畫成": "画成", +"畫景": "画景", +"畫本": "画本", +"畫架": "画架", +"畫框": "画框", +"畫法": "画法", +"畫王": "画王", +"畫界": "画界", +"畫符": "画符", +"畫紙": "画纸", +"畫線": "画线", +"畫航": "画航", +"畫舫": "画舫", +"畫虎": "画虎", +"畫論": "画论", +"畫譜": "画谱", +"畫象": "画象", +"畫質": "画质", +"畫貼": "画贴", +"畫軸": "画轴", +"畫頁": "画页", +"鹽鹼": "盐碱", +"鹼": "碱", +"鹼基": "碱基", +"鹼度": "碱度", +"鹼水": "碱水", +"鹼熔": "碱熔", +"磁畫": "磁画", +"策畫": "策画", +"組畫": "组画", +"絹畫": "绢画", +"耐鹼": "耐碱", +"肉鹼": "肉碱", +"膠畫": "胶画", +"茶鹼": "茶碱", +"西畫": "西画", +"貼畫": "贴画", +"返鹼": "返碱", +"鍾鍛": "锺锻", +"鍛鍾": "锻锺", +"雕畫": "雕画", +"鯰": "鲶", +"三聯畫": "三联画", +"中國畫": "中国画", +"書畫": "书画", +"書畫社": "书画社", +"五筆畫": "五笔画", +"作畫": "作画", +"入畫": "入画", +"寫生畫": "写生画", +"刻畫": "刻画", +"動畫": "动画", +"勾畫": "勾画", +"單色畫": "单色画", +"卡通畫": "卡通画", +"國畫": "国画", +"圖畫": "图画", +"壁畫": "壁画", +"字畫": "字画", +"宣傳畫": "宣传画", +"工筆畫": "工笔画", +"年畫": "年画", +"幽默畫": "幽默画", +"指畫": "指画", +"描畫": "描画", +"插畫": "插画", +"擘畫": "擘画", +"春畫": "春画", +"木刻畫": "木刻画", +"機械畫": "机械画", +"比畫": "比画", +"毛筆畫": "毛笔画", +"水粉畫": "水粉画", +"油畫": "油画", +"海景畫": "海景画", +"漫畫": "漫画", +"點畫": "点画", +"版畫": "版画", +"畫": "画", +"畫像": "画像", +"畫冊": "画册", +"畫刊": "画刊", +"畫匠": "画匠", +"畫捲": "画卷", +"畫圖": "画图", +"畫壇": "画坛", +"畫室": "画室", +"畫家": "画家", +"畫屏": "画屏", +"畫展": "画展", +"畫布": "画布", +"畫師": "画师", +"畫廊": "画廊", +"畫報": "画报", +"畫押": "画押", +"畫板": "画板", +"畫片": "画片", +"畫畫": "画画", +"畫皮": "画皮", +"畫眉鳥": "画眉鸟", +"畫稿": "画稿", +"畫筆": "画笔", +"畫院": "画院", +"畫集": "画集", +"畫面": "画面", +"筆畫": "笔画", +"細密畫": "细密画", +"繪畫": "绘画", +"自畫像": "自画像", +"蠟筆畫": "蜡笔画", +"裸體畫": "裸体画", +"西洋畫": "西洋画", +"透視畫": "透视画", +"銅版畫": "铜版画", +"鍾": "锺", +"靜物畫": "静物画", +"餘": "馀", +} + +zh2TW = { +"缺省": "預設", +"串行": "串列", +"以太网": "乙太網", +"位图": "點陣圖", +"例程": "常式", +"信道": "通道", +"光标": "游標", +"光盘": "光碟", +"光驱": "光碟機", +"全角": "全形", +"加载": "載入", +"半角": "半形", +"变量": "變數", +"噪声": "雜訊", +"脱机": "離線", +"声卡": "音效卡", +"老字号": "老字號", +"字号": "字型大小", +"字库": "字型檔", +"字段": "欄位", +"字符": "字元", +"存盘": "存檔", +"寻址": "定址", +"尾注": "章節附註", +"异步": "非同步", +"总线": "匯流排", +"括号": "括弧", +"接口": "介面", +"控件": "控制項", +"权限": "許可權", +"盘片": "碟片", +"硅片": "矽片", +"硅谷": "矽谷", +"硬盘": "硬碟", +"磁盘": "磁碟", +"磁道": "磁軌", +"程控": "程式控制", +"端口": "埠", +"算子": "運算元", +"算法": "演算法", +"芯片": "晶片", +"芯片": "晶元", +"词组": "片語", +"译码": "解碼", +"软驱": "軟碟機", +"快闪存储器": "快閃記憶體", +"闪存": "快閃記憶體", +"鼠标": "滑鼠", +"进制": "進位", +"交互式": "互動式", +"仿真": "模擬", +"优先级": "優先順序", +"传感": "感測", +"便携式": "攜帶型", +"信息论": "資訊理論", +"写保护": "防寫", +"分布式": "分散式", +"分辨率": "解析度", +"服务器": "伺服器", +"等于": "等於", +"局域网": "區域網", +"计算机": "電腦", +"扫瞄仪": "掃瞄器", +"宽带": "寬頻", +"数据库": "資料庫", +"奶酪": "乳酪", +"巨商": "鉅賈", +"手电": "手電筒", +"万历": "萬曆", +"永历": "永曆", +"词汇": "辭彙", +"习用": "慣用", +"元音": "母音", +"任意球": "自由球", +"头球": "頭槌", +"入球": "進球", +"粒入球": "顆進球", +"打门": "射門", +"火锅盖帽": "蓋火鍋", +"打印机": "印表機", +"打印機": "印表機", +"字节": "位元組", +"字節": "位元組", +"打印": "列印", +"打印": "列印", +"硬件": "硬體", +"硬件": "硬體", +"二极管": "二極體", +"二極管": "二極體", +"三极管": "三極體", +"三極管": "三極體", +"软件": "軟體", +"軟件": "軟體", +"网络": "網路", +"網絡": "網路", +"人工智能": "人工智慧", +"航天飞机": "太空梭", +"穿梭機": "太空梭", +"因特网": "網際網路", +"互聯網": "網際網路", +"机器人": "機器人", +"機械人": "機器人", +"移动电话": "行動電話", +"流動電話": "行動電話", +"调制解调器": "數據機", +"調制解調器": "數據機", +"短信": "簡訊", +"短訊": "簡訊", +"乌兹别克斯坦": "烏茲別克", +"乍得": "查德", +"乍得": "查德", +"也门": "葉門", +"也門": "葉門", +"伯利兹": "貝里斯", +"伯利茲": "貝里斯", +"佛得角": "維德角", +"佛得角": "維德角", +"克罗地亚": "克羅埃西亞", +"克羅地亞": "克羅埃西亞", +"冈比亚": "甘比亞", +"岡比亞": "甘比亞", +"几内亚比绍": "幾內亞比索", +"幾內亞比紹": "幾內亞比索", +"列支敦士登": "列支敦斯登", +"列支敦士登": "列支敦斯登", +"利比里亚": "賴比瑞亞", +"利比里亞": "賴比瑞亞", +"加纳": "迦納", +"加納": "迦納", +"加蓬": "加彭", +"加蓬": "加彭", +"博茨瓦纳": "波札那", +"博茨瓦納": "波札那", +"卡塔尔": "卡達", +"卡塔爾": "卡達", +"卢旺达": "盧安達", +"盧旺達": "盧安達", +"危地马拉": "瓜地馬拉", +"危地馬拉": "瓜地馬拉", +"厄瓜多尔": "厄瓜多", +"厄瓜多爾": "厄瓜多", +"厄立特里亚": "厄利垂亞", +"厄立特里亞": "厄利垂亞", +"吉布提": "吉布地", +"吉布堤": "吉布地", +"哈萨克斯坦": "哈薩克", +"哥斯达黎加": "哥斯大黎加", +"哥斯達黎加": "哥斯大黎加", +"图瓦卢": "吐瓦魯", +"圖瓦盧": "吐瓦魯", +"土库曼斯坦": "土庫曼", +"圣卢西亚": "聖露西亞", +"聖盧西亞": "聖露西亞", +"圣基茨和尼维斯": "聖克里斯多福及尼維斯", +"聖吉斯納域斯": "聖克里斯多福及尼維斯", +"圣文森特和格林纳丁斯": "聖文森及格瑞那丁", +"聖文森特和格林納丁斯": "聖文森及格瑞那丁", +"圣马力诺": "聖馬利諾", +"聖馬力諾": "聖馬利諾", +"圭亚那": "蓋亞那", +"圭亞那": "蓋亞那", +"坦桑尼亚": "坦尚尼亞", +"坦桑尼亞": "坦尚尼亞", +"埃塞俄比亚": "衣索比亞", +"埃塞俄比亞": "衣索比亞", +"基里巴斯": "吉里巴斯", +"基里巴斯": "吉里巴斯", +"塔吉克斯坦": "塔吉克", +"塞拉利昂": "獅子山", +"塞拉利昂": "獅子山", +"塞浦路斯": "塞普勒斯", +"塞浦路斯": "塞普勒斯", +"塞舌尔": "塞席爾", +"塞舌爾": "塞席爾", +"多米尼加": "多明尼加", +"多明尼加共和國": "多明尼加", +"多米尼加联邦": "多米尼克", +"多明尼加聯邦": "多米尼克", +"安提瓜和巴布达": "安地卡及巴布達", +"安提瓜和巴布達": "安地卡及巴布達", +"尼日利亚": "奈及利亞", +"尼日利亞": "奈及利亞", +"尼日尔": "尼日", +"尼日爾": "尼日", +"巴巴多斯": "巴貝多", +"巴巴多斯": "巴貝多", +"巴布亚新几内亚": "巴布亞紐幾內亞", +"巴布亞新畿內亞": "巴布亞紐幾內亞", +"布基纳法索": "布吉納法索", +"布基納法索": "布吉納法索", +"布隆迪": "蒲隆地", +"布隆迪": "蒲隆地", +"希腊": "希臘", +"帕劳": "帛琉", +"意大利": "義大利", +"意大利": "義大利", +"所罗门群岛": "索羅門群島", +"所羅門群島": "索羅門群島", +"文莱": "汶萊", +"斯威士兰": "史瓦濟蘭", +"斯威士蘭": "史瓦濟蘭", +"斯洛文尼亚": "斯洛維尼亞", +"斯洛文尼亞": "斯洛維尼亞", +"新西兰": "紐西蘭", +"新西蘭": "紐西蘭", +"格林纳达": "格瑞那達", +"格林納達": "格瑞那達", +"格鲁吉亚": "喬治亞", +"格魯吉亞": "喬治亞", +"佐治亚": "喬治亞", +"佐治亞": "喬治亞", +"毛里塔尼亚": "茅利塔尼亞", +"毛里塔尼亞": "茅利塔尼亞", +"毛里求斯": "模里西斯", +"毛里裘斯": "模里西斯", +"沙特阿拉伯": "沙烏地阿拉伯", +"沙地阿拉伯": "沙烏地阿拉伯", +"波斯尼亚和黑塞哥维那": "波士尼亞赫塞哥維納", +"波斯尼亞黑塞哥維那": "波士尼亞赫塞哥維納", +"津巴布韦": "辛巴威", +"津巴布韋": "辛巴威", +"洪都拉斯": "宏都拉斯", +"洪都拉斯": "宏都拉斯", +"特立尼达和托巴哥": "千里達托貝哥", +"特立尼達和多巴哥": "千里達托貝哥", +"瑙鲁": "諾魯", +"瑙魯": "諾魯", +"瓦努阿图": "萬那杜", +"瓦努阿圖": "萬那杜", +"溫納圖萬": "那杜", +"科摩罗": "葛摩", +"科摩羅": "葛摩", +"科特迪瓦": "象牙海岸", +"突尼斯": "突尼西亞", +"索马里": "索馬利亞", +"索馬里": "索馬利亞", +"老挝": "寮國", +"老撾": "寮國", +"肯尼亚": "肯亞", +"肯雅": "肯亞", +"苏里南": "蘇利南", +"莫桑比克": "莫三比克", +"莱索托": "賴索托", +"萊索托": "賴索托", +"贝宁": "貝南", +"貝寧": "貝南", +"赞比亚": "尚比亞", +"贊比亞": "尚比亞", +"阿塞拜疆": "亞塞拜然", +"阿塞拜疆": "亞塞拜然", +"阿拉伯联合酋长国": "阿拉伯聯合大公國", +"阿拉伯聯合酋長國": "阿拉伯聯合大公國", +"马尔代夫": "馬爾地夫", +"馬爾代夫": "馬爾地夫", +"马耳他": "馬爾他", +"马里共和国": "馬利共和國", +"馬里共和國": "馬利共和國", +"方便面": "速食麵", +"快速面": "速食麵", +"即食麵": "速食麵", +"薯仔": "土豆", +"蹦极跳": "笨豬跳", +"绑紧跳": "笨豬跳", +"冷菜": "冷盤", +"凉菜": "冷盤", +"出租车": "計程車", +"台球": "撞球", +"桌球": "撞球", +"雪糕": "冰淇淋", +"卫生": "衛生", +"衞生": "衛生", +"平治": "賓士", +"奔驰": "賓士", +"積架": "捷豹", +"福士": "福斯", +"雪铁龙": "雪鐵龍", +"马自达": "馬自達", +"萬事得": "馬自達", +"拿破仑": "拿破崙", +"拿破侖": "拿破崙", +"布什": "布希", +"布殊": "布希", +"克林顿": "柯林頓", +"克林頓": "柯林頓", +"侯赛因": "海珊", +"侯賽因": "海珊", +"凡高": "梵谷", +"狄安娜": "黛安娜", +"戴安娜": "黛安娜", +"赫拉": "希拉", +} + +zh2HK = { +"打印机": "打印機", +"印表機": "打印機", +"字节": "位元組", +"字節": "位元組", +"打印": "打印", +"列印": "打印", +"硬件": "硬件", +"硬體": "硬件", +"二极管": "二極管", +"二極體": "二極管", +"三极管": "三極管", +"三極體": "三極管", +"数码": "數碼", +"數位": "數碼", +"软件": "軟件", +"軟體": "軟件", +"网络": "網絡", +"網路": "網絡", +"人工智能": "人工智能", +"人工智慧": "人工智能", +"航天飞机": "穿梭機", +"太空梭": "穿梭機", +"因特网": "互聯網", +"網際網路": "互聯網", +"机器人": "機械人", +"機器人": "機械人", +"移动电话": "流動電話", +"行動電話": "流動電話", +"调制解调器": "調制解調器", +"數據機": "調制解調器", +"短信": "短訊", +"簡訊": "短訊", +"乍得": "乍得", +"查德": "乍得", +"也门": "也門", +"葉門": "也門", +"伯利兹": "伯利茲", +"貝里斯": "伯利茲", +"佛得角": "佛得角", +"維德角": "佛得角", +"克罗地亚": "克羅地亞", +"克羅埃西亞": "克羅地亞", +"冈比亚": "岡比亞", +"甘比亞": "岡比亞", +"几内亚比绍": "幾內亞比紹", +"幾內亞比索": "幾內亞比紹", +"列支敦士登": "列支敦士登", +"列支敦斯登": "列支敦士登", +"利比里亚": "利比里亞", +"賴比瑞亞": "利比里亞", +"加纳": "加納", +"迦納": "加納", +"加蓬": "加蓬", +"加彭": "加蓬", +"博茨瓦纳": "博茨瓦納", +"波札那": "博茨瓦納", +"卡塔尔": "卡塔爾", +"卡達": "卡塔爾", +"卢旺达": "盧旺達", +"盧安達": "盧旺達", +"危地马拉": "危地馬拉", +"瓜地馬拉": "危地馬拉", +"厄瓜多尔": "厄瓜多爾", +"厄瓜多": "厄瓜多爾", +"厄立特里亚": "厄立特里亞", +"厄利垂亞": "厄立特里亞", +"吉布提": "吉布堤", +"吉布地": "吉布堤", +"哥斯达黎加": "哥斯達黎加", +"哥斯大黎加": "哥斯達黎加", +"图瓦卢": "圖瓦盧", +"吐瓦魯": "圖瓦盧", +"圣卢西亚": "聖盧西亞", +"聖露西亞": "聖盧西亞", +"圣基茨和尼维斯": "聖吉斯納域斯", +"聖克里斯多福及尼維斯": "聖吉斯納域斯", +"圣文森特和格林纳丁斯": "聖文森特和格林納丁斯", +"聖文森及格瑞那丁": "聖文森特和格林納丁斯", +"圣马力诺": "聖馬力諾", +"聖馬利諾": "聖馬力諾", +"圭亚那": "圭亞那", +"蓋亞那": "圭亞那", +"坦桑尼亚": "坦桑尼亞", +"坦尚尼亞": "坦桑尼亞", +"埃塞俄比亚": "埃塞俄比亞", +"衣索匹亞": "埃塞俄比亞", +"衣索比亞": "埃塞俄比亞", +"基里巴斯": "基里巴斯", +"吉里巴斯": "基里巴斯", +"狮子山": "獅子山", +"塞普勒斯": "塞浦路斯", +"塞舌尔": "塞舌爾", +"塞席爾": "塞舌爾", +"多米尼加": "多明尼加共和國", +"多明尼加": "多明尼加共和國", +"多米尼加联邦": "多明尼加聯邦", +"多米尼克": "多明尼加聯邦", +"安提瓜和巴布达": "安提瓜和巴布達", +"安地卡及巴布達": "安提瓜和巴布達", +"尼日利亚": "尼日利亞", +"奈及利亞": "尼日利亞", +"尼日尔": "尼日爾", +"尼日": "尼日爾", +"巴巴多斯": "巴巴多斯", +"巴貝多": "巴巴多斯", +"巴布亚新几内亚": "巴布亞新畿內亞", +"巴布亞紐幾內亞": "巴布亞新畿內亞", +"布基纳法索": "布基納法索", +"布吉納法索": "布基納法索", +"布隆迪": "布隆迪", +"蒲隆地": "布隆迪", +"義大利": "意大利", +"所罗门群岛": "所羅門群島", +"索羅門群島": "所羅門群島", +"斯威士兰": "斯威士蘭", +"史瓦濟蘭": "斯威士蘭", +"斯洛文尼亚": "斯洛文尼亞", +"斯洛維尼亞": "斯洛文尼亞", +"新西兰": "新西蘭", +"紐西蘭": "新西蘭", +"格林纳达": "格林納達", +"格瑞那達": "格林納達", +"格鲁吉亚": "喬治亞", +"格魯吉亞": "喬治亞", +"梵蒂冈": "梵蒂岡", +"毛里塔尼亚": "毛里塔尼亞", +"茅利塔尼亞": "毛里塔尼亞", +"毛里求斯": "毛里裘斯", +"模里西斯": "毛里裘斯", +"沙烏地阿拉伯": "沙特阿拉伯", +"波斯尼亚和黑塞哥维那": "波斯尼亞黑塞哥維那", +"波士尼亞赫塞哥維納": "波斯尼亞黑塞哥維那", +"津巴布韦": "津巴布韋", +"辛巴威": "津巴布韋", +"洪都拉斯": "洪都拉斯", +"宏都拉斯": "洪都拉斯", +"特立尼达和托巴哥": "特立尼達和多巴哥", +"千里達托貝哥": "特立尼達和多巴哥", +"瑙鲁": "瑙魯", +"諾魯": "瑙魯", +"瓦努阿图": "瓦努阿圖", +"萬那杜": "瓦努阿圖", +"科摩罗": "科摩羅", +"葛摩": "科摩羅", +"索马里": "索馬里", +"索馬利亞": "索馬里", +"老挝": "老撾", +"寮國": "老撾", +"肯尼亚": "肯雅", +"肯亞": "肯雅", +"莫桑比克": "莫桑比克", +"莫三比克": "莫桑比克", +"莱索托": "萊索托", +"賴索托": "萊索托", +"贝宁": "貝寧", +"貝南": "貝寧", +"赞比亚": "贊比亞", +"尚比亞": "贊比亞", +"阿塞拜疆": "阿塞拜疆", +"亞塞拜然": "阿塞拜疆", +"阿拉伯联合酋长国": "阿拉伯聯合酋長國", +"阿拉伯聯合大公國": "阿拉伯聯合酋長國", +"马尔代夫": "馬爾代夫", +"馬爾地夫": "馬爾代夫", +"馬利共和國": "馬里共和國", +"方便面": "即食麵", +"快速面": "即食麵", +"速食麵": "即食麵", +"泡麵": "即食麵", +"土豆": "馬鈴薯", +"华乐": "中樂", +"民乐": "中樂", +"計程車": "的士", +"出租车": "的士", +"公車": "巴士", +"自行车": "單車", +"犬只": "狗隻", +"台球": "桌球", +"撞球": "桌球", +"冰淇淋": "雪糕", +"賓士": "平治", +"捷豹": "積架", +"福斯": "福士", +"雪铁龙": "先進", +"雪鐵龍": "先進", +"沃尓沃": "富豪", +"马自达": "萬事得", +"馬自達": "萬事得", +"寶獅": "標致", +"拿破崙": "拿破侖", +"布什": "布殊", +"布希": "布殊", +"克林顿": "克林頓", +"柯林頓": "克林頓", +"萨达姆": "薩達姆", +"海珊": "侯賽因", +"侯赛因": "侯賽因", +"大卫·贝克汉姆": "大衛碧咸", +"迈克尔·欧文": "米高奧雲", +"珍妮弗·卡普里亚蒂": "卡佩雅蒂", +"马拉特·萨芬": "沙芬", +"迈克尔·舒马赫": "舒麥加", +"希特勒": "希特拉", +"狄安娜": "戴安娜", +"黛安娜": "戴安娜", +} + +zh2CN = { +"記憶體": "内存", +"預設": "默认", +"串列": "串行", +"乙太網": "以太网", +"點陣圖": "位图", +"常式": "例程", +"游標": "光标", +"光碟": "光盘", +"光碟機": "光驱", +"全形": "全角", +"共用": "共享", +"載入": "加载", +"半形": "半角", +"變數": "变量", +"雜訊": "噪声", +"因數": "因子", +"功能變數名稱": "域名", +"音效卡": "声卡", +"字型大小": "字号", +"字型檔": "字库", +"欄位": "字段", +"字元": "字符", +"存檔": "存盘", +"定址": "寻址", +"章節附註": "尾注", +"非同步": "异步", +"匯流排": "总线", +"括弧": "括号", +"介面": "接口", +"控制項": "控件", +"許可權": "权限", +"碟片": "盘片", +"矽片": "硅片", +"矽谷": "硅谷", +"硬碟": "硬盘", +"磁碟": "磁盘", +"磁軌": "磁道", +"程式控制": "程控", +"運算元": "算子", +"演算法": "算法", +"晶片": "芯片", +"晶元": "芯片", +"片語": "词组", +"軟碟機": "软驱", +"快閃記憶體": "快闪存储器", +"滑鼠": "鼠标", +"進位": "进制", +"互動式": "交互式", +"優先順序": "优先级", +"感測": "传感", +"攜帶型": "便携式", +"資訊理論": "信息论", +"迴圈": "循环", +"防寫": "写保护", +"分散式": "分布式", +"解析度": "分辨率", +"伺服器": "服务器", +"等於": "等于", +"區域網": "局域网", +"巨集": "宏", +"掃瞄器": "扫瞄仪", +"寬頻": "宽带", +"資料庫": "数据库", +"乳酪": "奶酪", +"鉅賈": "巨商", +"手電筒": "手电", +"萬曆": "万历", +"永曆": "永历", +"辭彙": "词汇", +"母音": "元音", +"自由球": "任意球", +"頭槌": "头球", +"進球": "入球", +"顆進球": "粒入球", +"射門": "打门", +"蓋火鍋": "火锅盖帽", +"印表機": "打印机", +"打印機": "打印机", +"位元組": "字节", +"字節": "字节", +"列印": "打印", +"打印": "打印", +"硬體": "硬件", +"二極體": "二极管", +"二極管": "二极管", +"三極體": "三极管", +"三極管": "三极管", +"數位": "数码", +"數碼": "数码", +"軟體": "软件", +"軟件": "软件", +"網路": "网络", +"網絡": "网络", +"人工智慧": "人工智能", +"太空梭": "航天飞机", +"穿梭機": "航天飞机", +"網際網路": "因特网", +"互聯網": "因特网", +"機械人": "机器人", +"機器人": "机器人", +"行動電話": "移动电话", +"流動電話": "移动电话", +"調制解調器": "调制解调器", +"數據機": "调制解调器", +"短訊": "短信", +"簡訊": "短信", +"烏茲別克": "乌兹别克斯坦", +"查德": "乍得", +"乍得": "乍得", +"也門": "", +"葉門": "也门", +"伯利茲": "伯利兹", +"貝里斯": "伯利兹", +"維德角": "佛得角", +"佛得角": "佛得角", +"克羅地亞": "克罗地亚", +"克羅埃西亞": "克罗地亚", +"岡比亞": "冈比亚", +"甘比亞": "冈比亚", +"幾內亞比紹": "几内亚比绍", +"幾內亞比索": "几内亚比绍", +"列支敦斯登": "列支敦士登", +"列支敦士登": "列支敦士登", +"利比里亞": "利比里亚", +"賴比瑞亞": "利比里亚", +"加納": "加纳", +"迦納": "加纳", +"加彭": "加蓬", +"加蓬": "加蓬", +"博茨瓦納": "博茨瓦纳", +"波札那": "博茨瓦纳", +"卡塔爾": "卡塔尔", +"卡達": "卡塔尔", +"盧旺達": "卢旺达", +"盧安達": "卢旺达", +"危地馬拉": "危地马拉", +"瓜地馬拉": "危地马拉", +"厄瓜多爾": "厄瓜多尔", +"厄瓜多": "厄瓜多尔", +"厄立特里亞": "厄立特里亚", +"厄利垂亞": "厄立特里亚", +"吉布堤": "吉布提", +"吉布地": "吉布提", +"哈薩克": "哈萨克斯坦", +"哥斯達黎加": "哥斯达黎加", +"哥斯大黎加": "哥斯达黎加", +"圖瓦盧": "图瓦卢", +"吐瓦魯": "图瓦卢", +"土庫曼": "土库曼斯坦", +"聖盧西亞": "圣卢西亚", +"聖露西亞": "圣卢西亚", +"聖吉斯納域斯": "圣基茨和尼维斯", +"聖克里斯多福及尼維斯": "圣基茨和尼维斯", +"聖文森特和格林納丁斯": "圣文森特和格林纳丁斯", +"聖文森及格瑞那丁": "圣文森特和格林纳丁斯", +"聖馬力諾": "圣马力诺", +"聖馬利諾": "圣马力诺", +"圭亞那": "圭亚那", +"蓋亞那": "圭亚那", +"坦桑尼亞": "坦桑尼亚", +"坦尚尼亞": "坦桑尼亚", +"埃塞俄比亞": "埃塞俄比亚", +"衣索匹亞": "埃塞俄比亚", +"衣索比亞": "埃塞俄比亚", +"吉里巴斯": "基里巴斯", +"基里巴斯": "基里巴斯", +"塔吉克": "塔吉克斯坦", +"塞拉利昂": "塞拉利昂", +"塞普勒斯": "塞浦路斯", +"塞浦路斯": "塞浦路斯", +"塞舌爾": "塞舌尔", +"塞席爾": "塞舌尔", +"多明尼加共和國": "多米尼加", +"多明尼加": "多米尼加", +"多明尼加聯邦": "多米尼加联邦", +"多米尼克": "多米尼加联邦", +"安提瓜和巴布達": "安提瓜和巴布达", +"安地卡及巴布達": "安提瓜和巴布达", +"尼日利亞": "尼日利亚", +"奈及利亞": "尼日利亚", +"尼日爾": "尼日尔", +"尼日": "尼日尔", +"巴貝多": "巴巴多斯", +"巴巴多斯": "巴巴多斯", +"巴布亞新畿內亞": "巴布亚新几内亚", +"巴布亞紐幾內亞": "巴布亚新几内亚", +"布基納法索": "布基纳法索", +"布吉納法索": "布基纳法索", +"蒲隆地": "布隆迪", +"布隆迪": "布隆迪", +"希臘": "希腊", +"帛琉": "帕劳", +"義大利": "意大利", +"意大利": "意大利", +"所羅門群島": "所罗门群岛", +"索羅門群島": "所罗门群岛", +"汶萊": "文莱", +"斯威士蘭": "斯威士兰", +"史瓦濟蘭": "斯威士兰", +"斯洛文尼亞": "斯洛文尼亚", +"斯洛維尼亞": "斯洛文尼亚", +"新西蘭": "新西兰", +"紐西蘭": "新西兰", +"格林納達": "格林纳达", +"格瑞那達": "格林纳达", +"格魯吉亞": "乔治亚", +"喬治亞": "乔治亚", +"梵蒂岡": "梵蒂冈", +"毛里塔尼亞": "毛里塔尼亚", +"茅利塔尼亞": "毛里塔尼亚", +"毛里裘斯": "毛里求斯", +"模里西斯": "毛里求斯", +"沙地阿拉伯": "沙特阿拉伯", +"沙烏地阿拉伯": "沙特阿拉伯", +"波斯尼亞黑塞哥維那": "波斯尼亚和黑塞哥维那", +"波士尼亞赫塞哥維納": "波斯尼亚和黑塞哥维那", +"津巴布韋": "津巴布韦", +"辛巴威": "津巴布韦", +"宏都拉斯": "洪都拉斯", +"洪都拉斯": "洪都拉斯", +"特立尼達和多巴哥": "特立尼达和托巴哥", +"千里達托貝哥": "特立尼达和托巴哥", +"瑙魯": "瑙鲁", +"諾魯": "瑙鲁", +"瓦努阿圖": "瓦努阿图", +"萬那杜": "瓦努阿图", +"溫納圖": "瓦努阿图", +"科摩羅": "科摩罗", +"葛摩": "科摩罗", +"象牙海岸": "科特迪瓦", +"突尼西亞": "突尼斯", +"索馬里": "索马里", +"索馬利亞": "索马里", +"老撾": "老挝", +"寮國": "老挝", +"肯雅": "肯尼亚", +"肯亞": "肯尼亚", +"蘇利南": "苏里南", +"莫三比克": "莫桑比克", +"莫桑比克": "莫桑比克", +"萊索托": "莱索托", +"賴索托": "莱索托", +"貝寧": "贝宁", +"貝南": "贝宁", +"贊比亞": "赞比亚", +"尚比亞": "赞比亚", +"亞塞拜然": "阿塞拜疆", +"阿塞拜疆": "阿塞拜疆", +"阿拉伯聯合酋長國": "阿拉伯联合酋长国", +"阿拉伯聯合大公國": "阿拉伯联合酋长国", +"南韓": "韩国", +"馬爾代夫": "马尔代夫", +"馬爾地夫": "马尔代夫", +"馬爾他": "马耳他", +"馬利共和國": "马里共和国", +"即食麵": "方便面", +"快速面": "方便面", +"速食麵": "方便面", +"泡麵": "方便面", +"笨豬跳": "蹦极跳", +"绑紧跳": "蹦极跳", +"冷盤": "凉菜", +"冷菜": "凉菜", +"散钱": "零钱", +"谐星": "笑星", +"夜学": "夜校", +"华乐": "民乐", +"中樂": "民乐", +"屋价": "房价", +"的士": "出租车", +"計程車": "出租车", +"公車": "公共汽车", +"單車": "自行车", +"節慶": "节日", +"芝士": "乾酪", +"狗隻": "犬只", +"士多啤梨": "草莓", +"忌廉": "奶油", +"桌球": "台球", +"撞球": "台球", +"雪糕": "冰淇淋", +"衞生": "卫生", +"衛生": "卫生", +"賓士": "奔驰", +"平治": "奔驰", +"積架": "捷豹", +"福斯": "大众", +"福士": "大众", +"雪鐵龍": "雪铁龙", +"萬事得": "马自达", +"馬自達": "马自达", +"寶獅": "标志", +"拿破崙": "拿破仑", +"布殊": "布什", +"布希": "布什", +"柯林頓": "克林顿", +"克林頓": "克林顿", +"薩達姆": "萨达姆", +"海珊": "萨达姆", +"梵谷": "凡高", +"大衛碧咸": "大卫·贝克汉姆", +"米高奧雲": "迈克尔·欧文", +"卡佩雅蒂": "珍妮弗·卡普里亚蒂", +"沙芬": "马拉特·萨芬", +"舒麥加": "迈克尔·舒马赫", +"希特拉": "希特勒", +"黛安娜": "戴安娜", +"希拉": "赫拉", +} + +zh2SG = { +"方便面": "快速面", +"速食麵": "快速面", +"即食麵": "快速面", +"蹦极跳": "绑紧跳", +"笨豬跳": "绑紧跳", +"凉菜": "冷菜", +"冷盤": "冷菜", +"零钱": "散钱", +"散紙": "散钱", +"笑星": "谐星", +"夜校": "夜学", +"民乐": "华乐", +"住房": "住屋", +"房价": "屋价", +"泡麵": "快速面", +}