From 479423ab6a2377246a924b7ba7a939d5cb163924 Mon Sep 17 00:00:00 2001 From: ngc660sec <2596473306@qq.com> Date: Sun, 10 Sep 2023 15:34:49 +0800 Subject: [PATCH] =?UTF-8?q?NGCBot=201.5=E9=87=8D=E5=A4=A7=E6=9B=B4?= =?UTF-8?q?=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Api_Server/Api_Server_Main.py | 524 +++++++++++++++ .../Api_Server_Main.cpython-38.pyc | Bin 0 -> 18280 bytes BotServer/MainServer.py | 254 +++++++ BotServer/SendServer.py | 144 ++++ .../__pycache__/MainServer.cpython-38.pyc | Bin 0 -> 6954 bytes .../__pycache__/SendServer.cpython-38.pyc | Bin 0 -> 4101 bytes Cache/Cache_Server.py | 51 ++ Cache/__pycache__/Cache_Server.cpython-38.pyc | Bin 0 -> 2163 bytes Config/config.yaml | 204 ++++++ Db_Server/Db_Point_Server.py | 172 +++++ Db_Server/Db_User_Server.py | 222 +++++++ .../Db_Point_Server.cpython-38.pyc | Bin 0 -> 5693 bytes .../__pycache__/Db_User_Server.cpython-38.pyc | Bin 0 -> 7148 bytes Output/__init__.py | 0 Output/__pycache__/__init__.cpython-38.pyc | Bin 0 -> 144 bytes Output/__pycache__/output.cpython-38.pyc | Bin 0 -> 521 bytes Output/output.py | 17 + Push_Server/Push_Main_Server.py | 96 +++ .../Push_Main_Server.cpython-38.pyc | Bin 0 -> 3576 bytes README.MD | 617 ++++++++++++++++++ .../a78af2044e0109e90d0b39ba6c7269e.jpg | Bin 0 -> 288337 bytes .../bc9c03cf900720d493713361d6a1844.jpg | Bin 0 -> 79125 bytes README.assets/image-20221212162417977.png | Bin 0 -> 135011 bytes README.assets/image-20230305191526567.png | Bin 0 -> 30091 bytes README.assets/image-20230305191835360.png | Bin 0 -> 3648 bytes README.assets/image-20230305191853177.png | Bin 0 -> 18894 bytes README.assets/image-20230305192022516.png | Bin 0 -> 71662 bytes README.assets/image-20230305192150988.png | Bin 0 -> 24302 bytes README.assets/image-20230305194540725.png | Bin 0 -> 27585 bytes README.assets/image-20230305194645867.png | Bin 0 -> 31171 bytes README.assets/image-20230305194812168.png | Bin 0 -> 53381 bytes README.assets/image-20230305195314814.png | Bin 0 -> 48852 bytes README.assets/image-20230305195409045.png | Bin 0 -> 26181 bytes README.assets/image-20230305195433874.png | Bin 0 -> 26216 bytes README.assets/image-20230305195530398.png | Bin 0 -> 30581 bytes README.assets/image-20230305195628326.png | Bin 0 -> 25351 bytes README.assets/image-20230305195801227.png | Bin 0 -> 43487 bytes README.assets/image-20230305195945397.png | Bin 0 -> 76130 bytes README.assets/image-20230305204137643.png | Bin 0 -> 30302 bytes README.assets/image-20230305204308526.png | Bin 0 -> 17152 bytes README.assets/image-20230305204511873.png | Bin 0 -> 45696 bytes README.assets/image-20230305204619914.png | Bin 0 -> 18534 bytes README.assets/image-20230305205946424.png | Bin 0 -> 31491 bytes README.assets/image-20230305214235159.png | Bin 0 -> 21227 bytes README.assets/image-20230305214357922.png | Bin 0 -> 8263 bytes README.assets/image-20230305214449681.png | Bin 0 -> 18097 bytes README.assets/image-20230305220141174.png | Bin 0 -> 19710 bytes README.assets/image-20230305222312844.png | Bin 0 -> 21227 bytes README.assets/image-20230305222435542.png | Bin 0 -> 21596 bytes README.assets/image-20230305222721764.png | Bin 0 -> 24382 bytes README.assets/image-20230305223211110.png | Bin 0 -> 22839 bytes README.assets/image-20230305223648781.png | Bin 0 -> 20647 bytes README.assets/image-20230305223804540.png | Bin 0 -> 17773 bytes README.assets/image-20230305223951890.png | Bin 0 -> 17163 bytes README.assets/image-20230305224247670.png | Bin 0 -> 16263 bytes README.assets/image-20230305224907222.png | Bin 0 -> 23342 bytes README.assets/image-20230305225059253.png | Bin 0 -> 38858 bytes README.assets/image-20230305225932950.png | Bin 0 -> 46121 bytes README.assets/image-20230305230219618.png | Bin 0 -> 47242 bytes README.assets/image-20230305230345964.png | Bin 0 -> 39509 bytes README.assets/image-20230305230427577.png | Bin 0 -> 39457 bytes README.assets/image-20230305230611246.png | Bin 0 -> 89595 bytes README.assets/image-20230305230716625.png | Bin 0 -> 21514 bytes README.assets/image-20230305231120081.png | Bin 0 -> 26038 bytes README.assets/image-20230305231212883.png | Bin 0 -> 70340 bytes README.assets/image-20230305231323334.png | Bin 0 -> 13506 bytes README.assets/image-20230305231636005.png | Bin 0 -> 8785 bytes README.assets/image-20230305231701746.png | Bin 0 -> 11925 bytes README.assets/image-20230305231820468.png | Bin 0 -> 57940 bytes README.assets/image-20230305231930846.png | Bin 0 -> 80187 bytes README.assets/image-20230306085542234.png | Bin 0 -> 62460 bytes README.assets/image-20230306090537764.png | Bin 0 -> 9118 bytes README.assets/image-20230306090547336.png | Bin 0 -> 14556 bytes README.assets/image-20230306091138533.png | Bin 0 -> 66821 bytes README.assets/image-20230306091344261.png | Bin 0 -> 73653 bytes README.assets/image-20230306091443104.png | Bin 0 -> 103923 bytes README.assets/image-20230306091506855.png | Bin 0 -> 133414 bytes README.assets/image-20230306091542863.png | Bin 0 -> 35539 bytes README.assets/image-20230306091621220.png | Bin 0 -> 23879 bytes README.assets/image-20230306092504776.png | Bin 0 -> 58719 bytes README.assets/image-20230306092645321.png | Bin 0 -> 6423 bytes README.assets/image-20230306093225214.png | Bin 0 -> 123056 bytes README.assets/image-20230306101314509.png | Bin 0 -> 21276 bytes README.assets/image-20230306101510700.png | Bin 0 -> 28604 bytes README.assets/image-20230306101556676.png | Bin 0 -> 31272 bytes README.assets/image-20230306101820442.png | Bin 0 -> 15565 bytes README.assets/image-20230306101933687.png | Bin 0 -> 29506 bytes README.assets/image-20230910151905915.png | Bin 0 -> 30249 bytes "README.assets/\345\205\263\346\263\250.gif" | Bin 0 -> 320713 bytes Recv_Msg_Dispose/FriendMsg_dispose.py | 91 +++ Recv_Msg_Dispose/RoomMsg_dispose.py | 288 ++++++++ Recv_Msg_Dispose/Thread_function.py | 415 ++++++++++++ .../FriendMsg_dispose.cpython-38.pyc | Bin 0 -> 2874 bytes .../RoomMsg_dispose.cpython-38.pyc | Bin 0 -> 8584 bytes .../Thread_function.cpython-38.pyc | Bin 0 -> 16757 bytes main.py | 15 + requirements.txt | 10 + test.py | 75 +++ 98 files changed, 3195 insertions(+) create mode 100644 Api_Server/Api_Server_Main.py create mode 100644 Api_Server/__pycache__/Api_Server_Main.cpython-38.pyc create mode 100644 BotServer/MainServer.py create mode 100644 BotServer/SendServer.py create mode 100644 BotServer/__pycache__/MainServer.cpython-38.pyc create mode 100644 BotServer/__pycache__/SendServer.cpython-38.pyc create mode 100644 Cache/Cache_Server.py create mode 100644 Cache/__pycache__/Cache_Server.cpython-38.pyc create mode 100644 Config/config.yaml create mode 100644 Db_Server/Db_Point_Server.py create mode 100644 Db_Server/Db_User_Server.py create mode 100644 Db_Server/__pycache__/Db_Point_Server.cpython-38.pyc create mode 100644 Db_Server/__pycache__/Db_User_Server.cpython-38.pyc create mode 100644 Output/__init__.py create mode 100644 Output/__pycache__/__init__.cpython-38.pyc create mode 100644 Output/__pycache__/output.cpython-38.pyc create mode 100644 Output/output.py create mode 100644 Push_Server/Push_Main_Server.py create mode 100644 Push_Server/__pycache__/Push_Main_Server.cpython-38.pyc create mode 100644 README.MD create mode 100644 README.assets/a78af2044e0109e90d0b39ba6c7269e.jpg create mode 100644 README.assets/bc9c03cf900720d493713361d6a1844.jpg create mode 100644 README.assets/image-20221212162417977.png create mode 100644 README.assets/image-20230305191526567.png create mode 100644 README.assets/image-20230305191835360.png create mode 100644 README.assets/image-20230305191853177.png create mode 100644 README.assets/image-20230305192022516.png create mode 100644 README.assets/image-20230305192150988.png create mode 100644 README.assets/image-20230305194540725.png create mode 100644 README.assets/image-20230305194645867.png create mode 100644 README.assets/image-20230305194812168.png create mode 100644 README.assets/image-20230305195314814.png create mode 100644 README.assets/image-20230305195409045.png create mode 100644 README.assets/image-20230305195433874.png create mode 100644 README.assets/image-20230305195530398.png create mode 100644 README.assets/image-20230305195628326.png create mode 100644 README.assets/image-20230305195801227.png create mode 100644 README.assets/image-20230305195945397.png create mode 100644 README.assets/image-20230305204137643.png create mode 100644 README.assets/image-20230305204308526.png create mode 100644 README.assets/image-20230305204511873.png create mode 100644 README.assets/image-20230305204619914.png create mode 100644 README.assets/image-20230305205946424.png create mode 100644 README.assets/image-20230305214235159.png create mode 100644 README.assets/image-20230305214357922.png create mode 100644 README.assets/image-20230305214449681.png create mode 100644 README.assets/image-20230305220141174.png create mode 100644 README.assets/image-20230305222312844.png create mode 100644 README.assets/image-20230305222435542.png create mode 100644 README.assets/image-20230305222721764.png create mode 100644 README.assets/image-20230305223211110.png create mode 100644 README.assets/image-20230305223648781.png create mode 100644 README.assets/image-20230305223804540.png create mode 100644 README.assets/image-20230305223951890.png create mode 100644 README.assets/image-20230305224247670.png create mode 100644 README.assets/image-20230305224907222.png create mode 100644 README.assets/image-20230305225059253.png create mode 100644 README.assets/image-20230305225932950.png create mode 100644 README.assets/image-20230305230219618.png create mode 100644 README.assets/image-20230305230345964.png create mode 100644 README.assets/image-20230305230427577.png create mode 100644 README.assets/image-20230305230611246.png create mode 100644 README.assets/image-20230305230716625.png create mode 100644 README.assets/image-20230305231120081.png create mode 100644 README.assets/image-20230305231212883.png create mode 100644 README.assets/image-20230305231323334.png create mode 100644 README.assets/image-20230305231636005.png create mode 100644 README.assets/image-20230305231701746.png create mode 100644 README.assets/image-20230305231820468.png create mode 100644 README.assets/image-20230305231930846.png create mode 100644 README.assets/image-20230306085542234.png create mode 100644 README.assets/image-20230306090537764.png create mode 100644 README.assets/image-20230306090547336.png create mode 100644 README.assets/image-20230306091138533.png create mode 100644 README.assets/image-20230306091344261.png create mode 100644 README.assets/image-20230306091443104.png create mode 100644 README.assets/image-20230306091506855.png create mode 100644 README.assets/image-20230306091542863.png create mode 100644 README.assets/image-20230306091621220.png create mode 100644 README.assets/image-20230306092504776.png create mode 100644 README.assets/image-20230306092645321.png create mode 100644 README.assets/image-20230306093225214.png create mode 100644 README.assets/image-20230306101314509.png create mode 100644 README.assets/image-20230306101510700.png create mode 100644 README.assets/image-20230306101556676.png create mode 100644 README.assets/image-20230306101820442.png create mode 100644 README.assets/image-20230306101933687.png create mode 100644 README.assets/image-20230910151905915.png create mode 100644 "README.assets/\345\205\263\346\263\250.gif" create mode 100644 Recv_Msg_Dispose/FriendMsg_dispose.py create mode 100644 Recv_Msg_Dispose/RoomMsg_dispose.py create mode 100644 Recv_Msg_Dispose/Thread_function.py create mode 100644 Recv_Msg_Dispose/__pycache__/FriendMsg_dispose.cpython-38.pyc create mode 100644 Recv_Msg_Dispose/__pycache__/RoomMsg_dispose.cpython-38.pyc create mode 100644 Recv_Msg_Dispose/__pycache__/Thread_function.cpython-38.pyc create mode 100644 main.py create mode 100644 requirements.txt create mode 100644 test.py diff --git a/Api_Server/Api_Server_Main.py b/Api_Server/Api_Server_Main.py new file mode 100644 index 0000000..28d6d15 --- /dev/null +++ b/Api_Server/Api_Server_Main.py @@ -0,0 +1,524 @@ +# -*- encoding=UTF-8 -*- +import datetime +from lxml import etree +from urllib.parse import urljoin +from Output.output import output +import feedparser +import requests +import urllib3 +import random +import openai +import time +import yaml +import os +import re + + +class Api_Server_Main: + def __init__(self): + + # 全局header头 + self.headers = { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9", + "Accept-Language": "zh-CN,zh;q=0.9", + "Accept-Encoding": "gzip, deflate, br", + # 'Connection':'keep-alive' ,#默认时链接一次,多次爬取之后不能产生新的链接就会产生报错Max retries exceeded with url + "Upgrade-Insecure-Requests": "1", + "Pragma": "no-cache", + "Cache-Control": "no-cache", + "Connection": "close", # 解决Max retries exceeded with url报错 + } + # 忽略HTTPS告警 + urllib3.disable_warnings() + # 获取当前文件路径 + current_path = os.path.dirname(__file__) + + # 配置缓存文件夹路径 + current_list_path = current_path.split('\\') + current_list_path.pop() + self.Cache_path = '/'.join(current_list_path) + '/Cache' + # 初始化读取配置文件 + config = yaml.load(open(current_path + '/../Config/config.yaml', encoding='UTF-8'), yaml.Loader) + self.system_copyright = config['System_Config']['System_Copyright'] + self.OpenAi_Initiating_Message = config['System_Config']['Initiating_Message'] + # 读取openai的key + self.OpenAi_Key = config['Api_Server']['Api_Config']['OpenAi_Key'] + + # 设置初始上下文消息队列 + self.messages = [{"role": "system", "content": f"{self.OpenAi_Initiating_Message}"}] + + # 读取配置文件 + config = yaml.load(open(current_path + '/../Config/config.yaml', encoding='UTF-8'), yaml.Loader) + self.appid = config['Api_Server']['Api_Config']['Appid'] + self.appsecret = config['Api_Server']['Api_Config']['Appsecret'] + self.key = config['Api_Server']['Api_Config']['Key'] + self.threatbook_key = config['Api_Server']['Api_Config']['ThreatBook_Key'] + + self.pic_apis = config['Api_Server']['Pic_Api'] + self.video_apis = config['Api_Server']['Video_Api'] + self.icp_api = config['Api_Server']['Icp_Api'] + self.extensions_api = config['Api_Server']['Extensions_Api'] + self.attribution_api = config['Api_Server']['Attribution_Api'] + self.whois_api = config['Api_Server']['Whois_Api'] + self.fish_api = config['Api_Server']['Fish_Api'] + self.wether_api = config['Api_Server']['Wether_Api'] + self.dog_api = config['Api_Server']['Dog_Api'] + self.constellation_api = config['Api_Server']['Constellation_Api'] + self.morning_api = config['Api_Server']['Morning_Api'] + self.threatbook_url = config['Api_Server']['ThreatBook_Api'] + self.md5_url = config['Api_Server']['Md5_Api'] + + # MD5解密 + def get_md5(self, keyword): + try: + ciphertext = keyword.split(' ')[-1] + except Exception as e: + output(f'[ERROR]:MD5解密接口错误,错误信息:{e}') + return '语法格式:\nmd5解密 xxxx' + output('[-]:正在调用MD5解密对话API接口... ...') + try: + resp = requests.get(url=self.md5_url.format(ciphertext)) + except Exception as e: + output(f'[ERROR]:MD5解密接口错误,错误信息:{e}') + return f'[ERROR]:MD5解密接口错误,错误信息:{e}' + msg = f'\n======== MD5查询信息 =======\n密文: {ciphertext}\n明文: {resp.text}\n数据来源: #SOMD5\nBy: #{self.system_copyright if self.system_copyright else ""}\n========================' + return msg + + # AI对话接口 + def get_ai(self, keyword): + output('[-]:正在调用AI对话API接口... ...') + self.messages.append({"role": "user", "content": f'{keyword}'}) + data = { + "model": "gpt-3.5-turbo", + "messages": self.messages + } + url = 'https://api.openai-proxy.com/v1/chat/completions' + headers = { + "Content-Type": "application/json", + "Authorization": f"Bearer {self.OpenAi_Key}", + } + try: + resp = requests.post(url=url, headers=headers, json=data, timeout=15) + json_data = resp.json() + assistant_content = json_data['choices'][0]['message']['content'] + except Exception as e: + output(f'[ERROR]:AI对话接口出现错误,错误信息: {e}') + return '[ERROR]:对话过快!具体报错请查看日志!' + # print(json_data) + self.messages.append({"role": "assistant", "content": f"{assistant_content}"}) + if len(self.messages) == 13: + self.messages = self.messages[0] + return assistant_content + + # 美女图片接口 + def get_pic(self): + output('[-]:正在调用美女图片API接口... ...') + url = random.choice(self.pic_apis) + try: + pic_data = requests.get(url=url, headers=self.headers, timeout=30).content + save_path = self.Cache_path + '/Pic_Cache/' + str(int(time.time() * 1000)) + '.jpg' + with open(file=save_path, mode='wb') as pd: + pd.write(pic_data) + except Exception as e: + msg = f'[ERROR]:美女图片API接口出现错误,错误信息:{e}' + output(msg) + return msg + return save_path + + # 美女视频接口 + def get_video(self): + output('[-]:正在调用美女视频API接口... ...') + url = random.choice(self.video_apis) + # url = 'https://zj.v.api.aa1.cn/api/video_dyv2/' + try: + try: + resp = requests.get(url=url, headers=self.headers, timeout=80).json() + if 'url' in resp: + src = resp['url'] + else: + src = resp['mp4'] + except requests.exceptions.JSONDecodeError: + src = re.findall('src="(.*?)"', requests.get(url=url, headers=self.headers, timeout=20).text)[0] + # print(src) + mp4_url = src + if 'http' not in src: + mp4_url = 'http:' + src + video_data = requests.get(url=mp4_url, headers=self.headers, timeout=60).content + save_path = self.Cache_path + '/Video_Cache/' + str(int(time.time() * 1000)) + '.mp4' + with open(file=save_path, mode='wb') as vd: + vd.write(video_data) + except Exception as e: + msg = f'[ERROR]:美女视频API接口出现错误,错误信息:{e}' + output(msg) + return msg + return save_path + + # 备案查询接口 + def get_icp(self, keyword): + try: + domain = re.findall(r' (\w+.\w+)', keyword)[0] + except Exception as e: + msg = '语法格式:\nICP查询 qq.com' + output(f'[ERROR]:备案查询接口出现错误,错误信息:{e}') + return msg + url = self.icp_api.format(domain) + try: + data = requests.get(url=url, headers=self.headers, timeout=10).json() + except Exception as e: + msg = f'[ERROR]:备案查询接口超时,错误信息:{e}' + output(msg) + return msg + if data['icp'] == '未备案': + return '该域名未备案!' + msg = f'======== 查询信息 ========\nICP备案号:{data["icp"]}\n备案主体:{data["name"]}\n备案类型:{data["tyle"]}\n{"By: #" + self.system_copyright if self.system_copyright else ""}\n========================' + return msg.strip() + + # 后缀名查询接口 + def get_suffix(self, keyword): + try: + word = re.findall(r' (\w+)', keyword)[0] + except Exception as e: + msg = '语法格式:\n后缀名查询 EXE' + output(f'\n[ERROR]:后缀名查询接口出现错误,错误信息:{e}') + return msg + url = self.extensions_api.format(self.key, word) + try: + data = requests.get(url=url, headers=self.headers).json() + except TimeoutError as e: + msg = f'\n[ERROR]:后缀名查询接口超时,错误信息:{e}' + output(msg) + return msg + if data['code'] != 200: + msg = '查询结果为空!' + else: + msg = f'\n======== 查询后缀:{word} ========\n查询结果:{data["result"]["notes"]}\n{"By: #" + self.system_copyright if self.system_copyright else ""}\n============================' + return msg + + # 归属地查询 + def get_attribution(self, keyword): + try: + phone = re.findall(r' (\d+)', keyword)[0] + except Exception as e: + msg = '语法格式:\n归属查询 110' + output(f'\n[ERROR]:归属查询接口出现错误,错误信息:{e}') + return msg + url = self.attribution_api.format(phone) + try: + data = requests.get(url=url, headers=self.headers).json() + except TimeoutError as e: + msg = f'\n[ERROR]:归属查询接口超时,错误信息:{e}' + output(msg) + return msg + if not data['data']['province']: + msg = '查询结果为空!' + else: + msg = f'\n===== 查询信息 =====\n手机号码:{phone}\n省份:{data["data"]["province"]}\n城市:{data["data"]["city"]}\n运营商:{data["data"]["sp"]}\n{"By: #" + self.system_copyright if self.system_copyright else ""}\n=================' + return msg + + # Whois查询接口 + def get_whois(self, keyword): + try: + domain = re.findall(r' (\w+.\w+)', keyword)[0] + except Exception as e: + msg = '语法格式:\nWHOIS查询 qq.com' + output(f'[ERROR]:WHOIS查询接口出现错误,错误信息:{e}') + return msg + url = self.whois_api.format(domain) + try: + source_data = requests.get(url=url, headers=self.headers).text + except TimeoutError as e: + msg = f'\n[ERROR]:WHOIS查询接口超时,错误信息:{e}' + output(msg) + return msg + msg = '\n' + source_data.strip().split('For more information')[0].strip( + '
').strip() + f"\n{'By: #' + self.system_copyright if self.system_copyright else ''}" + return msg + + # 微步ip查询接口 + def get_threatbook_ip(self, keyword): + try: + keyword = keyword.split(' ')[-1] + except Exception as e: + output(f'[ERROR]:微步ip查询接口出现错误,错误信息:{e}') + reg = r"((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})(\.((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})){3}" + ip_result = re.match(reg, keyword.replace(' ', '').strip()) + if ip_result is None: + msg = "语法格式: \nIP查询 xx.xx.xx.xx" + return msg + elif len(keyword) > 0 and ip_result.group(): + search_ip = ip_result.group() + ips = str(search_ip).split('.') + continuous_bool = True if [i for i in ips if ips[0] != i] else False + if ips[0] in ['127', '192', '0', '224', '240', '255'] or \ + search_ip in ['1.1.1.1', '2.2.2.2', '3.3.3.3', '4.4.4.4', '5.5.5.5', '6.6.6.6', '7.7.7.7', + '8.8.8.8', '9.9.9.9', '10.10.10.10'] or \ + '.'.join(ips[0:2]) in ['169.254', '100.64', '198.51', '198.18', '172.16'] or \ + '.'.join(ips[0:3]) in ['203.0.113'] or \ + ips[-1] in ['255', '254']: + msg = "[微笑]暂不支持查询该地址!" + return msg + if not continuous_bool: + msg = "[微笑]暂不支持查询该地址!" + return msg + try: + + data = { + "apikey": self.threatbook_key, + "resource": search_ip, + } + + resp = requests.post( + self.threatbook_url, + data=data, + timeout=10, + verify=False, + ) + if resp.status_code == 200 and resp.json()["response_code"] == 0: + # 查风险等级 + sec_level = resp.json()["data"]["{}".format(search_ip)]["severity"] + # 查是否恶意IP + is_malicious = resp.json()["data"]["{}".format(search_ip)]["is_malicious"] + # 查可信度 + confidence_level = resp.json()["data"]["{}".format(search_ip)]["confidence_level"] + # 查IP归属国家 + country = resp.json()["data"]["{}".format(search_ip)]["basic"]["location"][ + "country" + ] + # 查IP归属省份 + province = resp.json()["data"]["{}".format(search_ip)]["basic"]["location"][ + "province" + ] + # 查IP归属城市 + city = resp.json()["data"]["{}".format(search_ip)]["basic"]["location"]["city"] + # 将IP归属的国家、省份、城市合并成一个字符串 + location = country + "-" + province + "-" + city + # 查威胁类型 + judgments = "" + for j in resp.json()["data"]["{}".format(search_ip)]["judgments"]: + judgments += j + " " + if is_malicious: + is_malicious_msg = "是" + else: + is_malicious_msg = "否" + msg = f"\n===================\n[+]ip:{search_ip}\n[+]风险等级:{sec_level}\n[+]是否为恶意ip:{is_malicious_msg}\n[+]可信度:{confidence_level}\n[+]威胁类型:{str(judgments)}\n[+]ip归属地:{location}\n更新时间:{resp.json()['data']['{}'.format(search_ip)]['update_time']}\n{'By: #' + self.system_copyright if self.system_copyright else ''}\n===================" + else: + msg = f"[ERROR]:查询失败,返回信息:{resp.json()['verbose_msg']}" + output(msg) + except Exception as e: + output(f"[ERROR]:微步IP查询出错,错误信息:{e}") + msg = f"[ERROR]:查询出错请稍后重试,错误信息:{e}" + return msg + + # 摸鱼日记接口 + def get_fish(self): + output('[-]:正在调用摸鱼日记API接口... ...') + try: + pic_data = requests.get(url=self.fish_api, headers=self.headers, timeout=10).content + save_path = self.Cache_path + '/Fish_Cache/' + str(int(time.time() * 1000)) + '.jpg' + with open(file=save_path, mode='wb') as pd: + pd.write(pic_data) + except Exception as e: + msg = f'[ERROR]:摸鱼日记API接口出现错误,错误信息:{e}' + output(msg) + return msg + return save_path + + # 天气查询接口 + def get_wether(self, keyword): + try: + city = re.findall(r' (\w+)', keyword)[0] + except Exception as e: + msg = '语法格式:\n天气查询 北京' + output(f'\n[ERROR]:天气查询接口出现错误,错误信息:{e}') + return msg + url = self.wether_api.format(self.appid, self.appsecret, city) + try: + data = requests.get(url=url, headers=self.headers).json() + except TimeoutError as e: + msg = f'\n[ERROR]:天气查询接口超时,错误信息:{e}' + output(msg) + return msg + try: + if city != data['city']: + msg = f'城市中不存在:{data["city"]}' + return msg + else: + msg = f'\n今日{data["city"]}天气:{data["wea"]}\n日期:{data["date"]}\n当前温度:{data["tem"]}\n最低温度:{data["tem_day"]}\n风向:{data["win"] + data["win_speed"]}\n风速:{data["win_meter"]}\n湿度:{data["humidity"]}\n{"By: #" + self.system_copyright if self.system_copyright else ""}' + return msg + except Exception as e: + output(f'[ERROR]:天气查询接口出现错误出现错误,错误信息:{e}') + msg = f'城市中不存在:{city}' + return msg + + # 舔狗日记 + def get_dog(self): + url = self.dog_api.format(self.key) + try: + data = requests.get(url=url, headers=self.headers).json() + except TimeoutError as e: + msg = f'\n[ERROR]:舔狗日记接口超时,错误信息:{e}' + output(msg) + return msg + try: + msg = data['newslist'][0]['content'].strip() + except Exception as e: + msg = f'[ERROR]:舔狗日记接口出现错误出现错误,错误信息:{e}' + output(msg) + return msg + + # 星座查询接口 + def get_constellation(self, keyword): + msg = '' + try: + constellation = re.findall(r' (\w+)', keyword)[0] + if '座' not in constellation: + constellation += '座' + except Exception as e: + msg = '语法格式:\n星座查询 白羊座' + output(f'\n[ERROR]:星座查询接口出现错误,错误信息:{e}') + return msg + url = self.constellation_api.format(self.key, constellation) + try: + data = requests.get(url=url, headers=self.headers).json() + except TimeoutError as e: + msg = f'\n[ERROR]:星座查询接口超时,错误信息:{e}' + output(msg) + return msg + for news in data['newslist']: + msg += news['type'] + ':' + news['content'] + '\n' + msg = f'\n星座:{constellation}\n' + msg.strip() + f"\n{'By: #' + self.system_copyright if self.system_copyright else ''}" + return msg + + # 早安寄语 + def get_morning(self): + url = self.morning_api.format(self.key) + try: + data = requests.get(url=url, headers=self.headers).json() + except TimeoutError as e: + msg = f'\n[ERROR]:早安寄语接口超时,错误信息:{e}' + output(msg) + return msg + msg = f'{data["result"]["content"]}' + return msg + + # 早报推送 + def get_freebuf_news(self, ): + yesterday = (datetime.date.today() + datetime.timedelta(-1)) + morning_time = yesterday.strftime("%a, %d %b %Y", ) + str_list = "#FreeBuf早报\n" + try: + rs1 = feedparser.parse('https://www.freebuf.com/feed') + # print(rs1['entries']) + for ent in rs1['entries']: + if morning_time in ent['published']: + title = ent['title'] + link = ent['link'] + str_list += '\n' + title + '\n' + link + '\n' + if 'http' not in str_list: + str_list += '\n今日暂无文章' + except Exception as e: + link6 = "\n今日暂无文章" + str_list += link6 + output("ERROR:获取FreeBuf早报出错,错误信息: {}".format(e)) + str_list += f"\n{self.system_copyright + '整理分享,更多内容请戳 #' + self.system_copyright if self.system_copyright else ''}\n{time.strftime('%Y-%m-%d %X')}" + return str_list + + # 获取先知社区文章 + def get_xz_news(self, news_list): + news_list = "#先知社区" + try: + rs1 = feedparser.parse('https://xz.aliyun.com/feed') + for ent in rs1['entries']: + if str(time.strftime('%Y-%m-%d')) in ent['published']: + title = ent['title'] + link = ent['link'] + news_list += '\n' + title + '\n' + link + '\n' + if 'http' not in news_list: + news_list += '\n今日暂无文章\n' + except Exception as e: + link6 = "\n今日暂无文章\n" + news_list += link6 + output("ERROR:获取先知社区文章出错,错误信息: {}".format(e)) + return news_list + + # 获取奇安信攻防社区文章 + def get_qax_news(self, news_list): + news_list += "\n#奇安信攻防社区" + try: + rs1 = feedparser.parse('https://forum.butian.net/Rss') + for ent in rs1['entries']: + if str(time.strftime('%Y-%m-%d')) in ent['published']: + title = ent['title'] + link = ent['link'] + news_list += '\n' + title + '\n' + link + '\n' + if 'http' not in news_list: + news_list += '\n今日暂无文章\n' + except Exception as e: + link6 = "\n今日暂无文章\n" + news_list += link6 + output("ERROR:获取奇安信攻防社区文章出错,错误信息: {}".format(e)) + return news_list + + # 获取安全客文章 + def get_anquanke_news(self, news_list): + news_list += "\n#安全客" + try: + resp = requests.get('https://www.anquanke.com/knowledge', timeout=5, verify=False) + tree = etree.HTML(resp.text) + divs = tree.xpath('//div[@class="article-item common-item"]/div') + for div in divs: + href = urljoin('https://www.anquanke.com/knowledge', div.xpath('.//div[@class="title"]/a/@href')[0]) + title = div.xpath('.//div[@class="title"]/a/text()')[0].strip() + publish_time = div.xpath('.//span[@style="vertical-align: middle;"]/text()')[1] + if str(time.strftime('%Y-%m-%d')) in publish_time: + news_list += '\n' + title + '\n' + href + '\n' + # print(href, title, publish_time) + if 'http' not in news_list: + news_list += '\n今日暂无文章\n' + except Exception as e: + link6 = "\n今日暂无文章\n" + news_list += link6 + output("ERROR:获取安全客文章出错,错误信息: {}".format(e)) + return news_list + + # 获取各平台安全文章 + def get_safety_news(self, ): + news_list = '' + output("[+]:正在爬取安全新闻... ...") + news_list = self.get_xz_news(news_list) + news_list = self.get_qax_news(news_list) + news_list = self.get_anquanke_news(news_list) + output("[+]:获取成功") + news_list += f"\n{self.system_copyright + '整理分享,更多内容请戳 #' + self.system_copyright if self.system_copyright else ''}\n{time.strftime('%Y-%m-%d %X')}" + return news_list.strip() + + # 测试专用 + def demo(self): + # url = 'https://tucdn.wpon.cn/api-girl/' + # data = requests.get(url=url, headers=self.headers).json() + # print(data) + domain = 'qq.com' + text = 'https://v.api.aa1.cn/api/icp/index.php?url={domain}'.format(domain=domain) + print(text) + + +if __name__ == '__main__': + Asm = Api_Server_Main() + # Asm.get_ai('你好') + # Asm.get_pic() + # Asm.demo() + # Asm.get_video() + # Asm.icp_query(keyword='ICP查询 qq.com') + # Asm.get_suffix(keyword='icp查询 apk') + # Asm.get_attribution(keyword='归属查询 17371963534') + # Asm.get_whois(keyword='whois查询 qq.com') + # Asm.get_wether(keyword='天气查询 123') + # Asm.get_dog() + # Asm.get_constellation('星座查询 白羊座') + # print(Asm.get_freebuf_news()) + # print(Asm.get_xz_news('')) + # print(Asm.get_qax_news('')) + # print(Asm.get_anquanke_news('')) + # print(Asm.get_safety_news()) + Asm.get_md5('md5解密 08bdbbeed946fc96') \ No newline at end of file diff --git a/Api_Server/__pycache__/Api_Server_Main.cpython-38.pyc b/Api_Server/__pycache__/Api_Server_Main.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c150f8b63ac8431f740ac320610ec760bff61cf4 GIT binary patch literal 18280 zcmch9Yj7OZo$qu{PtQ|N%kl$b#x^D%utt(?8CziD7Z4{{a51dOU|;QMPD>hTG&4Tk zV@u5pi(|lsU}J6olVCsw9PABXlTbj+>%JVD|DwIA;FjHIetmEEe%y;a_9 zvcLc7p3#gnGS1z~ReR2>&!fA~|NZ|TKibd`aN+Ns{(oVA*Y9%uFRE1kxl!4UpZ+Ei z=3-LH6{B2ENn>(MmZ !~!A@#)2Xb z#X=%)h&713G1e&ZrdZScF6LqC(=MhSlVi U2_XJm6mg8Eed$*63{PyZN+=88$o6_c67 #e38*<}AdjUU!{|K4~qosjS@ 1Q dymx$4es^(iNTH2~wmWh_dRV~X!OS{u@lc+6mYAZx-sZ+aI)RsB5m7=!X zsof%KH#xPisI72nt3>T)r?y(uRywscqIQc@yH(V}PHnBIt#WF&iP~zX_AOCc!(7<( zb$zD3H)AGKsd#5kv@5)Be=^N7NAz&tBjN6@XxCj~G;H2 w^if%V~3a#Rc7uO&t^k?^izo*C0Rw{D1bMK|?y_e8rlc8B-H z2je{H3^R`#+PKj cJW$1!O#5jT>Vbmus=+%Z14bu4w)p>18!t?QFx@gc1 Y<(J+%Jz&f7)TEj82X$)U8yI<)b`a6CPv-F0}|z(#vUv(X&x*wwe*9Cqq0 zLuN9&KFqYiRNT >=#AgN`)ivI+V@OLImbxR6(6WZv zWak|ZV3i!6w9;^II+0^pLsi(d-b9Gp%D!TGtXeu5~=D9m;9Cp~uvRczkFqZZ_ nsnfr)M=`nqKDbu8I5-0?qG7LGa<6*M0_k|dLDh`zK$)R zRX)vG)@s-{p&Qy*zuntvu2i!VJUKLM#9H^HlSUGokRIyatLZu(J{FiI2X@&R9e6OS zrFSIzzo$)DsxBtJD902$tY&%fAO=23%mY|SvX~zkUX*J_%#HrB#z%&^7B_ZgGNUv; z=6xuc=*K!S|6e4TmJvnoo_?#=Kty)SjFel9U^FYBQjky|bAu!arey5It- z 4R# zU{7g_`^5l-_RLaJnK-kQ48E+TK7g{ut!De%_9rssU0UXR`T3j0n?RN=- IZhPv1A(Ec-+YF1G_bS)W~EH z?93Pkc2xLXRZ+0MXcix*zaQg_{{B{CdEZ6iQe;V7vXlQ`U&tqi+yTiaHOtGTMyXM5 zb+@{gORe@LqowX;E}dQ5Ua-7af+UIZpNaxWR)XpN1_iSftQ4#lj8k6bD#-g?>CFmQ z?r4C2M{*V1lFM9bfGy|Uue;umk3pu{@A|&$ZG|cOAY&EWPr4sNJuN@xLN5>9M}IJC zFip>-Dj2eQQYt8z_a0~73(maZ+Ih=ssP+o--1(U|FM|#H^2&%8xgRU|_^&8U%PfGF z;2Yk8C+`6h3iVx+!ZUxwU#=7H`1rjKKm6ds2YdJK?wNk?o#LfuOQ+5kUwmig -YK5F zFn#&h)XNttlNT@ja{AI6J099&uM&+$!}x)Ex&eK;+c9@woAVdOpwe6Cr!T#2FCKQ< z1N4lq9`6n3NI(jdUOQ#iZW6UuE|*SzSbF1p>B{Ne@S1%OVv@kl2^1~YwPlsL%WIVL zh@UUVaLa%1II$K`JWdjr<>L;&u-rosPd8DUI+)>Oal=xGsq)omim1GY?s$RZM>3qn z0*Pc6M3FjJl4dDf)3cU)Odk@+VkcY02+Z1#@3#jPou0r2h;Nme0mVxJ mZ012=Y?^vQGd! zq{+N*4uZ4@0QNoUD We64u`U+4J@dKx@ETLkstzl&$ZYLGIeycdAn)|Xp{H+*~! ztnJuSAIK~v2Li=gFvM&a${HOTqdgr)jt^uaa?CT9VOol>p_^U9hLP2KJ3B!sqr@ZP z$&M_~j88-pnX%5p-JOtY49Eau5YGrybh8 eS_hP&iyO(*9V}Umq`i{j=YGakTi%r&quHQR(^fV)Um#z^Su8 zES))D{Q3;;#{6+z2XT+5jhO~454<5f5#P;H@fEZ*6U>qCKr@(h28>`Y_1I2zcS=iR z2t7Ezml_lnH{!Ez&+kWL%uk=7pYFt3D$9W{i?7J ;s?bO!REQ_Pk5-*P!Uf!E z1J_XgpehRT0CK`BpMy_JJo4WBLp=8Xm?V6vALk+mB|L; z3dBcxT>sAXu QY%5 +xy?V!yHsINQiL&-xW0L>NvjWXgJ@dI#vAi)Lz8$n<)$keL2yaG@|=Va!iQMRa( zcNY`@n0wUAUt@v18(^x4F~luY7*7be8^8x#BaLJ~Fq({Jqh+!Mz}-**?naDKjaKjo z7*_;vd-LAOMS0IW;3mPRZ8UIN;$05MSjk#!eo^oPy!`^a{WaiS%{NqlckA`Qd-}a+ zXWo8k9(X^5@6I2igkT}&9?NbrgE~)aTfHuN`?n*jXWHnVAiD}N1k*!l@66q3HXAx^ z1 J|zoaBW3DMOm$S2xr1)yr%Qj2ai zeRto3eY-U%z}mf>XSgME=!t`{GsIIVzMDo9^AOm=<5U`;Btc1-5=O~(B$2=@stCdi z 2#7jH?bLd?-&1O*>N|CoIEI+)`p%n@48571X9Y9w$+$oB2PnSdMug}zNzPzLpO z@Ts+oPs{32YB67p{8K}$A%3{bHp4Y3G1$Za GoQ>?Hezn*#zM?5o&9Tj^&AoW=}YH}Z@pDKeX`QLO7OR`I3KR3H*5>w zJUJqY|&Hy_FtSi|vKN8ZA3O)xza25Lza^a&i&m4(IFd}>$ zvheGqgOK9T24z738(J<{(sI;nW)wne?*c3db1aNNf55zdHUt7Q0TRhTqNRp+#3zu* z&papP$v_nf1%X1JR8UC$lTgSD6!ML_`L7ueA>9RLMmjQ~lB2i?Byx>}_&=~FpbnTB zP>0OfEzp)BjS1FrO%-V4pv)?Kl3J80o<248#Zv@~LRk&p``EoXViJK0+SGQq5zM(L z&&pl7&EGiLLil4T#0O^n78CrA@Wy_^sn35@dh_hnp{eys|2{gl3 `ihE_X zdt0D-bg!jCsm-NedQ4{w=qHCU4L?E&;f8s0Wy _r 7sB2K7~8kie}9L!#O&Q=-}|V+umFgKrJ^1?N+R zH3c2~YU?uzzu3Yosrco8D1P*&gIwL+T{*Ix%pzCS-5bFyp2z6i#_Lb95I%7t#ZVh~ z<}mzq8viSr>svIJfbKeMCs2Csho!Suz;LD}kM`z#)OYIa(W{?-=~Rkuohp9z1F)V% z(wN8*%mk*tK0ST 9i9A^lO2&AR%Cn5hPMNr@zjqZ>bcGtxOO1!=!4 z-34ugTnak@S_sZCTZQQ#qDtAN&_m7y`AN7DYz>_$FdVrjp{>9@;X!18=bTJ7SqM`A z80H%F@ht4Q!rX6o^JGEwjw+|!d;<(jhzFQ0K}YwK0SQhH0OoV9 ChwnY zhV=mv0~Bad)q;otcGF}_UOgwFgcyNB!0B6i2k`=hVBI^29VmqA-a#AzL-YVc%s`>x zx;<8-N8@#SAhw{;ly6|SB02+>6OlIo{hOJm&{B6KA`W)D4z?Cr^DX&S26N(_u0qRc z`OpLTAl^U4ZYwNGE9_f^MQmMOg+Lq0lN0Fn{34`xf;W9M6rkvE_tPas&9AGIc9{^ qI>;@LS)^6=neFWJh8DL r+4hQy> zHR xBr4nfEw zvL#2mEGc;r{ zSCA&f{v!@>Ot@2bSv(dX#nM6FL z--AMVmPhW3s4;i D>?&m+9RY6_@GV z6cv~0?TL!Z^lpxd%k `QHqErHBWMY~C8((6h-@ySuug znb21>E%nM7mnIsMD~TVmy2&awF<5wxHS-M0|zw}9>GbtK~uYhFv!U$ZmEdj zN)Ar&Cu#l$^7g?iq`_r@zycB(P5FsJ%%^MA&6u!4h@u#a!(o)n 7V9q zMt#1VxNTeD@jDJCv*gAlV58d1JEvxTd~xc7=ccZ_N9{|UcFcx}pd^-#eo}h+MSD=Q zbF=v3CHQ2ESAJSOQ}M#l>0?K2iwU)pnbBU)mf-P4saecXdi~?ltCwN(nK|<@8e_p+ z7Is9fU)by`s-)Rg?;Uc)rOW7V?^p5NkETC95Bt&d*Dn`ef7A9Ci+S {$dItLi+M~F(whUfd8UI`l( z`75-*tCakhk_rIw*QokB5=$D1HCID4eQcW)y+C~gJ!&Csp@zu(7Wec#lCsM?3@a5m zy%i@XJ65Bl{!wwa{fnZs{a*0|{#jA!t}6N{Zbg#+pn9l91c>}zRaeT(#kB&0nxfe0 zYPk(Y<&_ZPR7pjN$*r)DwPNlSlDX;|iD3VnrnKIaz3Q~3CV@iZWer%)*? z3M+xk6@ZNG @teApk%|K-n zkjfB03~7 YcPqR%h~lltl<pSA`qs{A-YuDrRAKY 2rk7BUPGJ}u~q`Xz}3&6 z2RaL SD!#ph0zKD%hM^q3pbs}7?+`_$Dh zPtD%(Qd}#GPuP<|cqpEJi6(O&Nv30dB>j3;(^%#9%u}?MeP>LA6W)1>Uw-W@ 9%p%c^Fb_Nm!`C3Y5i4P&N9k+6nN`k>w*_nk1 zRz+DBbkhhkvmKy`fI*i|M6K4q0Fy$MeM|;t0?(5T*vp7R1r{(l+f&xCCJ$z=u%=H? z0rtT2iImJ*k`s7Hbyy5wB33~sD4>z_Gm6(5sL% (H?&~HA5i3h zFg#N@<0i~nZ7yqPv((3#)zS8 ;3{0DOqLOyOoJdy%q z0)>#2-Q*0QVM`sJf($~d=7sDbKtrw}uhmkA?ItH?<(}u|^Vae5{kpOW07MXPtd$p0 zwfTit!Kof$3JDj$5c6IZ03gyK7ccqv=x~cLjmU?719v&t18aB#b54eY-Ia_=#A;Ru z@1M 2pr5s(+q zE=Z-XN*57oM+0*?4pt_$x#cZg-%pEt$=VXF_AB8Kx6Pti!{&gv8$rX)Oe)-u8IU zb=R$w;I6AH-Pg>yFbSoP^#6l|&Jxhq%l3XxJrY )$yx+&HkhEF=e1}%z?upu P6lo;8W=yfz;p~VBU2%ys(dp_ z5LXeF>=D6i2(}>+6%@cv)WFV(t{vJ8ft4uTQ|J+_qIARrzXA=Spyib;2otkA@2C5Q zkA-l24hC|fcn;gD4nd=pC;-Qzlqe46OUT#R2#VuJ KgnV>9p OJ&wl|D6kC8Me3^SEXkJ@6@DCV_IKDKxWlUM1?B;w|$el{uM3q+hI=)m-; zPm3?UTJr>8iFJ)5;U@~eTZ4H^uY5dp`q|=%XRlsC0Pzbj?G)erN%7fdiXS4>|I^Zm zUxe2PB6=;j_WK=c$2#a`AB%)6A6a~a!RH;!f``sPuC)Brf>3M(W%|Iw2dQcW=vA|E zj`(fMW9Qp3##R{#j)a6Jg4mp>wU~bb$GkL-DPy7X$rqXnW;lcQlYC&gx!!HL>HA%x zDK1k&+M?y554U+PA~XxN&;I`XM6q5aY#`~;g~*$Lph* =%TG`sV2S^dI$WWo7MA$u)K-tAj++9A-X|bhiB2|C3jlm58gecG)hDmc91BCv z$CwwpD$%a}Nzg+lVs8w3Ryfd;tphzD{#&4D37$Q$rg;81*dAGQU;cdNwVyk1RH2FR zFXzUhbVxCtj;1xE^I=^Vki@^l@CAX0e}%h3Etmr^^;Y{v$l+hpTK|!fIXfL9BtH}% z7h4VHQr>E^GcCB)E9y~-@+38TEy6{xECHqdzmZh-`fXyWWQL>@<0st^+vQ0Jz9Ym! z$;b${X){w$kOBDXaA+a#L8})YT*R3k!_fj!N00*5MZ7uUT+t(d7Fc`Wl_i5_fQ1Cr z@qyxO!s-oz)e;LN)@uvj(xFWdzKOzIK#!&>3PZttCBTSZP?#ooXQjNLKt_l)<0u4H zuVT6WC;c@Prlrr0msvw{(K8o{AHHp_F4Gs{mGShUTs%Fh2@*4!&KyZ;Y)G3SMfpBB zgZhy3myww3J3CqO@Z;MPDI7Q1wmQy@WFn;LN~S7%sH2Oj?vzAEa*P%4ltO!EA9a z-nkveJqLx_Y2LD6Cpr|iE@F0}gPx72AK$K1Z0WYu@Kj*gc&Y<*aVXszhE;^6w7W2| zJz@sX L(3blD6Lq>D38H4fE%E;_BoFKOUm22zV~Y4dL?L4#M_jR8KEg;_k5mdRpuCX+ zi~bJZ!Qr}uMa>|X6kF6L>?N(za=DuC*4F@P=BtrS=?jn*O(4_=3dD9{ GoimfdK1cm*k*##%bn*GOY-#T!Ov8VUB;vD~)_ ^9QY0w0K_aj|)Gh?t1<(&K}gF(GyU80*rT(VJKn0{6w`BN?Y|Tvye| zns4pK1oYd5pKyEAw`TGPeL*))#li??YyZMfs~}F$4sJ3xmXZ8$G>#K`@pyMMk*33X zod{;`#7PHjJenQOejA4rwmo5oR2SejpTIhJO ^q!77dV~v OnhKX!@Q|G$e3 zr9%4JfxEno5<2)2Q| #!P(rW6e~rX)@6gBWuUhA|E#KYtX52#$BVxRW WM3e<}lC>(AyYa7FbftWf+VZdI&Fh5# literal 0 HcmV?d00001 diff --git a/BotServer/MainServer.py b/BotServer/MainServer.py new file mode 100644 index 0000000..c0cd799 --- /dev/null +++ b/BotServer/MainServer.py @@ -0,0 +1,254 @@ +from Recv_Msg_Dispose.FriendMsg_dispose import FriendMsg_dispose +from Recv_Msg_Dispose.RoomMsg_dispose import RoomMsg_disposes +from Push_Server.Push_Main_Server import Push_Main_Server +from Db_Server.Db_User_Server import Db_User_Server +from concurrent.futures import ThreadPoolExecutor +from BotServer.SendServer import SendServer +from bs4 import BeautifulSoup +from Output.output import * +import websocket +import yaml +import json +import os + + +class MainServers: + + def __init__(self): + # 初始化读取配置文件 + current_path = os.path.dirname(__file__) + config = yaml.load(open(current_path + '/../Config/config.yaml', encoding='UTF-8'), yaml.Loader) + self.ip = config['BotServer']['IP'] + self.port = config['BotServer']['PORT'] + self.system_copyright = config['System_Config']['System_Copyright'] + + # 配置HOOK信息类型 + self.SERVER = f"ws://{self.ip}:{self.port}" + self.HEART_BEAT = 5005 + self.RECV_TXT_MSG = 1 + self.RECV_TXT_CITE_MSG = 49 + self.RECV_PIC_MSG = 3 + self.USER_LIST = 5000 + self.GET_USER_LIST_SUCCSESS = 5001 + self.GET_USER_LIST_FAIL = 5002 + self.TXT_MSG = 555 + self.PIC_MSG = 500 + self.AT_MSG = 550 + self.CHATROOM_MEMBER = 5010 + self.CHATROOM_MEMBER_NICK = 5020 + self.PERSONAL_INFO = 6500 + self.DEBUG_SWITCH = 6000 + self.PERSONAL_DETAIL = 6550 + self.DESTROY_ALL = 9999 + self.JOIN_ROOM = 10000 + self.ATTATCH_FILE = 5003 + + # 启动机器人 + self.ws = websocket.WebSocketApp( + self.SERVER, on_open=self.on_open, on_message=self.on_message, on_error=self.on_error, + on_close=self.on_close + ) + + # 实例化消息服务 + self.Ss = SendServer() + + # 实例化群消息处理类 + self.Rmd = RoomMsg_disposes() + + # 实例化好友消息处理 + self.Fmd = FriendMsg_dispose() + + # 实例化用户数据服务类 + self.Dus = Db_User_Server() + + # Robot初始化执行 + def on_open(self, ws): + # 实例化实时监控类 + self.Pms = Push_Main_Server(ws=self.ws) + pool = ThreadPoolExecutor(5) + pool.submit(self.Pms.run) + self.get_personal_info() + + # Robot 启动函数 + def Bot_start(self, ): + self.ws.run_forever() + + # Robot 关闭执行 + def on_close(self, ws): + output("The Robot is Closed...") + + # Robot 错误输出 + def on_error(self, ws, error): + output(f"[ERROR]:出现 错误,错误信息:{error}") + + # 启动完成输出 + def handle_wxuser_list(self): + output("Bot is Start!") + + # Robot 心跳输出 + def heartbeat(self, msgJson): + output(f'[*]:{msgJson["content"]}') + + # DEBUG选择HOOK信息类型 + def debug_switch(self, ): + qs = { + "id": self.Ss.get_id(), + "type": self.DEBUG_SWITCH, + "content": "off", + "wxid": "ROOT", + } + return json.dumps(qs) + + # 处理缺口 + def handle_nick(self, j): + data = j.content + i = 0 + for d in data: + output(f"nickname:{d.nickname}") + i += 1 + + # 处理所有Roomid + def hanle_memberlist(self, j): + data = j.content + i = 0 + for d in data: + output(f"roomid:{d.roomid}") + i += 1 + + # 销毁全部接口 + def destroy_all(self, ): + qs = { + "id": self.Ss.get_id(), + "type": self.DESTROY_ALL, + "content": "none", + "wxid": "node", + } + return json.dumps(qs) + + # 处理带引用的文字消息 + def handleMsg_cite(self, msgJson): + msgXml = ( + msgJson["content"]["content"] + .replace("&", "&") + .replace("<", "<") + .replace(">", ">") + ) + soup = BeautifulSoup(msgXml, "xml") + msgJson = { + "content": soup.select_one("title").text, + "id": msgJson["id"], + "id1": msgJson["content"]["id2"], + "id2": "wxid_fys2fico9put22", + "id3": "", + "srvid": msgJson["srvid"], + "time": msgJson["time"], + "type": msgJson["type"], + "wxid": msgJson["content"]["id1"], + } + self.handle_recv_msg(msgJson) + + # 选择消息类型 + def on_message(self, ws, message): + j = json.loads(message) + resp_type = j["type"] + # switch结构 + action = { + self.CHATROOM_MEMBER_NICK: self.handle_nick, + self.PERSONAL_DETAIL: self.handle_recv_msg, + self.AT_MSG: self.handle_recv_msg, + self.DEBUG_SWITCH: self.handle_recv_msg, + self.PERSONAL_INFO: self.handle_recv_msg, + self.TXT_MSG: self.handle_recv_msg, + self.PIC_MSG: self.handle_recv_msg, + self.CHATROOM_MEMBER: self.hanle_memberlist, + self.RECV_PIC_MSG: self.handle_recv_msg, + self.RECV_TXT_MSG: self.handle_recv_msg, + self.RECV_TXT_CITE_MSG: self.handleMsg_cite, + self.HEART_BEAT: self.heartbeat, + self.USER_LIST: self.handle_wxuser_list, + self.GET_USER_LIST_SUCCSESS: self.handle_wxuser_list, + self.GET_USER_LIST_FAIL: self.handle_wxuser_list, + self.JOIN_ROOM: self.welcome_join, + } + action.get(resp_type, print)(j) + + # 获取获取微信通讯录用户名字和wxid,好友列表 + def get_wx_user_list(self, ): + qs = { + "id": self.Ss.get_id(), + "type": self.USER_LIST, + "content": "user list", + "wxid": "null", + } + # Output(qs) + return json.dumps(qs) + + def get_personal_info(self, ): + # 获取本机器人的信息 + uri = "/api/get_personal_info" + data = { + "id": self.Ss.get_id(), + "type": self.PERSONAL_INFO, + "content": "op:personal info", + "wxid": "null", + } + respJson = self.Ss.send(uri, data) + wechatBotInfo = f""" + + NGCBot登录信息 + + 微信昵称:{json.loads(respJson["content"])['wx_name']} + 微信号:{json.loads(respJson["content"])['wx_code']} + 微信id:{json.loads(respJson["content"])['wx_id']} + 启动时间:{respJson['time']} + {'By: ' + self.system_copyright if self.system_copyright else ''} + """ + output(wechatBotInfo.strip()) + + # 入群欢迎函数 + def welcome_join(self, msgJson): + output(f"收到消息:{msgJson}") + if "邀请" in msgJson["content"]["content"]: + roomid = msgJson["content"]["id1"] + nickname = msgJson["content"]["content"].split('"')[-2] + msg = '\n欢迎新进群的小可爱[烟花]' + roomid_list, room_names = self.Dus.show_white_room() + if roomid in roomid_list: + self.ws.send(self.Ss.send_msg(msg=msg, roomid=roomid, wxid='null', + nickname=nickname)) + + # 消息接收函数 + def handle_recv_msg(self, msgJson): + if "wxid" not in msgJson and msgJson["status"] == "SUCCSESSED": + if msgJson['type'] == 3: + output(f"收到图片:{msgJson}") + else: + output(f"[*]:发送成功") + return + output(f"收到消息:{msgJson}") + # 判断群聊消息还是私人消息 + if "@chatroom" in msgJson["wxid"]: + # 获取群ID + roomid = msgJson["wxid"] + # 获取发送人ID + senderid = msgJson["id1"] + else: + roomid = None + nickname = "null" + # 获取发送人ID + senderid = msgJson["wxid"] + + + # 获取发送者的名字 + nickname = self.Ss.get_member_nick(roomid, senderid) + if roomid: + # 处理微信群消息 + self.Rmd.get_information(msgJson=msgJson, roomid=roomid, senderid=senderid, nickname=nickname, ws=self.ws) + else: + # 处理通讯录好友发送的消息 + self.Fmd.get_information(msgJson=msgJson, senderid=senderid, ws=self.ws) + + +if __name__ == '__main__': + Ms = MainServers() + Ms.Bot_start() diff --git a/BotServer/SendServer.py b/BotServer/SendServer.py new file mode 100644 index 0000000..c52e147 --- /dev/null +++ b/BotServer/SendServer.py @@ -0,0 +1,144 @@ +from Output.output import output +import requests +import time +import json +import yaml +import os + + +class SendServer: + + def __init__(self): + # 初始化读取配置文件 + current_path = os.path.dirname(__file__) + config = yaml.load(open(current_path + '/../config/config.yaml', encoding='UTF-8'), yaml.Loader) + self.ip = config['BotServer']['IP'] + self.port = config['BotServer']['PORT'] + + # 配置HOOK信息类型 + self.SERVER = f"ws://{self.ip}:{self.port}" + self.HEART_BEAT = 5005 + self.RECV_TXT_MSG = 1 + self.RECV_TXT_CITE_MSG = 49 + self.RECV_PIC_MSG = 3 + self.USER_LIST = 5000 + self.GET_USER_LIST_SUCCSESS = 5001 + self.GET_USER_LIST_FAIL = 5002 + self.TXT_MSG = 555 + self.PIC_MSG = 500 + self.AT_MSG = 550 + self.CHATROOM_MEMBER = 5010 + self.CHATROOM_MEMBER_NICK = 5020 + self.PERSONAL_INFO = 6500 + self.DEBUG_SWITCH = 6000 + self.PERSONAL_DETAIL = 6550 + self.DESTROY_ALL = 9999 + self.JOIN_ROOM = 10000 + self.ATTATCH_FILE = 5003 + + # 通用消息发送函数 + def send(self, uri, data): + base_data = { + "id": self.get_id(), + "type": "null", + "roomid": "null", + "wxid": "null", + "content": "null", + "nickname": "null", + "ext": "null", + } + base_data.update(data) + url = f'http://{self.ip}:{self.port}/{uri}' + res = requests.post(url, json={"para": base_data}, timeout=5) + return res.json() + + # 定义信息ID + def get_id(self): + return time.strftime("%Y-%m-%d %H:%M:%S") + + # 发送文本消息函数 + def send_msg(self, msg, wxid="null", roomid='null', nickname="null"): + if roomid != 'null': + msg_type = self.AT_MSG + else: + msg_type = self.TXT_MSG + qs = { + "id": self.get_id(), + "type": msg_type, + "roomid": roomid, + "wxid": wxid, + "content": msg, + "nickname": nickname, + "ext": "null", + } + output(f"[*]:发送消息: {qs}") + return json.dumps(qs) + + # 通用文件发送函数 + def send_file_room(self, file, roomid): + output("[+]:文件发送中... ...") + data = { + "id": self.get_id(), + "type": self.ATTATCH_FILE, + "roomid": "null", + "content": file, + "wxid": roomid, + "nickname": "null", + "ext": "null", + } + url = f"http://{self.ip}:{self.port}/api/sendattatch" + res = requests.post(url, json={"para": data}, timeout=5) + if res.status_code == 200 and res.json()["status"] == "SUCCSESSED": + output("[*]:文件发送成功") + else: + output(f"[ERROR]:出现错误,错误信息:{res.text}") + + # 图片发送函数 + def send_img_room(self, msg, roomid): + output("[+]:图片发送中... ...") + data = { + "id": self.get_id(), + "type": self.PIC_MSG, + "roomid": "null", + "content": msg, + "wxid": roomid, + "nickname": "null", + "ext": "null", + } + url = f"http://{self.ip}:{self.port}/api/sendpic" + res = requests.post(url, json={"para": data}, timeout=5) + if res.status_code == 200 and res.json()["status"] == "SUCCSESSED": + output("[*]:图片发送成功!") + else: + output(f"[ERROR]:出现错误,错误信息:{res.text}") + + # 获取所有群的wxid + def get_memberid(self, ): + uri = 'api/getmemberid' + data = { + 'type': self.CHATROOM_MEMBER, + 'content': 'op:list member' + } + output(self.send(uri, data)) + + # 获取@昵称 或 微信好友的昵称 + def get_member_nick(self, roomid, wxid): + uri = "api/getmembernick" + data = {"type": self.CHATROOM_MEMBER_NICK, "wxid": wxid, "roomid": roomid or "null"} + respJson = self.send(uri, data) + return json.loads(respJson["content"])["nick"] + + # 获取机器人微信ID + def get_bot_info(self, ): + uri = "/api/get_personal_info" + data = { + "id": self.get_id(), + "type": self.PERSONAL_INFO, + "content": "op:personal info", + "wxid": "null", + } + respJson = self.send(uri, data) + bot_wxid = json.loads(respJson["content"])['wx_id'] + return bot_wxid + + diff --git a/BotServer/__pycache__/MainServer.cpython-38.pyc b/BotServer/__pycache__/MainServer.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..43ffc1aa88b8a48d639a23b5fe1c382d9375f4a1 GIT binary patch literal 6954 zcmcIp>vJ2|b>9~jizmT{NKr3SvZDlcOxa5M2;-)rNJyq5ktzTs&RXgYh`S^g0 CFWAe+CF!52()&|UIfLST2*4yJSEZV4$}-VP zRjH|_DrmK;)gop@&{|cmMa`(7BUPgoGh>3*tMOXGOb9w!P1aIoO3+3%U8Lv5szc_G zz!@_m@US^7@Q68bUSe^UcvE7Dn~FJVkFn%6g>TxUHzo6cePDBZOTx2a1u2`_!Ahm9 z91Nf1j$LOLy;X}jUc>clG-mRyTkC1^sO?hITeB{foVr!8`D->uTY7%ky6o9}uVtjT z#_bZj ;M}FPO%Ag5ID^y*&*N|c9 *n0j0BwMukL*-+XF( sSFV`G2^*a5(CHV!z!CIAnzgMgE467Uc^1bCPo20X%!03P*^Ri41R@y5y& z%5jtvC{MDZw *kWt^)b#YJIkztez?h zG<~B~tF|JSi|3yGO$di!*UK(*>Z@k#tm}uTZ7K_wOzqNAzG$WjH$302S>YqhOt;#& z!JXALzZF^cW=@@YB+odvM 8*tGLJ0b-JK3vJGK2)sq$8Hk c)e7^K+9Tjs d|FMzhWsW=T&Yq;DGGG4glvfJ6CsTXqj zZ{+ep{KedCzG$7z%@%`XJ~#IbtN3!!x>z_L40mgD3&osh3I|+Tm=m?wWjw>Wuuv!l z 2E(byKo_h?!F+p`yhQbeB;pEi?hZ2($YoiV(#KuEN*O| z!CG9H`+AVNl*<>E7H2P53ybHLg5-Se?B(-T;hPJ^xfg?>Zs&ZiNUuxG=L&e}x2)L< z7lPPJOACt@y~0e+7K^i(VVzsJkPBk#_Oj=eui3tt{HDEJ5aev5!82evA0{wD0IZV& zW!>YXtASGRILSny=4*_T{Rz}_pdx~rZ+clZ&^)`kVkXN?&h5Hy5f@E86x%xz|1w5C znwguqLN?L6GRtaC-SK>0f)%_nZ+q8#w{ZnROeGZLD|;4Xx^aW#05g2cqBVNw03; UJ-nbpOt%%?GPhfXXT W<3~QwQ+_xDz{#$V&^MvR^?yn&VsbNRdJ{x_%-Sw7S5u027sibWdmo^8tvU* zM-}@lGO0anS8Oj00-KOFO#v1dVjOvj-J15_p^@BWCUB2I-=g4WYk;7`D8iaNxqny_=yE4h4r zDSvfl``bT#@ZEb;JMaA9;oZCc^0Pk-iGTiN>;4<4zQ k` zK7Nvvi}M=?A
fZmtrWUexM-`QK8H7mJB9qi>B(Xte6_CY4MI0 zC=T3@e*?OC2Gav={kp@l5q^p)I%%!LcvkdOu<#(lnze>^C)|&zyy^{ZCCTjN=Bnkb zJAQfXDkgfwK}j)WO;%*(=epiH*n951!~0I0w$(jxGE;52B5hz(8){pbm#!Y!(0pvL ztyQ{G+(x+g8`6gQYFfy%w#dmCv|@Fqe2u*C3{RmBnLPu ;3hIy z7__2h*OqNgO5uLSPL2%hq;JBnE`wU#t=lFb0v;0Hj>z%zwBBb3yhwnoE`N!@fMHHB z8}8P YAWC_l*fu5SK`pNIGK`8gcSb|J<&QeAg!?ayN~R1gA|!ep$LBe zB?up(L0dtx23``^H$=<>>#3p;jTEP%cW|_WjSi;NjQS}xBTOk0QnCsXGEqlLCNPq+ z3R1EP60!=?u?mv03R1BO5;1|1iV2Klta8xFY((0T&B?arAKFsdYL9ysJjoswsu4se zbMQEMY@R3ZG=UO<&k-P_&A&k4Ndiw1I7y&L;0Xdp2^=G^OyCHCvjnCH{5FB(1Wpk6 zB0!K_x2t8hW?L24sRt_jLl9|jr|xI B?c@* zzIFY&)s0N 1 z2wYqXDZzb&N*ih&ciM>OVIMj@ IAGDJV8L82il zq$L!CAyTa{{ #dRk}%_Fl=wbH&>Rw4MThe?;-703>+~ zB9RfApH`BJp~MyVRK?KJfQQu9;a+_o2;vsAV{}bL78BQ%am%W?tSPQ8la}>rvs4Xx z_^;zV;eFdziK4rS@X}2L5F(!VI<@5q6bVog9)=ur`^75+$XW@B4nvr|T?vXTKc_&Q znCDSEVkpLQhGA&ke;hT#h#TX^B;bUR6ys?JHTsfaWhcxNd5TXdFq{uRfK2cEBqDAD z&8d9@^ZlPm#Py+hM0_X-@Asw$KbnY3G4mk4n{)>Be?bwKjphh$2|8Dd(<@EC3DX|l zo{hn%cjoPVQ4zP7rn>BXISj;8OX8+zI=nFA&(a~0V+!5L7*TX)+ye-diyjvY`i!Fu fj2A-Yeoe+uAv#G2&fedEMG=2B{d-c~K ;KEX3bEjHLm9@P|oY-r#yH1m>tI@`1oUF6AoS7xb zYAjJTQqn@W2~~om!hXyH3QrY+3SRp+oL7<*KlKG3h!EoUo$+4m1p3U3=6CM5@B4n= zcV?}>Kd#`>Up&jsjws4ssnGlAD4f9Op9C<4sTHNF7FCt EjMn4} zLaY12Xq1A>!e(V&D^)$=xb9}T;<>IcXv4y&)Jsel^@djy))Mj_7h1W2VRaq|E1$`o z%j87-bS9lExO16wK_qgS`EzdJe8FALpAy5J()?l}BdekgtBdop6kEd_?$TnuAjVH+ z3T~(9=GW%u^O<~Jj2x^#nO #IH+HDP%`VQL z75%H3Tz(~+UUC<+Cs#ybAv3pj%FVyASeQR820M)lnF1}>w~)zW(hF{SX-UM+tSn|- zT0$h!g+dx5+>?t-nWQcZ->Ynj#72{IuNJscwpL^Z_Z9wCDDO#XKDEB)d)!}7vue3k z_5)rD>U@2{^REQ;#yZS_zQ`ojyX2W^+#u~>MBuu8n8}|3C|W|DR0q@neO$FZ^KFgx z%-5c4gKVn(5F;IYl9lI?36&jX7apnS)$ZBbdZ_QHp|(ptN(b9Cunuh7(vg~>3hr6k z1~_Ym2D3uFtTLN9cl2#DG _`zwXPt;j5VqV%aQM#`QW6Q7Cigr-0dhmQnTUeL8z{PY{ zv%yM%$H&l*9{~u5dsmyD9}o@dP{j99nY4J4+Vmzb3j+g6#n{D?@41wv+KSM*=SyWq zaGbhB^ELKm {Wa|9E75%t>K<+MAG52 zXxJbTwjUdrjww)J3U#Jl(K(#tma=WuETk$Fs_baHN@#|9sD&!jjQ|1zu>ypU(1Iao z@4!gNp@)_{iIJ6S@vmXZCZeJ8=2zZIJ^I-%_I~vC;}35?e)~ac3OblV1Amc#_ReYF zQa!?C&1%C>+WT6n`j_~(sPUTw-vJaI)Vb1}w5w0)$swt`= Qp3>NW zdVntNasQnzH!)WLs?d2M6%|qeF&Ie&NMVeK(?b(w%K%-h4@^+S+_E4$TT%sqHloUw z&Ei)y-T-MFkgyMdFF|Fj(od_@hL9TwO&RQ@oMiwS%r@y@Z@%(Y>hb%x9{%aWNV*UI z@Vl9rnJIiy0rzcAA%%Z~KuYi1l#{|FIr8rkkkv?@wT5O(jq)ssp%etAVB<1RQQP+j zNSJ#c1BB(Ht?47|@4N5JLUSAqq~zYsJih(&NALaiA1_l=CYM{u!3J*q@spqae(zVm z{@a5GpMLa{DD&_yyD*7QKl)8F9vOi&2O?UR$NU5p(*V&IE$@dXc>t0bE9#)CL8& z=&(dGzCe&6Am7|W=K-m184AfIWzp(C4}h`2P>ciA9tW`})wtH0$U``h pjy)X7CdK0oo2|_;WO@ z Wx$d_kyXYCaFafC3Yrt z{t}Xi3FMPeLD7oO5y+z-GUNog_x98QdinBKL^U)R@xLvjb+qSny?viDSp$RR;mAYa za1{0x^7)M+c|?617XVxe^w7XX-3+uHJv8aEzN^x89Wl&83_EaG3hUAr;TX~lN$1n? zMMZ-;Bn|#~IvpK%KLpUF)NiX^c9#P?LZHCzH_qT5aG2MF-6Og*`8Fo?Dat7z^@y5K zTa(X}hwOYn-=yn~zR43t`lj0w1x6AHGwvDqW9evpTMzUd17Q^6fKc$)0+AUIj7@(G z`;u`RxEt1Mr3$WkoAuTZjG 7%Q6rP#=@y2mN`AJ(v5DG#Fm*RlLPZdR>khC0-Qk1HsY!j_4&$w}7d!5;J z6pUR7IVch0f A;;ou3AsGtj(I5S(zDB{^zSiaN_Oo4rT4#`P7#^(wP9p>tz_ z$ Mf2j`CIN9X^-w=9-=8@CTVxs6#Z&^#Z++^yh*I z&&Yf-Cj!fH(wVGqoS=6}8A)NlK{SmvLcON|CPK9@B}LK~PTI|KA>%C2J&{cZu~bn? zk@p?6y-8$09Ou#L@sXK}o{-+mJ3N=kXFOjfeOJy*2yel63p4M!{)~z^l+7F^3Lj%k zu- Q@?2dk$6~tn5my0o!mFrq_D_!UtkhffPQSXEkk&% N zQJwhFg{b_4l8Q!2X^5M(-ZBEO`=qR6q-EVC)8r#^9jM7+)m7~h^z!Ty;gO17)?w6Y zuU;dySc?!nlf@U|%$HxD9r=6btH#!Md$&H@zqZl%{Kxy%dyShv@7`PAy|tA{Bu+r< z${SKrhxQ~iZxF;4py2Ei6$%-FD1dxG$}ia>c;BRt=y04$3s!BifF)iHbmY+{l`$An z43Lk37DPw00Da2M6~>-|zK0G>!bs^<7m!?J1riHvBu2AtDw*}hKsng@U*nXIgFA?` z2mU0UOCCjm1Xbb5W1tN{YsK|{Jt6T9^@Pq_o{FzQ@ABEHsq<5_BOyplz`niFSiQ6V z^|gmPUx2*7y}kQ;eeculhdbYYQYoU1=DKfIckkY4-25%v{9N&EH26vj_i%dS_TKuh zjkO;dcki6q+xn@o{!7^DvaxZyNr-r#L>fqhNn#-drdS3PJOy>2BO*ZrCEOrkTJgkz zDMij*5<$<|<&-G+88;u8X; FlX)mb zFI#%aCpA6n!POD!1{QHsH&KUjejUm=0_8jp Mu{{ZNAA;tgz literal 0 HcmV?d00001 diff --git a/Config/config.yaml b/Config/config.yaml new file mode 100644 index 0000000..c2e8f9f --- /dev/null +++ b/Config/config.yaml @@ -0,0 +1,204 @@ +## 机器人服务配置 +BotServer: + IP: 127.0.0.1 + PORT: 5555 + +## 超级管理员配置 +Administrators: + - 'wxid_7bizfilssbwi22' + +## 关键词配置 +Key_Word: + # 触发美女图片关键词 + Pic_Word: + - '图片' + - '美女图片' + # 触发美女视频关键词 + Video_Word: + - '视频' + - '美女视频' + # 触发备案查询关键词 + Icp_Word: + - '备案查询' + - 'ICP查询' + - 'icp查询' + # 触发后缀名查询关键词 + Suffix_Word: + - '后缀名查询' + - '后缀查询' + # 触发归属查询关键词 + Attribution_Word: + - '归属查询' + - '归属地查询' + # 触发WHOIS查询关键词 + Whois_Word: + - 'whois查询' + - 'WHOIS查询' + # 触发摸鱼日记关键词 + Fish_Word: + - '摸鱼日记' + - '摸鱼日历' + # 触发天气查询关键词 + Weather_Word: + - '天气查询' + - '查询天气' + # 触发舔狗日记关键词 + Dog_Word: + - '舔狗日记' + - '舔我' + # 触发星座查询关键词 + Constellation_Word: + - '星座查询' + - '查询星座' + - '运势查询' + - '查询运势' + # 触发早安寄语关键词 + Morning_Word: + - '早安' + # 触发微步IP查询关键词 + ThreatBook_Word: + - 'ip查询' + - 'IP查询' + - '查询ip' + - '查询IP' + - '微步查询' + # 新增管理员关键词 + Add_Admin_Word: + - '添加管理员' + - '添加管理' + - '新增管理员' + # 删除管理员关键词 + Del_Admin_Word: + - '删除管理员' + - '删除管理' + - '移除管理员' + # 新增黑名单群聊关键词 + Add_BlackRoom_Word: + - '拉黑群聊' + - '添加黑名单' + # 移出黑名单群聊关键词 + Del_BlackRoom_Word: + - '解除拉黑' + - '移出黑名单' + # 查看白名单群聊关键词 + Show_WhiteRoom_Word: + - '查看群聊' + - '查看推送群聊' + # 新增白名单群聊关键词 + Add_WhiteRoom_Word: + - '拉白' + - '添加白名单' + - '开启推送服务' + - '开启推送功能' + # 移出白名单群聊关键词 + Del_WhiteRoom_Word: + - '关闭推送服务' + - '关闭推送功能' + - '移出白名单' + # 触发早报关键词 + Morning_Page: + - '早报' + - '早间咨询' + # 触发晚报关键词 + Evening_Page: + - '晚报' + - '晚间咨询' + # MD5解密关键词 + Md5_Words: + - 'md5解密' + - 'MD5解密' + +## API接口服务配置 +Api_Server: + Api_Config: + Appid: '' + Appsecret: '' + Key: '' + ThreatBook_Key: '' + OpenAi_Key: 'sk-' + # 扩展名查询API + Extensions_Api: 'https://apis.tianapi.com/targa/index?key={}&word={}' + # 天气查询API + Wether_Api: 'https://www.tianqiapi.com/free/day?appid={}&appsecret={}&city={}' + # 舔狗日记API + Dog_Api: 'http://api.tianapi.com/tiangou/index?key={}' + # 星座查询API + Constellation_Api: 'http://api.tianapi.com/star/index?key={}&astro={}' + # 早安寄语API + Morning_Api: 'https://apis.tianapi.com/zaoan/index?key={}' + # 微步查询API + ThreatBook_Api: 'https://api.threatbook.cn/v3/scene/ip_reputation' + + # 摸鱼日记API + Fish_Api: 'https://api.vvhan.com/api/moyu' + # Whois查询API + Whois_Api: 'https://v.api.aa1.cn/api/whois/index.php?domain={}' + # 归属地查询API + Attribution_Api: 'https://v.api.aa1.cn/api/phone/guishu-api.php?phone={}' + # 备案查询API配置 + Icp_Api: 'https://v.api.aa1.cn/api/icp/index.php?url={}' + # SOMD5解密API配置 + Md5_Api: 'https://www.somd5.com/ss.php?api=4bc2161f&hash={}' + # 图片API配置 + Pic_Api: + - 'https://api.vvhan.com/api/girl' + - 'https://v.api.aa1.cn/api/pc-girl_bz/index.php?wpon=ro38d57y8rhuwur3788y3rd' + - 'https://api.vvhan.com/api/mobil.girl' + # 视频API配置 + Video_Api: + - 'https://v.api.aa1.cn/api/api-dy-girl/index.php?aa1=json' + - 'https://v.api.aa1.cn/api/api-girl-11-02/index.php?type=json' + +## 积分功能配置 +Point_Function: + # 签到口令 + Sign_Keyword: '签到:NGC660安全实验室祝大家天天得0day!' + # 签到积分配置 + Sign_Point: 10 + # 积分功能配置 + Function: + ThreatBook_Point: 8 + Ai_point: 10 + Md5_Point: 10 + # 增加积分关键词 + Add_Point_Word: + - '加' + - '+' + # 扣除积分关键词 + Del_Point_Word: + - '减' + - '-' + # 赠送积分关键词 + Give_Point_Word: + - '送' + # 查看积分关键词 + Query_Point: + - '查看积分' + - '积分查询' + +## 定时推送配置 +Timed_Push: + # 早报推送时间 + Morning_Page_Time: '08:00' + # 晚报推送时间 + Evening_Page_Time: '17:00' + # 摸鱼日记推送时间 + Fish_Time: '10:00' + # 下班消息推送时间 + Off_Work_Time: '18:00' + +## 系统相关配置 +System_Config: + # 缓存清除关键词配置 + Cache_Config_Word: + - '清除缓存' + - '清空缓存' + # 版权信息配置 + System_Copyright: 'NGC660安全实验室' + # OpenAi 初始化角色短语 + Initiating_Message: '你现在叫NGCBot,是一名网络安全专家,精通各种代码!' + # 帮助菜单关键词配置 + Help_Menu: + - '帮助菜单' + - 'help' + - 'HELP' \ No newline at end of file diff --git a/Db_Server/Db_Point_Server.py b/Db_Server/Db_Point_Server.py new file mode 100644 index 0000000..aa8a4bc --- /dev/null +++ b/Db_Server/Db_Point_Server.py @@ -0,0 +1,172 @@ +from Output.output import output +import sqlite3 +import yaml +import os + + +class Db_Point_Server: + def __init__(self): + current_path = os.path.dirname(__file__) + # 数据库存放地址 + self.db_file = current_path + '/../Config/Point_db.db' + self.judge_init() + config = yaml.load(open(current_path + '/../Config/config.yaml', encoding='UTF-8'), yaml.Loader) + + # 读取积分配置 + self.sign_point = config['Point_Function']['Sign_Point'] + + # 打开数据库 + def open_db(self): + conn = sqlite3.connect(database=self.db_file, ) + cursor = conn.cursor() + return conn, cursor + + # 关闭数据库 + def close_db(self, conn, cursor): + cursor.close() + conn.close() + + # 判断数据库是否初始化 + def judge_init(self, ): + conn, cursor = self.open_db() + judge_table_sql = '''SELECT name FROM sqlite_master;''' + cursor.execute(judge_table_sql) + data = cursor.fetchall() + if not data: + msg = '[+]:检测到积分数据库未初始化,正在初始化数据库' + self.init_db() + output(msg) + self.close_db(conn, cursor) + + + # 初始化数据库 + def init_db(self): + conn, cursor = self.open_db() + create_point_table_sql = '''CREATE TABLE IF NOT EXISTS points + (wx_id varchar(255), + wx_name varchar(255), + point int(20));''' + create_sign_table_sql = '''CREATE TABLE IF NOT EXISTS sign (wx_id varchar(255), wx_name varchar(255));''' + cursor.execute(create_point_table_sql) + cursor.execute(create_sign_table_sql) + self.close_db(conn, cursor) + output('[*]:积分服务初始化成功!') + + # 初始化新用户 + def init_user(self, wx_id, wx_name): + conn, cursor = self.open_db() + add_user_sql = f'''INSERT INTO points VALUES ('{wx_id}', '{wx_name}', 0);''' + cursor.execute(add_user_sql) + conn.commit() + self.close_db(conn, cursor) + + # 判断用户是否存在 + def judge_user(self, wx_id, sign_bool=False): + conn, cursor = self.open_db() + judge_user_sql = f'''SELECT wx_id FROM points WHERE wx_id='{wx_id}';''' + if sign_bool: + judge_user_sql = f'''SELECT wx_id FROM sign WHERE wx_id='{wx_id}';''' + cursor.execute(judge_user_sql) + data = cursor.fetchall() + if data: + return True + else: + return False + + # 增加积分 + def add_point(self, wx_id, point): + conn, cursor = self.open_db() + add_point_sql = f'''UPDATE points SET point=point+{point} WHERE wx_id='{wx_id}';''' + cursor.execute(add_point_sql) + conn.commit() + self.close_db(conn, cursor) + msg = f'\n基于你的优越表现,+{point}分\n当前未使用积分:{self.query_point(wx_id=wx_id, )}分' + return msg + + # 扣除积分 + def del_point(self, wx_id, point): + conn, cursor = self.open_db() + add_point_sql = f'''UPDATE points SET point=point-{point} WHERE wx_id='{wx_id}';''' + cursor.execute(add_point_sql) + conn.commit() + self.close_db(conn, cursor) + msg = f'\n介于你的近期表现,-{point}分\n当前未使用积分:{self.query_point(wx_id=wx_id, )}分' + return msg + + # 查询积分 + def query_point(self, wx_id, wx_name=None): + conn, cursor = self.open_db() + query_point_sql = f'''SELECT point,wx_id FROM points WHERE wx_id='{wx_id}';''' + cursor.execute(query_point_sql) + if not cursor.fetchone(): + self.init_user(wx_id=wx_id, wx_name=wx_name) + cursor.execute(query_point_sql) + data = cursor.fetchone() + return data[0] + + # 签到功能 + def sign(self, wx_id, wx_name): + conn, cursor = self.open_db() + sign_sql = f'''INSERT INTO sign VALUES ('{wx_id}', '{wx_name}');''' + self.add_point(wx_id=wx_id, point=self.sign_point) + cursor.execute(sign_sql) + conn.commit() + self.close_db(conn, cursor) + msg = f'签到成功 + {self.sign_point} 分\n当前可用积分:{self.query_point(wx_id=wx_id)}' + return msg + + # 清空签到表 + def clear_sign(self): + conn, cursor = self.open_db() + clear_sign_sql = 'DELETE FROM sign' + cursor.execute(clear_sign_sql) + conn.commit() + self.close_db(conn, cursor) + + # 积分赠送 + def give_point(self, wx_id, wx_name, at_wx_id, at_wx_name, point): + if self.query_point(wx_id=wx_id) >= self.query_point(wx_id=at_wx_id): + # 赠送人扣除积分 + self.judge_main(wx_id=wx_id, wx_name=wx_name, point=point, del_bool=True) + # 被赠送人增加积分 + self.judge_main(wx_id=at_wx_id, wx_name=at_wx_name, point=point, add_bool=True) + msg = f'\n您已给予 {at_wx_name} {point}分 \n当前可用积分 {self.query_point(wx_id=wx_id)}分' + else: + msg = f'\n您当前的余额不足\n当前可用积分:{self.query_point(wx_id=wx_id)} 分' + give_bool = True + return msg, give_bool + + # 主判断 + def judge_main(self, wx_id, wx_name, point=None, add_bool=False, del_bool=False, sign_bool=False): + msg = '' + if sign_bool: + if not self.judge_user(wx_id=wx_id, sign_bool=True): + if self.judge_user(wx_id=wx_id, ): + msg = self.sign(wx_id=wx_id, wx_name=wx_name, ) + else: + output('[+]:当前用户不存在,正在初始化该用户... ...') + self.init_user(wx_id=wx_id, wx_name=wx_name) + msg = self.sign(wx_id=wx_id, wx_name=wx_name) + elif add_bool: + if self.judge_user(wx_id=wx_id): + msg = self.add_point(wx_id=wx_id, point=point) + else: + output('[+]:当前用户不存在,正在初始化该用户... ...') + self.init_user(wx_id=wx_id, wx_name=wx_name) + msg = self.add_point(wx_id=wx_id, point=point) + elif del_bool: + if self.judge_user(wx_id=wx_id): + msg = self.del_point(wx_id=wx_id, point=point) + else: + output('[+]:当前用户不存在,正在初始化该用户... ...') + self.init_user(wx_id=wx_id, wx_name=wx_name) + msg = self.del_point(wx_id=wx_id, point=point) + return msg + + +if __name__ == '__main__': + Dps = Db_Point_Server() + # Dps.init_db() + msg = Dps.judge_main(wx_id='123123123', wx_name='123', sign_bool=True, point=230) + print(msg) + # Dps.query_point(wx_id='123') diff --git a/Db_Server/Db_User_Server.py b/Db_Server/Db_User_Server.py new file mode 100644 index 0000000..cf24126 --- /dev/null +++ b/Db_Server/Db_User_Server.py @@ -0,0 +1,222 @@ +from Output.output import output +import sqlite3 +import os + + +class Db_User_Server: + def __init__(self): + current_path = os.path.dirname(__file__) + # 数据库存放地址 + self.db_file = current_path + '/../Config/User_db.db' + self.judge_init() + + # 打开数据库 + def open_db(self): + conn = sqlite3.connect(database=self.db_file, ) + cursor = conn.cursor() + return conn, cursor + + # 关闭数据库 + def close_db(self, conn, cursor): + cursor.close() + conn.close() + + # 判断是否初始化 + def judge_init(self, ): + conn, cursor = self.open_db() + judge_table_sql = '''SELECT name FROM sqlite_master;''' + cursor.execute(judge_table_sql) + data = cursor.fetchall() + if not data: + msg = '[-]:检测到用户数据库未初始化,正在初始化数据库' + output(msg) + self.init_db() + self.close_db(conn, cursor) + + # 初始化数据库 + def init_db(self): + conn, cursor = self.open_db() + create_admin_table_sql = '''CREATE TABLE IF NOT EXISTS admins + (wx_id varchar(255), + wx_name varchar(255), + wx_roomid varchar(255), + wx_room_name varchar(255));''' + create_white_rooms = '''CREATE TABLE IF NOT EXISTS white_rooms + (wx_roomid varchar(255), + wx_room_name varchar(255));''' + create_black_rooms = '''CREATE TABLE IF NOT EXISTS black_rooms + (wx_roomid varchar(255), + wx_room_name varchar(255));''' + create_users_table = '''CREATE TABLE IF NOT EXISTS users + (wx_id varchar(255), + wx_name varchar(255));''' + + cursor.execute(create_admin_table_sql) + cursor.execute(create_white_rooms) + cursor.execute(create_black_rooms) + cursor.execute(create_users_table) + self.close_db(conn=conn, cursor=cursor) + output('[*]:用户数据库服务初始化成功!') + + # 查看用户WXID + def show_userid(self, wx_name): + data = self.judge_data(wx_name=wx_name, user_bool=True) + return data[0][0] + + # 添加用户数据(wx_name,wx_id) + def add_user(self, wx_id, wx_name): + if not self.judge_data(wx_name=wx_name, user_bool=True): + conn, cursor = self.open_db() + add_user_sql = f'''INSERT INTO users VALUES ("{wx_id}", "{wx_name}");''' + cursor.execute(add_user_sql) + conn.commit() + self.close_db(conn, cursor) + output(f'[+]:添加用户 {wx_name} 成功!') + + # 添加管理员 + def add_admin(self, wx_id, wx_roomid, wx_name, wx_room_name): + if not self.judge_data(wx_id=wx_id, wx_roomid=wx_roomid): + conn, cursor = self.open_db() + add_admin_sql = f'''INSERT INTO admins VALUES ( + '{wx_id}', '{wx_name}', '{wx_roomid}', '{wx_room_name}');''' + cursor.execute(add_admin_sql) + conn.commit() + self.close_db(conn=conn, cursor=cursor) + msg = f'添加管理员 {wx_name} 成功!' + else: + msg = f'管理员 {wx_name} 已存在!' + return msg + + # 删除管理员 + def del_admin(self, wx_id, wx_name, wx_roomid): + if self.judge_data(wx_id=wx_id, wx_roomid=wx_roomid): + conn, cursor = self.open_db() + del_admin_sql = f'''DELETE FROM admins WHERE wx_id='{wx_id}' and wx_roomid='{wx_roomid}';''' + cursor.execute(del_admin_sql) + conn.commit() + self.close_db(conn, cursor) + msg = f'移除管理员 {wx_name} 成功!' + else: + msg = f'管理员 {wx_name} 已移出!' + return msg + + # 查看所有管理员 + def show_admin(self): + conn, cursor = self.open_db() + show_admin_sql = '''SELECT wx_id, wx_roomid FROM admins;''' + cursor.execute(show_admin_sql) + data = cursor.fetchall() + self.close_db(conn, cursor) + msg = [] + for d in data: + msg.append({'wx_id': d[0], 'wx_roomid': d[1]}) + return msg + + # 添加黑名单群聊 + def add_black_room(self, wx_roomid, wx_room_name): + if not self.judge_data(black_bool=True, wx_roomid=wx_roomid): + conn, cursor = self.open_db() + add_black_room_sql = f'''INSERT INTO black_rooms VALUES ('{wx_roomid}', '{wx_room_name}');''' + cursor.execute(add_black_room_sql) + conn.commit() + self.close_db(conn, cursor) + msg = f'{wx_room_name} 群聊已拉黑! ' + else: + msg = '当前群聊已添加至黑名单' + return msg + + # 删除黑名单群聊 + def del_black_room(self, wx_roomid, wx_room_name): + if self.judge_data(wx_roomid=wx_roomid, black_bool=True): + conn, cursor = self.open_db() + del_black_room_sql = f'''DELETE FROM black_rooms WHERE wx_roomid='{wx_roomid}';''' + cursor.execute(del_black_room_sql) + conn.commit() + self.close_db(conn, cursor) + msg = f'移除黑名单群聊 {wx_room_name} 成功!' + else: + msg = '该群聊未被拉黑!' + return msg + + # 查看黑名单群聊 + def show_black_room(self): + conn, cursor = self.open_db() + show_black_room_sql = '''SELECT wx_roomid FROM black_rooms;''' + cursor.execute(show_black_room_sql) + data = cursor.fetchall() + self.close_db(conn, cursor) + msg = list() + for d in data: + msg.append({'wx_roomid': d[0]}) + return msg + + # 添加白名单群聊 + def add_white_room(self, wx_roomid, wx_room_name): + if not self.judge_data(wx_roomid=wx_roomid, white_bool=True): + conn, cursor = self.open_db() + add_white_room_sql = f'''INSERT INTO white_rooms VALUES ('{wx_roomid}', '{wx_room_name}');''' + cursor.execute(add_white_room_sql) + conn.commit() + self.close_db(conn, cursor) + msg = f'{wx_room_name} 群聊已开启推送服务!' + else: + msg = '该群聊已开启推送服务!' + return msg + + # 删除白名单群聊 + def del_white_room(self, wx_roomid, wx_room_name): + if self.judge_data(wx_roomid=wx_roomid, white_bool=True): + conn, cursor = self.open_db() + del_white_room_sql = f'''DELETE FROM white_rooms WHERE wx_roomid='{wx_roomid}';''' + cursor.execute(del_white_room_sql) + conn.commit() + self.close_db(conn, cursor) + msg = f'{wx_room_name} 群聊已关闭推送服务!' + else: + msg = '该群聊未开启推送服务!' + return msg + + # 查看白名单群聊 + def show_white_room(self, ): + conn, cursor = self.open_db() + show_white_room_sql = '''SELECT wx_roomid, wx_room_name FROM white_rooms;''' + cursor.execute(show_white_room_sql) + data = cursor.fetchall() + self.close_db(conn, cursor) + white_room_id = [] + white_room_name = [] + for d in data: + white_room_id.append(d[0]) + white_room_name.append(d[1]) + return white_room_id, white_room_name + + # 判断黑白表中数据是否存在 True False + def judge_data(self, wx_id=None, wx_name=None, wx_roomid=None, black_bool=False, white_bool=False, user_bool=False): + conn, cursor = self.open_db() + sql = '' + if wx_id and not user_bool: + sql = f'''SELECT wx_id FROM admins WHERE wx_id='{wx_id}' and wx_roomid='{wx_roomid}';''' + elif black_bool: + sql = f'''SELECT wx_roomid FROM black_rooms where wx_roomid='{wx_roomid}';''' + elif user_bool: + sql = f'''SELECT wx_id FROM users where wx_name="{wx_name}"''' + elif white_bool: + sql = f'''SELECT wx_roomid FROM white_rooms where wx_roomid='{wx_roomid}';''' + if sql: + cursor.execute(sql) + data = cursor.fetchall() + if data: + return data + else: + return False + + +if __name__ == '__main__': + Dus = Db_User_Server() + # Dus.init_db() + # Dus.add_admin(wx_id='yunyun', wx_name='云云', wx_roomid='123123', wx_room_name='测试') + # Dus.del_admin(wx_id='yunyun', wx_name='云云', wx_roomid='123123') + # Dus.show_admin() + # Dus.show_white_room() + # Dus.add_user('123', '云山') + Dus.show_userid('云山') diff --git a/Db_Server/__pycache__/Db_Point_Server.cpython-38.pyc b/Db_Server/__pycache__/Db_Point_Server.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b98adbe8a4cb105387282565fa58da6b704a607c GIT binary patch literal 5693 zcmd5=U2_xH8QyQL DJb$gx}fCFR}S9N%{|6gntGu4&!j%M8PB`=cF+?Da%w>a!OJWXEmvc zvzF9;DlwI5mn5dWrzCaTVES2wCvE*bDH*XNqb4(0gqf^~MW?i6lO462-lNf!K`GY! z0Pm1uvS$>E?s(CSXXrZo({OPZhx0B9TT04If(0^DE=jOJyf>*aof){+={-0b^e&tu zteLgoY_ct^jjg&QC!1J1TaA_|>tIje+{`StmaW5`7Pg*kKuas@WL-G7v5jmK&a2o~ z_B7j!9_?%mEZ*j=>KjhIQpo1r)S%7J+dLz~vZbGj3ITWwhx2n3t~4soD6TpyPsnAN z$?K)El+w!5j6N&Ll55OFTodiedI92;;u@n(v&w{0R+!!?F{6|EN123IN8+V*yL)?g zA1ma~WJh-UHn8DdHoT%eBX0LzOpoPC`su{Lt^>f=wDXw)%jQSCHvhSSVm{+$3;ASp zFgud>ClqV;l!D`F<7xLTFT%1spB}S4GnG1%&Dp6GnubNyi;foAh@Hyjv#zJni##n? zNHb3>jN5t7IDxv&y{JPYj}ufe)zch1cgAbU6gjtnop^`g+d3!lHGt~jPmUcNI_=op z89KtoFu3FLv|HdqeYSJfEsPHxEx1Df--n%QVK?-SUnEn>rc}x#_yx`779}d1a+g}# zQ2W4A=Q;~L zJ}-jF|aEuLeLYfmt(3!l-H&Q{MC0F??1gyZyfrXw%6!FwCXQamAyczvz z5T^r$B)7<#OpMj=XA QmRaZ19JukG zz5Dmac0RH*`U;mmS#R-b3&PT~cTX&KsPxif%p?`E8rfnsdS~oV(E@g_Kl{ePDsiq& zRW8pi6J+vtmCM(+#xy|>z6E^+1q2yldMyvuWw@PoZC?db0UeTStL;J}gXUUlY{lq1 za5!x!1T{1wM-(Kf*Mll6SLgvPM&gB7jE7MPIH68x3<2rSh{I(Cr8=!+0cu#9y5NLL zOH(XCwXA|COG^-(*mOKT*ncWv9ginYE|K6DM^2pXAGCV9A8Oq@t?rV6a!>5gTnHve zU}0=5>xNg1rwfjFk*X^~E2t&SSgHtxqUBQqjMpS4OLq@oQcFrNcZii!>a1NcLGOVT z=tS_WilbhtLg-AZz(wIbO!d(c*ULC*Lc)x)!H+U+P+~d`T02I(^h{N%#1wt4sxFyV zf7XAhpXirmFLXatx(}7M*Y_2?UC}c!5K}|6vtW8G;xn!rb+1XVX}D0xg>Y>1 =JvZO}Jqm+mqtHU)&f|3}phIPa@D9#hI4w{9Y2o9qf5+!4b zo{NC3z#KT6@zUnguk?{dRlyzXPx#drM8l4UZPp4D`LnR7_%w=W<@%lZJMYimn_2w$ z()`^I?|**z{_Ks#_irOE?D&r4AAuuUx%WZkH&X~3^Y^}9{KE}j6~4Xu@tn*F_3wy5 z=r^Z_T=NXt1kb(Zb48n9^w pLdd|HT6a+Q71<&Y zIv_RqHt<7znvM-@kPC# ikVy5v`Q6&S-6Fl<1%Z ziH>N|s0ATM6I9YE;4F`XD|0$BVdU4arWLJGXn=tvJ5n~v5wSUJjted%fCq&Nf87zQ zJd?DBB6WjXB-wPUNLgQW;oTdRFaELk )XGlr_jV>Ycs(NQN@Dr5`yuVDJJi zu(<^E{I#l6gy=foRIjutneRnixSi=!aMQVOT!k6_Mzbo@Xs=R%L|gRAUoLC>FQHK` zppHzWtU_HLKT4=qzOStFuq|I<6x!TYN6Bx0q%EOd<%r05JShP;2}aTGz>kJMLalfR z1#N!)oCTt^F!=@CUb*=pHo5h?-TSvb_51Yp_F6bZHjT~fP8#*cRERAu#SdS|eu!Ef z9el?>Po3!fT-ek=wD^m-dliR6p ZD1*S178t(KwVo8;N_+iJroM~T;}&nBg7i>~&-+mG)V^`Y px0pQQ>Ej%`=0?_g=JP&aFH$Dq(8q`t@d3hA+uo73nzDf<`d 5(u| zjS>h1jLlMZ5eP}_%5ES9PKsMdiYg$fN`A(?CR*E1dE&({$#;52Gty|+4z6NUb7p#` zyQlkn=X~dM>#>1>w1lIw>HAC`mZX1Cq5Du#cmSt60l_3DSEO0FAj@>GRFr}uu4+Mj zNMb6}UX+;jf>O{No#{_0{6R;1K`I!IF>f+sfm$h(QqH`HzNDP&8?{FLXrrDlQ@Q&v zP t}e(e*^`;P zLGq-c=1KGVf<)Rxk4nCI&DJejw(hD`56&FgD!OLVTiA5Y@RgeDYe!4wXR0&xoZ@S)Q#t5o$_>t)YQ0FU&q+Lk!Ccz0Yuf?p z-#xIC&7!(n=cRg$AK2}j`Ewbq>3gPIpvL!dy zCq^GuE7M>*2i+68yKuVeAUtJWA`Cq_xC$&~8nRxl)S%?GsFWOmC0=0&)Pt)*NHl z`Z~3G)JN*37Geb7!wswmBRHV6 J(uP+ zF=p5wsd+&OZBWfOZ=4)|czoBCO-5!DKr|y>5?tLP-RU{L)#jD7HNGj0ekF4J$ffwkM#Z{6q0&}hBc np z3(=50J-QQ&NM=t6Fntaf)Kz8>KEj5~eDfc>_KokH8n>r*KKSssy=TJC@13&8pV%`w zHEEZ~b6q=aCyvd>o-NKW` L(C}%EecZy zk+BR?+|}|^=M>)zUBXY%@QTy5T7^?Y2aktgmG~tW#1?Mj4ZofQ#nV8D(6YikTsu~z zE@s#cyb8G;!`_%+nXZaG0fy*Z$0_JNpcxDu#7;wZ3m_d?kiAM| YT)BbU^X+!&`+s<8?p zMCOBq^QT^FpMJ~cH{;=#6hO~M&l)RGwA-Klx&8iIh|fdk^aN&{{4fZ 9al zHiVxE$17+*=AOa;={w*ELhlA@knoaJROJ!86$x^Hp&~2))w)g#Nu>pJvkGv%HsL{0 zCuMT=&OwG4`Oje#LSR(_mOl{zt07Q#1FOM*3{MA`L15N8V9q0bf=^M3qzmsc0G ~9 iBXW8O7q~cAPGGr5r^%Tp1fXQp}~oiK?#!RT05hVn>~G> zr$gI%zIk()stUD^#_H_W{Fq?zi$vuD9oRXgok6gptWcP^Z UKhz4cY_W8fRbK&_Dpq9mxuU!26 z^pM>c!sGVeUT?oL7rztH Nhs!HRSN|2t;gHie0k3 z_3G$l38T&^n%ul$2}+5-&<979QWVf Xd;R+GCi&6TZ2t4^)_);_1%_#Bs zTsxwb4v+A=P`^RhQ$Qq _>$JvtAGkg#bY=GqRwT`vtXV`Q~s;E#V?Wuz5Uj zcPzk1 6thll zZc5m7qG_LD_wh_8SN?i<1}P6YxStM|3`91)Jkzz5SdwSR?PH#4fAL)V)Q5|&y?61s z=NHe=5@)DEDQ#rpl;-r;xw5Sjk;Fq;-qw5T{U!#cJBlt#IPn+yaES;f2&M5FhCh0B zgd><=KN~Q=5i-AtB>*i}dU+-u*0Ma4fZ-RPT>RDhmw|zHhOPz%B7}G}%frxH@7-P) zI+U{{481LTD5oc%Wa#s&Q4VD^I1Q22*vJ%h T#NFvF(2SeodLUdBYIDiJE6E}%S#~H7@nn^!^B;$+F;T}$@t=DZc1}|Q7)$J&roA-(sh6IVSPCcY z7NqmO)Vwu@2AgBc=K1^^7`KSX&Aa0k%fu7=*kOk|aT2?Iq&X5d>U<_xmq%3zobAJx z fo?7324 z(y*2b&Q8dJfhf!Dz={nQBcIPtOibj~(Vq@9UHsvZE*58NtRepV$P|lDH%gV@4X53J zU`n)WEOvf5ZU69_NNgr?CyBdB+)rW~i7^t}NjyMeCyCu8#5P7eHE~D#JY0pKb&goO zVi(!83`@5%)*xis%31@sABbdD)TbHDmS(EOVuPCg`?J&Sk3Y^?{=i=GKiHPw?=Z3X w#%USPiTy=O{t)hbb$7!JCbGnceCykRPIeFrxTJ^-asf-t{!IFTB^&1d0EIpd6951J literal 0 HcmV?d00001 diff --git a/Output/__init__.py b/Output/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/Output/__pycache__/__init__.cpython-38.pyc b/Output/__pycache__/__init__.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b8a93e7eb3d188ab6db4f751d5637d0e25ba8e4b GIT binary patch literal 144 zcmWIL<>g`kf;>6z6cGIwL?8o3AjbiSi&=m~3PUi1CZpd I z yUl8MzUlQYAT2fG25)&T}lrM>o*DI*J#bJ}1pHiBW MY6mjzGY~TX02V|cbpQYW literal 0 HcmV?d00001 diff --git a/Output/__pycache__/output.cpython-38.pyc b/Output/__pycache__/output.cpython-38.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fc91e22d6e02e94d6ce622a87bae04e167c0ae61 GIT binary patch literal 521 zcmYjOO-lnY5X~gJ>$X-94<5yX1*_;mZzAI7Nl>U1G;Wd7iKTRRQ<4;EX;1nuM9`yu zX|JCA3!a>;ARU-D?`1NXVbWS!sxq>C?GiOG_T|OAaT3Smc9Q@ZLdr6b0G{)dOO67A z7bb-g7(V-Re#08kH{E6pD5CDr^mBLBrMLf05DUrA$gLzmn6g1+my!EuR#D6#U&o+S z8yJ#W!KhSwxIikvcm|HW16Dp@#vRA%l)o}uoU&K;7EIxp`w3~1+Eo!MW3-XsMYDO` zl)@;Si2JR!47%e^PIS91qp?a;{UjH%PEX~oGg++P?bNfKI u(cB5Wko0^ZAuPcqFY_O4Wy3YM^RWirT7_^r1dNBtVsppp)Z0Cl~H~X75az zC`gHtO7xKeeP9(K)&2lVig>i8ltO_2 &dvOG zcJ6R0rEu^&{?sRAF3oZOV5jvbLg!t$o$rAVj_@XD@hZ Q?epzgz=IY zwPI?F@exzD;%c1nQB$!JYJ%}GGpQ!w88I`ZrdXR+)2z*?nGZQ4llTlr;?siKp?4DH zm_WbNJ4j-hS2ySzY8&euJSBFJ%O;n>E-uS^nSEtLJE+qWI@LbQ8zmI=4r=|jQF22$ zh|(ZB?0`z32@>U?ULucsQM=-nD=x|nM;o>2F_ItaE8rTfKLI-L!tL||(K(eToGK8W z2s4~25|K#IN+d#}&_+m%$k0YfoG8%7NP;Axl}U=Ep^cLayhn%E(O+?fndzZ%1zhFP zPXZ ^}S9#G`1;9* (cA)$^THpxB?dQx=pkTS&gDmhnpo$idD`zv zgrA1QF~N;QYSB73Ae;o~LN8X6>l{Fp@8ym@c~SyNyruw6j3g(-35f`^LLKHEf0cnu z?5k{sXCHa_=-$TF^M3WFU!C{AzUY59w>&vDFL )JpoO69figR3dZ}doZ#Z ztT!K_Pof}!vkjt|5D_(v9Ssr3`t(`Uhz1%gi~-q(;?6Se{Z{ 3jMTj-%`8%Sd)0!41*o$<}SR8x+><$<~Q&o AkA1wh#|WNT%|rmH0n0Qe^OQezE$~+5Cs?p?W@dSMZn-+QbnP$yk2!zl^uvX3L*434KxpHy-y5f{KU|m! z{-E~Y?)}9d=N{ax`4=V|_b)G=pIMrE&Yx;?!ke7BAgtEKI^fln1wFmo82DfBw33 z p&HcZ4 (mc=7=ISk+VE}BZ;cj#A9Om#Pwyh1nrh3~e zh%l4A!Z~1EuEy6nJe2@gQk}0wpp7D|R*b~L5xH$79*!t&BZ+V%xpIW?p*+RpX(FHt zVYLi8@c60lR2z@%+O>DruF5tr^2keYxB)g7CL3q2g{K@l-~0=+jj!v^K(#14g<+jk zOkIsY&Z1+U2xpon Dyd*Y;Yg<_IXdb^i+vW8%zYlUv zmet!q9oG$?20^`)1FrSEAt?Q}t{89mhzM%LE-1Rf>CG>Spj1p9U>_B^;M*ebcSm8^ zDCv%_74jx{Jx^OQ`kVNE=w^!FX6$X~+rX(}zheciTEior{8r%McW~c2815ugbdN4@ L5nf`tAE@vjGvnc) literal 0 HcmV?d00001 diff --git a/README.MD b/README.MD new file mode 100644 index 0000000..c42e147 --- /dev/null +++ b/README.MD @@ -0,0 +1,617 @@ + +NGCBot +
+ +![image-20221212162417977](./README.assets/image-20221212162417977.png) + ++一个基于✨HOOK机制的微信机器人,支持🌱安全新闻定时推送【FreeBuf,先知,安全客,奇安信攻防社区】,👯后缀名查询,⚡备案查询,⚡手机号归属地查询,⚡WHOIS信息查询,🎉星座查询,⚡天气查询,🌱摸鱼日历⚡微步威胁情报查询, +🐛美女视频,⚡美女图片,👯帮助菜单。📫 支持积分功能,😄自定义程度丰富,小白也可轻松上手! +
+ + +## 目录 + +- **1、[介绍](#1、介绍)** +- **2、[项目结构](#2、项目结构)** +- **3、[使用帮助](#3、使用帮助)** +- **4、[功能介绍](#4、功能介绍)** +- **5、[配置文件说明](#5、配置文件说明)** +- **6、[后续优化计划](#6、后续优化计划)** +- **7、[后续开发计划](#7、后续开发计划)** +- **8、[更新日志](#8、更新日志)** +- **9、[特别鸣谢](#9、特别鸣谢)** + +### 1、介绍 + + NGCBot是一个基于HOOK拦截机制的微信机器人,用户高强度自定义,支持多种功能,代码逻辑清晰,因为其HOOK机制,目前仅支持Windows版本。目前支持多种功能功能调用,其功能🌱安全新闻定时推送【FreeBuf,先知,安全客,奇安信攻防社区】,👯后缀名查询,⚡备案查询,⚡手机号归属地查询,⚡WHOIS信息查询,🎉星座查询,⚡天气查询,🌱摸鱼日历⚡微步威胁情报查询,🐛美女视频,⚡美女图片,👯帮助菜单。📫 支持积分功能,😄自定义程度丰富,小白也可轻松上手! + + + +### 2、项目结构 + +``` +│ main.py -- 启动主文件,启动此文件运行 +│ README.MD -- README.MD,一个介绍说明文档 +│ requirements.txt -- 该项目所需要的所有第三方库 +│ +├─Api_Server -- API模块文件夹 +│ Api_Server_Main.py -- API模块文件 +│ +├─BotServer -- Bot收发接收处理消息文件夹【重要!】 +│ MainServer.py -- Bot运行主服务文件 【重要!】 +│ SendServer.py -- Bot收发消息处理服务文件 【重要!】 +│ +├─Cache -- 缓存文件文件夹 +│ │ Cache_Server.py -- 缓存文件处理服务文件 +│ │ +│ ├─Fish_Cache -- 摸鱼日记缓存文件夹 +│ ├─Pic_Cache -- 图片缓存文件夹 +│ └─Video_Cache -- 视频缓存文件夹 +├─Config -- Bot配置文件夹 +│ config.yaml -- Bot配置文件 【重要!】 +│ +├─Db_Server -- 数据库相关文件夹 +│ Db_Point_Server.py -- 积分相关数据库操作文件 +│ Db_User_Server.py -- 用户管理数据库操作文件 +│ +├─Output -- 消息输出模块文件夹 +│ output.py -- 消息输出模块 +│ +├─Push_Server -- 定时推送模块文件夹 +│ Push_Main_Server.py -- 定时推送操作文件 +│ +├─README.assets -- 介绍说明文档贴图文件 +│ image-20221212162417977.png -- 没啥用 +│ 关注.gif -- 没啥用 +│ +└─Recv_Msg_Dispose -- 群与好友消息处理模块文件夹 + FriendMsg_dispose.py -- 好友消息处理文件 + RoomMsg_dispose.py -- 群消息处理文件 +``` + + + +### 3、使用帮助 + +#### 3.1、第一次使用请看此处 + +**注意:此Bot只能在Windowns系统上运行!!!无法在Linux上运行安装** + +首先请克隆代码到本地,使用命令如下 + +```shell +git clone https://github.com/ngc660sec/NGCBot.git +``` + +也可直接DownLoad + +![image-20230305191526567](./README.assets/image-20230305191526567.png) + +下载后解压放在本地,再下载DLL注入器以及安装相关版本微信 + +![image-20230305191835360](./README.assets/image-20230305191835360.png) + +![image-20230305191853177](./README.assets/image-20230305191853177.png) + +下载安装后请先打开微信,并且打开注入器进行注入 + +![image-20230305192022516](./README.assets/image-20230305192022516.png) + +**注意:选择适合自己微信版本的DLL** + +注入后,直接启动main文件即可,命令如下 + +```shell +python main.py +``` + +![image-20230305192150988](./README.assets/image-20230305192150988.png) + +**出现此处显示,恭喜你🎉,机器人启动成功!不过不要高兴,你还需要进行下一步操作** + +与机器人私聊发送一条消息并且在`Config`目录下找到`config.yaml` + +找到`id2`,这是你的微信ID号,请牢记! + +![image-20230305231120081](./README.assets/image-20230305231120081.png) + +打开配置文件,将你的微信ID,填入其中! + +![image-20230305231212883](./README.assets/image-20230305231212883.png) + +这一步是添加超级管理员,如果你想知道超级管理员有什么功能,请往下看文档。 + +那么问题来了,我想添加多个超级管理员怎么办?请按我下面的格式写 + +![image-20230305231323334](./README.assets/image-20230305231323334.png) + +**恭喜你配置好了超级管理员,你已经可以完美使用此Bot了!恭喜🎉** + +**如想要深度专研,请看下文!** + + + +#### 3.2、相关BUG说明 + +##### 3.2.1、Bot的微信号必须修改,否则会报错! + +##### 3.2.2、其它Bug请提交iessus,我有时间就会回复😄 + + + +### 4、功能介绍 + +#### 4.1、娱乐功能 + +##### 4.1.1、AI对话功能介绍 + +AI目前对接的是ChatGpt API接口,其AI算法强大,使用方法请看下图 + +![image-20230305194540725](./README.assets/image-20230305194540725.png) + +**此功能可私聊使用!**使用方法请看下图 + +![image-20230305194645867](./README.assets/image-20230305194645867.png) + +**已采用国内接口【V1.5更新】新版本不需要使用代理!** + +##### 4.1.2、美女图片功能介绍 + +图片功能,可在群内发送😍涩图,使用方法请看下图 + +![image-20230305194812168](./README.assets/image-20230305194812168.png) + +##### 4.1.3、美女视频功能介绍 + +美女视频功能,可在群类发送优质视频,使用方法请看下图 + +![image-20230305195314814](./README.assets/image-20230305195314814.png) + +若机器人发送的是如下文件,不要慌,只是接口问题而已,此问题只会偶尔出现,不用担心! + +![image-20230305195409045](./README.assets/image-20230305195409045.png) + +##### 4.1.4、备案查询功能介绍 + +此功能能查询网站备案信息,轻松获取逼站的备案主体,让社工跟进一步!使用方法请看下图 + +![image-20230305195433874](./README.assets/image-20230305195433874.png) + +##### 4.1.5、后缀名查询功能介绍 + +此功能能够查询任意后缀名,让文件不再陌生!使用方法请看下图 + +![image-20230305195530398](./README.assets/image-20230305195530398.png) + +##### 4.1.6、手机号归属地查询功能介绍 + +此功能能够查询任意手机号归属地,让你跟女神更进一步!使用方法请看下图 + +![image-20230305195628326](./README.assets/image-20230305195628326.png) + +**注意:手机号是我编的,不要尝试社工我!** + +##### 4.1.7、WHOIS查询功能介绍 + +此功能能够查询任意域名WHOIS信息,让你跟麻花腾跟进一步!使用方法请看下图 + +![image-20230305195801227](./README.assets/image-20230305195801227.png) + +##### 4.1.8、摸鱼日历功能介绍 + +此功能能够推送摸鱼日历,让您一天轻松摸鱼,把控摸鱼时长,打倒资本家!让资本家无话可说!使用方法请看下图 + +![image-20230305195945397](./README.assets/image-20230305195945397.png) + +**注意:此功能已开启定时推送,在工作日可定时推送,默认推送时间为10:00,可在配置文件中修改。如要修改配置文件,请看[配置文件说明](#5、配置文件说明)** + +##### 3.1.10、天气查询功能介绍 + +平平无奇的天气查询,轻松在群类掌握你本地的天气,让你约会更轻松!使用方法请看下图 + +![image-20230305204137643](./README.assets/image-20230305204137643.png) + +##### 3.1.11、舔狗日记功能介绍 + +舔狗的日常是怎样的?如何当一个舔狗?怎么去当舔狗?此功能让你专心学做当舔狗,让舔狗不再稀缺!使用方法请看下图 + +![image-20230305204308526](./README.assets/image-20230305204308526.png) + +##### 3.1.12、星座查询功能介绍 + +想知道你的星座运势?想明白今天该不该做什么?要知道今天适合干什么?此功能让你轻松把控星座运势,人生大事!使用方法请看下图 + +![image-20230305204511873](./README.assets/image-20230305204511873.png) + +##### 3.1.13、早安寄语功能介绍 + +一个人太孤单?早起没人说早安?想要每天的早安问候?此功能满足你的欲望!使用方法请看下图 + +![image-20230305204619914](./README.assets/image-20230305204619914.png) + +#### 4.2、积分功能 + +##### 4.2.1、微步威胁IP情报查询功能 + +你叫王大锤,是一个公司的唯一一个混子蓝队成员,某天你单位的服务器被黑客攻击了,还好公司的大牛迅速响应,实现毫秒级IP封锁,此时大佬交给你一个任务。 + +大佬:”大锤,你看看这个IP,是个跳板机还是黑客用的VPS“ + +你:”好,我看看...“ + +此时的你心中忐忑不安,因为你只是一个混子蓝队,VPS是什么,跳板机又是个什么,有什么用,你怎么会知道。于是你只能在群里求助各方大佬,突然某群的一位群友引起了你的注意,内容如下 + +![image-20230305205946424](./README.assets/image-20230305205946424.png) + +你敏锐的注意到了其中一点 —> ""是否为恶意IP:是",此时你更加确定了这台不是跳板机!此时大佬又交给了你一个任务,让你看看另一个IP,于是你也参考群友的格式来发送,但是却出现了下面的结果 + +![image-20230305214235159](./README.assets/image-20230305214235159.png) + +没有积分!怎么办!百度有用吗!我会百度吗!怎么搞积分!联系群主!对!联系群主,于是你赶紧联系了群主,让群主给你加积分,但是 + +![image-20230305214357922](./README.assets/image-20230305214357922.png) + +群主说了一句非常恐怖的话! + +![image-20230305214449681](./README.assets/image-20230305214449681.png) + +于是你只能含泪给群主转了50,让群主给你加了50积分,害,都怪自己没技术,你这样责备自己。我以后一定要好好学习,多多努力。做一名NGC660安全实验室的正式成员! + +![image-20230305220141174](./README.assets/image-20230305220141174.png) + +拥有了积分于是你又开始快乐的给大佬提交情报,又开始了新一天的混子生活。。。 + +编不下去了,目前只有这一个积分功能,其它想要加的可以提交iessus,或者自己添加即可! + +##### 4.2.2、签到功能 + +作为一名合格的超管,总不能让群员V你50才给他积分吧,所以请看签到功能 + +![image-20230305223211110](./README.assets/image-20230305223211110.png) + +但是总不能一天签到多次吧,群友嫖我积分怎么办? + +**放心,本作者有练习时长两年半的开发经验,一天只能签到一次,每日00.00清空签到表,请诸位放心🙂** + +##### 4.2.3、积分查询功能 + +什么?你居然忘记了你有多少积分?这还能忍,直接让管理员给你清零好不好!还好我贴心,给你们安排了这个功能 + +![image-20230305224247670](./README.assets/image-20230305224247670.png) + +**注意:虽然管理员使用积分功能免费,但是管理和超管还是有积分的** + +##### 4.2.4、赠送积分功能 + +普通群友使用此功能,可赠送对方积分🙂,管理员就可以不用,直接增加积分即可 + +![image-20230306101314509](./README.assets/image-20230306101314509.png) + +#### 4.2.5、MD5解密功能【V1.5更新】 + +![image-20230910151905915](./README.assets/image-20230910151905915.png) + +#### 4.3、定时推送功能 + +**注意:定时推送功能只有管理员或者超管开启才能使用** + +##### 4.3.1、开启推送服务 + +作为一名合格的管理员,当然要学会如何去开启推送服务,下面我来教你 + +![image-20230305222312844](./README.assets/image-20230305222312844.png) + +##### 4.3.2、关闭推送服务 + +作为一名拥有高情商的管理员,当然要去学会如何关闭推送服务,下面我来教你 + +![image-20230305222435542](./README.assets/image-20230305222435542.png) + +**什么?!你居然忘记了这个群有没有开服务?你真不是一个合格的管理员,还好有我在🙂** + +##### 4.3.3、查看推送服务 + +![image-20230305222721764](./README.assets/image-20230305222721764.png) + +**你都知道有推送服务了,推送服务能推送啥你不会不知道把!不会吧不会吧!** + +##### 4.3.4、推送服务介绍 + +推送服务,可在**工作日**定时推送**早报,晚报,摸鱼日历,下班提醒**。仅仅如此,如果你想定时推送比较哇塞的涩图,其实也不是不可以🙂 + +#### 4.4、超级管理员功能 + +**首先需要知道在本bot中,一共有三个权限,每个权限的功能都是不一样的,接下来我会逐一讲解每个权限的独有的功能,至于那些普通的通用的功能,基本上群友能用,管理、超管、都能用** + +##### 4.4.1、添加管理员 + +想要管理群聊更加轻松?让小弟帮你管理,输入这条命令让你的小弟变成管理员! + +![image-20230305223648781](./README.assets/image-20230305223648781.png) + +##### 4.4.2、删除管理 + +什么?你的小弟叛变了?!看来他这管理员的特权是不想要了,让我们把小弟的管理权限给踢掉! + +![image-20230305223804540](./README.assets/image-20230305223804540.png) + +**不同地方的小弟,只能负责他们所对应的区域。说人话就是【每个群的管理是不通用的】** + +什么?!你不知道你小弟有没有管理权限?!那不好意思,本作者没有写查看管理的功能,不过当你再次添加的时候,会有如下变化 + +![image-20230305223951890](./README.assets/image-20230305223951890.png) + +##### 4.4.3、机器人消息转发 + +**前女友给Bot发消息要复合你不知道?没有关系,有了这个功能再也不怕前女友给Bot发的消息收不到了!** + +![image-20230306085542234](./README.assets/image-20230306085542234.png) + +**注意:如果发起会话的是超级管理员,那么消息将不会转发,转发消息的接收者为超级管理员** + +##### 4.4.4、消息转发给好友 + +什么?你没有加你前女友,那你前女友怎么会有你Bot的微信?没关系,我也是经历过的人,我都懂,所以我贴心的撰写了消息转发给好友的功能 + +![image-20230306090537764](./README.assets/image-20230306090537764.png) + +![image-20230306090547336](./README.assets/image-20230306090547336.png) + +你说你女朋友是个非主流,喜欢用杀马特文?那不好意思,可能你的消息转发不了给你女朋友了! + +**注意:在最新的测试中,有些颜表情当名字的也可以转发,不过请复制对方名字!** + +##### 4.4.5、清除缓存功能 + +当你的群友调用了很多图片或者视频或者摸鱼日历功能,就会产生许多缓存,此时可以输入此条命令,会将缓存清空 + +![image-20230306101820442](./README.assets/image-20230306101820442.png) + + + +#### 4.5、管理员功能 + +##### 4.5.1、管理员功能介绍 + +作为一名合格的小弟,一定要知道管理员到底有个啥用,这样才能更好的帮助老大去进行管理,管理好了,步步高升。管理不好,可能小命不保🙂 + +作为一个合格的管理员,你掌握的功能有这么一些: + + 1、早报推送【手动早报推送】 + + 2、晚报推送【手动晚报推送】 + + 3、开启推送服务 + + 4、关闭推送服务 + + 5、拉黑群聊 + + 6、解除拉黑 + + 7、用户积分操作 + +但是你知道这些有啥用吗,别担心,听我慢慢讲述,故事还长,洗耳恭听! + +##### 4.5.2、早报推送 + +**注意:早报可以定时推送,也可以手动推送!** + +平平无奇的功能,无非就是爬虫了,我没有要讲述的亮点,而且也编不下去了,直接上图! + +![image-20230305224907222](./README.assets/image-20230305224907222.png) + +今天看来没有文章啊,可惜可惜🙂 + +##### 4.5.3、晚报推送 + +其实一样的,不过你是不是好奇怎么触发的,在下面[配置文件说明](#配置文件说明)一章中我们会讲到 + +![image-20230305225059253](./README.assets/image-20230305225059253.png) + +看来晚报文章不少啊,爬取的一些社区相信你们也是知道的,我就不介绍了,手都敲麻了... + +##### 4.5.4、开启推送服务 + +我讲过,没看到请[自行跳转](#4.3、定时推送功能) + +##### 4.5.5、关闭推送服务 + +我也讲过,没看到也[自行跳转](#4.3.2、关闭推送服务)去 + +##### 4.5.6、拉黑群聊功能 + +遇到傻逼天天发送图片、视频,消耗你服务器资源?这种人最可恨了,玛德!所以我在这里提供了拉黑群聊功能,让此群聊不能使用**娱乐功能** + +![image-20230305225932950](./README.assets/image-20230305225932950.png) + +**注意:即使拉黑了群聊,管理员以及超管仍然能够使用娱乐功能!** + +##### 4.5.7 、解除拉黑功能 + +啊?群主把傻逼踢了?求你解除拉黑?因为他要V你50?OK!马上解除! + +![image-20230305230219618](./README.assets/image-20230305230219618.png) + +##### 4.5.8、用户积分操作 + +既然你是小弟了,肯定是会收点保护费的,既然收了,那不得给人家加积分啊,什么?你不知道加积分? + +![image-20230305230345964](./README.assets/image-20230305230345964.png) + +什么?他骂你大傻逼? + +![image-20230305230427577](./README.assets/image-20230305230427577.png) + +#### 4.6、普通群友功能 + +**作为一名遵纪守法的好公民,当然是要正常使用Bot的相关功能,所以普通群友没有什么奇奇怪怪的操作,你不会用的话,请回复help,超级Bot就会马上帮助你!** + +##### 4.6、帮助功能 + +![image-20230305230611246](./README.assets/image-20230305230611246.png) + +什么?看不懂功能怎么用?本作者自有办法! + +回复help+相应编号即可! + +![image-20230305230716625](./README.assets/image-20230305230716625.png) + +**注意:私聊无法获取帮助信息,必须在群内发送HELP!** + +### 5、配置文件说明 + +##### 5.1、机器人服务配置 + +![image-20230305231636005](./README.assets/image-20230305231636005.png) + +此处别乱来,改了就GG + +##### 5.2、超级管理员配置 + +![image-20230305231701746](./README.assets/image-20230305231701746.png) + +添加超级管理员的地方,如果不会,[从头](#1、介绍)开始看文档! + +##### 5.3、关键词配置 + +![image-20230305231820468](./README.assets/image-20230305231820468.png) + +这个比较多,都是相应功能触发的关键词,比如说美女图片,如果你再多添加一个关键词,就可以换个关键词触发!来试试 + +![image-20230305231930846](./README.assets/image-20230305231930846.png) + +**注意:修改配置文件后需要重启Bot** + +其它的类似,相信自己!一定能调教好此Bot! + +##### 5.4、API接口服务配置 + +此处只需要获取相应的KEY + +打开此[网址](https://www.tianapi.com/source/e81d05c8b1) + +注册登录后,获取你的appid、key、appsecret + +![image-20230306091138533](./README.assets/image-20230306091138533.png) + +你要用什么功能,就开通什么接口,不过目前只接入了配置文件中的接口,相关接口请查看配置文件此处**【注意,此处展示的天气查询接口是旧版接口,如果你想使用这个旧版接口,那就不需要开启天气预报接口服务,直接打开如下网址】** + +![image-20230306091344261](./README.assets/image-20230306091344261.png) + +开通这些接口即可 + +![image-20230306091443104](./README.assets/image-20230306091443104.png) + +在此处搜索接口名称开通 + +![image-20230306091506855](./README.assets/image-20230306091506855.png) + +开通后你会获得一些配置,在此处查看 + +![image-20230306091542863](./README.assets/image-20230306091542863.png) + +这是你的Key,复制,粘贴到配置文件中 + +![image-20230306091621220](./README.assets/image-20230306091621220.png) + +**Appid与Appsecret,这两个是用于旧版天气查询接口,因为这个接口是免费的,所以采用了此API接口,如果你不想用,请自行修改天气查询的相关调用代码,如果你仍用旧版天气查询接口,请看此处** + +打开此[网站](https://www.tianqiapi.com/) + +![image-20230306092504776](./README.assets/image-20230306092504776.png) + +在此处将两个相关参数放到配置文件中即可! + +**微步Key:**这玩意自己去申请,我相信你混子蓝队的水准是能够自己申请的,申请key之后放入配置文件中即可 + +![image-20230306092645321](./README.assets/image-20230306092645321.png) + +**图片API和视频API:**这两玩意别乱改,调用的话是随机调用的,不会出现一直调用同一个接口的情况 + +##### 5.5、积分功能配置 + +很简单的配置,一张图概述 + +![image-20230306093225214](./README.assets/image-20230306093225214.png) + +赠送积分说明请[点击此处](#4.2.4、赠送积分功能) + +##### 5.6、定时推送配置 + +![image-20230306101510700](./README.assets/image-20230306101510700.png) + +**注意:如果是在早上8点,请输入`08:00`!注意格式!** + +##### 5.7、系统相关配置 + +![image-20230306101556676](./README.assets/image-20230306101556676.png) + +版权信息处,为使用各个功能时结尾处的信息 + +![image-20230306101933687](./README.assets/image-20230306101933687.png) + +其它的就不介绍了 + +### 6、后续优化计划 + +```shell +1. 优化群消息处理【已优化】 +2. 优化相关配置信息【已优化】 +3. 优化积分模块【已优化,可@多人加积分】 +4. 优化好友消息处理【已优化】 +5. 优化总体架构【优化中】 +6. 好友消息转发【已优化】 +7. 优化多线程消息处理【已优化】 +``` + +### 7、后续开发计划 + +``` +- Github工具 + CVE 实时推送【连接不上外国站,已阉割】 +- MD5解密【对接SOMD5】 +- 开发Web端管理系统【暂时搁置】 +- ... ... +``` + +### 8、更新日志 + +``` +- 【2022.12.8】 推送Bot 1.0版本,为初始版本 +- 【2022.12.17】推送Bot 1.2版本,新增部分接口,重写部分代码,新增积分功能 +- 【2023.1.1】 推送Bot 1.3版本,重写部分代码,优化代码逻辑,优化积分功能,优化定时推送功能 +- 【2023.3.6】 推送Bot 1.4版本,总体代码优化,优化定时推送,优化积分功能,新增消息转发,维护API服务调用 +- 【2023.3.29】 推送Bot 1.4.1版本,增加多线程处理消息,重写AI接口。可能会出现消息串群,@错人的问题,等后续优化更新 +- 【2023.3.31】 推送Bot 18诞辰版,修复1.4.1版本,消息乱串问题,支持AI上下文检索,优化消息处理代码,实现功能分区分块处理,由于挂了代理之后,当调用ai对话接口时,会出现ERROR报错,这种问题是正常的,能弄到国外服务器就别用国内的 +- 【2023.5.4】 推送Bot v18.1诞辰版,修复AI上下文消息过多无法回复的问题,修复天气查询小BUG +- 【2023.9.10】 推送Bot v1.5版本,优化AI回复,积分功能,代码逻辑,新增MD5解密功能 +``` + +#### 最后,若在使用过程中有任何问题,也提交Iessus,或者关注微信公众号,后台回复消息 + +![关注](./README.assets/关注.gif) + +#### 可以加入群聊,享受疑问解答! + +![a78af2044e0109e90d0b39ba6c7269e](./README.assets/a78af2044e0109e90d0b39ba6c7269e.jpg) + +#### 也可添加运营小姐姐微信,回复【Bot交流群】拉你进群 + +![bc9c03cf900720d493713361d6a1844](./README.assets/bc9c03cf900720d493713361d6a1844.jpg) + +### 9、特别鸣谢 + +- https://github.com/cixingguangming55555/wechat-bot + +- https://github.com/zhizhuoshuma/WechatBot +- https://github.com/tom-snow/wechat-windows-versions +- https://www.somd5.com/ diff --git a/README.assets/a78af2044e0109e90d0b39ba6c7269e.jpg b/README.assets/a78af2044e0109e90d0b39ba6c7269e.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7cf89672a405a2b22c469b44c42d5bde82fca681 GIT binary patch literal 288337 zcmeFZc|4Tu|2I4(*-duYrVy2okgRi+kV=zWDBC0+ + + + + + ++;^yZ$$n&pT{$HK;njj*)+<2}cu6>G- z{UZCgME32qL117%x&PHYu(SU@_U-37z I~IYJyA8>djGXJ+T-7Z#W3>l>R} zjBQ|N_wRA-gK+(OSm618IW7@!T>Jl)0ngv#+P6O#Y+ND-xQ}Wb6g_Xv Skl|4$?PKL_?d#x)KR A07DrlMYxdFaIH628sIi?lJ%IzuWs?+KK)9 z2h7AF*8j*Re-F}^AJC`|JoBWKGYqe|8IwLTQ}!VBq`_+4Wnj}sa`}2nP4XG@h;aKB z0`10{U4b? zsowg8qZU81X7*rqa7=qqtU10dTbpr`T~&Dy=1S9x^Iv9A;f(w+o~S(tIdczE 6&9$4Q X zH0}e=??DbcqaQ1cy$ eQ*2*@Gv#e#{r?dVnU=&U5XaOxMy-D zwS23~Fd1qyY=;>)-6g!5z_yrC;kyDZSn^c@%N9mU2}#@>(b$84|AAf 3aCv=bqUbxSX9)46(i7C8=o5h1c9hn4Ez!ruk1mv&JqA07U&_QF{w z|71K<`dm$&HaIs=W7~2!rRw(}O|P&WIN%c6au0GoypP3~!9tBTm2&a;O$!AmoB|eU z_AO#v1 -r8=Nft_y?3`c z^`?jEKpHXXO4^fIAu3$tL@P?qZ8=aA7{rN$;Na_$|7~u{(O8WMp^HinjDF!Rv$lZ( z{8BcC6u1Y$F5b%VRXtr8TNeL|E%UD#eKl|Yzn; *5>@fSNMgViR*km z<`$6E3K!K$uVG@J1*KOX{6o*>+&oRUC$8<2 zsNm^G+LfkLZYT;PdnR9BlaK}QS3a`-@%}ai>673 zL)NI)Mj_pHyI8L)99?n$=by4hM=JFPAC <4nIbX?aW0%{fOXSWNFdk z1+uHgcSEmUGZ~OR# _Hap)SI^1EeGaXO3VFrvad$p zRPc<_5Dx|?dsE9r`{P7ubx7ZKOvpQA%k4k|s|NPleKuUx68&RcT1r3Uwm*3F-_mNX zn;()$p*v1%wn87fh`;Cn*L~#+cURbc#Iam>WITN+H9Y%tmV w5ZM;F`%7X=LZW>pqErEf4O)@`U{`*H#Vv$@~6+~C1KKzFLpldWb%#D+PjP@ zrR>hfUO%1}o; s z0AYk;epQd+N=blB)hnS2oWaFU&b^mQ^a5S9nPHqUP$%Jc5l?EdaTv)Ey;YU)*G}H> zv9$;3QSgq0J;+-h?`_24$GAiC6R(5kGTL*L2hiFy^X;2ID+GLQ@VTFsH&~xMmV7(> zOwEz_wGWw3y7|n56k=zFku-bQL@-sO+UJcIT=XGbrQqRn^-ni1ygYTy;Eg*AwUx_2 z0YSnEWRyPIk1Qk a2ey(t z^j*jyVd`o=joJQtkgM2P&;pT;+BJecEHZ`_NQbY`Y5Ro&DeUzz?=vpy4HX~cC(d{N zFxBAY>K|^|^!o0z;%BEY^&oNx+t29Hqk2Ya`bawh<=1TF<`lD9YHRi&uC-W_uF=%- z0riTVt%+=J-HPg@98~nlKe*UaJk#+UU-*4&5}`sby75?uXGb~OnQovNzjf-@uY2P^ z+d_62=zg`&Zk%0w0B)MJYD4Q|gby1@k@p}8CZ~xNY~+tUi22vyTlwkw*t)sz6Y$AN zC&I+dkml}E E1 o$JpbA}?zLrZ1Z=aHCs2L72meCp3J@-EG z;^4&^(Ucm6fV?BYi $`L{lqPu zhc$e;8h(q&Hw00+*0-p*R<@JW0Z>r7J6&|Y_D77}yN_}=1|PsLZ?FD#0?=b9SnfiY z&svANEQPqjKKmjt=v1J072Z!qQLN5?*FM>d*4a|K2Z>Soshi!L|JPM(;zzDUM}jQt zd|t>EN^DH}@7@y*PT9ZnX3y=~cfc$CR*mTs <6w3INlLN-ijH`A(>fT8mjsZG~Wh=5ka(g*wiX1MI1`bViX^ z_@mn%H8|7o=Mz$R2n}n%+~)A5F^v}_u?H)V@l(bF#YpR)t7)U>el^$5i1ol3xxiQ2 z@=c(+AjI$L2syl^PmmEQdRh4O3#YDbp_s3$H67(YVKKQ?@D=^MkSyw(VH2pujAKu3 z#l$Q4a2E$VjxU0fNt$C$XhC*WOx>rD%o9NZxqQfuD#}gr j6y=z&3aD2C?^^ZsnC$)&zI)R0 6r%sEgiM+0 zciy>4jNgMaU&7w+lj4BRg=ghqR^bm5E8?VXaUohXy``0TZGGk})X1YA%6R+YYK(xo z%5dbx@JWlX4XqQ_ }HL=`3lb(;{=c|I0Ec9x@!lK7H=0N(E_1RcE#suI)R!vp45%9`Uj zS`d2hXUQ9!+tT8_u-N841>n;V<6{+FFz3iarf=cAw7|oiWk%Muf0 oZG?Ft4rZ657&q4P-y G|~_czIlawzUD zxtB5es>Jx?cDBbn%p9(1!7b~#m=@?$>~|H+BzsB>{@5>vhh6fdm+@!IPq+@?-m;1c zfj)}gAz+Acg{~4sUbHi|zU_5t@`eA@nGl6ax*toV@9Iq>`RTa++wzwu >`XrG-|{Uq2?#VynNgik9%vCI(f2en~eC zP8CdW n)G4(P+CMy%dny&thc~uh>d$Yh8Q;-2#*(vV7>Urqm_W zn_D5}*QE5v)q8rC-4+h&f8K-0brt~IElK>&cjY#9TSBm8Li83M8bd!_IkejTBX)(c z2Vps*B`#}!C`RQLG*eWqu9%LCJbkQu>L5bSz8ciWvn)gIJ; 1xOHLxBHHWXy5Dv&^z zGOckANA5>#7WtjXOMsm$t2XZ}4tphuyfwl|UWDmp&)vM)pLSgRS}XN}=LKT_>mtW% zTw$!V9W4D*S4@$Qx8v-_@C(3xNve&K#N${Y5H<5lj*JZ+CunfadY{*ofVL_x@ysIM ztwzHYdN{{fdl1t+;3wrBFT6`R z*stlD^lcCFs2=4A91W&tkj-BeE$Z1zZdZxyFY OVP$2rXG`MOn==yp@-VtHx_qxP;Sow&*W7 zd{%TR28R8vl7!3A0;&TGCzcKVD);Jy&Y5of=4?frVCu2%Hv%@Fy4{LGp1QOKrT(}k zZ@CgST^t7O+=Ijsgc{WVmkIOQpRClt=t(fe-CuIm_MXAn(zRZvk!sU9QoOd+Cl*&D z{ZWzOx7tVPRPtBVhc5NRHZ09=X4i>Cv+MDgz6@XJp ;pqV{*~`izk~GY zwau^w5*MAFABx+Vfp4DNOc`dQdN2p~YyNHq-H6f-F<-b~*=2o{mP1vY6t8%;ZKkfp zEpGkCKds3T+wnW1zVPMu*j*W753)ita-tJ1P-0|ssLJ!|6Xa!Wtvm_w}U7~ zXE8k&2-0AX{UkFcg?3Wl75cpH@CDvg-?z`c2i6@l7g+3{xh`NAqM3yCj4r38{ZcvY zKV(EDfark_?hxP!&Yt8R < _pT`gB3 3NHbtcDsL%Hfmr;_Jfhc@mbEIZ^T=qhB;m|i4#syJtw8P>N4NmUymcxnP*=(LJp z8ZEav)8?Dm4=?Xu8KVk_?mN8VYrNQzW~;LzS}1J(YAco{I{3q@7MXP4jcoSmVibv= zJ7Sv_qvOZ-Q3-g@30jA*IMedlNrDd}e8BML@IzF? +b)BY?QaF06OF5n1B^W=TJ$>x*^kBtn2{R8}4g0{E+%Ygn z#4^vZ0syr P}uGJ7V)r z42$8}yZBEg@@BMPihZPyiCoADO69 i*=>^$&XxD(cxR z;K4B1gH&jp1#k%jG8nlWu0OrI2Z<-RGc_ZFtAb4=i5jk7iLzH~m^uSndl08R2&k#d zdG
`Ort j4#3Nn^jO+Jh`!GT7&mY9v5a<07;UmiD;@ zaQnj!~WpuGgT4@KD%{d`u!XkbCyiD|5rc?tiHDh3I$PWJsRO?mGyiFs%VM^0lYC z(6}vGl;h)k%s}Q27l+S~USJM@u?TnAux^r!-9rSAvzq?>Nb`NVt(-~hmp+zc!t~lR zO%IyIO7o|#e1u`B2_n8CF8ey}C7O6UIjS; Wis3 zfz}H4)iq4QbS!W8M1C}DXe)k^C~T6wJlb;oq1XF>JEdx7UzyD`L(T=g+^sgO!N2W( zBTwMRsk?iS?xU>bK?|ELyxINGmj7<{PyZVQ|L *6jpwwRi}SY0*wy{t>-xgqQ47SI3H zYs`c3mgEJ)^GqQW(#Hn3DvM+vb`Ie`-R5>;FvBjc2<~b1Z5}NJO0 Oy1Z-PIm{f;5~=?HhHZK;tx6hK0Zts>WwV{0B>&V&OqE{XQ!q3i)Cj z#8Ox8AH7>KI1*sEjnDDjLI9WW^%j9MtAYkmgN+#`-@hD=kX$XCqm*tD6;p+X!b)>#+NeDFaGV{)PXG}~9t5UIFYh6e4|6ivaG^GoWB(H BGFcDQg#kJSsBCn053q5Ux!I zagx47&PgQCg3CT2#WkQezRbH;_o@F`YM6LKK-j~H98?Ja&NFupI}L=X>bjlb?JyzC zk)>cgpQlk5hE9Dra{CY_ykZOA3Lgc5Nyl7jbajlbkG8DyrCQ0xyJ=g5RUBpYa)e}W z*FHDtjhK%k+3?X4IXl wWYTPWRxr(+HdwV^D|Uj=T-%vsB9DgCk+I|fztoW> zQhWL%TDQ`fbitg9>yb6`-;6ek5ebAUSSv2lMICzpD6shXTf^=^T4u|+Tc^i5)sJlA zad7gaA^RGWV&8Ud%lOi-)sf;3e-LF7dPJ%=`74RO8{|ICG!TZbecJ7nZyD?uNi)b5 zs9r+nO1k;i2=Y|6`Vz 89z`~?=a`@G0R~(09GIwEdZ#FmX zli|C99gX_ArqA4W?i^lj56anJ?zj{Ec3`#YNmQV}%aq?= 0d%A#Xw}aGC)f&5jv?|Sg2Gdk@-EZpjF!;)uDw6gfTcND?>^n^ zRy6*sc!29n$`-z~Fn!kcbk4Yd8~wZ7m9{IA3nTtSCV_^is??PA3R8XJ%Q@=o*n7XY zB4b!N{&b^PqFMdN1JS+4m+&bTEGbXMH6ArGK|yfWYXr-BfxO0gSQ*nw){MWuO1%F7 zaM{&Sh*yu>PspjrJOd&1s?AU=uYDd|1lJ2&F{^>M3R4efNx3l)8Enr;R@ms)(8?ZU zN98%T`QaYq?g#j~QV6|)Q2wur1jVb#-3|K|+wX>Cb&ew=@5^2v-Z{b^n)*^`k+S5Q z&49agvZPQ91hS4c-$}4`_1uGW>A(PuzLnS45Up5+c}_Fq?>@$b*{_ V+h&HU3;y2r*yt{3c!p5Zi+s6(H@B2|tMW z`16}3dU-ma`G5XTi~6~h*h5z??Li*)^XSo0oQqkw-9;EDrg8_AKKI+3B!& QR@5t=R>?{a^TIuPldl)6`QU| z@zp7S23W|3UaNM+_zYCxa=OD+jO}NSgV#TXCCd~8b?t$yKO#v^!&@)!Wb&4k)r!qk zSDkMU?@R*CFg7MrH3m+RsUK2FpYIdUZK<+^WlO?n*I;}A(>#XR>Z1EKNgStfFj2l> z9p9&v(9%;>zTozxZOHBt1?~n<&V^z`fcOpjksBvUeC>{_7rR|m$oaXNTLD{LCHIN5 zj{ZcSC|Sh0hkffGeSWJPDUazV@vRZuVewxUJm|lbZ>IhH9xUha6)%Oh&uDW|sHkYD z_N&?{R BS*^l|g1}iC1*Nyz~z&u5@ojHlQ6c^Pta^k*Qg4d|e zuZ`t?`w?W7eJs)jnCannpBbX?Uz!HMIvSw!!Bn-05I;y00CK)n9n@!@z?bboP+2|> z&;+Z93U;QI)*pTVC~KLm^ z-8_2tr@&L3MOi}Elg917nc*|b4zrD~MM{)2=Gf#%#>e~9huSmrWMT?Jb&J#DJrGBT zy`VQf)vk+e JNvE7({pdo(m!PCw$*KJ zAGsp?x*TVkIR&`Wuua%QMqt9gr;$cQtO~deNZtc$QU)9LL{~aC0d1Xc_Wl}SRL~aF z PQJ;%7GsL0= ztYEzonItddQ=FLVZTLJVZF|T5(Dx8c*IU1_y8gKbx&^W ZV^THWyD?DU!+UW@G!`q5STr2B$2wBj5A@ (CRVHn~kqxBR+JMWd>F{;AY)g z;J$=0C5lDsq)H!^r}gWRsxrrh3@xrXv6LmP fM}c{A z9QqO F{=N>fTOJ>O7Z3R-wG*)4nGRsQ|5%@pfLvGpg(ZSke^VEq4EKY^7~tCX zAY-KKG~e8!(Xp<;2tI9Z4LhyM^3*?!;l&ZS|Kb^nK+iy?m%O5Z`Fj@?E4D=N;S( !pEia2KtKk+_GbTR-UGJ^)m^@51;$KV}awu<`51PSZ=|{|73X;EOE )$ 5uQ$kwGm6eIDhvDyfn{Kh7sFMg!9 z=BLrm7l;c5#B+F=p~^2q6PGsTyY&w+@YPLKWi^_}{+&dRnh$-8h8!Ud;74ON!FbVL znjqD@@$DxEBTm-H{({#V{lqd1F-OCm{ypS&qIh{cf)y;W0b|K3(M>M_u{2F8zgK#U zl2^%ip6FQLE*yB_GQjj%a wz3rPhaXBfh=GJkgg>#15t?sXC3mrxxdZF!^ z30|33kX%WfT+25wJ$S4;6?&+3I(2^+UsdK0`u38LYFjY&&?XUxaLYgVN~&kb7k4Lj zp8ctazD puwKPNt?|U%&inxxQg+lARnNOfm}bjCL^Mp z{$u<4#IJ0lw9wZ{W&8RjZGK@YY1q}yP&%Ap0$7I^b>%@tvpxS*Sq7ma+nIJ2tQl#- z3J2|5{UV(9T@qHV*K$cy@#n 0FjeEwQ(HYY7w}Q}8 zN-mp^h>dJx=oldZF~{lQ9LutP(2s379MJyPd|%J!*F=h6Gc0~&{9v}`6BGG+wMp^L zrQg4oepE8~@snvE8m`5Dn!dX_Hj_mOv{cgSIyLUEOx(bG(ZxEhBb2|mm?z3nA|V!F zp+NBG0sJqP`^bFupfQ4~Y^NYhR2oJf3lDdv@@dpBmN 4iwnX z74p2$+m7z3`mcAI!bT?7+LHACq#0#|{rp9g>0p!m1E!`k=j*vC-4Uj?ev+un2{Y-L z^G5fA!-Y}vrP5y4QzqrQ#rO-=6C0r9*hH-NT2gQ!Z`R6}QYq2Pv%ydYvWW>=kPcf} zo<5g1a>Meo-ST}|*aKS@YS}N6B%y e8zA;unDD6~!+CfkTVsVfw)3-~J)*V` ) zD_IaExGjZI$T?n;_AbC4)h!oa)YWx7-0u0(6?k%ohtZ3n{0JT WJ_lS_%o8&PpRio4ns|> z#^#&UdoAxz4UEOM1$+Z}G2DHzy0?CNlxNGE-n~EfRTeBwpiKsC{kHgCuF9dikktmU zELkX%3%Q6LyF$08KJRm`U5$nB9KETHZT^U*A-tw1^xE+WPs8Nh5S^Uo_8F(Dw1W+n z-2OChVjTn~>5{Ef;RYYwv{Dr6&v98}vp^Y-m$(N{AAIiQlIO-=0A1?A*Vtx5Ju=!A zDAQkL*A+n7ox^l6wJIRdu5DT45_2Uxhmb>r9i&T|jL?l4N2T6uTm22~%)hgMhdqW@ z03|v?mE)nNfn80Cc+0%X;zvG%OMhrg7I>-cCBrUSAuM!M5N_iDmA ZJVvJhW8PSd+XBcF8Cf> z|Do&?{d#nv=JgLBdtG+c5s^Oc0JZ7ze3y6ZPfo@8<0XpJTEAy9E9s4*)m6juSLzaq z@Omdv)pRIJ3{Szw Mh&U4sROGMA)%}kfTenpu8VWe=FyZMTv1|48f@d0y-HET( z6v3FpRbrahO+Q!Uau#m)t)@V=`^)!SHFVWaY^#EV@4DBWS+a^@unT%4@ X zQvxUKZDQNd&N7Q;kH;oK=HI$^A{};*aJrBJcN4ruwt6kXNB1B=d<$J_1xAZ%V+i;Z zh9o$ODy5da|8kcrS$j5WV&p4Gt@6LL%l|8)b*pf__Y4#FdJp1@lmWtEV`}X#lEXoU zS9Wv-BDznVIe3#)cf_#tb+UGc0g>GJ#y04doyxac?>kK15%T;LKoKfpJ@IilhihrQ zU+J)p(urRm1sT; ^xB;b)Oz= z8T58Wbf3%8>Mq@KqV<_B$Xot}Y32ggTjn(_(7TLt{C&Qy=UD#|Lk=G-r?s}$5?Xdl z#Ga`nAhOJS)Ez_{@BHDabz79Tmv>&ih>8GWp^Ot_(LgNywCB*DU_LW*dGqe76}m4q z`UUYD>$(N{*&+8j{z=Qb#7*2v&F7m=$G?;5$TB64Py;*O02hxG F*UB(7i5vMmr_9i4DEX zZUIQ(GTFg&U}3)FYaOIR93_j4Uqx=8Z@oc&ST-+FYQfS_IF=Z(#bB$k!HW*1CUrYj zVfsRg7uUpdeh^&e>bIU07}m-6_iCMU`qLJ4r|3RNx@Ih)lGO6D-uk^M@7HzhG^Mac zeI@p5;(5??T&I~6Xd4V>BkgzTz3&CB!Db#4>)#S^#PLQtEtn-rVg%AuQbEvQ%TJ`) z@35h@-)*@tf8LThkkGbb46@4#+K&Ns6lYV1+&?96IHY`ZzDVEkJ>A5ebjf5#hgOn* zvP5$G+6qzr@sCCG2ahsIKXwzycJK S!W=)H`U zRZZ%jar=nxU;8il%a1 52H($=1`o?DWoie)`}mFc4n@7fG47 z=RI~wrQ9yI1@;cRE)m`bLiG0uz&UNoc562@KCGbA*u_WIx>D-Uq+ hoW>`Xpz04J3XS z fIQ#+O(?&avr5Ux9^65 ;f0hY!ppP>)h;7}3lgoA=6|=KGaz F+m^sQw7(xywJ; zSkO6z!|y}K*FgN$p3ddKE;c#o98$7oKC(g{)X=DyxZ)9`7oAO%?C*fmf_Mr>2!Eov zK}cw6+>;TLciVEc3;z^Lev!ik@X?mZjc+NWNSU H=gG zo-c5`JnJTW*Gt7U@sr~0>-BSxtzvuvQeqPkqrg9G ##FjnyaP`K$zkV;`xUzu-Y7Yi!hGY6N@jhActqypal{e z79F4wCTqjndk|61uPNc-*99%Ov7t7DEYIx#=UZ{&yQ1#dys*d-Wo#9`o$}-p=KElR zF9^Z>bnWA0{MjhZjy2MncDAq{Qf0qIn_-I=311stTzl&9K43Q#RjCEo!NIV~vk!;m z(pe^mdnxEw(|<>SoQ9*)QzHVXZg&`3=vifza9x(}`slAt<9C0}RICs0CYm5ygJcpv zSvJOgK})hf6F?|F-eHUIB*>V5x^ ;M#(x{*w8!zt0}-vf7@zD=TixMAqeVx {Gs# zuyAp1xK9hVgU&|1XprNI$&X1^68dbgZ9tM+O7Nm&BkTsBkN5fcs5xr *A_ySc9EoCGxAhZPzW7GEw5EwmdIz C5H^#&4|XF*q#WIqe< zAdN>&ueITmv9! a)FMs`%B0q% z$sH(lX*Na_ w90oj$~w$Jw<)vBus;yakLO{<{p zbYnS+_1!nhGp;p+DD$j6i14l`6>W2i>IoQWF_4gRG~qg3l+=1B{~F@YzKbsyv+R#g zj-W4fvRm)}9q(*mM?D#DfC;+&^eb95j`d(X?b* =I*G#OjsU&1V( zogOsLGbwZ#0v+JOuudEM?OCDA6G~ROIDoIjYslK-tgOhh92FD#t|!e9HeO8@gr2}| zD!HUK@C?=y$+viJG#-gGN^6GMxcmiP`sy-2UK|PThj29$zrOFE)Ifmj;ou }RSd!We@ce*vE=HTSU?pQ*L1kI@b1e_woVwr zwOP+al>&{@ku|n={4%r|_lW&&B``US2|`N;)@T~p6nIpXgT`YLm=rxegxGzpjyZ}J zrbT+?iWIBsN;D-6b1Iqpn8qRL+f630p`g(>8>^2r9!z=Wqkp^G^?RxJ6*qP0yjdIG zf=Q$A0b`W4IG&cNqkx2(m*u0l@v6-EoUktfgLM;xgdAbIReta5Q_5M^k^5tQz+Pp@ zLzZt%$pa*c-{F|r3UzU7ojVuflAbE$H+SLna;VIyYoIlATy`ub z^Gu~L=NJ+ iOj_xRa}oNMq}Lm3@w tC}q-ED9E#^iuPC^L96j1gd6<$hq^;GP`5BeDC8u1fVNprIJ 5o%Kf;_p^MGtfl1B1f6!1#HpPZqk*f3^O{b8;_6t&h!zg5b_$bisVX)Q@k}S zAvd!sA7(#F__E!G7@Kc#&@E`4fXZ~f2hxf&n1NS+7URY}!0aN2xsAon?lgM$vp>OI zN&C=;XpM#RIx;S)lEB+r7Mk?#mdnau&V^9L$v;l^OhyU6zEeL$eS{~kIyRfg46vMO zPmCN*3WaCBBsaTXa^%t|Dy>QlXWIX`<2BquY`_P${W#YupJ8?VVd%TvDW+pS;m58U z721Y-3@`JGEf}u1{B$0SG*G_`)#sWVDD z#Yj{ fN)-BV^|ygbXSqH1=EJEwqHAiq-^v8qKDEQdL-6b2!*U+=<3hom z7)f@XE*9q^@sr<_?07eF=@<4>qtJTS;T;Z#R7=ofR_@I4e`=zuzpus;=P=btGi|iS zvhwPMh*J6`5lVwU6j|y7W?%bsfi a1IZuYVUACm<{3 zoxs>1px-SG^@(^}v8G@kb-fK!$=b#?yEST!123j^tD{-RK6cC1K2SgPysIOGt6*pg zKk?;d-1SfS%9vvo>C!cqFE2W6Y4TwD9N@{AQ>tw}&_A!Bva)Vt1`X}U2z;9f#`adj zx_%-dPfGk&bcQ5a{d^w3AxC#{6=ROEPP6fZdq@Zft#h9E(e-Y89gLpqI(4@;py;(= z0Jc|cYq|+@Z20#c#6uugG9>s0Q+Fy~M^EY?iQ^b^-#$CJ{kR8z1$6LeT DYSjIeFpV z4?-ct0c;tr&4!8<99^za+V&18$dNL#9|)6bSK$#dZazHYq<64^|0Vd)l=N!2de4^% zl$-L@{7k{>G;Q7<*XAPe<+-y)whqtg*)})DI?$OZxv^A` 9<^b}I_m@lid*pjxCznCdQBK%a#HcpoDj+ib6?1|m z1q4e*f9&Hr8uQKkIk#_(?H}R0nYho*#n#=?P3G$53z| 8 z<6PJ#Z8c-F!|drC-QGSgH8layt(|`N4|~|jdu*+jm$c~V<6K$)1)h`GnFh0_w{=X- z6 8j&lqs-pbY(UmcvfzE-0kWyH_E2=L@D>{hodn#iM$uKKzo zl~Rx@*k-9Mzty6MpuU)zR5O+NW#s!QIpCD?E8jcS 6pY2Q|mt1(E x z0A|O~9`Oz^VA`bV>Yj@WR<@6y&`Wehlz z7Es>RIW)fm1B(I8<)yqBNtTrr7$U@f=)*Bxk)?YO0dZ`Lt_W9tmju8DagE6~MZlka z>Nq(hbqKyaN4VW6c@XqY9*Ty}azx?~W^to0@CSkX*7^*mXSb-)((#-0mjkQUTc0Eb zA`h`{{|qWtqGDS^>(%I@eu9R#tY)1r(xU&WFr7W2>{DYunOiL%?~N>nKhsElrNmAr z^#sR4jtH6r@Xa;eYyh0eP>}y1jD|}kRG^$MANP6g@T+4;IYkU+t$g>sLgj`&wQVwB zCs#G|&V!vtK^GcATykEMo?!Z>?N>ebuYM&OX;FFOc1k=4jwQW}Fl&P4yP++HvG)*3 z2H*yYcE32r^@VC4DF=^)54=~4#suo%u=AO;B%anhvfi^TO#zk `r z |Ko&d>w(UE9Q+IqVUYm*l3Y&Q6rlU#R0R_$r|^}uKmGC$`w_CDJbE?@c8 zlIi??s>=^#*lQz)k%`5oi!w=(k=j0IZf{BBBmg(2IjD^?STCdu+Ig6B5`eaa$w>zM zdL?ss?m_Pa&ZwicAtFXmeW*+&_N4dxcLFzo4B~v1u(m8+Ac;~eIuf3BjA=2d{Lt=! zA!`sii*!fp08!xH7hpdaG^Dsy4Ie$Gq4e_ONptg`9q{ZRWcmEcHq!~MKTrZq7*VOJ ztkycSxV hYCvB8G0Vie= zL*&cP`zGQy6Fzhtbs=2d ^tj` z8o;Y6@w+8zHmNVEqmDWgJjDkj6(YSxhwqzoCnS2p=LhQ~zS2iZ>Ds1NXQnyIu@}GU zp|>&swbmf0tTNYqi&>i#XJQj9&X0 Or>Rm+dMRb$Zmd+x^mv1T*uFra!cGSM||pKd}^3lPheG^^v)v59V$es5Njm zuJ@8m>W|3HkBSPmVMJ;HOXAT`J4^(APk{Jk0Ph*oU*X2)CeTS45=_l9w8Z$RvDwi` zQ moKaV*(23UdvLh6735oNVKAlTz *XK_%*E_4$acdV|?>>iTpKR8eb)Bx#W~)ubq!?Axofw+pi@PeNd0qKS z2l &KmnPo(=0gI|hbqussaYU &C?W{-`6ucq?}!3gGJ#u`S2V98w BRdz>SOI}Af5K~`o zn|_$LoYW>`6BKyq)lJSPhgv1Q{AbL3q$6*>A+brni@nfF^uzt9IHXU&e$KAfZttJq ze%Vt^n6&M4)j`Zsx5Z1Y9!sx2%)LnwP5A5UD>@ X@l_b=0uuLjV{wB5xpDaO-Ms$+8Cs`I_McjcAw9leH^qy%KRt#2eB zR1 Ba{SUM+Wy57Gj0 3+6FJceEJ8B~h_hTBea~1r$IMtq{orsVgtTCwyy4nTqd%22f z%7s>tp1~?{?T&c9h0MlE_A586N(Q-m?aWNO^1IVjDc{ID555I7K{L3^{&)jj7>Vbg z8c$=J&EVuY_+vu3eKhtyED?72cSUY2MmJoSMv4P#=jdan>rr)~zCL>pe{tv;zN0Y~ z+ynmALKSH|j8+C0xL Y#azbg37!5>ENM@Y)>} zp1F;yu&78|?14m>nqfesu6ZAU{Ek$CZR!J#ueE^>`G{SerK>vstjv{O-u}`YPA#^( z^2(?F%H2NMca}$(86diC!SBF(02Mn824_(*Sk&LCPNgcimxt1~f@CU({2%PShgVbE z_b(cxiHK3E6p2bx5mBlI6R}W4iWQ|rMWhLcv>-8?j-ZHuih>Xo5u}K8sUcJm5$O_I z0wSmcb_B!5?8LYH{_Y#^A9&+;$M24N#xTc|lfC!abImo&XSN~xzTe$(L&53z