feat:初版

This commit is contained in:
2025-12-03 15:48:44 +08:00
commit b4df26f61d
199 changed files with 23434 additions and 0 deletions

192
WechatHook/callbacks.py Normal file
View File

@@ -0,0 +1,192 @@
"""
回调处理器
实现 Socket 回调的装饰器和处理机制
"""
import copy
import ctypes
from ctypes import WINFUNCTYPE
from functools import wraps
from typing import Callable, List
from loguru import logger
# 全局回调列表
_GLOBAL_CONNECT_CALLBACK_LIST: List[Callable] = []
_GLOBAL_RECV_CALLBACK_LIST: List[Callable] = []
_GLOBAL_CLOSE_CALLBACK_LIST: List[Callable] = []
def CONNECT_CALLBACK(in_class: bool = False):
"""
连接回调装饰器
Args:
in_class: 是否是类方法
Usage:
@CONNECT_CALLBACK()
def on_connect(client_id):
pass
@CONNECT_CALLBACK(in_class=True)
def on_connect(self, client_id):
pass
"""
def decorator(f):
@wraps(f)
def wrapper(*args, **kwargs):
return f(*args, **kwargs)
if in_class:
wrapper._wx_connect_handled = True
else:
_GLOBAL_CONNECT_CALLBACK_LIST.append(wrapper)
return wrapper
return decorator
def RECV_CALLBACK(in_class: bool = False):
"""
接收消息回调装饰器
Args:
in_class: 是否是类方法
Usage:
@RECV_CALLBACK()
def on_receive(client_id, message_type, data):
pass
@RECV_CALLBACK(in_class=True)
def on_receive(self, client_id, message_type, data):
pass
"""
def decorator(f):
@wraps(f)
def wrapper(*args, **kwargs):
return f(*args, **kwargs)
if in_class:
wrapper._wx_recv_handled = True
else:
_GLOBAL_RECV_CALLBACK_LIST.append(wrapper)
return wrapper
return decorator
def CLOSE_CALLBACK(in_class: bool = False):
"""
断开连接回调装饰器
Args:
in_class: 是否是类方法
Usage:
@CLOSE_CALLBACK()
def on_close(client_id):
pass
@CLOSE_CALLBACK(in_class=True)
def on_close(self, client_id):
pass
"""
def decorator(f):
@wraps(f)
def wrapper(*args, **kwargs):
return f(*args, **kwargs)
if in_class:
wrapper._wx_close_handled = True
else:
_GLOBAL_CLOSE_CALLBACK_LIST.append(wrapper)
return wrapper
return decorator
def add_callback_handler(callback_handler):
"""
添加回调处理器实例
Args:
callback_handler: 包含回调方法的对象
"""
import inspect
for name, method in inspect.getmembers(callback_handler, callable):
if hasattr(method, '_wx_connect_handled'):
_GLOBAL_CONNECT_CALLBACK_LIST.append(method)
logger.debug(f"注册连接回调: {name}")
elif hasattr(method, '_wx_recv_handled'):
_GLOBAL_RECV_CALLBACK_LIST.append(method)
logger.debug(f"注册接收回调: {name}")
elif hasattr(method, '_wx_close_handled'):
_GLOBAL_CLOSE_CALLBACK_LIST.append(method)
logger.debug(f"注册断开回调: {name}")
@WINFUNCTYPE(None, ctypes.c_void_p)
def wechat_connect_callback(client_id):
"""
微信连接回调C 函数)
Args:
client_id: 客户端 ID
"""
logger.info(f"[回调] 客户端连接: {client_id}")
for func in _GLOBAL_CONNECT_CALLBACK_LIST:
try:
func(client_id)
except Exception as e:
logger.error(f"连接回调执行失败: {e}")
@WINFUNCTYPE(None, ctypes.c_long, ctypes.c_char_p, ctypes.c_ulong)
def wechat_recv_callback(client_id, data, length):
"""
微信接收消息回调C 函数)
Args:
client_id: 客户端 ID
data: 消息数据JSON 字符串)
length: 数据长度
"""
try:
import json
# 深拷贝数据
data = copy.deepcopy(data)
json_data = data.decode('utf-8')
dict_data = json.loads(json_data)
msg_type = dict_data.get('type')
msg_data = dict_data.get('data', {})
logger.info(f"[回调] 收到消息: type={msg_type}, data={msg_data}")
# 调用所有注册的回调
for func in _GLOBAL_RECV_CALLBACK_LIST:
try:
func(client_id, msg_type, msg_data)
except Exception as e:
logger.error(f"接收回调执行失败: {e}")
except Exception as e:
logger.error(f"解析消息失败: {e}")
@WINFUNCTYPE(None, ctypes.c_ulong)
def wechat_close_callback(client_id):
"""
微信断开连接回调C 函数)
Args:
client_id: 客户端 ID
"""
logger.warning(f"[回调] 客户端断开: {client_id}")
for func in _GLOBAL_CLOSE_CALLBACK_LIST:
try:
func(client_id)
except Exception as e:
logger.error(f"断开回调执行失败: {e}")