shawenguan 1 рік тому
батько
коміт
ace82cbd30

+ 21 - 19
addons/elife/OfpayDataSync.py

@@ -7,11 +7,13 @@ import json
 from decimal import Decimal
 
 # 自定义 JSON 编码器
-class DecimalEncoder(json.JSONEncoder):
-    def default(self, o):
-        if isinstance(o, Decimal):
-            return str(o);
-        return super().default(o);
+class CustomEncoder(json.JSONEncoder):
+    def default(self, obj):
+        if isinstance(obj, Decimal):
+            return str(obj);
+        elif isinstance(obj, datetime):
+            return obj.strftime('%Y-%m-%d %H:%M:%S');
+        return super().default(obj);
 
 class OfpayDataSyncer:
 
@@ -69,13 +71,13 @@ class OfpayDataSyncer:
             column_names = [desc[0] for desc in cursor.description];
             for row in results:
                 data_dict = dict(zip(column_names, row));
-                update_time = data_dict['update_time'];
-                if isinstance(update_time, datetime):
-                    formatted_date = update_time.strftime('%Y-%m-%d %H:%M:%S');
-                    data_dict['update_time'] = formatted_date;
+                # update_time = data_dict['update_time'];
+                # if isinstance(update_time, datetime):
+                #     formatted_date = update_time.strftime('%Y-%m-%d %H:%M:%S');
+                #     data_dict['update_time'] = formatted_date;
                 data_list.append(data_dict);
             with open(filepath, 'w', newline='', encoding='utf-8') as f:
-                json_str = json.dumps(data_list, cls=DecimalEncoder, ensure_ascii=False);
+                json_str = json.dumps(data_list, cls=CustomEncoder, ensure_ascii=False);
                 f.write(json_str);
 
     def sync_activities(self, filename='results.json'):
@@ -92,10 +94,10 @@ class OfpayDataSyncer:
         for row in results:
             data_dict = dict(zip(column_names, row));
             activity_id = data_dict['activityId'];
-            update_time = data_dict['updateTime'];
-            if isinstance(update_time, datetime):
-                formatted_date = update_time.strftime('%Y-%m-%d %H:%M:%S');
-                data_dict['updateTime'] = formatted_date;
+            # update_time = data_dict['updateTime'];
+            # if isinstance(update_time, datetime):
+            #     formatted_date = update_time.strftime('%Y-%m-%d %H:%M:%S');
+            #     data_dict['updateTime'] = formatted_date;
             activity_list.append(data_dict);
             activity_ids.append(activity_id);
             activity_dict[activity_id] = data_dict;
@@ -109,10 +111,10 @@ class OfpayDataSyncer:
         for row in aw_results:
             data_dict = dict(zip(column_names, row));
             activity_id = data_dict['activityId'];
-            update_time = data_dict['updateTime'];
-            if isinstance(update_time, datetime):
-                formatted_date = update_time.strftime('%Y-%m-%d %H:%M:%S');
-                data_dict['updateTime'] = formatted_date;
+            # update_time = data_dict['updateTime'];
+            # if isinstance(update_time, datetime):
+            #     formatted_date = update_time.strftime('%Y-%m-%d %H:%M:%S');
+            #     data_dict['updateTime'] = formatted_date;
             if activity_id in activity_dict:
                 entity = activity_dict[activity_id];
                 if 'awardList' not in entity:
@@ -122,7 +124,7 @@ class OfpayDataSyncer:
         # print(sql_query);
         # print(activity_list);
         with open(filename, 'w', newline='', encoding='utf-8') as f:
-            json_str = json.dumps(activity_list, cls=DecimalEncoder, ensure_ascii=False);
+            json_str = json.dumps(activity_list, cls=CustomEncoder, ensure_ascii=False);
             f.write(json_str);
 
     def read_csv(self, filename='results.csv'):

+ 43 - 6
addons/elife/OfpayGrab.py

@@ -4,6 +4,7 @@ import csv
 import requests
 import json
 from datetime import datetime
+# from http.cookies import SimpleCookie
 from cachetools import TTLCache
 import pickle
 import multiprocessing
@@ -70,7 +71,7 @@ class OfpayGrabber:
         self.host = 'market-web.ofpay.com';
         self.market_id = accout_data['market_id'];
         self.event_visitor_id = accout_data['event_visitor_id'];
-        self.accout = accout_data['account'];
+        self.accout_id = accout_data['account'];
 
         uuid = accout_data['uuid'];
         user_agent = accout_data['user_agent'];
@@ -98,6 +99,12 @@ class OfpayGrabber:
         # print(self.headers);
 
     def start(self):
