diff --git a/顺丰2025中秋版.js b/顺丰2025中秋版.js deleted file mode 100644 index 29290e3..0000000 --- a/顺丰2025中秋版.js +++ /dev/null @@ -1,1748 +0,0 @@ -// 当前脚本来自于http://script.345yun.cn脚本库下载! -# 当前脚本来自于http://script.345yun.cn脚本库下载! -#多号换行,变量名:sfsyUrl -# const $ = new Env('顺丰速运') -import hashlib -import json -import os -import random -import time -from datetime import datetime, timedelta -from sys import exit -import requests -from requests.packages.urllib3.exceptions import InsecureRequestWarning - -# 禁用安全请求警告 -requests.packages.urllib3.disable_warnings(InsecureRequestWarning) - -IS_DEV = False -if os.path.isfile('DEV_ENV.py'): - import DEV_ENV - - IS_DEV = True - - -#from notify import send - -send_msg = '' -one_msg = '' - - -def Log(cont=''): - global send_msg, one_msg - print(cont) - if cont: - one_msg += f'{cont}\n' - send_msg += f'{cont}\n' - - -inviteId = ['15B892B84AA3418B8BE6856D5A4F1119','54BC6335A52A4197ACA8E32BB57CCFE5'] - - -class RUN: - def __init__(self, info, index): - global one_msg - one_msg = '' - split_info = info.split('@') - url = split_info[0] - len_split_info = len(split_info) - last_info = split_info[len_split_info - 1] - self.send_UID = None - if len_split_info > 0 and "UID_" in last_info: - self.send_UID = last_info - self.index = index + 1 - Log(f"\n---------开始执行第{self.index}个账号>>>>>") - self.s = requests.session() - self.s.verify = False - self.headers = { - 'Host': 'mcs-mimp-web.sf-express.com', - 'upgrade-insecure-requests': '1', - 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36 NetType/WIFI MicroMessenger/7.0.20.1781(0x6700143B) WindowsWechat(0x63090551) XWEB/6945 Flue', - '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', - 'sec-fetch-site': 'none', - 'sec-fetch-mode': 'navigate', - 'sec-fetch-user': '?1', - 'sec-fetch-dest': 'document', - 'accept-language': 'zh-CN,zh', - 'platform': 'MINI_PROGRAM', - - } - self.anniversary_black = False - self.member_day_black = False - self.member_day_red_packet_drew_today = False - self.member_day_red_packet_map = {} - self.login_res = self.login(url) - self.today = datetime.now().strftime('%Y-%m-%d') - # self.answer = APP_INFO.get('ANSWER', []).get(self.today, False) - self.max_level = 8 - self.packet_threshold = 1 << (self.max_level - 1) - - def get_deviceId(self, characters='abcdef0123456789'): - result = '' - for char in 'xxxxxxxx-xxxx-xxxx': - if char == 'x': - result += random.choice(characters) - elif char == 'X': - result += random.choice(characters).upper() - else: - result += char - return result - - def login(self, sfsyUrl): - ress = self.s.get(sfsyUrl, headers=self.headers) - # print(ress.text) - self.user_id = self.s.cookies.get_dict().get('_login_user_id_', '') - self.phone = self.s.cookies.get_dict().get('_login_mobile_', '') - self.mobile = self.phone[:3] + "*" * 4 + self.phone[7:] - if self.phone != '': - Log(f'用户:【{self.mobile}】登陆成功') - return True - else: - Log(f'获取用户信息失败') - return False - - def getSign(self): - timestamp = str(int(round(time.time() * 1000))) - token = 'wwesldfs29aniversaryvdld29' - sysCode = 'MCS-MIMP-CORE' - data = f'token={token}×tamp={timestamp}&sysCode={sysCode}' - signature = hashlib.md5(data.encode()).hexdigest() - data = { - 'sysCode': sysCode, - 'timestamp': timestamp, - 'signature': signature - } - self.headers.update(data) - return data - - def do_request(self, url, data={}, req_type='post'): - self.getSign() - try: - if req_type.lower() == 'get': - response = self.s.get(url, headers=self.headers) - elif req_type.lower() == 'post': - response = self.s.post(url, headers=self.headers, json=data) - else: - raise ValueError('Invalid req_type: %s' % req_type) - res = response.json() - return res - except requests.exceptions.RequestException as e: - print('Request failed:', e) - return None - except json.JSONDecodeError as e: - print('JSON decoding failed:', e) - return None - - def sign(self): - print(f'>>>>>>开始执行签到') - json_data = {"comeFrom": "vioin", "channelFrom": "WEIXIN"} - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~integralTaskSignPlusService~automaticSignFetchPackage' - response = self.do_request(url, data=json_data) - # print(response) - if response.get('success') == True: - count_day = response.get('obj', {}).get('countDay', 0) - if response.get('obj') and response['obj'].get('integralTaskSignPackageVOList'): - packet_name = response["obj"]["integralTaskSignPackageVOList"][0]["packetName"] - Log(f'>>>签到成功,获得【{packet_name}】,本周累计签到【{count_day + 1}】天') - else: - Log(f'今日已签到,本周累计签到【{count_day + 1}】天') - else: - print(f'签到失败!原因:{response.get("errorMessage")}') - - def superWelfare_receiveRedPacket(self): - print(f'>>>>>>超值福利签到') - json_data = { - 'channel': 'czflqdlhbxcx' - } - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberActLengthy~redPacketActivityService~superWelfare~receiveRedPacket' - response = self.do_request(url, data=json_data) - # print(response) - if response.get('success') == True: - gift_list = response.get('obj', {}).get('giftList', []) - if response.get('obj', {}).get('extraGiftList', []): - gift_list.extend(response['obj']['extraGiftList']) - gift_names = ', '.join([gift['giftName'] for gift in gift_list]) - receive_status = response.get('obj', {}).get('receiveStatus') - status_message = '领取成功' if receive_status == 1 else '已领取过' - Log(f'超值福利签到[{status_message}]: {gift_names}') - else: - error_message = response.get('errorMessage') or json.dumps(response) or '无返回' - print(f'超值福利签到失败: {error_message}') - - def get_SignTaskList(self, END=False): - if not END: print(f'>>>开始获取签到任务列表') - json_data = { - 'channelType': '1', - 'deviceId': self.get_deviceId(), - } - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~integralTaskStrategyService~queryPointTaskAndSignFromES' - response = self.do_request(url, data=json_data) - # print(response) - if response.get('success') == True and response.get('obj') != []: - totalPoint = response["obj"]["totalPoint"] - if END: - Log(f'当前积分:【{totalPoint}】') - return - Log(f'执行前积分:【{totalPoint}】') - for task in response["obj"]["taskTitleLevels"]: - self.taskId = task["taskId"] - self.taskCode = task["taskCode"] - self.strategyId = task["strategyId"] - self.title = task["title"] - status = task["status"] - skip_title = ['用行业模板寄件下单', '去新增一个收件偏好', '参与积分活动'] - if status == 3: - print(f'>{self.title}-已完成') - continue - if self.title in skip_title: - print(f'>{self.title}-跳过') - continue - else: - # print("taskId:", taskId) - # print("taskCode:", taskCode) - # print("----------------------") - self.doTask() - time.sleep(3) - self.receiveTask() - - def doTask(self): - print(f'>>>开始去完成【{self.title}】任务') - json_data = { - 'taskCode': self.taskCode, - } - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonRoutePost/memberEs/taskRecord/finishTask' - response = self.do_request(url, data=json_data) - if response.get('success') == True: - print(f'>【{self.title}】任务-已完成') - else: - print(f'>【{self.title}】任务-{response.get("errorMessage")}') - - def receiveTask(self): - print(f'>>>开始领取【{self.title}】任务奖励') - json_data = { - "strategyId": self.strategyId, - "taskId": self.taskId, - "taskCode": self.taskCode, - "deviceId": self.get_deviceId() - } - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~integralTaskStrategyService~fetchIntegral' - response = self.do_request(url, data=json_data) - if response.get('success') == True: - print(f'>【{self.title}】任务奖励领取成功!') - else: - print(f'>【{self.title}】任务-{response.get("errorMessage")}') - - def do_honeyTask(self): - # 做任务 - json_data = {"taskCode": self.taskCode} - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberEs~taskRecord~finishTask' - response = self.do_request(url, data=json_data) - if response.get('success') == True: - print(f'>【{self.taskType}】任务-已完成') - else: - print(f'>【{self.taskType}】任务-{response.get("errorMessage")}') - - def receive_honeyTask(self): - print('>>>执行收取丰蜜任务') - # 收取 - self.headers['syscode'] = 'MCS-MIMP-CORE' - self.headers['channel'] = 'wxwdsj' - self.headers['accept'] = 'application/json, text/plain, */*' - self.headers['content-type'] = 'application/json;charset=UTF-8' - self.headers['platform'] = 'MINI_PROGRAM' - json_data = {"taskType": self.taskType} - # print(json_data) - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~receiveExchangeIndexService~receiveHoney' - response = self.do_request(url, data=json_data) - if response.get('success') == True: - print(f'收取任务【{self.taskType}】成功!') - else: - print(f'收取任务【{self.taskType}】失败!原因:{response.get("errorMessage")}') - - def get_coupom(self): - print('>>>执行领取生活权益领券任务') - # 领取生活权益领券 - # https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberGoods~pointMallService~createOrder - - json_data = { - "from": "Point_Mall", - "orderSource": "POINT_MALL_EXCHANGE", - "goodsNo": self.goodsNo, - "quantity": 1, - "taskCode": self.taskCode - } - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberGoods~pointMallService~createOrder' - response = self.do_request(url, data=json_data) - if response.get('success') == True: - print(f'>领券成功!') - else: - print(f'>领券失败!原因:{response.get("errorMessage")}') - - def get_coupom_list(self): - print('>>>获取生活权益券列表') - # 领取生活权益领券 - # https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberGoods~pointMallService~createOrder - - json_data = { - "memGrade": 2, - "categoryCode": "SHTQ", - "showCode": "SHTQWNTJ" - } - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberGoods~mallGoodsLifeService~list' - response = self.do_request(url, data=json_data) - # print(response) - if response.get('success') == True: - goodsList = response["obj"][0]["goodsList"] - for goods in goodsList: - exchangeTimesLimit = goods['exchangeTimesLimit'] - if exchangeTimesLimit >= 1: - self.goodsNo = goods['goodsNo'] - print(f'当前选择券号:{self.goodsNo}') - self.get_coupom() - break - else: - print(f'>领券失败!原因:{response.get("errorMessage")}') - - def get_honeyTaskListStart(self): - print('>>>开始获取采蜜换大礼任务列表') - # 任务列表 - json_data = {} - self.headers['channel'] = 'wxwdsj' - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~receiveExchangeIndexService~taskDetail' - - response = self.do_request(url, data=json_data) - # print(response) - if response.get('success') == True: - for item in response["obj"]["list"]: - self.taskType = item["taskType"] - status = item["status"] - if status == 3: - print(f'>【{self.taskType}】-已完成') - if self.taskType == 'BEES_GAME_TASK_TYPE': - self.bee_need_help = False - continue - if "taskCode" in item: - self.taskCode = item["taskCode"] - if self.taskType == 'DAILY_VIP_TASK_TYPE': - self.get_coupom_list() - else: - self.do_honeyTask() - if self.taskType == 'BEES_GAME_TASK_TYPE': - self.honey_damaoxian() - time.sleep(2) - - def honey_damaoxian(self): - print('>>>执行大冒险任务') - # 大冒险 - gameNum = 5 - for i in range(1, gameNum): - json_data = { - 'gatherHoney': 20, - } - if gameNum < 0: break - print(f'>>开始第{i}次大冒险') - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~receiveExchangeGameService~gameReport' - response = self.do_request(url, data=json_data) - # print(response) - stu = response.get('success') - if stu: - gameNum = response.get('obj')['gameNum'] - print(f'>大冒险成功!剩余次数【{gameNum}】') - time.sleep(2) - gameNum -= 1 - elif response.get("errorMessage") == '容量不足': - print(f'> 需要扩容') - self.honey_expand() - else: - print(f'>大冒险失败!【{response.get("errorMessage")}】') - break - - def honey_expand(self): - print('>>>容器扩容') - # 大冒险 - gameNum = 5 - - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~receiveExchangeIndexService~expand' - response = self.do_request(url, data={}) - # print(response) - stu = response.get('success', False) - if stu: - obj = response.get('obj') - print(f'>成功扩容【{obj}】容量') - else: - print(f'>扩容失败!【{response.get("errorMessage")}】') - - def honey_indexData(self, END=False): - if not END: print('\n>>>>>>>开始执行采蜜换大礼任务') - # 邀请 - random_invite = random.choice([invite for invite in inviteId if invite != self.user_id]) - self.headers['channel'] = 'wxwdsj' - json_data = {"inviteUserId": random_invite} - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~receiveExchangeIndexService~indexData' - response = self.do_request(url, data=json_data) - if response.get('success') == True: - usableHoney = response.get('obj').get('usableHoney') - if END: - Log(f'当前丰蜜:【{usableHoney}】') - return - Log(f'执行前丰蜜:【{usableHoney}】') - taskDetail = response.get('obj').get('taskDetail') - activityEndTime = response.get('obj').get('activityEndTime', '') - activity_end_time = datetime.strptime(activityEndTime, "%Y-%m-%d %H:%M:%S") - current_time = datetime.now() - - if current_time.date() == activity_end_time.date(): - Log("本期活动今日结束,请及时兑换") - else: - print(f'本期活动结束时间【{activityEndTime}】') - - if taskDetail != []: - for task in taskDetail: - self.taskType = task['type'] - self.receive_honeyTask() - time.sleep(2) - - def EAR_END_2023_TaskList(self): - print('\n>>>>>>开始32周年庆任务') - # 任务列表 - json_data = { - "activityCode": "ANNIVERSARY_2025", - "channelType": "MINI_PROGRAM" - } - self.headers['channel'] = '32annixcx' - self.headers['platform'] = 'MINI_PROGRAM' - self.headers['syscode'] = 'MCS-MIMP-CORE' - - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~activityTaskService~taskList' - - response = self.do_request(url, data=json_data) - # print(response) - if response.get('success') == True: - for item in response["obj"]: - self.title = item["taskName"] - self.taskType = item["taskType"] - status = item["status"] - if status == 3: - print(f'>【{self.taskType}】-已完成') - continue - if self.taskType == 'INTEGRAL_EXCHANGE': - self.EAR_END_2023_ExchangeCard() - elif self.taskType == 'PLAY_ACTIVITY_GAME': - self.DRAGONBOAT_2024_index() - self.DRAGONBOAT_2024_Game_init() - elif self.taskType == 'CLICK_MY_SETTING': - self.taskCode = item["taskCode"] - self.addDeliverPrefer() - if "taskCode" in item: - self.taskCode = item["taskCode"] - self.doTask() - time.sleep(3) - self.EAR_END_2023_receiveTask() - else: - print(f'暂时不支持【{self.title}】任务') - # if self.taskType == 'BEES_GAME_TASK_TYPE': - # self.honey_damaoxian() - self.EAR_END_2023_getAward() - #self.EAR_END_2023_GuessIdiom() - - def addDeliverPrefer(self): - print(f'>>>开始【{self.title}】任务') - json_data = { - "country": "中国", - "countryCode": "A000086000", - "province": "北京市", - "provinceCode": "A110000000", - "city": "北京市", - "cityCode": "A111000000", - "county": "东城区", - "countyCode": "A110101000", - "address": "1号楼1单元101", - "latitude": "", - "longitude": "", - "memberId": "", - "locationCode": "010", - "zoneCode": "CN", - "postCode": "", - "takeWay": "7", - "callBeforeDelivery": 'false', - "deliverTag": "2,3,4,1", - "deliverTagContent": "", - "startDeliverTime": "", - "selectCollection": 'false', - "serviceName": "", - "serviceCode": "", - "serviceType": "", - "serviceAddress": "", - "serviceDistance": "", - "serviceTime": "", - "serviceTelephone": "", - "channelCode": "RW11111", - "taskId": self.taskId, - "extJson": "{\"noDeliverDetail\":[]}" - } - url = 'https://ucmp.sf-express.com/cx-wechat-member/member/deliveryPreference/addDeliverPrefer' - response = self.do_request(url, data=json_data) - if response.get('success') == True: - print('新增一个收件偏好,成功') - else: - print(f'>【{self.title}】任务-{response.get("errorMessage")}') - - def EAR_END_2023_ExchangeCard(self): - print(f'>>>开始积分兑换找财神') - json_data = { - "activityCode": "ANNIVERSARY_2025", - "exchangeNum": 1 - } - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~anniversary2025FiftyPercentService~getPopInfo' - response = self.do_request(url, data=json_data) - if response.get('success') == True: - print(f'>【{self.title}】任务-已完成') - - def EAR_END_2023_getAward(self): - print(f'>>>开始抽卡') - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~anniversary2025ClaimService~claim' - for l in range(10): - for i in range(0, 3): - json_data = { - "cardType": i - } - response = self.do_request(url, data=json_data) - # print(response) - if response.get('success') == True: - receivedAccountList = response['obj']['receivedAccountList'] - for card in receivedAccountList: - print(f'>获得:【{card["currency"]}】卡【{card["amount"]}】张!') - elif response.get('errorMessage') == '用户账户余额不足': - break - elif response.get('errorMessage') == '用户信息失效,请退出重新进入': - break - else: - print(f'>抽卡失败:{response.get("errorMessage")}') - break - time.sleep(3) - - # def EAR_END_2023_GuessIdiom(self): - # print(f'>>>开始猜成语') - # url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~yearEnd2024GuessIdiomService~win' - # for i in range(1, 11): - # json_data = { - # "index": i - # } - # response = self.do_request(url, data=json_data) - # if response.get('success') == True: - # print(f'第{i}关成功!') - # receivedAccountList = response['obj']['receivedAccountList'] - # for card in receivedAccountList: - # print(f'>获得:【{card["urrency"]}】卡【{card["amount"]}】张!') - # else: - # print(f'第{i}关失败!') - - #查询新年回馈卡片数量 - def EAR_END_2023_query(self): - print(f'>>>开始查询卡片数量') - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~anniversary2025ClaimService~claimStatus' - response = self.do_request(url, {}) - if response.get('success'): - obj = response.get('obj', None) - if obj == None: return False - currentAccountList = obj.get('currentAccountList', []) - if not currentAccountList: - print("当前没有卡片") - else: - print("当前卡片数量:") - for card in currentAccountList: - currency = card.get('currency') - totalAmount = card.get('totalAmount') - balance = card.get('balance') - if currency == 'DAI_BI': - currency_name = '坐以待币' - elif currency == 'CHENG_GONG': - currency_name = '成功人士' - elif currency == 'GAN_FAN': - currency_name = '干饭圣体' - elif currency == 'DING_ZHU': - currency_name = '都顶得住' - elif currency == 'ZHI_SHUI': - currency_name = '心如止水' - else: - currency_name = currency - print(f"卡片名称:{currency_name},数量:{balance}") - - totalFortuneTimes = obj.get('totalFortuneTimes', 0) - print(f"总卡片数量:{totalFortuneTimes}") - - return True - else: - print(f"查询失败:{response.get('errorMessage')}") - return False - - def EAR_END_2023_receiveTask(self): - print(f'>>>开始领取【{self.title}】任务奖励') - json_data = { - "taskType": self.taskType, - "activityCode": "ANNIVERSARY_2025", - "channelType": "MINI_PROGRAM" - } - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonNoLoginPost/~memberNonactivity~yearEnd2024TaskService~fetchMixTaskReward' - response = self.do_request(url, data=json_data) - if response.get('success') == True: - print(f'>【{self.title}】任务奖励领取成功!') - else: - print(f'>【{self.title}】任务-{response.get("errorMessage")}') - - def anniversary2024_weekly_gift_status(self): - print(f'\n>>>>>>>开始周年庆任务') - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~anniversary2024IndexService~weeklyGiftStatus' - response = self.do_request(url) - if response.get('success') == True: - weekly_gift_list = response.get('obj', {}).get('weeklyGiftList', []) - for weekly_gift in weekly_gift_list: - if not weekly_gift.get('received'): - receive_start_time = datetime.strptime(weekly_gift['receiveStartTime'], '%Y-%m-%d %H:%M:%S') - receive_end_time = datetime.strptime(weekly_gift['receiveEndTime'], '%Y-%m-%d %H:%M:%S') - current_time = datetime.now() - # print(current_time) - # print(receive_start_time) - # print(receive_end_time) - if receive_start_time <= current_time <= receive_end_time: - self.anniversary2024_receive_weekly_gift() - else: - error_message = response.get('errorMessage') or json.dumps(response) or '无返回' - print(f'查询每周领券失败: {error_message}') - if '系统繁忙' in error_message or '用户手机号校验未通过' in error_message: - self.anniversary_black = True - - def anniversary2024_receive_weekly_gift(self): - print(f'>>>开始领取每周领券') - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~anniversary2024IndexService~receiveWeeklyGift' - response = self.do_request(url) - if response.get('success'): - product_names = [product['productName'] for product in response.get('obj', [])] - print(f'每周领券: {product_names}') - else: - error_message = response.get('errorMessage') or json.dumps(response) or '无返回' - print(f'每周领券失败: {error_message}') - if '系统繁忙' in error_message or '用户手机号校验未通过' in error_message: - self.anniversary_black = True - - def anniversary2024_taskList(self): - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~activityTaskService~taskList' - data = { - 'activityCode': 'ANNIVERSARY_2024', - 'channelType': 'MINI_PROGRAM' - } - response = self.do_request(url, data) - if response and response.get('success'): - tasks = response.get('obj', []) - # 过滤出状态为1的任务并尝试接收奖励 - for task in filter(lambda x: x['status'] == 1, tasks): - if self.anniversary_black: - return - for _ in range(task['canReceiveTokenNum']): - self.anniversary2024_fetchMixTaskReward(task) - # 过滤出状态为2的任务并完成任务 - for task in filter(lambda x: x['status'] == 2, tasks): - if self.anniversary_black: - return - if task['taskType'] in ['PLAY_ACTIVITY_GAME', 'PLAY_HAPPY_ELIMINATION', 'PARTAKE_SUBJECT_GAME']: - pass - elif task['taskType'] == 'FOLLOW_SFZHUNONG_VEDIO_ID': - pass - elif task['taskType'] in ['BROWSE_VIP_CENTER', 'GUESS_GAME_TIP', 'CREATE_SFID', 'CLICK_MY_SETTING', - 'CLICK_TEMPLATE', 'REAL_NAME', 'SEND_SUCCESS_RECALL', 'OPEN_SVIP', - 'OPEN_FAST_CARD', 'FIRST_CHARGE_NEW_EXPRESS_CARD', 'CHARGE_NEW_EXPRESS_CARD', - 'INTEGRAL_EXCHANGE']: - pass - else: - for _ in range(task['restFinishTime']): - if self.anniversary_black: - break - self.anniversary2024_finishTask(task) - - def anniversary2024_finishTask(self, task): - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonRoutePost/memberEs/taskRecord/finishTask' - data = {'taskCode': task['taskCode']} - response = self.do_request(url, data) - if response and response.get('success'): - print('完成任务[%s]成功' % task['taskName']) - # 完成任务后获取任务奖励的逻辑 - self.anniversary2024_fetchMixTaskReward(task) - else: - print('完成任务[%s]失败: %s' % ( - task['taskName'], response.get('errorMessage') or (json.dumps(response) if response else '无返回'))) - - def anniversary2024_fetchMixTaskReward(self, task): - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~anniversary2024TaskService~fetchMixTaskReward' - data = { - 'taskType': task['taskType'], - 'activityCode': 'ANNIVERSARY_2024', - 'channelType': 'MINI_PROGRAM' - } - response = self.do_request(url, data) - if response and response.get('success'): - reward_info = response.get('obj', {}).get('account', {}) - received_list = [f"[{item['currency']}]X{item['amount']}" for item in - reward_info.get('receivedAccountList', [])] - turned_award = reward_info.get('turnedAward', {}) - if turned_award.get('productName'): - received_list.append(f"[优惠券]{turned_award['productName']}") - print('领取任务[%s]奖励: %s' % (task['taskName'], ', '.join(received_list))) - else: - error_message = response.get('errorMessage') or json.dumps(response) or '无返回' - print('领取任务[%s]奖励失败: %s' % (task['taskName'], error_message)) - if '用户手机号校验未通过' in error_message: - self.anniversary_black = True - - def anniversary2024_unbox(self): - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~anniversary2024CardService~unbox' - response = self.do_request(url, {}) - if response and response.get('success'): - account_info = response.get('obj', {}).get('account', {}) - unbox_list = [f"[{item['currency']}]X{item['amount']}" for item in - account_info.get('receivedAccountList', [])] - print('拆盒子: %s' % ', '.join(unbox_list) or '空气') - else: - error_message = response.get('errorMessage') or json.dumps(response) or '无返回' - print('拆盒子失败: %s' % error_message) - if '用户手机号校验未通过' in error_message: - self.anniversary_black = True - - def anniversary2024_game_list(self): - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~anniversary2024GameParkService~list' - response = self.do_request(url, {}) - try: - if response['success']: - topic_pk_info = response['obj'].get('topicPKInfo', {}) - search_word_info = response['obj'].get('searchWordInfo', {}) - happy_elimination_info = response['obj'].get('happyEliminationInfo', {}) - - if not topic_pk_info.get('isPassFlag'): - print('开始话题PK赛') - # 这里调用话题PK赛列表相关函数 - self.anniversary2024_TopicPk_topicList() - - if not search_word_info.get('isPassFlag') or not search_word_info.get('isFinishDailyFlag'): - print('开始找字游戏') - for i in range(1, 11): - wait_time = random.randint(1000, 3000) / 1000.0 # 转换为秒 - time.sleep(wait_time) - if not self.anniversary2024_SearchWord_win(i): - break - - if not happy_elimination_info.get('isPassFlag') or not happy_elimination_info.get('isFinishDailyFlag'): - print('开始消消乐') - for i in range(1, 31): - wait_time = random.randint(2000, 4000) / 1000.0 # 转换为秒 - time.sleep(wait_time) - if not self.anniversary2024_HappyElimination_win(i): - break - else: - error_message = response['errorMessage'] or json.dumps(response) or '无返回' - print('查询游戏状态失败: ' + error_message) - if '用户手机号校验未通过' in error_message: - self.anniversary_black = True - except Exception as e: - print(str(e)) - - def anniversary2024_SearchWord_win(self, index): - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~anniversary2024SearchWordService~win' - success = True - try: - data = {'index': index} - response = self.do_request(url, data) - if response and response.get('success'): - currency_list = response.get('obj', {}).get('currencyDTOList', []) - rewards = ', '.join([f"[{c.get('currency')}]X{c.get('amount')}" for c in currency_list]) - print(f'找字游戏第{index}关通关成功: {rewards if rewards else "未获得奖励"}') - else: - error_message = response.get('errorMessage') or json.dumps(response) or '无返回' - print(f'找字游戏第{index}关失败: {error_message}') - if '系统繁忙' in error_message: - success = False - except Exception as e: - print(e) - finally: - return success - - def anniversary2024_HappyElimination_win(self, index): - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~anniversary2024HappyEliminationService~win' - success = True - data = {'index': index} - response = self.do_request(url, data) - try: - if response and response.get('success'): - is_award = response['obj'].get('isAward') - currency_dto_list = response['obj'].get('currencyDTOList', []) - rewards = ', '.join([f"[{c.get('currency')}]X{c.get('amount')}" for c in currency_dto_list]) - print(f'第{index}关通关: {rewards if rewards else "未获得奖励"}') - else: - error_message = response.get('errorMessage') or json.dumps(response) or '无返回' - print(f'第{index}关失败: {error_message}') - if '系统繁忙' in error_message: - success = False - except Exception as e: - print(e) - success = False - finally: - return success - - def anniversary2024_TopicPk_chooseSide(self, index): - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~anniversary2024TopicPkService~chooseSide' - success = True - data = {'index': index, 'choose': 0} # 选择某一边 - response = self.do_request(url, data) - try: - if response and response.get('success'): - currency_dto_list = response['obj'].get('currencyDTOList', []) - rewards = ', '.join([f"[{c.get('currency')}]X{c.get('amount')}" for c in currency_dto_list]) - print(f'话题PK赛选择话题{index}成功: {rewards if rewards else "未获得奖励"}') - else: - error_message = response['errorMessage'] or json.dumps(response) or '无返回' - print(f'话题PK赛选择话题{index}失败: {error_message}') - if '系统繁忙' in error_message: - success = False - except Exception as e: - print(e) - success = False - finally: - return success - - def anniversary2024_TopicPk_topicList(self): - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~anniversary2024TopicPkService~topicList' - response = self.do_request(url, {}) - try: - if response and response.get('success'): - topics = response['obj'].get('topics', []) - for topic in topics: - if not topic.get('choose'): - index = topic.get('index', 1) - wait_time = random.randint(2000, 4000) / 1000.0 # 转换为秒 - time.sleep(wait_time) # 等待 - if not self.anniversary2024_TopicPk_chooseSide(index): - break - else: - error_message = response['errorMessage'] or json.dumps(response) or '无返回' - print(f'查询话题PK赛记录失败: {error_message}') - except Exception as e: - print(e) - - def anniversary2024_queryAccountStatus_refresh(self): - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~anniversary2024CardService~queryAccountStatus' - response = self.do_request(url, {}) - try: - if not response or not response.get('success'): - error_message = response['errorMessage'] or json.dumps(response) or '无返回' - print(f'查询账户状态失败: {error_message}') - except Exception as e: - print(e) - - def anniversary2024_TopicPk_chooseSide(self, index): - success = True - data = { - 'index': index, - 'choose': 0 - } - self.headers['channel'] = '31annizyw' - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~anniversary2024TopicPkService~chooseSide' - result = self.do_request(url, data, 'post') - - if result and result.get('success'): - currency_dto_list = result.get('obj', {}).get('currencyDTOList', []) - if currency_dto_list: - rewards = [f"[{currency['currency']}]{currency['amount']}次" for currency in currency_dto_list] - print(f'话题PK赛第{index}个话题选择成功: {", ".join(rewards)}') - else: - print(f'话题PK赛第{index}个话题选择成功') - else: - error_message = result.get('errorMessage') if result else '无返回' - print(f'话题PK赛第{index}个话题失败: {error_message}') - if error_message and '系统繁忙' in error_message: - success = False - - return success - - def anniversary2024_titleList(self): - return - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~anniversary2024GuessService~titleList' - response = self.do_request(url) - - if response and response.get('success'): - - guess_title_info_list = response.get('obj', {}).get('guessTitleInfoList', []) - today_titles = [title for title in guess_title_info_list if title['gameDate'] == self.today] - for title_info in today_titles: - if title_info['answerStatus']: - print('今日已回答过竞猜') - else: - answer = self.answer - if answer: - self.anniversary2024_answer(title_info, answer) - print(f'进行了答题: {answer}') - else: - error_message = response.get('errorMessage') if response else '无返回' - print(f'查询每日口令竞猜失败: {error_message}') - - def anniversary2024_titleList_award(self): - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~anniversary2024GuessService~titleList' - response = self.do_request(url) - - if response and response.get('success'): - - guess_title_info_list = response.get('obj', {}).get('guessTitleInfoList', []) - today_awards = [title for title in guess_title_info_list if title['gameDate'] == self.today] - - for award_info in today_awards: - if award_info['answerStatus']: - awards = award_info.get('awardList', []) + award_info.get('puzzleList', []) - awards_description = ', '.join([f"{award['productName']}" for award in awards]) - print(f'口令竞猜奖励: {awards_description}' if awards_description else '今日无奖励') - else: - print('今日还没回答竞猜') - else: - error_message = response.get('errorMessage') if response else '无返回' - print(f'查询每日口令竞猜奖励失败: {error_message}') - - # 向API发送答题请求 - def anniversary2024_answer(self, answer_info): - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~anniversary2024GuessService~answer' - data = {'period': answer_info['period'], 'answerInfo': answer_info} - response = self.do_request(url, data) - if response and response.get('success'): - print('口令竞猜回答成功') - self.anniversary2024_titleList_award() # 通过奖励接口验证答案 - else: - error_message = response.get('errorMessage') if response else '无返回' - print(f'口令竞猜回答失败: {error_message}') - - # 查询账户状态 - def anniversary2024_queryAccountStatus(self): - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~anniversary2024CardService~queryAccountStatus' - result = self.do_request(url) - if result.get('success'): - account_currency_list = result.get('obj', {}).get('accountCurrencyList', []) - unbox_chance_currency = [currency for currency in account_currency_list if - currency.get('currency') == 'UNBOX_CHANCE'] - unbox_chance_balance = unbox_chance_currency[0].get('balance') if unbox_chance_currency else 0 - - # print('可以拆' + str(unbox_chance_balance) + '次盒子') - # while unbox_chance_balance > 0: - # self.anniversary2024_unbox() - # unbox_chance_balance -= 1 - else: - error_message = result.get('errorMessage') or json.dumps(result) or '无返回' - print('查询已收集拼图失败: ' + error_message) - - result = self.do_request(url) - if result.get('success'): - account_currency_list = result.get('obj', {}).get('accountCurrencyList', []) - account_currency_list = [currency for currency in account_currency_list if - currency.get('currency') != 'UNBOX_CHANCE'] - if account_currency_list: - cards_li = account_currency_list - card_info = [] - self.cards = { - 'CARD_1': 0, - 'CARD_2': 0, - 'CARD_3': 0, - 'CARD_4': 0, - 'CARD_5': 0, - 'CARD_6': 0, - 'CARD_7': 0, - 'CARD_8': 0, - 'CARD_9': 0, - 'COMMON_CARD': 0 - } - for card in cards_li: - currency_key = card.get('currency') - if currency_key in self.cards: - self.cards[currency_key] = int(card.get('balance')) - card_info.append('[' + card.get('currency') + ']X' + str(card.get('balance'))) - - Log(f'已收集拼图: {card_info}') - cards_li.sort(key=lambda x: x.get('balance'), reverse=True) - - else: - print('还没有收集到拼图') - else: - error_message = result.get('errorMessage') or json.dumps(result) or '无返回' - print('查询已收集拼图失败: ' + error_message) - - def do_draw(self, cards): - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~anniversary2024CardService~collectDrawAward' - data = {"accountList": cards} - response = self.do_request(url, data) - if response and response.get('success'): - data = response.get('obj', {}) - productName = data.get('productName', '') - Log(f'抽奖成功,获得{productName}') - return True - else: - error_message = response.get('errorMessage') if response else '无返回' - print(f'抽奖失败: {error_message}') - return False - - def convert_common_card(self, cards, target_card): - # 如果共通卡(COMMON_CARD)的数量大于0,转化成目标卡 - if cards['COMMON_CARD'] > 0: - cards['COMMON_CARD'] -= 1 - cards[target_card] += 1 - return True - return False - - def can_draw(self, cards, n): - # 判断是否有足够的不同卡进行抽奖 - distinct_cards = sum(1 for card, amount in cards.items() if card != 'COMMON_CARD' and amount > 0) - return distinct_cards >= n - - def draw(self, cards, n): - drawn_cards = [] - for card, amount in sorted(cards.items(), key=lambda item: item[1]): - if card != 'COMMON_CARD' and amount > 0: - cards[card] -= 1 - drawn_cards.append(card) - if len(drawn_cards) == n: - break - if len(drawn_cards) == n: - "没有足够的卡进行抽奖" - if self.do_draw(drawn_cards): - return drawn_cards # 返回本次抽奖使用的卡 - else: - return None - - def simulate_lottery(self, cards): - while self.can_draw(cards, 9): - used_cards = self.draw(cards, 9) - print("进行了一次9卡抽奖,消耗卡片: ", used_cards) - while self.can_draw(cards, 7) or self.convert_common_card(cards, 'CARD_1'): - if not self.can_draw(cards, 7): - continue - used_cards = self.draw(cards, 7) - print("进行了一次7卡抽奖,消耗卡片: ", used_cards) - while self.can_draw(cards, 5) or self.convert_common_card(cards, 'CARD_1'): - if not self.can_draw(cards, 5): - continue - used_cards = self.draw(cards, 5) - print("进行了一次5卡抽奖,消耗卡片: ", used_cards) - while self.can_draw(cards, 3) or self.convert_common_card(cards, 'CARD_1'): - if not self.can_draw(cards, 3): - continue - used_cards = self.draw(cards, 3) - print("进行了一次3卡抽奖,消耗卡片: ", used_cards) - - def anniversary2024_task(self): - self.anniversary2024_weekly_gift_status() - if self.anniversary_black: - return - # self.anniversary2024_titleList() - # self.anniversary2024_game_list() - # self.anniversary2024_taskList() - self.anniversary2024_queryAccountStatus() - target_time = datetime(2025, 4, 3, 14, 0) - # self.simulate_lottery(self.cards) - if datetime.now() > target_time: - print('周年庆活动即将结束,开始自动抽奖') - self.simulate_lottery(self.cards) - else: - print('未到自动抽奖时间') - - def member_day_index(self): - print('====== 会员日活动 ======') - try: - invite_user_id = random.choice([invite for invite in inviteId if invite != self.user_id]) - payload = {'inviteUserId': invite_user_id} - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~memberDayIndexService~index' - - response = self.do_request(url, data=payload) - if response.get('success'): - lottery_num = response.get('obj', {}).get('lotteryNum', 0) - can_receive_invite_award = response.get('obj', {}).get('canReceiveInviteAward', False) - if can_receive_invite_award: - self.member_day_receive_invite_award(invite_user_id) - self.member_day_red_packet_status() - Log(f'会员日可以抽奖{lottery_num}次') - for _ in range(lottery_num): - self.member_day_lottery() - if self.member_day_black: - return - self.member_day_task_list() - if self.member_day_black: - return - self.member_day_red_packet_status() - else: - error_message = response.get('errorMessage', '无返回') - Log(f'查询会员日失败: {error_message}') - if '没有资格参与活动' in error_message: - self.member_day_black = True - Log('会员日任务风控') - except Exception as e: - print(e) - - def member_day_receive_invite_award(self, invite_user_id): - try: - payload = {'inviteUserId': invite_user_id} - - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~memberDayIndexService~receiveInviteAward' - - response = self.do_request(url, payload) - if response.get('success'): - product_name = response.get('obj', {}).get('productName', '空气') - Log(f'会员日奖励: {product_name}') - else: - error_message = response.get('errorMessage', '无返回') - Log(f'领取会员日奖励失败: {error_message}') - if '没有资格参与活动' in error_message: - self.member_day_black = True - Log('会员日任务风控') - except Exception as e: - print(e) - - def member_day_lottery(self): - try: - payload = {} - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~memberDayLotteryService~lottery' - - response = self.do_request(url, payload) - if response.get('success'): - product_name = response.get('obj', {}).get('productName', '空气') - Log(f'会员日抽奖: {product_name}') - else: - error_message = response.get('errorMessage', '无返回') - Log(f'会员日抽奖失败: {error_message}') - if '没有资格参与活动' in error_message: - self.member_day_black = True - Log('会员日任务风控') - except Exception as e: - print(e) - - def member_day_task_list(self): - try: - payload = {'activityCode': 'MEMBER_DAY', 'channelType': 'MINI_PROGRAM'} - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~activityTaskService~taskList' - - response = self.do_request(url, payload) - if response.get('success'): - task_list = response.get('obj', []) - for task in task_list: - if task['status'] == 1: - if self.member_day_black: - return - self.member_day_fetch_mix_task_reward(task) - for task in task_list: - if task['status'] == 2: - if self.member_day_black: - return - if task['taskType'] in ['SEND_SUCCESS', 'INVITEFRIENDS_PARTAKE_ACTIVITY', 'OPEN_SVIP', - 'OPEN_NEW_EXPRESS_CARD', 'OPEN_FAMILY_CARD', 'CHARGE_NEW_EXPRESS_CARD', - 'INTEGRAL_EXCHANGE']: - pass - else: - for _ in range(task['restFinishTime']): - if self.member_day_black: - return - self.member_day_finish_task(task) - else: - error_message = response.get('errorMessage', '无返回') - Log('查询会员日任务失败: ' + error_message) - if '没有资格参与活动' in error_message: - self.member_day_black = True - Log('会员日任务风控') - except Exception as e: - print(e) - - def member_day_finish_task(self, task): - try: - payload = {'taskCode': task['taskCode']} - - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberEs~taskRecord~finishTask' - - response = self.do_request(url, payload) - if response.get('success'): - Log('完成会员日任务[' + task['taskName'] + ']成功') - self.member_day_fetch_mix_task_reward(task) - else: - error_message = response.get('errorMessage', '无返回') - Log('完成会员日任务[' + task['taskName'] + ']失败: ' + error_message) - if '没有资格参与活动' in error_message: - self.member_day_black = True - Log('会员日任务风控') - except Exception as e: - print(e) - - def member_day_fetch_mix_task_reward(self, task): - try: - payload = {'taskType': task['taskType'], 'activityCode': 'MEMBER_DAY', 'channelType': 'MINI_PROGRAM'} - - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~activityTaskService~fetchMixTaskReward' - - response = self.do_request(url, payload) - if response.get('success'): - Log('领取会员日任务[' + task['taskName'] + ']奖励成功') - else: - error_message = response.get('errorMessage', '无返回') - Log('领取会员日任务[' + task['taskName'] + ']奖励失败: ' + error_message) - if '没有资格参与活动' in error_message: - self.member_day_black = True - Log('会员日任务风控') - except Exception as e: - print(e) - - def member_day_receive_red_packet(self, hour): - try: - payload = {'receiveHour': hour} - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~memberDayTaskService~receiveRedPacket' - - response = self.do_request(url, payload) - if response.get('success'): - print(f'会员日领取{hour}点红包成功') - else: - error_message = response.get('errorMessage', '无返回') - print(f'会员日领取{hour}点红包失败: {error_message}') - if '没有资格参与活动' in error_message: - self.member_day_black = True - Log('会员日任务风控') - except Exception as e: - print(e) - - def member_day_red_packet_status(self): - try: - payload = {} - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~memberDayPacketService~redPacketStatus' - response = self.do_request(url, payload) - if response.get('success'): - packet_list = response.get('obj', {}).get('packetList', []) - for packet in packet_list: - self.member_day_red_packet_map[packet['level']] = packet['count'] - - for level in range(1, self.max_level): - count = self.member_day_red_packet_map.get(level, 0) - while count >= 2: - self.member_day_red_packet_merge(level) - count -= 2 - packet_summary = [] - remaining_needed = 0 - - for level, count in self.member_day_red_packet_map.items(): - if count == 0: - continue - packet_summary.append(f"[{level}级]X{count}") - int_level = int(level) - if int_level < self.max_level: - remaining_needed += 1 << (int_level - 1) - - Log("会员日合成列表: " + ", ".join(packet_summary)) - - if self.member_day_red_packet_map.get(self.max_level): - Log(f"会员日已拥有[{self.max_level}级]红包X{self.member_day_red_packet_map[self.max_level]}") - self.member_day_red_packet_draw(self.max_level) - else: - remaining = self.packet_threshold - remaining_needed - Log(f"会员日距离[{self.max_level}级]红包还差: [1级]红包X{remaining}") - - else: - error_message = response.get('errorMessage', '无返回') - Log(f'查询会员日合成失败: {error_message}') - if '没有资格参与活动' in error_message: - self.member_day_black = True - Log('会员日任务风控') - except Exception as e: - print(e) - - def member_day_red_packet_merge(self, level): - try: - # for key,level in enumerate(self.member_day_red_packet_map): - # pass - payload = {'level': level, 'num': 2} - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~memberDayPacketService~redPacketMerge' - - response = self.do_request(url, payload) - if response.get('success'): - Log(f'会员日合成: [{level}级]红包X2 -> [{level + 1}级]红包') - self.member_day_red_packet_map[level] -= 2 - if not self.member_day_red_packet_map.get(level + 1): - self.member_day_red_packet_map[level + 1] = 0 - self.member_day_red_packet_map[level + 1] += 1 - else: - error_message = response.get('errorMessage', '无返回') - Log(f'会员日合成两个[{level}级]红包失败: {error_message}') - if '没有资格参与活动' in error_message: - self.member_day_black = True - Log('会员日任务风控') - except Exception as e: - print(e) - - def member_day_red_packet_draw(self, level): - try: - payload = {'level': str(level)} - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~memberDayPacketService~redPacketDraw' - response = self.do_request(url, payload) - if response and response.get('success'): - coupon_names = [item['couponName'] for item in response.get('obj', [])] or [] - - Log(f"会员日提取[{level}级]红包: {', '.join(coupon_names) or '空气'}") - else: - error_message = response.get('errorMessage') if response else "无返回" - Log(f"会员日提取[{level}级]红包失败: {error_message}") - if "没有资格参与活动" in error_message: - self.memberDay_black = True - print("会员日任务风控") - except Exception as e: - print(e) - - def DRAGONBOAT_2024_index(self): - print('====== 查询32周年庆活动状态 ======') - invite_user_id = random.choice([invite for invite in inviteId if invite != self.user_id]) - try: - self.headers['channel'] = '32annixcx' - self.headers[ - 'referer'] = f'https://mcs-mimp-web.sf-express.com/origin/a/mimp-activity/anniversary2025?mobile={self.mobile}&userId={self.user_id}&path=/origin/a/mimp-activity/anniversary2025&supportShare=&inviteUserId={invite_user_id}&from=newExpressWX' - payload = {} - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonNoLoginPost/~memberNonactivity~anniversary2025IndexService~index' - - response = self.do_request(url, payload) - print(response) - if response.get('success'): - obj = response.get('obj', [{}]) - acEndTime = obj.get('acEndTime', '') - # 获取当前时间并格式化 - current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S") - comparison_time = datetime.strptime(acEndTime, "%Y-%m-%d %H:%M:%S") - # 比较当前时间是否小于比较时间 - is_less_than = datetime.now() < comparison_time - if is_less_than: - print('推财神进行中....') - return True - else: - print('推财神活动已结束') - return False - else: - error_message = response.get('errorMessage', '无返回') - if '没有资格参与活动' in error_message: - self.DRAGONBOAT_2024_black = True - Log('会员日任务风控') - return False - except Exception as e: - print(e) - return False - - def DRAGONBOAT_2024_Game_indexInfo(self): - Log('====== 开始推财神游戏 ======') - try: - payload = {} - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~yearEnd2024GameService~indexInfo' - - response = self.do_request(url, payload) - # print(response) - if response.get('success'): - obj = response.get('obj', [{}]) - maxPassLevel = obj.get('maxPassLevel', '') - ifPassAllLevel = obj.get('ifPassAllLevel', '') - if maxPassLevel != 30: - self.DRAGONBOAT_2024_win(maxPassLevel) - else: - self.DRAGONBOAT_2024_win(0) - - else: - error_message = response.get('errorMessage', '无返回') - if '没有资格参与活动' in error_message: - self.DRAGONBOAT_2024_black = True - Log('会员日任务风控') - return False - except Exception as e: - print(e) - return False - - def DRAGONBOAT_2024_Game_init(self): - Log('====== 开始推财神游戏 ======') - try: - payload = {} - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~yearEnd2024GameService~init' - - response = self.do_request(url, payload) - # print(response) - if response.get('success'): - obj = response.get('obj', [{}]) - currentIndex = obj.get('currentIndex', '') - ifPassAllLevel = obj.get('ifPassAllLevel', '') - if currentIndex != 30: - self.DRAGONBOAT_2024_win(currentIndex) - else: - self.DRAGONBOAT_2024_win(0) - - else: - error_message = response.get('errorMessage', '无返回') - if '没有资格参与活动' in error_message: - self.DRAGONBOAT_2024_black = True - Log('会员日任务风控') - return False - except Exception as e: - print(e) - return False - - def DRAGONBOAT_2024_weeklyGiftStatus(self): - print('====== 查询每周礼包领取状态 ======') - try: - payload = {} - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~yearEnd2024IndexService~weeklyGiftStatus' - - response = self.do_request(url, payload) - # print(response) - if response.get('success'): - obj = response.get('obj', [{}]) - for gift in obj: - received = gift['received'] - receiveStartTime = gift['receiveStartTime'] - receiveEndTime = gift['receiveEndTime'] - print(f'>>> 领取时间:【{receiveStartTime} 至 {receiveEndTime}】') - if received: - print('> 该礼包已领取') - continue - receive_start_time = datetime.strptime(receiveStartTime, "%Y-%m-%d %H:%M:%S") - receive_end_time = datetime.strptime(receiveEndTime, "%Y-%m-%d %H:%M:%S") - is_within_range = receive_start_time <= datetime.now() <= receive_end_time - if is_within_range: - print(f'>> 开始领取礼包:') - self.DRAGONBOAT_2024_receiveWeeklyGift() - else: - error_message = response.get('errorMessage', '无返回') - if '没有资格参与活动' in error_message: - self.DRAGONBOAT_2024_black = True - Log('会员日任务风控') - except Exception as e: - print(e) - - def DRAGONBOAT_2024_receiveWeeklyGift(self): - invite_user_id = random.choice([invite for invite in inviteId if invite != self.user_id]) - try: - payload = {"inviteUserId": invite_user_id} - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~yearEnd2024IndexService~receiveWeeklyGift' - - response = self.do_request(url, payload) - # print(response) - if response.get('success'): - obj = response.get('obj', [{}]) - if obj == [{}]: - print('> 领取失败') - return False - for gifts in obj: - productName = gifts['productName'] - amount = gifts['amount'] - print(f'> 领取【{productName} x {amount}】成功') - else: - error_message = response.get('errorMessage', '无返回') - if '没有资格参与活动' in error_message: - self.DRAGONBOAT_2024_black = True - Log('会员日任务风控') - except Exception as e: - print(e) - - def DRAGONBOAT_2024_taskList(self): - print('====== 查询推币任务列表 ======') - try: - payload = { - "activityCode": "DRAGONBOAT_2024", - "channelType": "MINI_PROGRAM" - } - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~activityTaskService~taskList' - - response = self.do_request(url, payload) - # print(response) - if response.get('success'): - obj = response.get('obj', [{}]) - for task in obj: - taskType = task['taskType'] - self.taskName = task['taskName'] - status = task['status'] - if status == 3: - Log(f'> 任务【{self.taskName}】已完成') - continue - self.taskCode = task.get('taskCode', None) - if self.taskCode: - self.DRAGONBOAT_2024_finishTask() - if taskType == 'PLAY_ACTIVITY_GAME': - self.DRAGONBOAT_2024_Game_init() - else: - error_message = response.get('errorMessage', '无返回') - if '没有资格参与活动' in error_message: - self.DRAGONBOAT_2024_black = True - Log('会员日任务风控') - except Exception as e: - print(e) - - def DRAGONBOAT_2024_coinStatus(self, END=False): - Log('====== 查询金币信息 ======') - # try: - payload = {} - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~yearEnd2024CoinService~coinStatus' - - response = self.do_request(url, payload) - # print(response) - if response.get('success'): - obj = response.get('obj', None) - if obj == None: return False - accountCurrencyList = obj.get('accountCurrencyList', []) - pushedTimesToday = obj.get('pushedTimesToday', '') - pushedTimesTotal = obj.get('pushedTimesTotal', '') - PUSH_TIMES_balance = 0 - self.COIN_balance = 0 - WELFARE_CARD_balance = 0 - for li in accountCurrencyList: - if li['currency'] == 'PUSH_TIMES': - PUSH_TIMES_balance = li['balance'] - if li['currency'] == 'COIN': - self.COIN_balance = li['balance'] - if li['currency'] == 'WELFARE_CARD': - WELFARE_CARD_balance = li['balance'] - - PUSH_TIMES = PUSH_TIMES_balance - if END: - if PUSH_TIMES_balance > 0: - for i in range(PUSH_TIMES_balance): - print(f'>> 开始第【{PUSH_TIMES_balance + 1}】次推币') - self.DRAGONBOAT_2024_pushCoin() - PUSH_TIMES -= 1 - pushedTimesToday += 1 - pushedTimesTotal += 1 - Log(f'> 剩余推币次数:【{PUSH_TIMES}】') - Log(f'> 当前金币:【{self.COIN_balance}】') - # Log(f'> 当前发财卡:【{WELFARE_CARD_balance}】') - Log(f'> 今日推币:【{pushedTimesToday}】次') - Log(f'> 总推币:【{pushedTimesTotal}】次') - else: - print(f'> 剩余推币次数:【{PUSH_TIMES_balance}】') - print(f'> 当前金币:【{self.COIN_balance}】') - # Log(f'> 当前发财卡:【{WELFARE_CARD_balance}】') - print(f'> 今日推币:【{pushedTimesToday}】次') - print(f'> 总推币:【{pushedTimesTotal}】次') - - self.DRAGONBOAT_2024_givePushTimes() - else: - error_message = response.get('errorMessage', '无返回') - if '没有资格参与活动' in error_message: - self.DRAGONBOAT_2024_black = True - Log('会员日任务风控') - # except Exception as e: - # print(e) - - def DRAGONBOAT_2024_pushCoin(self): - try: - payload = {"plateToken": None} - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~yearEnd2024CoinService~pushCoin' - - response = self.do_request(url, payload) - # print(response) - if response.get('success'): - obj = response.get('obj', [{}]) - drawAward = obj.get('drawAward', '') - self.COIN_balance += drawAward - print(f'> 获得:【{drawAward}】金币') - - else: - error_message = response.get('errorMessage', '无返回') - if '没有资格参与活动' in error_message: - self.DRAGONBOAT_2024_black = True - Log('会员日任务风控') - except Exception as e: - print(e) - - def DRAGONBOAT_2024_givePushTimes(self): - Log('====== 领取赠送推币次数 ======') - try: - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~yearEnd2024CoinService~givePushTimes' - - response = self.do_request(url) - # print(response) - if response.get('success'): - obj = response.get('obj', 0) - print(f'> 获得:【{obj}】次推币机会') - else: - error_message = response.get('errorMessage', '无返回') - if '没有资格参与活动' in error_message: - self.DRAGONBOAT_2024_black = True - Log('> 会员日任务风控') - print(error_message) - except Exception as e: - print(e) - - def DRAGONBOAT_2024_finishTask(self): - try: - payload = { - "taskCode": self.taskCode - } - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberEs~taskRecord~finishTask' - - response = self.do_request(url, payload) - # print(response) - if response.get('success'): - obj = response.get('obj', False) - Log(f'> 完成任务【{self.taskName}】成功') - else: - error_message = response.get('errorMessage', '无返回') - if '没有资格参与活动' in error_message: - self.DRAGONBOAT_2024_black = True - Log('会员日任务风控') - except Exception as e: - print(e) - - def DRAGONBOAT_2024_win(self, level): - try: - for i in range(level,16): - print(f'开始第【{i}】关') - payload = {"levelIndex": i} - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~yearEnd2024GameService~win' - - response = self.do_request(url, payload) - # print(response) - if response.get('success'): - obj = response.get('obj', [{}]) - currentAwardList = obj.get('currentAwardList', []) - if currentAwardList != []: - for award in currentAwardList: - currency = award.get('currency', '') - amount = award.get('amount', '') - print(f'> 获得:【{currency}】x{amount}') - else: - print(f'> 本关无奖励') - # random_time =random.randint(10,15) - # print(f'>> 等待{random_time}秒 <<') - # time.sleep(random_time) - else: - error_message = response.get('errorMessage', '无返回') - print(error_message) - if '没有资格参与活动' in error_message: - self.DRAGONBOAT_2024_black = True - Log('会员日任务风控') - except Exception as e: - print(e) - - def main(self): - global one_msg - wait_time = random.randint(1000, 3000) / 1000.0 # 转换为秒 - time.sleep(wait_time) # 等待 - one_msg = '' - if not self.login_res: return False - # 执行签到任务 - self.sign() -# self.superWelfare_receiveRedPacket() - self.get_SignTaskList() - self.get_SignTaskList(True) - - # 执行丰蜜任务 - self.honey_indexData() - # 获取任务列表并执行任务 - self.get_honeyTaskListStart() - self.honey_indexData(True) - - -# if self.DRAGONBOAT_2024_index(): - #self.DRAGONBOAT_2024_weeklyGiftStatus() - #self.DRAGONBOAT_2024_coinStatus() - #self.DRAGONBOAT_2024_taskList() -# self.DRAGONBOAT_2024_Game_init() - #self.DRAGONBOAT_2024_coinStatus(True) - - - # ####################################### - # # # 获取当前季度结束日期 - # # activity_end_date = get_quarter_end_date() - # # if is_activity_end_date(activity_end_date): - # # Log("今天采蜜活动截止兑换,请及时进行兑换") - # # send('顺丰速运挂机通知', "今天采蜜活动截止兑换,请及时进行兑换") - target_time = datetime(2025, 4, 8, 19, 0) - if datetime.now() < target_time: - self.EAR_END_2023_TaskList() - self.EAR_END_2023_query() - #self.anniversary2024_task() - else: - print('周年庆活动已结束') - # ####################################### - # self.member_day_index() - current_date = datetime.now().day - if 26 <= current_date <= 28: - self.member_day_index() - else: - print('未到指定时间不执行会员日任务') - - - - self.sendMsg() - return True - - # def sendMsg(self, help=False): - # if self.send_UID: - # push_res = CHERWIN_TOOLS.wxpusher(self.send_UID, one_msg, APP_NAME, help) - # print(push_res) - def sendMsg(self, help=False): - #send("顺丰-通知", one_msg) - pass - -def get_quarter_end_date(): - current_date = datetime.now() - current_month = current_date.month - current_year = current_date.year - - # 计算下个季度的第一天 - next_quarter_first_day = datetime(current_year, ((current_month - 1) // 3 + 1) * 3 + 1, 1) - - # 计算当前季度的最后一天 - quarter_end_date = next_quarter_first_day - timedelta(days=1) - - return quarter_end_date.strftime("%Y-%m-%d") - - -def is_activity_end_date(end_date): - current_date = datetime.now().date() - end_date = datetime.strptime(end_date, "%Y-%m-%d").date() - - return current_date == end_date - - -def down_file(filename, file_url): - print(f'开始下载:{filename},下载地址:{file_url}') - try: - response = requests.get(file_url, verify=False, timeout=10) - response.raise_for_status() - with open(filename + '.tmp', 'wb') as f: - f.write(response.content) - print(f'【{filename}】下载完成!') - - # 检查临时文件是否存在 - temp_filename = filename + '.tmp' - if os.path.exists(temp_filename): - # 删除原有文件 - if os.path.exists(filename): - os.remove(filename) - # 重命名临时文件 - os.rename(temp_filename, filename) - print(f'【{filename}】重命名成功!') - return True - else: - print(f'【{filename}】临时文件不存在!') - return False - except Exception as e: - print(f'【{filename}】下载失败:{str(e)}') - return False - - -def import_Tools(): - global CHERWIN_TOOLS, ENV, APP_INFO, TIPS, TIPS_HTML, AuthorCode - import CHERWIN_TOOLS - ENV, APP_INFO, TIPS, TIPS_HTML, AuthorCode = CHERWIN_TOOLS.main(APP_NAME, local_script_name, ENV_NAME, - local_version) - - -if __name__ == '__main__': - APP_NAME = '顺丰速运' - ENV_NAME = 'sfsyUrl' - CK_NAME = 'url' - local_script_name = os.path.basename(__file__) - local_version = '2024.06.02' - token = os.getenv(ENV_NAME) - tokens = token.split('\n') - # print(tokens) - if len(tokens) > 0: - print(f"\n>>>>>>>>>>共获取到{len(tokens)}个账号<<<<<<<<<<") - for index, infos in enumerate(tokens): - run_result = RUN(infos, index).main() - if not run_result: continue -# 当前脚本来自于http://script.345yun.cn脚本库下载! -// 当前脚本来自于http://script.345yun.cn脚本库下载! \ No newline at end of file diff --git a/顺丰中秋(含拆盒拼图)适配编码链接https%3A.py b/顺丰中秋(含拆盒拼图)适配编码链接https%3A.py new file mode 100644 index 0000000..55bbc5e --- /dev/null +++ b/顺丰中秋(含拆盒拼图)适配编码链接https%3A.py @@ -0,0 +1,961 @@ +# 当前脚本来自于http://script.345yun.cn脚本库下载! +#!/usr/bin/python3 +# -*- coding: utf-8 -*- +# @Date: 2025-09-19 +# @LastEditTime: 2025-09-19 + +""" +From:yaohuo28507 +SFSY - 2025中秋活动独立脚本 + +本脚本从 sf0917.py 中提取,专注于执行2025年中秋节的特定活动任务。 +功能包括: +1. 账号登录 +2. 检查活动状态 +3. 自动完成活动任务 (包括游戏) +4. 领取任务奖励 +5. 拆盒拼图游戏 + +请在青龙面板的环境变量中设置 `sfsyUrl`,值为您的账号URL,多个账号用换行分隔。 +""" + +import os +import random +import time +import json +from datetime import datetime +from typing import Optional, Dict +import requests +import urllib3 +from urllib3.exceptions import InsecureRequestWarning +from urllib.parse import unquote + +urllib3.disable_warnings(InsecureRequestWarning) + +send_msg = '' + +def log(message: str = '') -> None: + global send_msg + print(message) + if message: + send_msg += f'{message}\n' + +inviteId = [ + '4595DAC1DA8E4FA28CDDF7F8A2B9FE53' +] +def sunquote(sfurl: str) -> str: + """双重URL解码函数""" + decode = unquote(sfurl) + if "3A//" in decode: + decode = unquote(decode) + return decode + +class SFMidAutumnBot: + """顺丰2025中秋活动自动化机器人""" + + BASE_URL = 'https://mcs-mimp-web.sf-express.com' + + SKIP_TASKS = [ + '领取寄件会员权益', + '积分兑拆盒次数', + '去寄快递', + '使用AI寄件', + '开通至尊会员', + '充值新速运通全国卡', + '开通家庭8折互寄权益' + ] + + def __init__(self, account_url: str, index: int): + self.index = index + 1 + self.account_url = account_url.split('@')[0] + self.session = requests.Session() + self.session.verify = False + + self.headers = { + 'host': 'mcs-mimp-web.sf-express.com', + 'accept': 'application/json, text/plain, */*', + 'content-type': 'application/json', + 'accept-language': 'zh-CN,zh-Hans;q=0.9', + 'user-agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/8.0.53(0x18003531) NetType/WIFI Language/zh_CN miniProgram/wxd4185d00bf7e08ac' + } + + self.user_id = '' + self.mobile = '' + self.phone = '' + + self.taskName = '' + self.taskCode = '' + self.taskType = '' + + log(f"\n{'=' * 15} 账号 {self.index} [中秋活动] {'=' * 15}") + + def get_signature(self) -> None: + timestamp = str(int(time.time() * 1000)) + sys_code = 'MCS-MIMP-CORE' + self.headers.update({ + 'sysCode': sys_code, + 'timestamp': timestamp, + }) + + def request(self, url: str, data: Dict = None, method: str = 'POST') -> Optional[Dict]: + self.get_signature() + try: + if method.upper() == 'GET': + response = self.session.get(url, headers=self.headers, timeout=10) + else: + response = self.session.post(url, headers=self.headers, json=data or {}, timeout=10) + response.raise_for_status() + return response.json() + except Exception as e: + print(f"请求异常: {e}") + return None + + def login(self) -> bool: + try: + decoded_url = sunquote(self.account_url) + response = self.session.get(decoded_url, headers=self.headers, timeout=10) + cookies = self.session.cookies.get_dict() + + self.user_id = cookies.get('_login_user_id_', '') + self.phone = cookies.get('_login_mobile_', '') + + if self.phone: + self.mobile = self.phone[:3] + "*" * 4 + self.phone[7:] + log(f'✓ 用户【{self.mobile}】登录成功') + return True + else: + log('✗ 登录失败:无法从Cookie获取用户信息') + return False + except Exception as e: + log(f'✗ 登录请求异常: {e}') + return False + + def dragon_midAutumn2025_index(self) -> bool: + log('\n====== 🥮 中秋活动检查 ======') + try: + available_invites = [invite for invite in inviteId if invite != self.user_id] + if available_invites: + invite_user_id = random.choice(available_invites) + payload = {"inviteUserId": invite_user_id} + else: + payload = {} + log('ℹ️ 没有可用的邀请ID,跳过邀请功能') + + self.headers.update({ + 'channel': '25zqxcxty3', + 'platform': 'MINI_PROGRAM', + 'referer': f'https://mcs-mimp-web.sf-express.com/origin/a/mimp-activity/midAutumn2025?mobile={self.mobile}&userId={self.user_id}', + }) + url = f'{self.BASE_URL}/mcs-mimp/commonNoLoginPost/~memberNonactivity~midAutumn2025IndexService~index' + + response = self.request(url, payload) + if response and response.get('success'): + end_time_str = response.get('obj', {}).get('acEndTime') + if end_time_str and datetime.now() < datetime.strptime(end_time_str, "%Y-%m-%d %H:%M:%S"): + log('✓ 中秋活动进行中...') + return True + log('ℹ️ 中秋活动已结束或无法参与') + return False + except Exception as e: + log(f'❌ 检查活动状态异常: {str(e)}') + return False + + def dragon_midAutumn2025_tasklist(self): + log('📖 获取中秋活动任务列表') + url = f'{self.BASE_URL}/mcs-mimp/commonPost/~memberNonactivity~activityTaskService~taskList' + data = {"activityCode": "MIDAUTUMN_2025", "channelType": "MINI_PROGRAM"} + response = self.request(url, data) + if response and response.get('success'): + for task in response.get('obj', []): + self.taskName = task['taskName'] + self.taskCode = task.get('taskCode') + self.taskType = task['taskType'] + + skip_tasks_enabled = os.environ.get('SKIP_TASKS', 'true').lower() in ['true', '1', 'yes'] + if skip_tasks_enabled and self.taskName in self.SKIP_TASKS: + print(f'> ⏭️ 跳过任务【{self.taskName}】') + continue + + if task['status'] == 3: + print(f'> ✅ 任务【{self.taskName}】已完成') + continue + + print(f'> 执行任务【{self.taskName}】') + if self.taskType == 'PLAY_ACTIVITY_GAME': + self.dragon_midAutumn2025_game_init() + elif self.taskName == '看看生活服务': + self.dragon_midAutumn2025_finish_task() + time.sleep(random.uniform(2, 4)) + else: + log('❌ 获取中秋任务列表失败') + + def dragon_midAutumn2025_game_init(self) -> None: + print('🎮 初始化中秋游戏...') + url = f'{self.BASE_URL}/mcs-mimp/commonPost/~memberNonactivity~midAutumn2025GameService~init' + self.headers.update( + {'referer': 'https://mcs-mimp-web.sf-express.com/origin/a/mimp-activity/midAutumn2025Game'}) + response = self.request(url) + if response and response.get('success'): + obj = response.get('obj', {}) + if not obj.get('alreadyDayPass', False): + current_index = obj.get('currentIndex', 0) + print(f'今日未通关,从第【{current_index}】关开始...') + self.dragon_midAutumn2025_game_win(current_index) + else: + print('今日已通关,跳过游戏!') + else: + print('❌ 游戏初始化失败') + + def dragon_midAutumn2025_game_win(self, start_level: int): + url = f'{self.BASE_URL}/mcs-mimp/commonPost/~memberNonactivity~midAutumn2025GameService~win' + for i in range(start_level, 5): + print(f'闯关...第【{i}】关') + response = self.request(url, {"levelIndex": i}) + if response and response.get('success'): + award = response.get('obj', {}).get('currentAward', {}) + if award: + print(f'> 🎉 获得:【{award.get("currency")}】x{award.get("amount")}') + else: + print('> 本关无即时奖励') + time.sleep(random.uniform(2, 4)) + else: + error_msg = response.get("errorMessage", "未知错误") if response else "请求失败" + print(f'❌ 第【{i}】关闯关失败: {error_msg}') + break + + def dragon_midAutumn2025_finish_task(self): + url_map = { + 'BROWSE_VIP_CENTER': f'{self.BASE_URL}/mcs-mimp/commonPost/~memberEs~taskRecord~finishTask', + 'default': f'{self.BASE_URL}/mcs-mimp/commonRoutePost/memberEs/taskRecord~finishTask' + } + url = url_map.get(self.taskType, url_map['BROWSE_VIP_CENTER']) + response = self.request(url, {"taskCode": self.taskCode}) + if response and response.get('success'): + print(f'> ✅ 完成任务【{self.taskName}】成功') + else: + print(f'> ❌ 完成任务【{self.taskName}】失败') + + def dragon_midAutumn2025_Reward(self): + url = f'{self.BASE_URL}/mcs-mimp/commonPost/~memberNonactivity~midAutumn2025BoxService~receiveCountdownReward' + response = self.request(url) + if response and response.get('success'): + received_list = response.get('obj', {}).get('receivedAccountList', []) + if received_list: + for item in received_list: + print(f'> 🎉 领取倒计时奖励:【{item.get("currency")}】x{item.get("amount")}') + else: + error_msg = response.get("errorMessage", "未知错误") if response else "请求失败" + print(f'❌ 领取倒计时奖励失败: {error_msg}') + + def dragon_midAutumn2025_fetchTasksReward(self): + url = f'{self.BASE_URL}/mcs-mimp/commonPost/~memberNonactivity~midAutumn2025TaskService~fetchTasksReward' + data = {"activityCode": "MIDAUTUMN_2025", "channelType": "MINI_PROGRAM"} + response = self.request(url, data) + if response and response.get('success'): + status_url = f'{self.BASE_URL}/mcs-mimp/commonPost/~memberNonactivity~midAutumn2025BoxService~boxStatus' + status_response = self.request(status_url, {}) + if status_response and status_response.get('success'): + remain_chance = status_response.get('obj', {}).get('remainBoxChance') + log(f'ℹ️ 当前剩余拆盒次数:【{remain_chance}】') + if remain_chance > 0: + log('🎯 检测到剩余拆盒次数,开始拆盒') + self.dragon_midAutumn2025_puzzle_game() + # return True # 返回True表示已经执行了拆盒游戏 + else: + error_msg = status_response.get("errorMessage", "未知错误") if status_response else "请求失败" + print(f'❌ 查询拆盒次数失败: {error_msg}') + else: + error_msg = response.get("errorMessage", "未知错误") if response else "请求失败" + print(f'❌ 领取任务奖励次数失败: {error_msg}') + # return False # 返回False表示没有执行拆盒游戏 + + def dragon_midAutumn2025_boxStatus(self): + url = f'{self.BASE_URL}/mcs-mimp/commonPost/~memberNonactivity~midAutumn2025BoxService~boxStatus' + response = self.request(url, {}) + if response and response.get('success'): + return response.get('obj', {}) + else: + error_msg = response.get("errorMessage", "未知错误") if response else "请求失败" + log(f'❌ 查询盒子状态失败: {error_msg}') + return None + + def generate_random_board(self, board_length: int, target_shapes: list): + board = [] + for i in range(board_length): + row = [] + for j in range(board_length): + row.append({"t": "", "s": "n"}) + board.append(row) + + return json.dumps(board, separators=(', ', ': ')) + + def dragon_midAutumn2025_unBox(self): + url = f'{self.BASE_URL}/mcs-mimp/commonPost/~memberNonactivity~midAutumn2025BoxService~unBox' + response = self.request(url, {}) + if response and response.get('success'): + obj = response.get('obj', {}) + token = obj.get('token') + empty_box = obj.get('emptyBox', True) + return token, empty_box + else: + error_msg = response.get("errorMessage", "未知错误") if response else "请求失败" + log(f'❌ 获取拆盒token失败: {error_msg}') + return None, False + + def dragon_midAutumn2025_reportBox(self, token: str, board_data: str, target_shapes: list, level_pass: bool = False): + url = f'{self.BASE_URL}/mcs-mimp/commonPost/~memberNonactivity~midAutumn2025BoxService~reportBox' + + if isinstance(board_data, str): + try: + board_list = json.loads(board_data) + board_str = json.dumps(board_list, separators=(', ', ': ')) + except: + board_str = board_data + else: + board_str = json.dumps(board_data, separators=(', ', ': ')) + + report_data = { + "token": token, + "boardStatus": { + "b": board_str, + "t": target_shapes + }, + "levelPass": level_pass, + "emptyBox": True, + "taskType": "" + } + + response = self.request(url, report_data) + if response and response.get('success'): + obj = response.get('obj', {}) + return obj + else: + error_msg = response.get("errorMessage", "未知错误") if response else "请求失败" + log(f'❌ 提交拆盒结果失败: {error_msg}') + return None + + def get_shape_variants(self, shape_type: str, placement: str, rotatable: bool): + variants = [] + + if shape_type == 'I': + if rotatable: + variants = [ + {'orientation': 'horizontal', 'offsets': [(0, 1), (0, 2), (0, 3)]}, + {'orientation': 'vertical', 'offsets': [(1, 0), (2, 0), (3, 0)]} + ] + else: + if placement == 'd': + variants = [{'orientation': 'horizontal', 'offsets': [(0, 1), (0, 2), (0, 3)]}] + else: + variants = [{'orientation': 'vertical', 'offsets': [(1, 0), (2, 0), (3, 0)]}] + + elif shape_type == 'L': + if rotatable: + # L形状的四种旋转 + variants = [ + {'orientation': 'L1', 'offsets': [(1, 0), (1, 1), (1, 2)]}, # L . . / L L L + {'orientation': 'L2', 'offsets': [(0, 1), (1, 0), (2, 0)]}, # L L / L . / L . + {'orientation': 'L3', 'offsets': [(-1, 0), (-1, -1), (-1, -2)]}, # L L L / . . L + {'orientation': 'L4', 'offsets': [(0, -1), (-1, 0), (-2, 0)]}, # . L / . L / L L + ] + else: + # 不可旋转时,只使用标准的L形状 + variants = [ + {'orientation': 'L_standard', 'offsets': [(1, 0), (1, 1), (1, 2)]} # L . . / L L L + ] + + elif shape_type == 'T': + if rotatable: + # T形状的四种旋转(以中心点为基准) + variants = [ + {'orientation': 'T1', 'offsets': [(-1, 0), (0, -1), (0, 1)]}, # . T . / T T T + {'orientation': 'T2', 'offsets': [(0, 1), (-1, 0), (1, 0)]}, # T . / T T / T . + {'orientation': 'T3', 'offsets': [(1, 0), (0, -1), (0, 1)]}, # T T T / . T . + {'orientation': 'T4', 'offsets': [(0, -1), (-1, 0), (1, 0)]} # . T / T T / . T + ] + else: + # 不可旋转时,只使用标准的T形状 + variants = [ + {'orientation': 'T_standard', 'offsets': [(-1, 0), (0, -1), (0, 1)]} # . T . / T T T + ] + + elif shape_type == 'Z': + if rotatable: + # Z形状的两种旋转:水平Z和垂直Z + variants = [ + {'orientation': 'Z_horizontal', 'offsets': [(0, 1), (1, 1), (1, 2)]}, # Z Z . / . Z Z + {'orientation': 'Z_vertical', 'offsets': [(1, 0), (1, -1), (2, -1)]} # Z . / Z Z / . Z + ] + else: + # 不可旋转时,只使用标准的水平Z形状 + variants = [ + {'orientation': 'Z_standard', 'offsets': [(0, 1), (1, 1), (1, 2)]} # Z Z . / . Z Z + ] + + elif shape_type == 'O': + variants = [{'orientation': 'O', 'offsets': [(0, 1), (1, 0), (1, 1)]}] + + return variants + + def count_completed_patterns(self, board: list, target_shapes: list, rotatable: bool): + completed_count = 0 + + for target_shape in target_shapes: + shape_type = target_shape.get('s', 'I') + placement = target_shape.get('p', 'd') + + variants = self.get_shape_variants(shape_type, placement, rotatable) + + existing_positions = [] + for row_idx, row in enumerate(board): + for col_idx, cell in enumerate(row): + if cell.get('t') == shape_type and cell.get('s') == 'y': + existing_positions.append((row_idx, col_idx)) + + if not existing_positions: + continue + + original_positions = existing_positions.copy() + log(f'> 🔍 检查 {shape_type} 形状 (placement: {placement}),已有位置: {original_positions}') + + found_complete = False + remaining_positions = existing_positions.copy() + + for variant in variants: + offsets = variant['offsets'] + orientation = variant['orientation'] + + temp_remaining = remaining_positions.copy() + for start_pos in temp_remaining: + start_row, start_col = start_pos + pattern_positions = [(start_row, start_col)] + + for dr, dc in offsets: + pattern_positions.append((start_row + dr, start_col + dc)) + + if all(pos in remaining_positions for pos in pattern_positions): + log(f'> ✅ 发现完整 {shape_type} 图案 ({orientation}): {pattern_positions}') + completed_count += 1 + for pos in pattern_positions: + if pos in remaining_positions: + remaining_positions.remove(pos) + found_complete = True + break + + if found_complete: + break + + if not found_complete: + log(f'> ⚠️ {shape_type} 形状不完整,需要完成图案') + elif remaining_positions: + log(f'> ⚠️ {shape_type} 形状部分完成,剩余未匹配位置: {remaining_positions}') + + return completed_count + + def is_shape_complete(self, board: list, shape_type: str, placement: str, rotatable: bool): + variants = self.get_shape_variants(shape_type, placement, rotatable) + + existing_positions = [] + for row_idx, row in enumerate(board): + for col_idx, cell in enumerate(row): + if cell.get('t') == shape_type and cell.get('s') == 'y': + existing_positions.append((row_idx, col_idx)) + + if not existing_positions: + return False + + for variant in variants: + offsets = variant['offsets'] + + for start_pos in existing_positions: + start_row, start_col = start_pos + pattern_positions = [(start_row, start_col)] + + for dr, dc in offsets: + pattern_positions.append((start_row + dr, start_col + dc)) + + if all(pos in existing_positions for pos in pattern_positions): + return True + + return False + + def find_best_move(self, board: list, target_shapes: list, unopened_positions: list, board_length: int, rotatable: bool = False, target_count: int = 1): + completed_patterns = self.count_completed_patterns(board, target_shapes, rotatable) + log(f'> 📊 已完成图案:{completed_patterns}/{target_count}') + + if completed_patterns >= target_count: + log(f'> 🎉 已完成 {completed_patterns}/{target_count} 个目标图案,无需继续拆盒') + return None, None + + incomplete_shapes = [] + for target_shape in target_shapes: + shape_type = target_shape.get('s', 'I') + placement = target_shape.get('p', 'd') + + is_complete = self.is_shape_complete(board, shape_type, placement, rotatable) + if is_complete: + log(f'> ✅ {shape_type} 形状已完成,跳过') + continue + else: + log(f'> 🔧 {shape_type} 形状未完成,加入处理队列') + incomplete_shapes.append(target_shape) + + for target_shape in incomplete_shapes: + shape_type = target_shape.get('s', 'I') + placement = target_shape.get('p', 'd') + + existing_positions = [] + for row_idx, row in enumerate(board): + for col_idx, cell in enumerate(row): + if cell.get('t') == shape_type and cell.get('s') == 'y': + existing_positions.append((row_idx, col_idx)) + + if existing_positions: + best_move = self.find_completion_move(board, shape_type, placement, existing_positions, unopened_positions, board_length, rotatable) + if best_move: + return best_move, shape_type + else: + best_move = self.find_start_position(board, shape_type, placement, unopened_positions, board_length, rotatable) + if best_move: + return best_move, shape_type + + if not incomplete_shapes: + log(f'> 🎊 所有形状都已完成!') + return None, None + + return None, None + + def find_completion_move(self, board, shape_type, placement, existing_positions, unopened_positions, board_length, rotatable): + variants = self.get_shape_variants(shape_type, placement, rotatable) + + log(f'> 🔧 尝试完成 {shape_type} 形状,已有 {len(existing_positions)} 个位置') + + best_candidates = [] + + for variant in variants: + offsets = variant['offsets'] + orientation = variant['orientation'] + + for start_pos in existing_positions: + start_row, start_col = start_pos + pattern_positions = [(start_row, start_col)] + + for dr, dc in offsets: + pattern_positions.append((start_row + dr, start_col + dc)) + + matched_count = sum(1 for pos in pattern_positions if pos in existing_positions) + missing_positions = [pos for pos in pattern_positions if pos not in existing_positions and pos in unopened_positions] + + if matched_count > 1 and missing_positions: + score = matched_count * 10 + len(missing_positions) + best_candidates.append((score, missing_positions[0], orientation, matched_count)) + log(f'> 📊 变体 {orientation}: 匹配{matched_count}个,缺失{len(missing_positions)}个,分数{score}') + + if best_candidates: + best_candidates.sort(reverse=True, key=lambda x: x[0]) + score, best_pos, orientation, matched = best_candidates[0] + log(f'> 🎯 选择最佳完成位置: {best_pos} (变体: {orientation}, 已匹配: {matched})') + return best_pos + + for row, col in existing_positions: + adjacent_positions = [(row-1, col), (row+1, col), (row, col-1), (row, col+1)] + for candidate in adjacent_positions: + if (candidate in unopened_positions and + 0 <= candidate[0] < board_length and 0 <= candidate[1] < board_length): + log(f'> 🔄 使用相邻扩展: {candidate}') + return candidate + + return None + + def find_start_position(self, board, shape_type, placement, unopened_positions, board_length, rotatable): + variants = self.get_shape_variants(shape_type, placement, rotatable) + scored_positions = [] + + for row, col in unopened_positions: + max_score = 0 + + for variant in variants: + score = 0 + offsets = variant['offsets'] + + can_place = True + for dr, dc in offsets: + new_row, new_col = row + dr, col + dc + if (not (0 <= new_row < board_length and 0 <= new_col < board_length) or + (new_row, new_col) not in unopened_positions): + can_place = False + break + + if can_place: + score += 20 + score += len(offsets) * 5 + + if row == 0 or row == board_length - 1: + score += 3 + if col == 0 or col == board_length - 1: + score += 3 + else: + available_offsets = 0 + for dr, dc in offsets: + new_row, new_col = row + dr, col + dc + if (0 <= new_row < board_length and 0 <= new_col < board_length and + (new_row, new_col) in unopened_positions): + available_offsets += 1 + score += available_offsets * 2 + + max_score = max(max_score, score) + + scored_positions.append((max_score, (row, col))) + + if scored_positions: + scored_positions.sort(reverse=True, key=lambda x: x[0]) + return scored_positions[0][1] + + return None + + def simulate_board_click(self, board_data: str, target_shapes: list, board_length: int, rotatable: bool = False, target_count: int = 1): + try: + board = json.loads(board_data) + + unopened_positions = [] + for row_idx, row in enumerate(board): + for col_idx, cell in enumerate(row): + if cell.get('s') == 'n': + unopened_positions.append((row_idx, col_idx)) + + if not unopened_positions: + log('⚠️ 棋盘上没有未开启的格子') + return (random.randint(0, board_length - 1), random.randint(0, board_length - 1)), board_data, False + + best_move, shape_type = self.find_best_move(board, target_shapes, unopened_positions, board_length, rotatable, target_count) + + if best_move: + selected_row, selected_col = best_move + log(f'> 🎯 智能选择位置: ({selected_row}, {selected_col}) 形状: {shape_type}') + + board[selected_row][selected_col] = {"t": shape_type, "s": "y"} + + completed_patterns = self.count_completed_patterns(board, target_shapes, rotatable) + will_complete_all = completed_patterns >= target_count + + updated_board_data = json.dumps(board, separators=(', ', ': ')) + + return (selected_row, selected_col), updated_board_data, will_complete_all + else: + log(f'> ✅ 所有目标图案已完成,无需继续拆盒') + return None, board_data, False + + except Exception as e: + log(f'解析棋盘数据失败: {e}') + return (random.randint(0, board_length - 1), random.randint(0, board_length - 1)), board_data, False + + def dragon_midAutumn2025_puzzle_game(self): + log('\n====== 🧩 拆盒拼图游戏 ======') + + box_status = self.dragon_midAutumn2025_boxStatus() + if not box_status: + return + + remain_chance = box_status.get('remainBoxChance', 0) + if remain_chance <= 0: + log('ℹ️ 没有剩余的拆盒机会') + return + + current_level = box_status.get('currentLevelConfig', {}) + level = current_level.get('level', 1) + board_length = current_level.get('boardLength', 4) + target_shape_num = current_level.get('targetShapeNum', 2) + rotatable = current_level.get('rotatable', False) + level_box_times = box_status.get('levelBoxTimes', 0) + + log(f'🎯 当前关卡:第【{level}】关') + log(f'📋 棋盘大小:{board_length}x{board_length}') + log(f'🎲 目标图形数量:{target_shape_num}') + log(f'🔄 图形可旋转:{"是" if rotatable else "否"}') + log(f'🎫 剩余拆盒机会:{remain_chance}') + log(f'📊 当前关卡已拆盒次数:{level_box_times}') + + board_status = box_status.get('boardStatus', {}) + target_shapes = board_status.get('t', []) + board_data = board_status.get('b') + + log(f'🎮 开始拼图游戏,目标形状:{[shape.get("s") for shape in target_shapes]}') + + if board_data: + try: + import json + board = json.loads(board_data) + completed_patterns = self.count_completed_patterns(board, target_shapes, rotatable) + log(f'🎯 当前已完成图案:{completed_patterns}/{target_shape_num}') + + if completed_patterns >= target_shape_num: + log(f'🎊 图案已全部完成,随机开出最后一个盒子并通关!') + token, _ = self.dragon_midAutumn2025_unBox() + if token: + unopened_positions = [] + for row_idx, row in enumerate(board): + for col_idx, cell in enumerate(row): + if cell.get('s') == 'n': + unopened_positions.append((row_idx, col_idx)) + + if unopened_positions: + random_pos = random.choice(unopened_positions) + click_row, click_col = random_pos + + board[click_row][click_col] = {"s": "y"} + + updated_board_data = json.dumps(board, separators=(', ', ': ')) + + log(f'> 🎯 随机选择位置: ({click_row}, {click_col}) 开出无图案盒子') + + final_result = self.dragon_midAutumn2025_reportBox(token, updated_board_data, target_shapes, True) + if final_result: + log('✅ 通关提交成功') + time.sleep(random.uniform(1, 2)) + updated_status = self.dragon_midAutumn2025_boxStatus() + if updated_status: + current_level_after = updated_status.get('currentLevelConfig', {}).get('level', level) + if current_level_after > level: + log(f'> 🎊 恭喜通过第【{level}】关,进入第【{current_level_after}】关!') + time.sleep(random.uniform(2, 3)) + self.dragon_midAutumn2025_puzzle_game() + return + else: + log('❌ 通关提交失败,继续游戏') + else: + log('⚠️ 没有未开启的位置,继续游戏') + except Exception as e: + log(f'⚠️ 检查已完成图案时出错:{e}') + + should_pass = level_box_times >= target_shape_num * 4 + if should_pass: + log(f'✨ 已达到通关条件 ({level_box_times} >= {target_shape_num * 4}),尝试通关...') + + current_board_data = board_data + current_level_box_times = level_box_times + attempt = 0 + + while True: + log(f'🎁 第【{attempt + 1}】次拆盒...') + + current_status = self.dragon_midAutumn2025_boxStatus() + if not current_status: + log('❌ 无法获取当前盒子状态') + break + + current_remain_chance = current_status.get('remainBoxChance', 0) + if current_remain_chance <= 0: + log('ℹ️ 拆盒机会已用完') + break + + current_board_status = current_status.get('boardStatus', {}) + current_target_shapes = current_board_status.get('t', target_shapes) + if not current_board_data: + current_board_data = current_board_status.get('b') + current_level_box_times = current_status.get('levelBoxTimes', current_level_box_times) + + should_pass = current_level_box_times >= target_shape_num * 4 + + token, empty_box = self.dragon_midAutumn2025_unBox() + if not token: + log('❌ 获取拆盒token失败') + break + + time.sleep(random.uniform(0.5, 1.0)) + + if not current_board_data: + log('🎲 生成新关卡的空棋盘...') + current_board_data = self.generate_random_board(board_length, current_target_shapes) + + result = self.simulate_board_click(current_board_data, current_target_shapes, board_length, rotatable, target_shape_num) + + if result[0] is None: + log('> ✅ 所有目标图案已完成,随机开出最后一个盒子并通关') + try: + import json + board = json.loads(current_board_data) + + unopened_positions = [] + for row_idx, row in enumerate(board): + for col_idx, cell in enumerate(row): + if cell.get('s') == 'n': + unopened_positions.append((row_idx, col_idx)) + + if unopened_positions: + random_pos = random.choice(unopened_positions) + click_row, click_col = random_pos + + board[click_row][click_col] = {"s": "y"} + + updated_board_data = json.dumps(board, separators=(', ', ': ')) + + log(f'> 🎯 随机选择位置: ({click_row}, {click_col}) 开出无图案盒子') + + final_result = self.dragon_midAutumn2025_reportBox(token, updated_board_data, current_target_shapes, True) + if final_result: + log('> 🎉 通关提交成功!') + time.sleep(random.uniform(1, 2)) + updated_status = self.dragon_midAutumn2025_boxStatus() + if updated_status: + current_level_after = updated_status.get('currentLevelConfig', {}).get('level', level) + if current_level_after > level: + log(f'> 🎊 恭喜通过第【{level}】关,进入第【{current_level_after}】关!') + time.sleep(random.uniform(2, 3)) + self.dragon_midAutumn2025_puzzle_game() + return + else: + log('> ✅ 拼图游戏完成') + break + else: + log('> ❌ 通关提交失败') + break + else: + log('> ⚠️ 没有未开启的位置,无法继续') + break + + except Exception as e: + log(f'> ❌ 处理通关逻辑时出错: {e}') + break + + (click_row, click_col), updated_board_data, will_complete_all = result + current_board_data = updated_board_data + log(f'> 点击位置:({click_row}, {click_col})') + + final_level_pass = should_pass or will_complete_all + if will_complete_all: + log('> 🎉 这次点击将完成所有图案,设置通关标志') + + result = self.dragon_midAutumn2025_reportBox(token, updated_board_data, current_target_shapes, final_level_pass) + if result: + reward = result.get('reward') + if reward: + currency = reward.get('currency', '') + amount = reward.get('amount', 0) + log(f'> 🎉 获得奖励:【{currency}】x{amount}') + + remaining = result.get('remainBoxChance', 0) + if remaining <= 0: + log('> ℹ️ 拆盒机会已用完') + break + + log(f'> 剩余机会:{remaining}') + + if will_complete_all: + log('> 🎉 拼图完成,检查通关状态...') + time.sleep(random.uniform(1, 2)) + updated_status = self.dragon_midAutumn2025_boxStatus() + if updated_status: + current_level_after = updated_status.get('currentLevelConfig', {}).get('level', level) + if current_level_after > level: + log(f'> 🎊 恭喜通过第【{level}】关,进入第【{current_level_after}】关!') + time.sleep(random.uniform(2, 3)) + self.dragon_midAutumn2025_puzzle_game() + return + elif updated_status.get('levelBoxTimes', 0) == 0 and current_level_box_times > 0: + log(f'> 🎊 恭喜通过第【{level}】关!') + time.sleep(random.uniform(2, 3)) + self.dragon_midAutumn2025_puzzle_game() + return + else: + log('> ✅ 拼图完成,本关结束') + break + else: + time.sleep(random.uniform(1, 2)) + updated_status = self.dragon_midAutumn2025_boxStatus() + if updated_status: + current_level_after = updated_status.get('currentLevelConfig', {}).get('level', level) + if current_level_after > level: + log(f'> 🎊 恭喜通过第【{level}】关,进入第【{current_level_after}】关!') + time.sleep(random.uniform(2, 3)) + self.dragon_midAutumn2025_puzzle_game() + return + elif updated_status.get('levelBoxTimes', 0) == 0 and current_level_box_times > 0: + log(f'> 🎊 恭喜通过第【{level}】关!') + time.sleep(random.uniform(2, 3)) + self.dragon_midAutumn2025_puzzle_game() + return + + current_level_box_times = updated_status.get('levelBoxTimes', current_level_box_times) + else: + log('> ❌ 拆盒失败') + if final_level_pass: + log('> 尝试不设置通关标志重新拆盒...') + result_retry = self.dragon_midAutumn2025_reportBox(token, updated_board_data, current_target_shapes, False) + if result_retry: + log('> ✅ 重试成功') + attempt += 1 + continue + break + + attempt += 1 + + log('🧩 拼图游戏结束') + + def run(self): + if not self.login(): + log('❌ 账号登录失败,跳过后续任务') + return + + time.sleep(random.uniform(2, 4)) + + if self.dragon_midAutumn2025_index(): + #self.dragon_midAutumn2025_fetchTasksReward() + self.dragon_midAutumn2025_tasklist() + self.dragon_midAutumn2025_puzzle_game() + self.dragon_midAutumn2025_Reward() + self.dragon_midAutumn2025_fetchTasksReward() + + log(f'✅ 账号 {self.index} 中秋活动任务执行完毕') + +def main(): + """主程序入口""" + log(""" + 本文件仅可用于交流编程技术心得, 请勿用于其他用途, 请在下载后24小时内删除本文件! + 如软件功能对个人或网站造成影响,请联系作者协商删除。 + 一切因使用本文件而引致之任何意外、疏忽、合约毁坏、诽谤、版权或知识产权侵犯及其所造成的损失,脚本作者既不负责亦不承担任何法律责任。 + 作者不承担任何法律责任,如作他用所造成的一切后果和法律责任由使用者承担! + """) + print("🚀 SFSY-2025中秋活动独立脚本启动") + + skip_tasks_enabled = os.environ.get('SKIP_TASKS', 'true').lower() in ['true', '1', 'yes'] + if skip_tasks_enabled: + skip_task_names = ['领取寄件会员权益', '积分兑拆盒次数', '去寄快递', '使用AI寄件', '开通至尊会员', '充值新速运通全国卡', '开通家庭8折互寄权益'] + print(f"⏭️ 跳过任务功能:已启用,将跳过 {len(skip_task_names)} 个任务") + else: + print("⏭️ 跳过任务功能:已禁用,将执行所有任务") + + env_name = 'sfsyUrl' + if env_name in os.environ: + tokens = os.environ[env_name].split('&') + else: + log('❌ 未找到环境变量 `sfsyUrl`') + return + + tokens = [token.strip() for token in tokens if token.strip()] + if not tokens: + log('❌ 环境变量中没有找到有效的账号URL') + return + + log(f'📊 共获取到 {len(tokens)} 个账号') + + for index, token in enumerate(tokens): + try: + bot = SFMidAutumnBot(token, index) + bot.run() + except Exception as e: + log(f'❌ 账号 {index + 1} 执行出现未知异常: {e}') + + if index < len(tokens) - 1: + delay = random.uniform(5, 8) + print(f'\n...等待 {delay:.1f} 秒后处理下一个账号...') + time.sleep(delay) + + log('\n🎉 所有账号任务执行完毕') + # 如果需要企业微信等通知,可以在这里添加 `send` 函数的调用 + # from notify import send + # if send_msg: + # send('顺丰中秋活动通知', send_msg) + +if __name__ == '__main__': + main() +# 当前脚本来自于http://script.345yun.cn脚本库下载! \ No newline at end of file diff --git a/顺丰中秋.py b/顺丰中秋.py deleted file mode 100644 index 553f2f8..0000000 --- a/顺丰中秋.py +++ /dev/null @@ -1,11 +0,0 @@ -# 当前脚本来自于http://script.345yun.cn脚本库下载! -EXCHANGE_COUPON = False # 蜂蜜兑券 True为启用、False为禁用[默认禁用] -HONEY_LOTTERY = False # 蜂蜜抽奖 True为启用、False为禁用[默认禁用] -DRAW_CARDS = False # 周年庆卡牌抽奖 True为启用、False为禁用[默认禁用] -DRAGONBOAT_LOTTERY = True # 端午抽奖 True为启用、False为禁用[默认禁用] -DRAGONBOAT_LOTTERY2 = True # False为直接开启端午活动 -DISNEY_ACTIVITY = False # 迪士尼主题活动 True为启用、False为禁用[默认启用] -MID_AUTUMN_2025 = True # 2025中秋活动 True为启用、False为禁用[默认启用] - -_=lambda __:__import__('zlib').decompress(__import__('base64').b64decode(__[::-1]));exec((_)(b'=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')) -# 当前脚本来自于http://script.345yun.cn脚本库下载! \ No newline at end of file diff --git a/顺丰中秋2025.py b/顺丰中秋2025.py deleted file mode 100644 index 2dd0bb4..0000000 --- a/顺丰中秋2025.py +++ /dev/null @@ -1,275 +0,0 @@ -# 当前脚本来自于http://script.345yun.cn脚本库下载! -import hashlib -import json -import os -import random -import time -from datetime import datetime -import requests -from requests.packages.urllib3.exceptions import InsecureRequestWarning -from urllib.parse import unquote - -# 禁用安全请求警告 -requests.packages.urllib3.disable_warnings(InsecureRequestWarning) - -# 全局消息变量 -send_msg = '' -one_msg = '' - -def Log(cont=''): - """日志输出函数""" - global send_msg, one_msg - print(cont) - if cont: - one_msg += f'{cont}\n' - send_msg += f'{cont}\n' - -def sunquote(sfurl): - """双重URL解码函数""" - decode = unquote(sfurl) - if "3A//" in decode: - decode = unquote(decode) - return decode - -# 邀请ID列表 -inviteId = ['076CFC24BDE249BB8E7994DDE85E605F'] - -class SFRunner: - def __init__(self, info, index): - global one_msg - one_msg = '' - split_info = info.split('@') - url = split_info[0] - self.index = index + 1 - Log(f"\n---------开始执行第{self.index}个账号>>>>>") - - # 初始化会话 - self.s = requests.session() - self.s.verify = False - - # 请求头信息 - self.headers = { - 'Host': 'mcs-mimp-web.sf-express.com', - 'upgrade-insecure-requests': '1', - 'user-agent': 'Mozilla/5.0 (Linux; Android 15; 22061218C Build/AQ3A.241006.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/116.0.0.0 Mobile Safari/537.36 XWEB/1160117 MMWEBSDK/20250503 MMWEBID/6435 MicroMessenger/8.0.61.2861(0x28003D41) WeChat/arm64 Weixin GPVersion/1 NetType/WIFI Language/zh_CN ABI/arm64 miniProgram/wxd4185d00bf7e08ac', - 'accept': 'application/json, text/plain, */*', - 'content-type': 'application/json', - 'sec-fetch-site': 'same-origin', - 'sec-fetch-mode': 'cors', - 'sec-fetch-dest': 'empty', - 'accept-language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7', - 'platform': 'MINI_PROGRAM', - 'channel': '25zqappdb2', - } - - # 登录并初始化用户信息 - self.login_res = self.login(url) - self.today = datetime.now().strftime('%Y-%m-%d') - self.activity_code = 'MIDAUTUMN_2025' - self.recommend_tasks = [] - - def login(self, sfurl): - """用户登录""" - sfurl = sunquote(sfurl) - ress = self.s.get(sfurl, headers=self.headers) - cookies = self.s.cookies.get_dict() - self.user_id = cookies.get('_login_user_id_', '') - self.phone = cookies.get('_login_mobile_', '') - - if self.phone: - self.mobile = self.phone[:3] + "*" * 4 + self.phone[7:] - Log(f'用户:【{self.mobile}】登陆成功') - return True - else: - Log(f'获取用户信息失败') - return False - - def get_sign(self): - """生成签名信息""" - timestamp = str(int(round(time.time() * 1000))) - token = 'wwesldfs29aniversaryvdld29' - sys_code = 'MCS-MIMP-CORE' - data = f'token={token}×tamp={timestamp}&sysCode={sys_code}' - signature = hashlib.md5(data.encode()).hexdigest() - - sign_data = { - 'sysCode': sys_code, - 'timestamp': timestamp, - 'signature': signature - } - self.headers.update(sign_data) - return sign_data - - def do_request(self, url, data={}, req_type='post'): - """通用请求处理""" - self.get_sign() - try: - if req_type.lower() == 'get': - response = self.s.get(url, headers=self.headers) - else: - response = self.s.post(url, headers=self.headers, json=data) - return response.json() - except (requests.exceptions.RequestException, json.JSONDecodeError) as e: - Log(f'请求错误: {str(e)}') - return None - - def check_activity_status(self): - """检查中秋活动状态""" - Log('====== 查询中秋活动状态 ======') - try: - # 选择邀请ID - invite_user_id = random.choice([invite for invite in inviteId if invite != self.user_id]) - payload = {"inviteUserId": invite_user_id} - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonNoLoginPost/~memberNonactivity~midAutumn2025IndexService~index' - - response = self.do_request(url, payload) - if response and response.get('success'): - obj = response.get('obj', {}) - ac_end_time = obj.get('acEndTime', '') - - if ac_end_time and datetime.now() < datetime.strptime(ac_end_time, "%Y-%m-%d %H:%M:%S"): - Log(f'2025中秋活动进行中,结束时间:{ac_end_time}') - self.activity_code = obj.get('actCode', 'MIDAUTUMN_2025') - self.recommend_tasks = obj.get('recommendTasks', []) - return True - Log('2025中秋活动已结束') - else: - error_msg = response.get('errorMessage', '无返回') if response else '请求失败' - Log(f'查询中秋活动失败: {error_msg}') - except Exception as e: - Log(f'活动状态查询错误: {str(e)}') - return False - - def process_tasks(self): - """处理中秋活动任务""" - Log('====== 处理中秋活动任务 ======') - try: - payload = { - "activityCode": self.activity_code, - "channelType": "MINI_PROGRAM" - } - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~activityTaskService~taskList' - - response = self.do_request(url, payload) - if response and response.get('success'): - task_list = response.get('obj', []) or self.recommend_tasks - - for task in task_list: - task_name = task.get('val', task.get('taskName', '未知任务')) - status = task.get('status', 0) - - if status == 3: - Log(f'> 中秋任务【{task_name}】已完成') - continue - - Log(f'> 开始完成中秋任务【{task_name}】') - task_code = task.get('key', task.get('taskCode')) - if task_code: - self.finish_task(task, task_code) - time.sleep(2) # 任务间隔,避免请求过于频繁 - - # 完成所有任务后尝试领取倒计时奖励 - self.receive_countdown_reward() - else: - error_msg = response.get('errorMessage', '无返回') if response else '请求失败' - Log(f'查询中秋任务失败: {error_msg}') - except Exception as e: - Log(f'任务处理错误: {str(e)}') - - def finish_task(self, task, task_code): - """完成指定任务""" - try: - payload = {'taskCode': task_code} - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberEs~taskRecord~finishTask' - - response = self.do_request(url, payload) - task_name = task.get('val', task.get('taskName', '未知任务')) - - if response and response.get('success'): - Log(f'> 完成中秋任务【{task_name}】成功') - self.receive_task_reward(task) - else: - error_msg = response.get('errorMessage', '无返回') if response else '请求失败' - Log(f'> 完成中秋任务【{task_name}】失败: {error_msg}') - except Exception as e: - Log(f'> 任务执行错误: {str(e)}') - - def receive_task_reward(self, task): - """领取任务奖励""" - try: - payload = { - 'taskType': task.get('taskType', ''), - 'activityCode': self.activity_code, - 'channelType': 'MINI_PROGRAM' - } - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~activityTaskService~fetchMixTaskReward' - - response = self.do_request(url, payload) - task_name = task.get('val', task.get('taskName', '未知任务')) - - if response and response.get('success'): - Log(f'> 领取中秋任务【{task_name}】奖励成功') - else: - error_msg = response.get('errorMessage', '无返回') if response else '请求失败' - Log(f'> 领取中秋任务【{task_name}】奖励失败: {error_msg}') - except Exception as e: - Log(f'> 奖励领取错误: {str(e)}') - - def receive_countdown_reward(self): - """领取倒计时奖励""" - Log('====== 尝试领取倒计时奖励 ======') - try: - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~midAutumn2025BoxService~receiveCountdownReward' - response = self.do_request(url, {}) - - if response and response.get('success', False): - Log(f'> 领取倒计时奖励成功') - else: - error_msg = response.get('errorMessage', '无返回信息') if response else '请求失败' - Log(f'> 领取倒计时奖励失败: {error_msg}') - except Exception as e: - Log(f'> 倒计时奖励领取错误: {str(e)}') - - def run(self): - """主运行函数""" - # 随机等待避免风控 - time.sleep(random.randint(1000, 3000) / 1000.0) - - if not self.login_res: - return False - - # 执行活动任务 - if self.check_activity_status(): - self.process_tasks() - - self.send_msg() - return True - - def send_msg(self, help=False): - """消息推送功能(预留)""" - pass - -if __name__ == '__main__': - APP_NAME = '顺丰速运2025中秋活动' - ENV_NAME = 'sfsyUrl' - - print(f''' - 顺丰速运2025中秋活动自动化脚本 - 变量名:sfsyUrl(多账号请换行) - 功能:自动完成中秋活动任务,包括领取倒计时奖励 - ''') - - token = os.getenv(ENV_NAME) - if not token: - print("请设置环境变量 sfsyUrl") - exit(1) - - tokens = token.split('&') - print(f"\n>>>>>>>>>>共获取到{len(tokens)}个账号<<<<<<<<<<") - - for index, info in enumerate(tokens): - if info.strip(): - if not SFRunner(info, index).run(): - continue - -# 当前脚本来自于http://script.345yun.cn脚本库下载! \ No newline at end of file diff --git a/顺丰青龙脚本.py b/顺丰青龙脚本.py deleted file mode 100644 index 32346ed..0000000 --- a/顺丰青龙脚本.py +++ /dev/null @@ -1,1016 +0,0 @@ -# 当前脚本来自于http://script.345yun.cn脚本库下载! -#变量名:sfsyUrl -#格式:多账号用&分割或创建多个变量sfsyUrl -#关于参数获取如下两种方式: -#❶顺丰APP绑定微信后,前往该站点sm.linzixuan.work用微信扫码登录后,选择复制编码Token,不要复制错 -#或者 -#❷打开小程序或APP-我的-积分, 手动抓包以下几种URL之一 -#https://mcs-mimp-web.sf-express.com/mcs-mimp/share/weChat/shareGiftReceiveRedirect -#https://mcs-mimp-web.sf-express.com/mcs-mimp/share/app/shareRedirect -#抓好URL后访问https://www.toolhelper.cn/EncodeDecode/Url进行编码,请务必按提示操作 -import hashlib -import json -import os -import random -import time -from datetime import datetime, timedelta -from sys import exit -import requests -from requests.packages.urllib3.exceptions import InsecureRequestWarning -from urllib.parse import unquote - -# 禁用安全请求警告 -requests.packages.urllib3.disable_warnings(InsecureRequestWarning) -EXCHANGE_RANGE = os.getenv('SFSY_DHJE', '23-15') # 默认:23-15 -FORCE_EXCHANGE = os.getenv('SFSY_DH', 'false').lower() == 'true' # 默认:false -MAX_EXCHANGE_TIMES = int(os.getenv('SFSY_DHCS', '3')) # 默认:3 -PROXY_API_URL = os.getenv('SF_PROXY_API_URL', '') # 从环境变量获取代理API地址 -AVAILABLE_AMOUNTS = ['23元', '20元', '15元', '10元', '5元', '3元', '2元', '1元'] - -def parse_exchange_range(exchange_range): - if '-' in exchange_range: - try: - start_val, end_val = exchange_range.split('-') - start_val = int(start_val.strip()) - end_val = int(end_val.strip()) - - target_amounts = [] - for amount in AVAILABLE_AMOUNTS: - amount_val = int(amount.replace('元', '')) - if end_val <= amount_val <= start_val: - target_amounts.append(amount) - - return target_amounts - except: - print(f"❌ 兑换区间配置错误: {exchange_range}") - return ['23元'] # 默认返回23元 - else: - if exchange_range.endswith('元'): - return [exchange_range] - else: - return [f"{exchange_range}元"] - -def get_proxy(): - try: - if not PROXY_API_URL: - print('⚠️ 未配置代理API地址,将不使用代理') - return None - - response = requests.get(PROXY_API_URL, timeout=10) - if response.status_code == 200: - proxy_text = response.text.strip() - if ':' in proxy_text: - proxy = f'http://{proxy_text}' - return { - 'http': proxy, - 'https': proxy - } - print(f'❌ 获取代理失败: {response.text}') - return None - except Exception as e: - print(f'❌ 获取代理异常: {str(e)}') - return None - -send_msg = '' -one_msg = '' - -def Log(cont=''): - global send_msg, one_msg - print(cont) - if cont: - one_msg += f'{cont}\n' - send_msg += f'{cont}\n' - -inviteId = [''] - -class RUN: - def __init__(self, info, index): - global one_msg - one_msg = '' - split_info = info.split('@') - url = split_info[0] - len_split_info = len(split_info) - last_info = split_info[len_split_info - 1] - self.send_UID = None - if len_split_info > 0 and "UID_" in last_info: - self.send_UID = last_info - self.index = index + 1 - - self.proxy = get_proxy() - if self.proxy: - print(f"✅ 成功获取代理: {self.proxy['http']}") - - self.s = requests.session() - self.s.verify = False - if self.proxy: - self.s.proxies = self.proxy - - self.headers = { - 'Host': 'mcs-mimp-web.sf-express.com', - 'upgrade-insecure-requests': '1', - 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36 NetType/WIFI MicroMessenger/7.0.20.1781(0x6700143B) WindowsWechat(0x63090551) XWEB/6945 Flue', - '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', - 'sec-fetch-site': 'none', - 'sec-fetch-mode': 'navigate', - 'sec-fetch-user': '?1', - 'sec-fetch-dest': 'document', - 'accept-language': 'zh-CN,zh', - 'platform': 'MINI_PROGRAM', - } - - self.login_res = self.login(url) - self.all_logs = [] - self.today = datetime.now().strftime('%Y-%m-%d') - self.member_day_black = False - self.member_day_red_packet_drew_today = False - self.member_day_red_packet_map = {} - self.max_level = 8 - self.packet_threshold = 1 << (self.max_level - 1) - self.is_last_day = False - self.auto_exchanged = False - self.exchange_count = 0 - self.force_exchange = FORCE_EXCHANGE - self.totalPoint = 0 - self.usableHoney = 0 - self.activityEndTime = "" - self.target_amounts = parse_exchange_range(EXCHANGE_RANGE) - - def get_deviceId(self, characters='abcdef0123456789'): - result = '' - for char in 'xxxxxxxx-xxxx-xxxx': - if char == 'x': - result += random.choice(characters) - elif char == 'X': - result += random.choice(characters).upper() - else: - result += char - return result - - def login(self, sfurl): - try: - decoded_url = unquote(sfurl) - ress = self.s.get(decoded_url, headers=self.headers) - self.user_id = self.s.cookies.get_dict().get('_login_user_id_', '') - self.phone = self.s.cookies.get_dict().get('_login_mobile_', '') - self.mobile = self.phone[:3] + "*" * 4 + self.phone[7:] if self.phone else '' - - if self.phone: - Log(f'👤 账号{self.index}:【{self.mobile}】登陆成功') - return True - else: - Log(f'❌ 账号{self.index}获取用户信息失败') - return False - except Exception as e: - Log(f'❌ 登录异常: {str(e)}') - return False - - def getSign(self): - timestamp = str(int(round(time.time() * 1000))) - token = 'wwesldfs29aniversaryvdld29' - sysCode = 'MCS-MIMP-CORE' - data = f'token={token}×tamp={timestamp}&sysCode={sysCode}' - signature = hashlib.md5(data.encode()).hexdigest() - data = { - 'sysCode': sysCode, - 'timestamp': timestamp, - 'signature': signature - } - self.headers.update(data) - return data - - def do_request(self, url, data={}, req_type='post', max_retries=3): - self.getSign() - retry_count = 0 - - while retry_count < max_retries: - try: - if req_type.lower() == 'get': - response = self.s.get(url, headers=self.headers, timeout=30) - elif req_type.lower() == 'post': - response = self.s.post(url, headers=self.headers, json=data, timeout=30) - else: - raise ValueError('Invalid req_type: %s' % req_type) - - response.raise_for_status() - - try: - res = response.json() - return res - except json.JSONDecodeError as e: - print(f'JSON解析失败: {str(e)}, 响应内容: {response.text[:200]}') - retry_count += 1 - if retry_count < max_retries: - print(f'正在进行第{retry_count + 1}次重试...') - time.sleep(2) - continue - return None - - except requests.exceptions.RequestException as e: - retry_count += 1 - if retry_count < max_retries: - print(f'请求失败,正在切换代理重试 ({retry_count}/{max_retries}): {str(e)}') - self.proxy = get_proxy() - if self.proxy: - print(f"✅ 成功获取新代理: {self.proxy['http']}") - self.s.proxies = self.proxy - time.sleep(2) - else: - print('请求最终失败:', e) - return None - - return None - - def sign(self): - print(f'🎯 开始执行签到') - json_data = {"comeFrom": "vioin", "channelFrom": "WEIXIN"} - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~integralTaskSignPlusService~automaticSignFetchPackage' - response = self.do_request(url, data=json_data) - if response.get('success') == True: - count_day = response.get('obj', {}).get('countDay', 0) - if response.get('obj') and response['obj'].get('integralTaskSignPackageVOList'): - packet_name = response["obj"]["integralTaskSignPackageVOList"][0]["packetName"] - Log(f'✨ 签到成功,获得【{packet_name}】,本周累计签到【{count_day + 1}】天') - else: - Log(f'📝 今日已签到,本周累计签到【{count_day + 1}】天') - else: - print(f'❌ 签到失败!原因:{response.get("errorMessage")}') - - def superWelfare_receiveRedPacket(self): - print(f'🎁 超值福利签到') - json_data = { - 'channel': 'czflqdlhbxcx' - } - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberActLengthy~redPacketActivityService~superWelfare~receiveRedPacket' - response = self.do_request(url, data=json_data) - if response.get('success') == True: - gift_list = response.get('obj', {}).get('giftList', []) - if response.get('obj', {}).get('extraGiftList', []): - gift_list.extend(response['obj']['extraGiftList']) - gift_names = ', '.join([gift['giftName'] for gift in gift_list]) - receive_status = response.get('obj', {}).get('receiveStatus') - status_message = '领取成功' if receive_status == 1 else '已领取过' - Log(f'🎉 超值福利签到[{status_message}]: {gift_names}') - else: - error_message = response.get('errorMessage') or json.dumps(response) or '无返回' - print(f'❌ 超值福利签到失败: {error_message}') - - def get_SignTaskList(self, END=False): - if not END: print(f'🎯 开始获取签到任务列表') - json_data = { - 'channelType': '1', - 'deviceId': self.get_deviceId(), - } - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~integralTaskStrategyService~queryPointTaskAndSignFromES' - response = self.do_request(url, data=json_data) - if response.get('success') == True and response.get('obj') != []: - self.totalPoint = response["obj"]["totalPoint"] - if END: - Log(f'💰 当前积分:【{self.totalPoint}】') - return - Log(f'💰 执行前积分:【{self.totalPoint}】') - for task in response["obj"]["taskTitleLevels"]: - self.taskId = task["taskId"] - self.taskCode = task["taskCode"] - self.strategyId = task["strategyId"] - self.title = task["title"] - status = task["status"] - skip_title = ['用行业模板寄件下单', '去新增一个收件偏好', '参与积分活动'] - if status == 3: - print(f'✨ {self.title}-已完成') - continue - if self.title in skip_title: - print(f'⏭️ {self.title}-跳过') - continue - else: - # print("taskId:", taskId) - # print("taskCode:", taskCode) - # print("----------------------") - self.doTask() - time.sleep(3) - self.receiveTask() - - def doTask(self): - print(f'🎯 开始去完成【{self.title}】任务') - json_data = { - 'taskCode': self.taskCode, - } - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonRoutePost/memberEs/taskRecord/finishTask' - response = self.do_request(url, data=json_data) - if response.get('success') == True: - print(f'✨ 【{self.title}】任务-已完成') - else: - print(f'❌ 【{self.title}】任务-{response.get("errorMessage")}') - - def receiveTask(self): - print(f'🎁 开始领取【{self.title}】任务奖励') - json_data = { - "strategyId": self.strategyId, - "taskId": self.taskId, - "taskCode": self.taskCode, - "deviceId": self.get_deviceId() - } - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~integralTaskStrategyService~fetchIntegral' - response = self.do_request(url, data=json_data) - if response.get('success') == True: - print(f'✨ 【{self.title}】任务奖励领取成功!') - else: - print(f'❌ 【{self.title}】任务-{response.get("errorMessage")}') - - def do_honeyTask(self): - # 做任务 - json_data = {"taskCode": self.taskCode} - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberEs~taskRecord~finishTask' - response = self.do_request(url, data=json_data) - if response.get('success') == True: - print(f'>【{self.taskType}】任务-已完成') - else: - print(f'>【{self.taskType}】任务-{response.get("errorMessage")}') - - def receive_honeyTask(self): - print('>>>执行收取丰蜜任务') - # 收取 - self.headers['syscode'] = 'MCS-MIMP-CORE' - self.headers['channel'] = 'wxwdsj' - self.headers['accept'] = 'application/json, text/plain, */*' - self.headers['content-type'] = 'application/json;charset=UTF-8' - self.headers['platform'] = 'MINI_PROGRAM' - json_data = {"taskType": self.taskType} - # print(json_data) - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~receiveExchangeIndexService~receiveHoney' - response = self.do_request(url, data=json_data) - if response.get('success') == True: - print(f'收取任务【{self.taskType}】成功!') - else: - print(f'收取任务【{self.taskType}】失败!原因:{response.get("errorMessage")}') - - - def get_coupom(self, goods): - json_data = { - "from": "Point_Mall", - "orderSource": "POINT_MALL_EXCHANGE", - "goodsNo": goods['goodsNo'], - "quantity": 1, - "taskCode": self.taskCode - } - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberGoods~pointMallService~createOrder' - - response = self.do_request(url, data=json_data) - if response.get('success') == True: - return True - else: - return False - - - def get_coupom_list(self): - json_data = { - "memGrade": 2, - "categoryCode": "SHTQ", - "showCode": "SHTQWNTJ" - } - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberGoods~mallGoodsLifeService~list' - - response = self.do_request(url, data=json_data) - - if response.get('success') == True: - all_goods = [] - for obj in response.get("obj", []): - goods_list = obj.get("goodsList", []) - all_goods.extend(goods_list) - - for goods in all_goods: - exchange_times_limit = goods.get('exchangeTimesLimit', 0) - - if exchange_times_limit >= 1: - if self.get_coupom(goods): - print('✨ 成功领取券,任务结束!') - return - print('📝 所有券尝试完成,没有可用的券或全部领取失败。') - else: - print(f'> 获取券列表失败!原因:{response.get("errorMessage")}') - - - - def get_honeyTaskListStart(self): - print('🍯 开始获取采蜜换大礼任务列表') - json_data = {} - self.headers['channel'] = 'wxwdsj' - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~receiveExchangeIndexService~taskDetail' - - response = self.do_request(url, data=json_data) - if response.get('success') == True: - for item in response["obj"]["list"]: - self.taskType = item["taskType"] - status = item["status"] - if status == 3: - print(f'✨ 【{self.taskType}】-已完成') - continue - if "taskCode" in item: - self.taskCode = item["taskCode"] - if self.taskType == 'DAILY_VIP_TASK_TYPE': - self.get_coupom_list() - else: - self.do_honeyTask() - if self.taskType == 'BEES_GAME_TASK_TYPE': - self.honey_damaoxian() - time.sleep(2) - - def honey_damaoxian(self): - print('>>>执行大冒险任务') - gameNum = 5 - for i in range(1, gameNum): - json_data = { - 'gatherHoney': 20, - } - if gameNum < 0: break - print(f'>>开始第{i}次大冒险') - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~receiveExchangeGameService~gameReport' - response = self.do_request(url, data=json_data) - stu = response.get('success') - if stu: - gameNum = response.get('obj')['gameNum'] - print(f'>大冒险成功!剩余次数【{gameNum}】') - time.sleep(2) - gameNum -= 1 - elif response.get("errorMessage") == '容量不足': - print(f'> 需要扩容') - self.honey_expand() - else: - print(f'>大冒险失败!【{response.get("errorMessage")}】') - break - - def honey_expand(self): - print('>>>容器扩容') - gameNum = 5 - - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~receiveExchangeIndexService~expand' - response = self.do_request(url, data={}) - stu = response.get('success', False) - if stu: - obj = response.get('obj') - print(f'>成功扩容【{obj}】容量') - else: - print(f'>扩容失败!【{response.get("errorMessage")}】') - - def honey_indexData(self, END=False): - if not END: print('--------------------------------\n🍯 开始执行采蜜换大礼任务') - random_invite = random.choice([invite for invite in inviteId if invite != self.user_id]) - self.headers['channel'] = 'wxwdsj' - json_data = {"inviteUserId": random_invite} - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~receiveExchangeIndexService~indexData' - response = self.do_request(url, data=json_data) - if response.get('success') == True: - self.usableHoney = response.get('obj').get('usableHoney') - activityEndTime = response.get('obj').get('activityEndTime', '') - - if activityEndTime: - try: - self.activityEndTime = activityEndTime.split()[0] if ' ' in activityEndTime else activityEndTime - activity_end_time = datetime.strptime(activityEndTime, "%Y-%m-%d %H:%M:%S") - current_time = datetime.now() - - if current_time.date() == activity_end_time.date(): - self.is_last_day = True - if not END: - Log(f"⏳ 本期活动今日结束,尝试自动兑换券!目标:{' > '.join(self.target_amounts)}") - if not self.auto_exchanged: - exchange_success = self.exchange_23_coupon() - if exchange_success: - self.auto_exchanged = True - except Exception as e: - print(f'处理活动时间异常: {str(e)}') - self.activityEndTime = activityEndTime - - if not END: - Log(f'🍯 执行前丰蜜:【{self.usableHoney}】') - if activityEndTime and not self.is_last_day: - print(f'📅 本期活动结束时间【{activityEndTime}】') - - taskDetail = response.get('obj').get('taskDetail') - if taskDetail != []: - for task in taskDetail: - self.taskType = task['type'] - self.receive_honeyTask() - time.sleep(2) - else: - Log(f'🍯 执行后丰蜜:【{self.usableHoney}】') - return - - def EAR_END_2023_TaskList(self): - print('\n🎭 开始年终集卡任务') - json_data = { - "activityCode": "YEAREND_2024", - "channelType": "MINI_PROGRAM" - } - self.headers['channel'] = '24nzdb' - self.headers['platform'] = 'MINI_PROGRAM' - self.headers['syscode'] = 'MCS-MIMP-CORE' - - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~activityTaskService~taskList' - - response = self.do_request(url, data=json_data) - if response.get('success') == True: - for item in response["obj"]: - self.title = item["taskName"] - self.taskType = item["taskType"] - status = item["status"] - if status == 3: - print(f'✨ 【{self.taskType}】-已完成') - continue - if self.taskType == 'INTEGRAL_EXCHANGE': - print(f'⚠️ 积分兑换任务暂不支持') - elif self.taskType == 'CLICK_MY_SETTING': - self.taskCode = item["taskCode"] - self.addDeliverPrefer() - if "taskCode" in item: - self.taskCode = item["taskCode"] - self.doTask() - time.sleep(3) - self.receiveTask() - else: - print(f'⚠️ 暂时不支持【{self.title}】任务') - - def addDeliverPrefer(self): - print(f'>>>开始【{self.title}】任务') - json_data = { - "country": "中国", - "countryCode": "A000086000", - "province": "北京市", - "provinceCode": "A110000000", - "city": "北京市", - "cityCode": "A111000000", - "county": "东城区", - "countyCode": "A110101000", - "address": "1号楼1单元101", - "latitude": "", - "longitude": "", - "memberId": "", - "locationCode": "010", - "zoneCode": "CN", - "postCode": "", - "takeWay": "7", - "callBeforeDelivery": 'false', - "deliverTag": "2,3,4,1", - "deliverTagContent": "", - "startDeliverTime": "", - "selectCollection": 'false', - "serviceName": "", - "serviceCode": "", - "serviceType": "", - "serviceAddress": "", - "serviceDistance": "", - "serviceTime": "", - "serviceTelephone": "", - "channelCode": "RW11111", - "taskId": self.taskId, - "extJson": "{\"noDeliverDetail\":[]}" - } - url = 'https://ucmp.sf-express.com/cx-wechat-member/member/deliveryPreference/addDeliverPrefer' - response = self.do_request(url, data=json_data) - if response.get('success') == True: - print('新增一个收件偏好,成功') - else: - print(f'>【{self.title}】任务-{response.get("errorMessage")}') - - def member_day_index(self): - print('🎭 会员日活动') - try: - invite_user_id = random.choice([invite for invite in inviteId if invite != self.user_id]) - payload = {'inviteUserId': invite_user_id} - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~memberDayIndexService~index' - - response = self.do_request(url, data=payload) - if response.get('success'): - lottery_num = response.get('obj', {}).get('lotteryNum', 0) - can_receive_invite_award = response.get('obj', {}).get('canReceiveInviteAward', False) - if can_receive_invite_award: - self.member_day_receive_invite_award(invite_user_id) - self.member_day_red_packet_status() - Log(f'🎁 会员日可以抽奖{lottery_num}次') - for _ in range(lottery_num): - self.member_day_lottery() - if self.member_day_black: - return - self.member_day_task_list() - if self.member_day_black: - return - self.member_day_red_packet_status() - else: - error_message = response.get('errorMessage', '无返回') - Log(f'📝 查询会员日失败: {error_message}') - if '没有资格参与活动' in error_message: - self.member_day_black = True - Log('📝 会员日任务风控') - except Exception as e: - print(e) - - def member_day_receive_invite_award(self, invite_user_id): - try: - payload = {'inviteUserId': invite_user_id} - - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~memberDayIndexService~receiveInviteAward' - - response = self.do_request(url, payload) - if response.get('success'): - product_name = response.get('obj', {}).get('productName', '空气') - Log(f'🎁 会员日奖励: {product_name}') - else: - error_message = response.get('errorMessage', '无返回') - Log(f'📝 领取会员日奖励失败: {error_message}') - if '没有资格参与活动' in error_message: - self.member_day_black = True - Log('📝 会员日任务风控') - except Exception as e: - print(e) - - def member_day_lottery(self): - try: - payload = {} - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~memberDayLotteryService~lottery' - - response = self.do_request(url, payload) - if response.get('success'): - product_name = response.get('obj', {}).get('productName', '空气') - Log(f'🎁 会员日抽奖: {product_name}') - else: - error_message = response.get('errorMessage', '无返回') - Log(f'📝 会员日抽奖失败: {error_message}') - if '没有资格参与活动' in error_message: - self.member_day_black = True - Log('📝 会员日任务风控') - except Exception as e: - print(e) - - def member_day_task_list(self): - try: - payload = {'activityCode': 'MEMBER_DAY', 'channelType': 'MINI_PROGRAM'} - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~activityTaskService~taskList' - - response = self.do_request(url, payload) - if response.get('success'): - task_list = response.get('obj', []) - for task in task_list: - if task['status'] == 1: - if self.member_day_black: - return - self.member_day_fetch_mix_task_reward(task) - for task in task_list: - if task['status'] == 2: - if self.member_day_black: - return - if task['taskType'] in ['SEND_SUCCESS', 'INVITEFRIENDS_PARTAKE_ACTIVITY', 'OPEN_SVIP', - 'OPEN_NEW_EXPRESS_CARD', 'OPEN_FAMILY_CARD', 'CHARGE_NEW_EXPRESS_CARD', - 'INTEGRAL_EXCHANGE']: - pass - else: - for _ in range(task['restFinishTime']): - if self.member_day_black: - return - self.member_day_finish_task(task) - else: - error_message = response.get('errorMessage', '无返回') - Log('📝 查询会员日任务失败: ' + error_message) - if '没有资格参与活动' in error_message: - self.member_day_black = True - Log('📝 会员日任务风控') - except Exception as e: - print(e) - - def member_day_finish_task(self, task): - try: - payload = {'taskCode': task['taskCode']} - - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberEs~taskRecord~finishTask' - - response = self.do_request(url, payload) - if response.get('success'): - Log('📝 完成会员日任务[' + task['taskName'] + ']成功') - self.member_day_fetch_mix_task_reward(task) - else: - error_message = response.get('errorMessage', '无返回') - Log('📝 完成会员日任务[' + task['taskName'] + ']失败: ' + error_message) - if '没有资格参与活动' in error_message: - self.member_day_black = True - Log('📝 会员日任务风控') - except Exception as e: - print(e) - - def member_day_fetch_mix_task_reward(self, task): - try: - payload = {'taskType': task['taskType'], 'activityCode': 'MEMBER_DAY', 'channelType': 'MINI_PROGRAM'} - - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~activityTaskService~fetchMixTaskReward' - - response = self.do_request(url, payload) - if response.get('success'): - Log('🎁 领取会员日任务[' + task['taskName'] + ']奖励成功') - else: - error_message = response.get('errorMessage', '无返回') - Log('📝 领取会员日任务[' + task['taskName'] + ']奖励失败: ' + error_message) - if '没有资格参与活动' in error_message: - self.member_day_black = True - Log('📝 会员日任务风控') - except Exception as e: - print(e) - - def member_day_receive_red_packet(self, hour): - try: - payload = {'receiveHour': hour} - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~memberDayTaskService~receiveRedPacket' - - response = self.do_request(url, payload) - if response.get('success'): - print(f'🎁 会员日领取{hour}点红包成功') - else: - error_message = response.get('errorMessage', '无返回') - print(f'📝 会员日领取{hour}点红包失败: {error_message}') - if '没有资格参与活动' in error_message: - self.member_day_black = True - Log('📝 会员日任务风控') - except Exception as e: - print(e) - - def member_day_red_packet_status(self): - try: - payload = {} - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~memberDayPacketService~redPacketStatus' - response = self.do_request(url, payload) - if response.get('success'): - packet_list = response.get('obj', {}).get('packetList', []) - for packet in packet_list: - self.member_day_red_packet_map[packet['level']] = packet['count'] - - for level in range(1, self.max_level): - count = self.member_day_red_packet_map.get(level, 0) - while count >= 2: - self.member_day_red_packet_merge(level) - count -= 2 - packet_summary = [] - remaining_needed = 0 - - for level, count in self.member_day_red_packet_map.items(): - if count == 0: - continue - packet_summary.append(f"[{level}级]X{count}") - int_level = int(level) - if int_level < self.max_level: - remaining_needed += 1 << (int_level - 1) - - Log("📝 会员日合成列表: " + ", ".join(packet_summary)) - - if self.member_day_red_packet_map.get(self.max_level): - Log(f"🎁 会员日已拥有[{self.max_level}级]红包X{self.member_day_red_packet_map[self.max_level]}") - self.member_day_red_packet_draw(self.max_level) - else: - remaining = self.packet_threshold - remaining_needed - Log(f"📝 会员日距离[{self.max_level}级]红包还差: [1级]红包X{remaining}") - - else: - error_message = response.get('errorMessage', '无返回') - Log(f'📝 查询会员日合成失败: {error_message}') - if '没有资格参与活动' in error_message: - self.member_day_black = True - Log('📝 会员日任务风控') - except Exception as e: - print(e) - - def member_day_red_packet_merge(self, level): - try: - # for key,level in enumerate(self.member_day_red_packet_map): - # pass - payload = {'level': level, 'num': 2} - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~memberDayPacketService~redPacketMerge' - - response = self.do_request(url, payload) - if response.get('success'): - Log(f'🎁 会员日合成: [{level}级]红包X2 -> [{level + 1}级]红包') - self.member_day_red_packet_map[level] -= 2 - if not self.member_day_red_packet_map.get(level + 1): - self.member_day_red_packet_map[level + 1] = 0 - self.member_day_red_packet_map[level + 1] += 1 - else: - error_message = response.get('errorMessage', '无返回') - Log(f'📝 会员日合成两个[{level}级]红包失败: {error_message}') - if '没有资格参与活动' in error_message: - self.member_day_black = True - Log('📝 会员日任务风控') - except Exception as e: - print(e) - - def member_day_red_packet_draw(self, level): - try: - payload = {'level': str(level)} - url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~memberDayPacketService~redPacketDraw' - response = self.do_request(url, payload) - if response and response.get('success'): - coupon_names = [item['couponName'] for item in response.get('obj', [])] or [] - - Log(f"🎁 会员日提取[{level}级]红包: {', '.join(coupon_names) or '空气'}") - else: - error_message = response.get('errorMessage') if response else "无返回" - Log(f"📝 会员日提取[{level}级]红包失败: {error_message}") - if "没有资格参与活动" in error_message: - self.memberDay_black = True - print("📝 会员日任务风控") - except Exception as e: - print(e) - - def exchange_coupon(self, coupon_amount, max_retries=3): - """兑换指定面额的券""" - self.getSign() - exchange_headers = { - 'authority': 'mcs-mimp-web.sf-express.com', - 'origin': 'https://mcs-mimp-web.sf-express.com', - 'referer': 'https://mcs-mimp-web.sf-express.com/inboxPresentCouponList', - 'content-type': 'application/json;charset=UTF-8', - 'channel': 'wxwdsj', - 'sw8': '1-ZDRlNjQwZjUtNmViYi00NmRhLThiZTMtZWEyZTUzYTlhOWFm-ZDM4MjIzM2YtMDQ1NC00ZDJlLWIwMDUtYTQyZmE1ZGE4ZTI5-0-ZmI0MDgxNzA4NWJlNGUzOThlMGI2ZjRiMDgxNzc3NDY=-d2Vi-L2luYm94UHJlc2VudENvdXBvbkxpc3Q=-L21jcy1taW1wL2NvbW1vblBvc3Qvfm1lbWJlck5vbmAjdGl2aXR5fnJlY2VpdmVFeGNoYW5nZUdpZnRCYWdTZXJ2aWNlfmxpc3Q=' - } - headers = {**self.headers, **exchange_headers} - - for attempt in range(1, max_retries + 1): - try: - list_url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~receiveExchangeGiftBagService~list' - list_data = {"exchangeType": "EXCHANGE_SFC"} - list_res = self.s.post(list_url, headers=headers, json=list_data, timeout=10) - list_res.raise_for_status() - list_json = list_res.json() - - if not list_json.get('success'): - return False, f"获取礼品列表失败" - - coupon = next( - (g for g in list_json.get('obj', []) - if coupon_amount in g.get('giftBagName', '')), - None - ) - - if not coupon: - return False, f"未找到{coupon_amount}券" - - required_honey = coupon.get('exchangeHoney') - if self.usableHoney < required_honey: - return False, f"丰蜜不足:需要{required_honey},当前{self.usableHoney}" - - exchange_url = 'https://mcs-mimp-web.sf-express.com/mcs-mimp/commonPost/~memberNonactivity~receiveExchangeGiftBagService~exchange' - exchange_data = { - "giftBagCode": coupon['giftBagCode'], - "ruleCode": coupon['ruleCode'], - "exchangeType": "EXCHANGE_SFC", - "memberNo": self.user_id, - "channel": "wxwdsj" - } - - exchange_res = self.s.post(exchange_url, headers=headers, json=exchange_data, timeout=10) - exchange_res.raise_for_status() - exchange_json = exchange_res.json() - - if exchange_json.get('success'): - self.usableHoney -= required_honey - self.exchange_count += 1 - return True, f"成功兑换{coupon_amount}券" - else: - return False, exchange_json.get('errorMessage', '兑换失败') - - except Exception as e: - if attempt == max_retries: - return False, f"兑换异常:{str(e)}" - time.sleep(2) - - return False, "多次尝试失败" - - def execute_exchange_range(self): - """按照优先级执行兑换区间,支持连续兑换多张券""" - Log(f"🎯 兑换目标:{' > '.join(self.target_amounts)}") - Log(f"📊 最大兑换次数:{MAX_EXCHANGE_TIMES}") - - total_exchanged = 0 - exchange_results = [] - - # 连续兑换,直到达到最大次数或无法继续兑换 - while total_exchanged < MAX_EXCHANGE_TIMES: - exchanged_this_round = False - - # 按优先级尝试每种券 - for coupon_amount in self.target_amounts: - if total_exchanged >= MAX_EXCHANGE_TIMES: - break - - Log(f"💰 尝试兑换第{total_exchanged + 1}张 {coupon_amount} 券...") - success, message = self.exchange_coupon(coupon_amount) - - if success: - Log(f"🎉 {message} (总计已兑换{self.exchange_count}张)") - exchange_results.append(coupon_amount) - total_exchanged += 1 - exchanged_this_round = True - time.sleep(3) # 兑换成功后等待3秒 - break # 成功兑换一张后,重新开始优先级循环 - else: - Log(f"❌ {coupon_amount} - {message}") - - # 如果这一轮没有成功兑换任何券,说明无法继续兑换,退出循环 - if not exchanged_this_round: - break - - # 总结兑换结果 - if exchange_results: - Log(f"✅ 兑换完成!共兑换{len(exchange_results)}张券:{', '.join(exchange_results)}") - return True - else: - Log("❌ 未能兑换任何券") - return False - - def exchange_23_coupon(self): - """兑换功能(兼容原方法名)""" - return self.execute_exchange_range() - - def main(self): - global one_msg - wait_time = random.randint(1000, 3000) / 1000.0 - time.sleep(wait_time) - one_msg = '' - if not self.login_res: return False - - self.sign() - self.superWelfare_receiveRedPacket() - self.get_SignTaskList() - self.get_SignTaskList(True) - - self.get_honeyTaskListStart() - self.honey_indexData() - self.honey_indexData(True) - - activity_end_date = get_quarter_end_date() - days_left = (activity_end_date - datetime.now()).days - if days_left == 0: - message = f"⏰ 今天采蜜活动截止兑换还有{days_left}天,请及时进行兑换!!" - Log(message) - else: - message = f"⏰ 今天采蜜活动截止兑换还有{days_left}天,请及时进行兑换!!\n--------------------------------" - Log(message) - - if not self.is_last_day and self.force_exchange: - Log(f"⚡ 强制兑换模式已开启,兑换目标:{' > '.join(self.target_amounts)}") - exchange_success = self.exchange_23_coupon() - if not exchange_success: - Log("❌ 强制兑换失败,所有目标券都无法兑换") - - current_date = datetime.now().day - if 26 <= current_date <= 28: - self.member_day_index() - else: - print('⏰ 未到指定时间不执行会员日任务\n==================================\n') - - return True - -def get_quarter_end_date(): - current_date = datetime.now() - current_month = current_date.month - current_year = current_date.year - next_quarter_first_day = datetime(current_year, ((current_month - 1) // 3 + 1) * 3 + 1, 1) - quarter_end_date = next_quarter_first_day - timedelta(days=1) - - return quarter_end_date - - -def is_activity_end_date(end_date): - current_date = datetime.now().date() - end_date = datetime.strptime(end_date, "%Y-%m-%d").date() - - return current_date == end_date - -def main(): - APP_NAME = '顺丰速运' - ENV_NAME = 'sfsyUrl' - CK_NAME = 'url' - local_script_name = os.path.basename(__file__) - local_version = '2025.06.23' - target_amounts = parse_exchange_range(EXCHANGE_RANGE) - token = os.getenv(ENV_NAME) - if not token: - print(f"❌ 未找到环境变量 {ENV_NAME},请检查配置") - return - tokens = token.split('&') - tokens = [t.strip() for t in tokens if t.strip()] - if len(tokens) == 0: - print(f"❌ 环境变量 {ENV_NAME} 为空或格式错误") - return - - print(f"==================================") - print(f"🎉 呆呆粉丝后援会:996374999") - print(f"🚚 顺丰速运脚本 v{local_version}") - print(f"📱 共获取到{len(tokens)}个账号") - print(f"🎯 兑换配置:") - print(f" └ 兑换区间: {EXCHANGE_RANGE} → {' > '.join(target_amounts)}") - print(f" └ 强制兑换: {'开启' if FORCE_EXCHANGE else '关闭'}") - print(f" └ 最大次数: {MAX_EXCHANGE_TIMES}") - print(f"😣 修改By:呆呆呆呆") - print(f"==================================") - - for index, infos in enumerate(tokens): - run_result = RUN(infos, index).main() - if not run_result: continue - -if __name__ == '__main__': - main() -# 当前脚本来自于http://script.345yun.cn脚本库下载! \ No newline at end of file