diff --git a/Utils/Dy/DyUtils.py b/Utils/Dy/DyUtils.py index d305149..d92d272 100644 --- a/Utils/Dy/DyUtils.py +++ b/Utils/Dy/DyUtils.py @@ -1022,22 +1022,20 @@ class DouYinMessageHandler: try: message = blackboxprotobuf.decode_message(content)[0] - # 🔥 优化:只记录有效消息类型,过滤无用日志 - # 首先检查是否是心跳响应(优先处理,减少不必要的解析) - if "5" in message: - kv_pairs = message["5"] - if isinstance(kv_pairs, list): - for pair in kv_pairs: - if isinstance(pair, dict) and pair.get("1") == b"code" and pair.get("2") == b"0": - self._log("💓 心跳响应正常", "DEBUG") - return + # 解析二进制数据 + decoded_message_readable = self.decode_binary_data(message) + print(f"\n📨 收到消息: {decoded_message_readable}") - # 解析用户Token(静默处理) user, token = self.code_parse(message=message) if user and token: receiver_id = int(user.split(":")[0]) self._init_user_info(receiver_id, token) - self._log(f"✅ 获取到用户Token: 用户ID={receiver_id}", "DEBUG") + + print(f"✅ 获取到用户Token: 用户ID={receiver_id}") + + # 获取消息类型 + msg_type = message.get('1') + print(f"📋 消息类型: {msg_type}") # 获取内部消息结构 inner_msg = message.get('8', {}) @@ -1046,37 +1044,48 @@ class DouYinMessageHandler: if isinstance(inner_msg, bytes): try: inner_msg = blackboxprotobuf.decode_message(inner_msg)[0] - except Exception: - # 无法解析的消息静默忽略 + print(f"🔄 解析内部消息字节成功") + except Exception as e: + print(f"⚠️ 无法解析内部消息字节: {e}") return if not inner_msg or not isinstance(inner_msg, dict): - # 消息结构不完整,静默忽略 + print("⚠️ 消息结构不完整") return # 获取内部消息类型 inner_type = inner_msg.get('1') inner_data = inner_msg.get('6', {}) - # 🔥 只处理和记录有意义的消息类型 + # 首先检查是否是心跳响应 + if "5" in message: + kv_pairs = message["5"] + if isinstance(kv_pairs, list): + for pair in kv_pairs: + if isinstance(pair, dict) and pair.get("1") == b"code" and pair.get("2") == b"0": + self._log("💓 心跳响应正常", "DEBUG") + return + print(f"📋 内部消息类型: {inner_type}") + print(f"📋 内部消息数据键: {list(inner_data.keys()) if isinstance(inner_data, dict) else type(inner_data)}") + + # 处理不同类型的消息 if inner_type == 610: # Token消息 - self._log("🔑 处理Token消息", "DEBUG") + print("🔑 处理Token消息") self._handle_token_message(inner_data) - elif inner_type == 500: # 聊天消息(真正的用户消息) - # 🔥 只有聊天消息才打印详细日志 - decoded_message_readable = self.decode_binary_data(message) - self._log(f"💬 收到用户消息: {decoded_message_readable}", "INFO") + elif inner_type == 500: # 聊天消息 + print("💬 处理聊天消息") self._handle_chat_message(inner_data, message) elif inner_type == 200: # 心跳消息 - self._log("💓 收到心跳消息", "DEBUG") + print("💓 收到心跳消息") - # 🔥 其他未知消息类型静默忽略,不打印日志 + else: + print(f"❓ 未知内部消息类型: {inner_type}") except Exception as e: - # 只记录真正的错误,忽略解析失败 - self._log(f"❌ 处理消息时出错: {e}", "ERROR") + print(f"❌ 解析消息时出错: {e}") + traceback.print_exc() async def _process_pending_message(self, sender_id, message_content): """处理待发送的消息""" @@ -1286,6 +1295,8 @@ class DouYinMessageHandler: def _extract_message_text(self, msg_content): """从消息内容中提取文本和图片URL""" try: + print("🔍 开始提取消息内容...") + # 初始化返回结果 result = { 'text': None, @@ -1300,22 +1311,27 @@ class DouYinMessageHandler: # 方法1: 处理文本消息(从'8'字段获取) text_content = msg_content.get('8') if text_content: + print(f"📄 检测到文本内容") if isinstance(text_content, bytes): try: decoded = text_content.decode('utf-8') result['text'] = decoded + self._log(f"✅ UTF-8解码成功: {decoded}", "SUCCESS") except UnicodeDecodeError: try: decoded = text_content.decode('gbk') result['text'] = decoded + self._log(f"✅ GBK解码成功: {decoded}", "SUCCESS") except: - pass + self._log("⚠️ 无法解码文本内容", "DEBUG") elif isinstance(text_content, str): result['text'] = text_content + self._log(f"✅ 直接使用文本内容: {text_content}") # 方法2: 统一处理'9'字段中的数据(包括文本和图片、消息、视频 meta_data = msg_content.get('9', []) if meta_data: + print(f"🔍 检测到消息元数据") for item in meta_data: if not isinstance(item, dict): continue @@ -1328,13 +1344,17 @@ class DouYinMessageHandler: # 处理所有类型的URL if key == 'avatar_uri': result['avatar'] = value + self._log(f"✅ 找到头像URL: {value}", "SUCCESS") elif key == 'imageUrl': result['image_url'] = value + self._log(f"✅ 找到图片URL: {value}", "SUCCESS") elif key == 'thumbnailUrl': result['thumbnail_url'] = value + self._log(f"✅ 找到缩略图URL: {value}", "SUCCESS") elif key == 'goods_id': goods_id = value result['goods_id'] = goods_id + self._log(f"✅ 找到商品ID: {goods_id}", "SUCCESS") elif key == 'msg_render_model': try: video_info = json.loads(value) @@ -1344,17 +1364,22 @@ class DouYinMessageHandler: viedo_url = render_body.get('coverURL') viedo_vid = render_body.get('vid') if viedo_vid and viedo_url: + self._log(f"✅ 找到视频原始vid: {viedo_vid}", "SUCCESS") + # 解析获取视频播放地址 play_url = self.parse_video(viedo_vid) if play_url: result['video_url'] = play_url else: - # 如果解析失败,使用备用封面图片作为地址 + # 如果解析失败 在打印对应的日志后 使用备用封面图片作为地址 if '\\u0026' in viedo_url: viedo_url = viedo_url.replace('\\u0026', '&') result['video_url'] = viedo_url - except json.JSONDecodeError: - pass + self._log("⚠️ 使用视频封面作为备选", "WARNING") + else: + self._log("⚠️ 未找到视频核心id 可能出现新的数据存放地址", "DEBUG") + except json.JSONDecodeError as e: + self._log(f"解析视频信息失败: {e}", "ERROR") elif key == 'sku_order_id': # 取到了对应的订单号 id order_id = value @@ -1367,6 +1392,7 @@ class DouYinMessageHandler: # 方法3: 兼容处理旧的'9-1'字段(如果存在) image_data = msg_content.get('9-1', []) # 如果没有拿到这个arrayList那么就不需要在对里面的数据进行解析了 if image_data != []: + print(f"📸 检测到旧的图片数据格式", "DEBUG") for item in image_data: if not isinstance(item, dict): continue @@ -1378,13 +1404,17 @@ class DouYinMessageHandler: if key == 'avatar_uri' and not result['avatar']: result['avatar'] = value + self._log(f"✅ 找到头像URL: {value}", "SUCCESS") elif key == 'imageUrl' and not result['image_url']: result['image_url'] = value + self._log(f"✅ 找到图片URL: {value}", "SUCCESS") elif key == 'thumbnailUrl' and not result['thumbnail_url']: result['thumbnail_url'] = value + self._log(f"✅ 找到缩略图URL: {value}", "SUCCESS") elif key == 'goods_id': goods_id = value result['goods_id'] = goods_id + self._log(f"✅ 找到商品ID: {goods_id}", "SUCCESS") elif key == 'msg_render_model': try: video_info = json.loads(value) @@ -1394,22 +1424,42 @@ class DouYinMessageHandler: viedo_url = render_body.get('coverURL') viedo_vid = render_body.get('vid') if viedo_vid and viedo_url: + self._log(f"✅ 找到视频原始vid: {viedo_vid}", "SUCCESS") + # 解析获取视频播放地址 play_url = self.parse_video(viedo_vid) if play_url: result['video_url'] = play_url else: - # 如果解析失败,使用备用封面图片作为地址 + # 如果解析失败 在打印对应的日志后 使用备用封面图片作为地址 if '\\u0026' in viedo_url: viedo_url = viedo_url.replace('\\u0026', '&') result['video_url'] = viedo_url - except json.JSONDecodeError: - pass + self._log("⚠️ 使用视频封面作为备选", "WARNING") + else: + self._log("⚠️ 未找到视频核心id 可能出现新的数据存放地址", "DEBUG") + except json.JSONDecodeError as e: + self._log(f"解析视频信息失败: {e}", "ERROR") elif key == 'sku_order_id': # 取到了对应的订单号 id order_id = value result['order_id'] = order_id + # 如果都没找到内容,打印调试信息 + if not any(result.values()): + print("🔍 未找到有效内容,打印所有字段:") + for key, value in msg_content.items(): + if isinstance(value, bytes): + try: + decoded = value.decode('utf-8', errors='ignore') + print(f" {key}: {decoded[:100]}...") + except: + print(f" {key}: [无法解码的字节数据,长度: {len(value)}]") + elif isinstance(value, list): + print(f" {key}: [列表数据,长度: {len(value)}]") + else: + print(f" {key}: {value}") + return result except Exception as e: @@ -1428,6 +1478,8 @@ class DouYinMessageHandler: def _handle_chat_message(self, message, msg_type): """处理聊天消息 - 修改版本,支持多种消息类型""" try: + self._log(f"🔍 开始解析{message} 消息结构", "DEBUG") + msg_500 = message.get('500', {}) if not msg_500: return @@ -1440,21 +1492,28 @@ class DouYinMessageHandler: inner_msg_type = msg_content.get("6", 0) sender_id = msg_content.get("7", 0) + self._log(f"📊 内部消息类型: {inner_msg_type}, 发送者ID: {sender_id}", "DEBUG") + + print("会不会到这里来呢") + # 处理不同类型的消息 if inner_msg_type == 1000 and sender_id and sender_id != int(self.cookie['PIGEON_CID']): # 用户文本消息 - 处理AI回复 - self._log(f"✅ 检测到用户消息 (类型1000),发送者: {sender_id}", "INFO") + self._log("✅ 检测到1000状态的有效消息", "INFO") self._handle_user_text_message(msg_content, sender_id) elif inner_msg_type == 50002 and sender_id and sender_id != int(self.cookie['PIGEON_CID']): # 系统消息 - 触发token请求 - self._log(f"✅ 检测到系统消息 (类型50002),发送者: {sender_id}", "DEBUG") + self._log("✅ 检测到50002类型的系统消息", "INFO") self._handle_system_message(msg_content, sender_id) - # 🔥 其他消息类型静默忽略 + else: + # 忽略其他消息 + self._log(f"🔍 忽略消息类型: {inner_msg_type}", "DEBUG") except Exception as e: self._log(f"❌ 处理聊天消息失败: {e}", "ERROR") + self._log(f"❌ 错误详情: {traceback.format_exc()}", "DEBUG") def _handle_user_text_message(self, msg_content, sender_id): """处理用户文本消息""" diff --git a/build_production.py b/build_production.py index fda513d..58a1912 100644 --- a/build_production.py +++ b/build_production.py @@ -1,57 +1,63 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- """ -生产环境打包脚本 - 自动禁用日志功能 +Production build script - Automatically disable logging functionality """ import os import shutil import subprocess +import sys + +# Ensure script runs in correct directory +SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) +os.chdir(SCRIPT_DIR) +print(f"Working directory: {SCRIPT_DIR}") def disable_logging(): - """自动禁用所有日志功能""" + """Disable all logging functionality""" print("Disabling logging functionality...") - # 备份原文件 + # Backup original files files_to_backup = ['main.py', 'exe_file_logger.py'] for file_name in files_to_backup: if os.path.exists(file_name): shutil.copy(file_name, f'{file_name}.backup') print(f"Backed up {file_name}") - # 1. 修改 main.py - 注释掉日志初始化 + # 1. Modify main.py - comment out logging initialization if os.path.exists('main.py'): with open('main.py', 'r', encoding='utf-8') as f: content = f.read() - # 注释掉日志相关的导入和初始化 + # Comment out logging related imports and initialization content = content.replace( 'from exe_file_logger import setup_file_logging, log_to_file', - '# from exe_file_logger import setup_file_logging, log_to_file # 生产环境禁用' + '# from exe_file_logger import setup_file_logging, log_to_file # Production disabled' ).replace( 'setup_file_logging()', - '# setup_file_logging() # 生产环境禁用' + '# setup_file_logging() # Production disabled' ).replace( 'print("文件日志系统已在main.py中初始化")', - '# print("文件日志系统已在main.py中初始化") # 生产环境禁用' + '# print("文件日志系统已在main.py中初始化") # Production disabled' ) with open('main.py', 'w', encoding='utf-8') as f: f.write(content) print("Disabled logging in main.py") - # 2. 修改 exe_file_logger.py - 让所有函数变成空操作 + # 2. Modify exe_file_logger.py - make all functions no-op if os.path.exists('exe_file_logger.py'): with open('exe_file_logger.py', 'r', encoding='utf-8') as f: content = f.read() - # 将 setup_file_logging 函数替换为空函数 + # Replace setup_file_logging function with empty function content = content.replace( 'def setup_file_logging():', - 'def setup_file_logging():\n """生产环境 - 禁用文件日志"""\n return None\n\ndef setup_file_logging_original():' + 'def setup_file_logging():\n """Production - Logging disabled"""\n return None\n\ndef setup_file_logging_original():' ).replace( 'def log_to_file(message):', - 'def log_to_file(message):\n """生产环境 - 禁用文件日志"""\n pass\n\ndef log_to_file_original(message):' + 'def log_to_file(message):\n """Production - Logging disabled"""\n pass\n\ndef log_to_file_original(message):' ) with open('exe_file_logger.py', 'w', encoding='utf-8') as f: @@ -61,37 +67,54 @@ def disable_logging(): print("All logging functionality disabled") def restore_logging(): - """恢复日志功能""" + """Restore logging functionality""" + print("Restoring development configuration...") files_to_restore = ['main.py', 'exe_file_logger.py'] + restored_count = 0 + for file_name in files_to_restore: backup_file = f'{file_name}.backup' - if os.path.exists(backup_file): - shutil.copy(backup_file, file_name) - os.remove(backup_file) - print(f"Restored {file_name}") - print("All files restored to development configuration") + try: + if os.path.exists(backup_file): + # Ensure target file is writable + if os.path.exists(file_name): + os.chmod(file_name, 0o666) + + shutil.copy(backup_file, file_name) + os.remove(backup_file) + print(f"[OK] Restored {file_name}") + restored_count += 1 + else: + print(f"[WARN] Backup file not found: {backup_file}") + except Exception as e: + print(f"[ERROR] Failed to restore {file_name}: {e}") + + if restored_count == len(files_to_restore): + print("[OK] All files restored to development configuration") + else: + print(f"[WARN] Restored {restored_count}/{len(files_to_restore)} files") def main(): - """主函数""" + """Main function""" print("Production Build Tool (No Logging Version)") print("=" * 60) try: - # 1. 禁用日志功能 + # 1. Disable logging functionality disable_logging() - # 2. 执行打包 + # 2. Execute build print("\nStarting build...") result = subprocess.run(['python', 'quick_build.py'], capture_output=False) if result.returncode == 0: - # 验证最终输出(quick_build.py 已统一输出到 MultiPlatformGUI) + # Verify output (quick_build.py outputs to MultiPlatformGUI) if os.path.exists('dist/MultiPlatformGUI'): print("\nProduction build completed successfully!") print("Output directory: dist/MultiPlatformGUI/") print("All logging disabled - client will not generate log files") - # 验证关键文件 + # Verify key files exe_path = 'dist/MultiPlatformGUI/main.exe' if os.path.exists(exe_path): size = os.path.getsize(exe_path) / 1024 / 1024 # MB @@ -107,8 +130,8 @@ def main(): print(f"ERROR: Build process error: {e}") finally: - # 3. 恢复日志功能(用于开发) - print("\nRestoring development configuration...") + # 3. Restore logging functionality (for development) + print() restore_logging() print("\n" + "=" * 60)