+        ret_code = self.check_refresh_token();
+        if ret_code < 0:
+            print(f"账号[{self.accout_id}]token已失效");
+            return;
+        if ret_code == 1:
+            self.sync_new_token();
         cate_items = self.get_market_items_from_cache();
         if not cate_items:
             cate_items = self.get_market_items_from_svr(self.market_id, self.event_visitor_id);
@@ -121,6 +128,35 @@ class OfpayGrabber:
             save_cache();
         return all_ret_list;
 
+    def check_refresh_token(self, force_refresh=False):
+        expire_time_str = self.accout_data['expire_time'];
+        expire_dt = datetime.strptime(expire_time_str, "%Y-%m-%d %H:%M:%S")
+        now_dt = datetime.now();
+        is_valid = False;
+        if now_dt < expire_dt:
+            is_valid = True;
+        if not force_refresh and is_valid:
+            return 0;
+        login_params = self.accout_data['login_params'];
+        url = f'https://{self.host}/h5/union/interactiveIGoChoose/index?loginParams={login_params}';
+        response = self.get_request(url);
+        # print(response.content);
+        cookie_dict = dict(response.cookies);
+        authorization = None;
+        for key in cookie_dict:
+            self.cookies[key] = cookie_dict[key];
+            if key == 'unionToken_interactiveIGoChoose':
+                authorization = self.cookies[key];
+        if authorization:
+            self.headers['Authorization'] = authorization;
+            cookies_str = '; '.join([f'{key}={value}' for key, value in self.cookies.items()]);
+            self.headers['Cookie'] = cookies_str;
+            return 1;
+        return -1;
+
+    def sync_new_token(self):
+        print('sync_new_token');
+
     def get_will_market_buy_list_all(self):
         def_val = '星巴克|霸王茶姬|百果园|京东E卡|滴滴快车';
         name_arr = [];
@@ -209,7 +245,7 @@ class OfpayGrabber:
 
     def check_to_buy_one(self, activity_id, sub_activity_id, sub_login_type, item_name, award_list):
         one_ret = None;
-        check_buy_repeat_key = f"lkOfPayBuyItemKey#{item_name}#{self.accout}";
+        check_buy_repeat_key = f"lkOfPayBuyItemKey#{item_name}#{self.accout_id}";
         now_string = datetime.now().strftime('%Y-%m-%d %H:%M:%S');
 
         if OfpayGrabber.CheckBuyRepeatEnable:
@@ -255,7 +291,7 @@ class OfpayGrabber:
         # 假设 ofpay_account_phone 和 event_visitor_id 在这段代码之外被定义
         # 或者作为参数传递给这个函数
         event_visitor_id = self.event_visitor_id;
-        game_account = self.accout;
+        game_account = self.accout_id;
         third_info = json.loads(award_data['thirdInfo']);
         award_id = award_data['awardId'];
         pay_info = self.get_pay_info(activity_id, award_id, '', '', game_account, event_visitor_id);
@@ -292,7 +328,7 @@ class OfpayGrabber:
         return None;
 
     def pay(self, activity_id, event_visitor_id, detail_id):
