Skip to content

Commit

Permalink
新增ws文件缓冲大小参数,修复bug
Browse files Browse the repository at this point in the history
  • Loading branch information
barryblueice committed Aug 22, 2024
1 parent 4d5f93c commit c4ec8c7
Show file tree
Hide file tree
Showing 7 changed files with 245 additions and 29 deletions.
35 changes: 29 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
<a href="https://github.com/barryblueice/Vanilla-Client/blob/main/LICENSE"><img src="https://img.shields.io/github/license/barryblueice/Vanilla-Client" alt="License"></a>
</p>

> [!CAUTION]\
> **请不要在 QQ 官方群聊和任何影响力较大的简中互联网平台(包括但不限于: 哔哩哔哩,微博,知乎,抖音等)发布和讨论*任何*与本Client存在相关性的信息!**
## 简介

[wxhelper](https://github.com/ttttupup/wxhelper)的OneBot V12客户端实现。
Expand Down Expand Up @@ -48,6 +51,21 @@ poetry install
poetry run python main.py
```

## .env环境配置详解:

|参数名|解释|范例/默认值|备注
|:-:|:-:|:-:|:-:|
|connect_url|目标WeChat.exe被hook后的地址|127.0.0.1||
|PORT|目标WeChat.exe被hook后的端口|19088||
|HOOK_PORT|HookMsg接收端口|8000||
|onebot_ip|onebot链接地址|127.0.0.1|暂时仅支持反向连接和ip连接。|
|onebot_port|onebot链接端口号|8080|暂时仅支持反向连接。|
|data_path|运行数据路径|C:\\\data或C:\\data|请使用绝对路径。|
|wx_data_path|微信数据路径|C:\\<路径>\\WeChat Files或C:\<路径>\WeChat Files|请使用绝对路径。</br>路径可自行在微信设置中查询,如果为空则部分功能可能受到限制。|
|ws_max_size|websocket文件缓冲大小|4|单位MB,**不能为0或空。**|
|wx_version|微信版本号|3.9.8.25|请勿修改!|
|V_version|Vanilla Client版本号|1.3.1|请勿修改!|

## Onebot V12连接支持情况:

- [ ] HTTP
Expand All @@ -74,7 +92,7 @@ poetry run python main.py
**Notice事件:**
|Event|实现情况|备注|
|:-:|:-:|:-:|
|notice.friend_increase||后续可能更新|
|notice.friend_increase||后续可能更新|
|notice.friend_decrease||后续可能更新|
|notice.private_message_delete|✔️||
|notice.group_member_increase||后续可能更新|
Expand All @@ -94,13 +112,13 @@ poetry run python main.py
|Action|实现情况|备注|
|:-:|:-:|:-:|
|get_self_info|✔️||
|get_user_info|✔️|由于上游端限制,bot在群聊中会通过监听消息的方式收集群成员的wxid和username并保存为member.db。</br>在私聊事件中,若被触发wxid不存在于member.db,则username默认返回wxid。</br>你可以通过修改db文件的方式进行username的自定义。</br>通过数据库解包方式进行用户Action的实现暂不考虑支持。|
|get_friend_list||后续可能更新|
|get_user_info|✔️|由于上游端限制,bot在群聊中会通过监听消息的方式收集群成员的wxid和username并保存为member.db。</br>在私聊事件中,若被触发wxid不存在于member.db,则username默认返回wxid。</br>你可以通过修改db文件的方式进行username的自定义。|
|get_friend_list|✔️||

**Message Action:**
|Action|实现情况|备注|
|:-:|:-:|:-:|
|send_message|✔️/⭕|群聊/个人消息均支持。</br>目前仅支持发送图片和文本,文件发送仍在测试阶段,表情发送后续会支持|
|send_message|✔️/⭕|群聊/个人消息均支持。</br>目前仅支持发送静态图片和文本。</br>由于上游端支持问题,gif动图默认以静态图片形式发送|
|delete_message||因上游端问题无法实现|

**文件Action:**
Expand Down Expand Up @@ -137,12 +155,17 @@ poetry run python main.py

|Event|实现情况|备注|
|:-:|:-:|:-:|
|notice.get_private_poke|✔️|参考自[ComWeChatBotClient](https://justundertaker.github.io/ComWeChatBotClient/event/notice.html),用法相同。|
|notice.wx.get_group_poke|✔️|参考自[ComWeChatBotClient](https://justundertaker.github.io/ComWeChatBotClient/event/notice.html),用法相同。|
|notice.get_private_poke|✔️|参考自[ComWeChatBotClient](https://justundertaker.github.io/ComWeChatBotClient/event/notice.html#%E7%A7%81%E8%81%8A%E6%8B%8D%E4%B8%80%E6%8B%8D%E9%80%9A%E7%9F%A5),用法相同。|
|notice.wx.get_group_poke|✔️|参考自[ComWeChatBotClient](https://justundertaker.github.io/ComWeChatBotClient/event/notice.html#%E7%BE%A4%E8%81%8A%E6%8B%8D%E4%B8%80%E6%8B%8D%E9%80%9A%E7%9F%A5),用法相同。|

**扩展Action:**
|Action|实现情况|备注|
|:-:|:-:|:-:|

## 其他实现情况

|名称|实现情况|备注|
|:-:|:-:|:-:|
|OneBot V11支持||由于wxid的性质与OneBot V11标准冲突,</br>(在OneBot V11中,user_id要求为int64),故不提供支持。|
|多开支持||由于某些特殊原因,不提供支持。|
|他人被at检测||上游端暂未实现,所以暂不考虑支持|
185 changes: 180 additions & 5 deletions connection/ws_reversed/api/ActionHandle.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@
video_path = os.path.join(data_path,'video')
file_path = os.path.join(data_path,'file')

connect_url = os.getenv("connect_url")
PORT = os.getenv("PORT")

loop = asyncio.get_event_loop()

FILE_TYPES = {
Expand Down Expand Up @@ -104,7 +107,7 @@ async def member_find_by_user_id(
conn.close()

async def MessageActionHandle(self,msg):
# print (msg)
match msg["action"]:

case "send_message":
Expand All @@ -114,6 +117,7 @@ async def MessageActionHandle(self,msg):
MsgTextList = ''
MsgImageList = []
MsgFileList = []
MsgEmojiList = []
echo = msg["echo"]

try:
Expand All @@ -131,6 +135,8 @@ async def MessageActionHandle(self,msg):
MsgTextList += i['data']['text']
case "image":
MsgImageList.append(i['data']['file_id'])
case "file":
MsgFileList.append(i['data']['file_id'])
case _:
MsgImageList.append(i['data']['file_id'])
except:
Expand All @@ -152,6 +158,17 @@ async def MessageActionHandle(self,msg):
)
break

if MsgEmojiList != []:
for m in MsgEmojiList:
for i in os.listdir(img_path):
if str(i).startswith(m):
await self.PrivateEmojiAction(
user_id=user_id,
img=os.path.join(img_path,i),
echo=echo
)
break

if MsgFileList != []:
for m in MsgFileList:
for i in os.listdir(audio_path):
Expand Down Expand Up @@ -190,6 +207,7 @@ async def MessageActionHandle(self,msg):
MsgTextList = ''
MsgImageList = []
MsgFileList = []
MsgEmojiList = []
for i in list(msg["params"]["message"]):
match i["type"]:
case "mention":
Expand All @@ -204,6 +222,8 @@ async def MessageActionHandle(self,msg):
MsgTextList += i['data']['text']
case "image":
MsgImageList.append(i['data']['file_id'])
case "file":
MsgFileList.append(i['data']['file_id'])
case _:
MsgImageList.append(i['data']['file_id'])

Expand All @@ -229,6 +249,17 @@ async def MessageActionHandle(self,msg):
)
break

if MsgEmojiList != []:
for m in MsgEmojiList:
for i in os.listdir(img_path):
if str(i).startswith(m):
await self.GroupEmojiAction(
group_id=group_id,
img=os.path.join(img_path,i),
echo=echo
)
break

if MsgFileList != []:
for m in MsgFileList:
for i in os.listdir(audio_path):
Expand Down Expand Up @@ -297,7 +328,19 @@ async def MessageActionHandle(self,msg):
await self.GetSelfInfoAction(
echo=echo
)


case "get_friend_list":
echo = msg["echo"]
await self.GetFriendListAction(
echo=echo
)

# case "wx.link":
# echo = msg["echo"]
# await self.GetFriendListAction(
# echo=echo
# )

case _:
echo = msg["echo"]
await self.UnsupportedMessageAction(
Expand Down Expand Up @@ -505,6 +548,100 @@ async def GroupImageAction(
echo=echo
)

async def PrivateEmojiAction(
self,
user_id: str,
img: str,
echo: str,
):
logger.info(f"向好友 {user_id} 发送私聊Emoji消息")
headers = {
'Content-Type': 'application/json'
}
payload = json.dumps({
"wxid": user_id,
"filePath": img
})
response = requests.request("POST", f"{self.ActionUrl}/api/sendCustomEmotion", headers=headers, data=payload).json()
try:
if (response['code'] == 1) or (response["msg"] == "success"):
status = 'ok'
retcode = 0
msgId = str(int(time.time()))
createdtime = time.time()
message = ""
echo = echo
else:
status = 'failed'
retcode = 10001
msgId = str(0)
createdtime = time.time()
message = response["msg"]
echo = echo
except:
status = 'failed'
retcode = 10001
msgId = str(0)
createdtime = time.time()
message = response["msg"]
echo = echo

await MessageAction.MessageSentAction(
status=status,
retcode=retcode,
msgId=msgId,
createdtime=createdtime,
message=message,
echo=echo
)

async def GroupEmojiAction(
self,
group_id: str,
img: str,
echo: str,
):
logger.info(f"向群聊 {group_id} 发送Emoji消息")
headers = {
'Content-Type': 'application/json'
}
payload = json.dumps({
"wxid": group_id,
"filePath": img
})
response = requests.request("POST", f"{self.ActionUrl}/api/sendFileMsg", headers=headers, data=payload).json()
try:
if (response['code'] == 1) or (response["msg"] == "success"):
status = 'ok'
retcode = 0
msgId = str(int(time.time()))
createdtime = time.time()
message = ""
echo = echo
else:
status = 'failed'
retcode = 10001
msgId = str(0)
createdtime = time.time()
message = response["msg"]
echo = echo
except:
status = 'failed'
retcode = 10001
msgId = str(0)
createdtime = time.time()
message = response["msg"]
echo = echo

await MessageAction.MessageSentAction(
status=status,
retcode=retcode,
msgId=msgId,
createdtime=createdtime,
message=message,
echo=echo
)

async def PrivateFileAction(
self,
user_id: str,
Expand All @@ -519,7 +656,7 @@ async def PrivateFileAction(
"wxid": user_id,
"filePath": file
})
response = requests.request("POST", f"{self.ActionUrl}/api/sendImagesMsg", headers=headers, data=payload).json()
response = requests.request("POST", f"{self.ActionUrl}/api/sendFileMsg", headers=headers, data=payload).json()
try:
if (response['code'] == 1) or (response["msg"] == "success"):
status = 'ok'
Expand Down Expand Up @@ -566,7 +703,7 @@ async def GroupFileAction(
"wxid": group_id,
"filePath": file
})
response = requests.request("POST", f"{self.ActionUrl}/api/sendImagesMsg", headers=headers, data=payload).json()
response = requests.request("POST", f"{self.ActionUrl}/api/sendFileMsg", headers=headers, data=payload).json()
try:
if (response['code'] == 1) or (response["msg"] == "success"):
status = 'ok'
Expand Down Expand Up @@ -668,7 +805,7 @@ async def UploadFileAction(
case "data":
if type(data) != bytes:
data = base64.b64decode(data)
with open(os.path.join(img_path,f"{file_id}.png"),'wb') as file_obj:
with open(os.path.join(img_path,f"{file_id}.gif"),'wb') as file_obj:
file_obj.write(data)
case _:
raise ValueError("Type Not Supported")
Expand Down Expand Up @@ -716,7 +853,45 @@ async def GetSelfInfoAction(
message=message,
echo=echo
)

async def GetFriendListAction(
self,
echo: str
):
member_list = []
try:
url = f"http://{connect_url}:{PORT}/api/getContactList"
payload = {}
headers = {}
response = requests.request("POST", url, headers=headers, data=payload).json()
for i in response['data']:
if str(i['wxid']).startswith('wxid_'):
member_list.append({
"user_id": i['wxid'],
"user_name": i['nickname']
})
status = 'ok'
retcode = 0
message = ''

except Exception as e:

self_id = '0',
self_name = '0'
status = 'failed'
retcode = 10001
message = f"Error: {e}"

await UserAction.GetFriendList(
status=status,
retcode=retcode,
self_id=self_id,
self_name=self_name,
message=message,
echo=echo,
data=member_list
)

async def UnsupportedMessageAction(
self,
echo: str
Expand Down
2 changes: 0 additions & 2 deletions connection/ws_reversed/api/UserAction.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,6 @@ async def GetUserInfo(
async def GetFriendList(
status: str,
retcode: int,
user_id: str,
user_name: str,
message: str,
echo: str,
data: list
Expand Down
6 changes: 3 additions & 3 deletions connection/ws_reversed/event/MetaEvent.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ async def connect(client):
except Exception as e:
logger.error(f'MetaEvent.connect元事件发送失败:{e}')

async def status_update(client, self_id: str):
async def status_update(client, self_id: str, online: bool):
try:
message = json.dumps({
"id": str(uuid.uuid4()),
Expand All @@ -48,12 +48,12 @@ async def status_update(client, self_id: str):
"platform": "wechat",
"user_id": self_id
},
"online": True
"online": online
}
]
}
})

# print (message)
await client.append_requests(message)
logger.success('已发送MetaEvent.status_update元事件')
except Exception as e:
Expand Down
Loading

0 comments on commit c4ec8c7

Please sign in to comment.