-        account_phone = self.accout;
+        account_phone = self.accout_id;
         post_data = {
             "detailId": detail_id,
             "rechargeAccount": account_phone,
@@ -353,7 +389,7 @@ class OfpayGrabber:
                     award_data = new_award_item;
                     break;
 
-        game_account = self.accout;
+        game_account = self.accout_id;
         third_info = json.loads(award_data["thirdInfo"]);
         award_id = award_data["awardId"];
         award_price = float(award_data["price"]);
@@ -464,6 +500,7 @@ def main():
     print(f"CPU支持 {cpu_threads} 个线程/核心");
     activities_data = read_json('elife_activities_data.json');
     accout_data = read_csv('elife_accout_data.csv');
+    cpu_threads = 0;
     if cpu_threads > 1:
         # 创建进程池
         pool = multiprocessing.Pool(cpu_threads);
@@ -487,4 +524,4 @@ def main():
             print('########################################');
 
 if __name__ == "__main__":
-    main();
+    main();

+ 5 - 11
addons/elife/OfpayHelper.py

@@ -54,11 +54,6 @@ flow.response.timestamp_start #响应开始的时间戳
 flow.response.timestamp_end #响应结束的时间戳
 
 """
-def seconds_to_beijing_time(seconds):
-    utc_time  = datetime.fromtimestamp(seconds, tz=timezone.utc);
-    beijing_time = utc_time.astimezone(timezone(timedelta(hours=8)));
-    formatted_time = beijing_time.strftime('%Y-%m-%d %H:%M:%S');
-    return formatted_time;
 
 class OfpayHelper:
 
@@ -174,7 +169,6 @@ class OfpayHelper:
             print('mysql重连...');
             self.connect_mysql();
 
-
     def check_host_pass(self, host):
         if self.host_ip:
             if host != self.host_ip and host != self.domain_name:
@@ -278,8 +272,8 @@ class OfpayHelper:
                 payload['customerInfo'] = customer_info;
                 account = customer_info['phone'];
 
-            sign_time = seconds_to_beijing_time(payload['iat']);
-            expire_time = seconds_to_beijing_time(payload['exp']);
+            sign_time = Utils.seconds_to_beijing_time(payload['iat']);
+            expire_time = Utils.seconds_to_beijing_time(payload['exp']);
 
         except Exception as e:
             print(e);
@@ -298,7 +292,7 @@ class OfpayHelper:
                 WHERE account = %s;
             ''';
             sql_params = (authorization, repr(cookies), sign_time, expire_time, login_params, account);
-            print(sql_params);
+            # print(sql_params);
             self.check_mysql_connect();
             cursor = self.db_conn.cursor();
             cursor.execute(sql_query, sql_params);
@@ -432,8 +426,8 @@ class OfpayHelper:
             rsp_data['list'].insert(0, simple_data);
 
         update_time = create_time;
-        sign_time = seconds_to_beijing_time(payload['iat']);
-        expire_time = seconds_to_beijing_time(payload['exp']);
+        sign_time = Utils.seconds_to_beijing_time(payload['iat']);
+        expire_time = Utils.seconds_to_beijing_time(payload['exp']);
         simple_data['createTime'] = expire_time;
         simple_data['endEffectTime'] = expire_time;
         # simple_data['rechargeTime'] = expire_time;

+ 225 - 0
addons/elife/OfpayTokenCheck.py

@@ -0,0 +1,225 @@
+# -*- coding: utf-8 -*-
+import os
+import requests
+import json
+import csv
+import base64
+from datetime import datetime, timezone, timedelta
+import pymysql
+
+def base64url_decode(base64_str):
+    size = len(base64_str) % 4
+    if size == 2:
+        base64_str += '=='
+    elif size == 3:
+        base64_str += '='
+    elif size != 0:
+        raise ValueError('Invalid base64 string')
+    return base64.urlsafe_b64decode(base64_str.encode('utf-8'))
+
+
+def parse_jwt(jwt_token):
+    jwt_token_list = jwt_token.split('.')
+    header = base64url_decode(jwt_token_list[0]).decode()
+    payload = base64url_decode(jwt_token_list[1]).decode()
+    return {
+        'header': json.loads(header),
+        'payload': json.loads(payload),
+        'signature': jwt_token_list[-1]
+    }
+
+def read_csv(filename='results.csv'):
+    data = []
+    try:
+        with open(filename, mode='r', encoding='utf-8') as csvfile:
+            reader = csv.DictReader(csvfile);
+            for row in reader:
+                data.append(row);
+    except IOError as e:
+        print(f"read_csv error occurred: {e}");
+    # print(data);
+    return data;
+
+def read_json(filename='results.json'):
+    data = None;
+    try:
+        with open(filename, 'r', encoding='utf-8') as file:
+            data = json.load(file);
+    except IOError as e:
+        print(f"read_json error occurred: {e}");
+    # print(data);
+    return data;
+
+def seconds_to_beijing_time(seconds):
+    utc_time  = datetime.fromtimestamp(seconds, tz=timezone.utc);
+    beijing_time = utc_time.astimezone(timezone(timedelta(hours=8)));
+    formatted_time = beijing_time.strftime('%Y-%m-%d %H:%M:%S');
+    return formatted_time;
+
+class OfpayChecker:
+    def __init__(self, accout_data):
+        self.force_refresh = True;
+
+        self.accout_data = accout_data;
+        self.host = 'market-web.ofpay.com';
+        self.market_id = accout_data['market_id'];
+        self.event_visitor_id = accout_data['event_visitor_id'];
+        self.accout_id = accout_data['account'];
+
+        uuid = accout_data['uuid'];
+        user_agent = accout_data['user_agent'];
+        authorization = accout_data['authorization'];
+        self.cookies = eval(accout_data['cookies']);
+        cookies_str = '; '.join([f'{key}={value}' for key, value in self.cookies.items()]);
+        self.headers = {
+            'Host': self.host,
+            'UUID': uuid,
+            'Accept': '*/*',
+            'Sec-Fetch-Site': 'same-origin',
+            'Origin': 'https://market-web.ofpay.com',
+            'Accept-Language': 'zh-CN,zh-Hans;q=0.9',
+            'Accept-Encoding': 'gzip, deflate, br',
+            'Sec-Fetch-Mode': 'cors',
+            'Content-Type': 'application/json; charset=utf-8',
+            'Connection': 'keep-alive',
+            'User-Agent': user_agent,
+            'Accept-Language': 'zh-CN,zh-Hans;q=0.9',
+            'Authorization': authorization,
+            'Sec-Fetch-Dest': 'empty',
+            'Referer': 'https://market-web.ofpay.com/h5/union/standard/interactiveIGoChoose/index',
+            'Cookie': cookies_str,
+        };
+        self.connect_mysql();
+
+    def connect_mysql(self):
+        config = {
+            'host':'47.106.225.136',
+            'port':3306,
+            'user':'root',
+            'passwd':'sjojo123456',
+            'database':'mitmproxy',
+            'charset':'utf8'
+        };
+        db_conn = None;
+        while True:
+            try:
+                db_conn = pymysql.connect(**config);
+                db_conn.ping(reconnect=True);
+            except pymysql.OperationalError as e:
+                print(e);
+                print('连接断开,正在尝试重新连接...');
+                if db_conn:
+                    db_conn.close();
+                db_conn = pymysql.connect(**config);
+                time.sleep(1);
+            else:
+                break;
+        self.db_conn = db_conn;
+
+    def check_mysql_connect(self):
+        try:
+            with self.db_conn.cursor() as cursor:
+                cursor.execute('SELECT 1');
+        except pymysql.MySQLError as e:
+            print(e);
+            self.db_conn.close();
+            print('mysql重连...');
+            self.connect_mysql();
+
+    def check_refresh_token(self, force_refresh=False):
+        expire_time_str = self.accout_data['expire_time'];
+        expire_dt = datetime.strptime(expire_time_str, "%Y-%m-%d %H:%M:%S")
+        now_dt = datetime.now();
+        is_valid = False;
+        if now_dt < expire_dt:
+            is_valid = True;
+        if not force_refresh and is_valid:
+            return 0;
+        login_params = self.accout_data['login_params'];
+        url = f'https://{self.host}/h5/union/interactiveIGoChoose/index?loginParams={login_params}';
+        response = self.get_request(url);
+        # print(response.content);
+        cookie_dict = dict(response.cookies);
+        authorization = None;
+        for key in cookie_dict:
+            self.cookies[key] = cookie_dict[key];
+            if key == 'unionToken_interactiveIGoChoose':
+                authorization = self.cookies[key];
+        if authorization:
+            self.headers['Authorization'] = authorization;
+            cookies_str = '; '.join([f'{key}={value}' for key, value in self.cookies.items()]);
+            self.headers['Cookie'] = cookies_str;
+            return 1;
+        return -1;
+
+    def start(self):
+        ret_code = self.check_refresh_token(self.force_refresh);
+        if ret_code == 1:
+            self.sync_new_token();
+            print('刷新token成功');
+        elif ret_code == 0:
+            print('无需刷新token');
+        else:
+            print('刷新token失败');
+
+    def sync_new_token(self):
+        account = self.accout_id;
+        if not account:
+            return;
+        authorization = self.headers['Authorization'];
+        cookies = self.cookies;
+        sign_time = None
+        expire_time = None;
+        try:
+            jwt_data = parse_jwt(authorization);
+            if not jwt_data:
+                return;
+            payload = jwt_data['payload'];
+            if 'customerInfo' in payload:
+                info_str = payload['customerInfo'];
+                customer_info = json.loads(info_str);
+                payload['customerInfo'] = customer_info;
+                account = customer_info['phone'];
+            sign_time = seconds_to_beijing_time(payload['iat']);
+            expire_time = seconds_to_beijing_time(payload['exp']);
+        except Exception as e:
+            print(e);
+
+        try:
+            sql_query = f'''
+                UPDATE elife_account_data
+                SET
+                    authorization = %s,
+                    cookies = %s,
+                    update_time = %s,
+                    expire_time = %s
+                WHERE account = %s;
+            ''';
+            sql_params = (authorization, repr(cookies), sign_time, expire_time, account);
+            # print(sql_params);
+            self.check_mysql_connect();
+            cursor = self.db_conn.cursor();
+            cursor.execute(sql_query, sql_params);
+            self.db_conn.commit();
+            cursor.close();
+        except pymysql.OperationalError as e:
+            print(e);
+
+    def get_request(self, url, params=None):
+        response = requests.get(url, headers=self.headers, params=params, cookies=self.cookies);
+        return response;
+
+    def post_request(self, url, data):
+        response = requests.post(url, data=data, headers=self.headers, cookies=self.cookies);
+        return response;
+
+def main():
+    accout_data = read_csv('elife_accout_data.csv');
+    for item in accout_data:
+        print('########账号[%s]开始检查刷新Token########' % item['account']);
+        checker = OfpayChecker(item);
+        checker.start();
+        print('########################################');
+
+if __name__ == "__main__":
+    main();