From 391011b69610395d50e9e9e1fe2ddf3885cbaf1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=B6=9B?= <2450572350@qq.com> Date: Thu, 1 Jun 2023 09:57:03 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B8=B8=E8=A7=81=E7=9A=84=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E5=92=8C=E8=AF=B7=E6=B1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- java_client/README.md | 1 + .../com/example/wxhk/constant/WxMsgType.java | 10 +- .../wxhk/controller/WxMsgController.java | 4 +- .../java/com/example/wxhk/infe/SendMsg.java | 11 +++ .../example/wxhk/model/PrivateChatMsg.java | 3 +- .../wxhk/model/request/AddFriends.java | 20 ++++ .../wxhk/model/request/ConfirmThePayment.java | 27 +++++ .../wxhk/model/request/FindWeChat.java | 19 ++++ .../wxhk/model/request/ForwardMessages.java | 23 +++++ .../wxhk/model/request/GetGroupMembers.java | 16 +++ .../GetsTheNicknameOfAGroupMember.java | 23 +++++ .../request/IncreaseGroupMembership.java | 23 +++++ .../wxhk/model/request/SendAtText.java | 25 +++++ .../example/wxhk/model/request/SendFile.java | 22 +++++ .../example/wxhk/model/request/SendImg.java | 22 +++++ .../example/wxhk/model/request/SendMsg.java | 52 ++++++++++ .../example/wxhk/model/request/SendText.java | 18 ++++ .../wxhk/model/request/ThroughFriends.java | 27 +++++ .../com/example/wxhk/msg/WxMsgHandle.java | 98 ++++++++++--------- .../com/example/wxhk/tcp/vertx/ArrHandle.java | 59 ++++++----- .../example/wxhk/tcp/vertx/InitWeChat.java | 12 +-- .../com/example/wxhk/tcp/vertx/VertxTcp.java | 15 ++- .../com/example/wxhk/util/HttpAsyncUtil.java | 14 +-- .../com/example/wxhk/util/HttpSendUtil.java | 53 +++++++--- .../com/example/wxhk/util/HttpSyncUtil.java | 8 +- 25 files changed, 489 insertions(+), 116 deletions(-) create mode 100644 java_client/src/main/java/com/example/wxhk/infe/SendMsg.java create mode 100644 java_client/src/main/java/com/example/wxhk/model/request/AddFriends.java create mode 100644 java_client/src/main/java/com/example/wxhk/model/request/ConfirmThePayment.java create mode 100644 java_client/src/main/java/com/example/wxhk/model/request/FindWeChat.java create mode 100644 java_client/src/main/java/com/example/wxhk/model/request/ForwardMessages.java create mode 100644 java_client/src/main/java/com/example/wxhk/model/request/GetGroupMembers.java create mode 100644 java_client/src/main/java/com/example/wxhk/model/request/GetsTheNicknameOfAGroupMember.java create mode 100644 java_client/src/main/java/com/example/wxhk/model/request/IncreaseGroupMembership.java create mode 100644 java_client/src/main/java/com/example/wxhk/model/request/SendAtText.java create mode 100644 java_client/src/main/java/com/example/wxhk/model/request/SendFile.java create mode 100644 java_client/src/main/java/com/example/wxhk/model/request/SendImg.java create mode 100644 java_client/src/main/java/com/example/wxhk/model/request/SendMsg.java create mode 100644 java_client/src/main/java/com/example/wxhk/model/request/SendText.java create mode 100644 java_client/src/main/java/com/example/wxhk/model/request/ThroughFriends.java diff --git a/java_client/README.md b/java_client/README.md index 9c712ab..d41a462 100644 --- a/java_client/README.md +++ b/java_client/README.md @@ -1,5 +1,6 @@ 环境为jdk17 执行之后会在当前项目所处磁盘根路径生成一个exec文件夹,然后会把src/main/resources/exec下的文件放在那避免因为路径问题出错 +java_client/src/main/resources/exec/c.exe 为注入器,只不过把名字改短了,更新的话换成最新版,改个名字就行, wxhelper.dll同理 项目启动之后,会生成一个tcp服务端,用来接受hook信息,然后把接收的信息放在队列中,之后用一个线程去循环处理消息. 具体实现可以看 diff --git a/java_client/src/main/java/com/example/wxhk/constant/WxMsgType.java b/java_client/src/main/java/com/example/wxhk/constant/WxMsgType.java index 59b9570..d46ffde 100644 --- a/java_client/src/main/java/com/example/wxhk/constant/WxMsgType.java +++ b/java_client/src/main/java/com/example/wxhk/constant/WxMsgType.java @@ -16,7 +16,7 @@ public enum WxMsgType { 收到名片(42), 表情(47), 转账和收款(49), - 收到转账之后(51), + 收到转账之后或者文件助手等信息(51), /** * 扫码触发,会触发2次, 有一次有编号,一次没有,还有登陆之后也有,很多情况都会调用这个 */ @@ -25,11 +25,11 @@ public enum WxMsgType { ; Integer type; - public Integer getType() { - return type; - } - WxMsgType(Integer type) { this.type = type; } + + public Integer getType() { + return type; + } } diff --git a/java_client/src/main/java/com/example/wxhk/controller/WxMsgController.java b/java_client/src/main/java/com/example/wxhk/controller/WxMsgController.java index 05e4ede..78b2e5d 100644 --- a/java_client/src/main/java/com/example/wxhk/controller/WxMsgController.java +++ b/java_client/src/main/java/com/example/wxhk/controller/WxMsgController.java @@ -5,10 +5,10 @@ import org.dromara.hutool.log.Log; public class WxMsgController { - protected static final Log log = Log.get(); + protected static final Log log = Log.get(); - void init(){ + void init() { } } diff --git a/java_client/src/main/java/com/example/wxhk/infe/SendMsg.java b/java_client/src/main/java/com/example/wxhk/infe/SendMsg.java new file mode 100644 index 0000000..1ab7d3a --- /dev/null +++ b/java_client/src/main/java/com/example/wxhk/infe/SendMsg.java @@ -0,0 +1,11 @@ +package com.example.wxhk.infe; + +/** + * http接口请求的基础接口 + * + * @author wt + * @date 2023/06/01 + */ +public interface SendMsg extends java.io.Serializable{ + +} diff --git a/java_client/src/main/java/com/example/wxhk/model/PrivateChatMsg.java b/java_client/src/main/java/com/example/wxhk/model/PrivateChatMsg.java index ceb6da0..25424b7 100644 --- a/java_client/src/main/java/com/example/wxhk/model/PrivateChatMsg.java +++ b/java_client/src/main/java/com/example/wxhk/model/PrivateChatMsg.java @@ -17,6 +17,7 @@ import java.io.Serializable; @JsonIgnoreProperties(ignoreUnknown = true) public class PrivateChatMsg implements Serializable { + String path; /** * 内容 */ @@ -41,8 +42,6 @@ public class PrivateChatMsg implements Serializable { private String signature; private String time; private Integer timestamp; - - String path; /** * 类型 */ diff --git a/java_client/src/main/java/com/example/wxhk/model/request/AddFriends.java b/java_client/src/main/java/com/example/wxhk/model/request/AddFriends.java new file mode 100644 index 0000000..cc20d11 --- /dev/null +++ b/java_client/src/main/java/com/example/wxhk/model/request/AddFriends.java @@ -0,0 +1,20 @@ +package com.example.wxhk.model.request; + +import com.example.wxhk.infe.SendMsg; +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * 添加wxid 好友 + * @author wt + * @date 2023/06/01 + */ +@Data +@Accessors(chain = true) +public class AddFriends implements SendMsg { + String wxid; + /** + * 验证信息 + */ + String msg; +} diff --git a/java_client/src/main/java/com/example/wxhk/model/request/ConfirmThePayment.java b/java_client/src/main/java/com/example/wxhk/model/request/ConfirmThePayment.java new file mode 100644 index 0000000..26e0f0b --- /dev/null +++ b/java_client/src/main/java/com/example/wxhk/model/request/ConfirmThePayment.java @@ -0,0 +1,27 @@ +package com.example.wxhk.model.request; + +import com.example.wxhk.infe.SendMsg; +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * 确认收款 + * @author wt + * @date 2023/06/01 + */ +@Data +@Accessors(chain = true) +public class ConfirmThePayment implements SendMsg { + /** + * 转账人微信id,从hook的消息中获取 + */ + String wxid; + /** + * 从hook的消息中获取对应的字段内容 + */ + String transcationId; + /** + * 从hook的消息中获取对应的字段内容。 + */ + String transferId; +} diff --git a/java_client/src/main/java/com/example/wxhk/model/request/FindWeChat.java b/java_client/src/main/java/com/example/wxhk/model/request/FindWeChat.java new file mode 100644 index 0000000..dc3d4a0 --- /dev/null +++ b/java_client/src/main/java/com/example/wxhk/model/request/FindWeChat.java @@ -0,0 +1,19 @@ +package com.example.wxhk.model.request; + +import com.example.wxhk.infe.SendMsg; +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * 通过手机或者qq查找微信 + * @author wt + * @date 2023/06/01 + */ +@Data +@Accessors(chain = true) +public class FindWeChat implements SendMsg { + /** + * 通过 手机或qq查询信息 + */ + String keyword; +} diff --git a/java_client/src/main/java/com/example/wxhk/model/request/ForwardMessages.java b/java_client/src/main/java/com/example/wxhk/model/request/ForwardMessages.java new file mode 100644 index 0000000..723e928 --- /dev/null +++ b/java_client/src/main/java/com/example/wxhk/model/request/ForwardMessages.java @@ -0,0 +1,23 @@ +package com.example.wxhk.model.request; + +import com.example.wxhk.infe.SendMsg; +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * 转发消息 + * @author wt + * @date 2023/06/01 + */ +@Data +@Accessors(chain = true) +public class ForwardMessages implements SendMsg { + /** + * 消息接收人wxid + */ + String wxid; + /** + * 消息id + */ + String msgid; +} diff --git a/java_client/src/main/java/com/example/wxhk/model/request/GetGroupMembers.java b/java_client/src/main/java/com/example/wxhk/model/request/GetGroupMembers.java new file mode 100644 index 0000000..7f48379 --- /dev/null +++ b/java_client/src/main/java/com/example/wxhk/model/request/GetGroupMembers.java @@ -0,0 +1,16 @@ +package com.example.wxhk.model.request; + +import com.example.wxhk.infe.SendMsg; +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * 获取群成员 + * @author wt + * @date 2023/06/01 + */ +@Data +@Accessors(chain = true) +public class GetGroupMembers implements SendMsg { + String chatRoomId; +} diff --git a/java_client/src/main/java/com/example/wxhk/model/request/GetsTheNicknameOfAGroupMember.java b/java_client/src/main/java/com/example/wxhk/model/request/GetsTheNicknameOfAGroupMember.java new file mode 100644 index 0000000..60e4e22 --- /dev/null +++ b/java_client/src/main/java/com/example/wxhk/model/request/GetsTheNicknameOfAGroupMember.java @@ -0,0 +1,23 @@ +package com.example.wxhk.model.request; + +import com.example.wxhk.infe.SendMsg; +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * 获取群成员昵称 + * @author wt + * @date 2023/06/01 + */ +@Data +@Accessors(chain = true) +public class GetsTheNicknameOfAGroupMember implements SendMsg { + /** + * 聊天室id + */ + String chatRoomId; + /** + * 成员id + */ + String memberId; +} diff --git a/java_client/src/main/java/com/example/wxhk/model/request/IncreaseGroupMembership.java b/java_client/src/main/java/com/example/wxhk/model/request/IncreaseGroupMembership.java new file mode 100644 index 0000000..a43a1e4 --- /dev/null +++ b/java_client/src/main/java/com/example/wxhk/model/request/IncreaseGroupMembership.java @@ -0,0 +1,23 @@ +package com.example.wxhk.model.request; + +import com.example.wxhk.infe.SendMsg; +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * 增加群成员 + * @author wt + * @date 2023/06/01 + */ +@Data +@Accessors(chain = true) +public class IncreaseGroupMembership implements SendMsg { + /** + * 聊天室id + */ + String chatRoomId; + /** + * 成员id,以,分割 + */ + String memberIds; +} diff --git a/java_client/src/main/java/com/example/wxhk/model/request/SendAtText.java b/java_client/src/main/java/com/example/wxhk/model/request/SendAtText.java new file mode 100644 index 0000000..28b93b0 --- /dev/null +++ b/java_client/src/main/java/com/example/wxhk/model/request/SendAtText.java @@ -0,0 +1,25 @@ +package com.example.wxhk.model.request; + +import com.example.wxhk.infe.SendMsg; +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * 发送at文本 + * @author wt + * @date 2023/06/01 + */ +@Data +@Accessors(chain = true) +public class SendAtText implements SendMsg { + /** + * 聊天室id,群聊用 + */ + String chatRoomId; + /** + * 群聊的时候用at多个用逗号隔开,@所有人则是notify@all + */ + String wxids; + + String msg; +} diff --git a/java_client/src/main/java/com/example/wxhk/model/request/SendFile.java b/java_client/src/main/java/com/example/wxhk/model/request/SendFile.java new file mode 100644 index 0000000..ee5e409 --- /dev/null +++ b/java_client/src/main/java/com/example/wxhk/model/request/SendFile.java @@ -0,0 +1,22 @@ +package com.example.wxhk.model.request; + +import com.example.wxhk.infe.SendMsg; +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * 发送文件 + * + * @author wt + * @date 2023/06/01 + */ +@Data +@Accessors(chain = true) +public class SendFile implements SendMsg { + String wxid; + /** + * 发送文件路径 + * "filePath": "C:/Users/123.txt" + */ + String filePath; +} diff --git a/java_client/src/main/java/com/example/wxhk/model/request/SendImg.java b/java_client/src/main/java/com/example/wxhk/model/request/SendImg.java new file mode 100644 index 0000000..a019d02 --- /dev/null +++ b/java_client/src/main/java/com/example/wxhk/model/request/SendImg.java @@ -0,0 +1,22 @@ +package com.example.wxhk.model.request; + +import com.example.wxhk.infe.SendMsg; +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * 发送图片 + * + * @author wt + * @date 2023/06/01 + */ +@Data +@Accessors(chain = true) +public class SendImg implements SendMsg { + String wxid; + /** + * 发送图片接口 + * "imagePath": "C:/Users/123.png" + */ + String imagePath; +} diff --git a/java_client/src/main/java/com/example/wxhk/model/request/SendMsg.java b/java_client/src/main/java/com/example/wxhk/model/request/SendMsg.java new file mode 100644 index 0000000..e86b213 --- /dev/null +++ b/java_client/src/main/java/com/example/wxhk/model/request/SendMsg.java @@ -0,0 +1,52 @@ +package com.example.wxhk.model.request; + +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * http请求参数 + * + * @author wt + * @date 2023/06/01 + */ +@Data +@Accessors(chain = true) +public class SendMsg { + /** + * wxid + */ + String wxid; + /** + * 消息内容 + */ + String msg; + + /** + * 聊天室id,群聊用 + */ + String chatRoomId; + /** + * 成员id + */ + String memberId; + + /** + * 群聊的时候用at多个用逗号隔开,@所有人则是notify@all + */ + String wxids; + /** + * 发送图片接口 + * "imagePath": "C:/Users/123.png" + */ + String imagePath; + /** + * 发送文件路径 + * "filePath": "C:/Users/123.txt" + */ + String filePath; + /** + * 通过 手机或qq查询信息 + */ + String keyword; + +} diff --git a/java_client/src/main/java/com/example/wxhk/model/request/SendText.java b/java_client/src/main/java/com/example/wxhk/model/request/SendText.java new file mode 100644 index 0000000..f15056e --- /dev/null +++ b/java_client/src/main/java/com/example/wxhk/model/request/SendText.java @@ -0,0 +1,18 @@ +package com.example.wxhk.model.request; + +import com.example.wxhk.infe.SendMsg; +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * 发送文本 + * + * @author wt + * @date 2023/06/01 + */ +@Data +@Accessors(chain = true) +public class SendText implements SendMsg { + String wxid; + String msg; +} diff --git a/java_client/src/main/java/com/example/wxhk/model/request/ThroughFriends.java b/java_client/src/main/java/com/example/wxhk/model/request/ThroughFriends.java new file mode 100644 index 0000000..2134b40 --- /dev/null +++ b/java_client/src/main/java/com/example/wxhk/model/request/ThroughFriends.java @@ -0,0 +1,27 @@ +package com.example.wxhk.model.request; + +import com.example.wxhk.infe.SendMsg; +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * 通过好友请求 + * @author wt + * @date 2023/06/01 + */ +@Data +@Accessors(chain = true) +public class ThroughFriends implements SendMsg { + /** + * 添加好友消息内容里的encryptusername + */ + String v3; + /** + * 添加好友消息内容里的ticket + */ + String v4; + /** + * 好友权限,0是无限制,1是不让他看我,2是不看他,3是1+2 + */ + String permission; +} diff --git a/java_client/src/main/java/com/example/wxhk/msg/WxMsgHandle.java b/java_client/src/main/java/com/example/wxhk/msg/WxMsgHandle.java index a31fec0..0f99519 100644 --- a/java_client/src/main/java/com/example/wxhk/msg/WxMsgHandle.java +++ b/java_client/src/main/java/com/example/wxhk/msg/WxMsgHandle.java @@ -18,42 +18,49 @@ import org.w3c.dom.NodeList; import java.math.BigDecimal; import java.util.Iterator; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @Component public class WxMsgHandle { - public static final ConcurrentHashMap map = new ConcurrentHashMap<>(32); - + public static final ConcurrentHashMap map = new ConcurrentHashMap<>(32); + protected static final Log log = Log.get(); public static ConcurrentHashMap cache = new ConcurrentHashMap<>(); - protected static final Log log=Log.get(); - - public WxMsgHandle() { add(chatMsg -> { + if(Objects.equals(chatMsg.getIsSendMsg(), 1) && Objects.equals(chatMsg.getIsSendByPhone(), 1)){ + log.info("手机端对:{}发出:{}",chatMsg.getFromUser(),chatMsg.getContent()); + return 1; + } return 1; - },WxMsgType.私聊信息);// 好友请求 + }, WxMsgType.私聊信息); + add(chatMsg -> { + if("filehelper".equals(chatMsg.getFromUser())){ + log.info("文件助手:{},",chatMsg.getContent()); + } + return 1; + }, WxMsgType.收到转账之后或者文件助手等信息); add(chatMsg -> { HttpSendUtil.通过好友请求(chatMsg); return 1; - },WxMsgType.好友请求);// 好友请求 + }, WxMsgType.好友请求);// 好友请求 add(chatMsg -> { boolean f = 解析扫码支付第二段(chatMsg); - if(f){ - f=解析收款信息1段(chatMsg); - if(f){ + if (f) { + f = 解析收款信息1段(chatMsg); + if (f) { 解析收款信息2段(chatMsg); } } return null; - },WxMsgType.转账和收款); + }, WxMsgType.转账和收款); add(chatMsg -> { boolean f = 解析扫码支付第一段(chatMsg); return null; - },WxMsgType.扫码触发); - + }, WxMsgType.扫码触发); } @@ -69,14 +76,14 @@ public class WxMsgHandle { Document document = XmlUtil.parseXml(chatMsg.getContent()); Element documentElement = document.getDocumentElement(); String localName = documentElement.getLocalName(); - if("sysmsg".equals(localName)){ + if ("sysmsg".equals(localName)) { String type = documentElement.getAttribute("type"); - if("paymsg".equals(type)){ + if ("paymsg".equals(type)) { NodeList outtradeno = documentElement.getElementsByTagName("outtradeno"); - if (outtradeno.getLength()>0) { + if (outtradeno.getLength() > 0) { String textContent = outtradeno.item(0).getTextContent(); String textContent1 = documentElement.getElementsByTagName("username").item(0).getTextContent(); - cache.put(textContent,textContent1); + cache.put(textContent, textContent1); return false; } } @@ -99,23 +106,23 @@ public class WxMsgHandle { Document document = XmlUtil.parseXml(chatMsg.getContent()); Element documentElement = document.getDocumentElement(); String localName = documentElement.getLocalName(); - if("msg".equals(localName)){ + if ("msg".equals(localName)) { NodeList outtradeno = documentElement.getElementsByTagName("weapp_path"); - if(outtradeno.getLength()>1){ + if (outtradeno.getLength() > 1) { String textContent = outtradeno.item(1).getTextContent(); Set> entries = cache.entrySet(); Iterator> iterator = entries.iterator(); - while (iterator.hasNext()){ + while (iterator.hasNext()) { Map.Entry next = iterator.next(); if (textContent.contains(next.getKey())) { // 得到了交易信息 NodeList word = documentElement.getElementsByTagName("word"); String monery = word.item(1).getTextContent(); String remark = word.item(3).getTextContent(); - if(monery.startsWith("¥")){ + if (monery.startsWith("¥")) { String substring = monery.substring(1); BigDecimal decimal = new BigDecimal(substring); - log.info("扫码收款:{},付款人:{},付款备注:{}",decimal.stripTrailingZeros().toPlainString(),next.getValue(),remark); + log.info("扫码收款:{},付款人:{},付款备注:{}", decimal.stripTrailingZeros().toPlainString(), next.getValue(), remark); iterator.remove(); return false; } @@ -130,25 +137,26 @@ public class WxMsgHandle { } return true; } + public static boolean 解析收款信息2段(PrivateChatMsg chatMsg) { try { Document document = XmlUtil.parseXml(chatMsg.getContent()); Element documentElement = document.getDocumentElement(); String localName = documentElement.getLocalName(); - if("msg".equals(localName)){ - if (documentElement.getElementsByTagName("transcationid").getLength()>0) { + if ("msg".equals(localName)) { + if (documentElement.getElementsByTagName("transcationid").getLength() > 0) { String remark = documentElement.getElementsByTagName("pay_memo").item(0).getTextContent(); String monery = documentElement.getElementsByTagName("feedesc").item(0).getTextContent(); String receiver_username = documentElement.getElementsByTagName("receiver_username").item(0).getTextContent(); - if(InitWeChat.WXID_MAP.contains(receiver_username)){ + if (InitWeChat.WXID_MAP.contains(receiver_username)) { // 如果是自己转出去的,则不需要解析了 return false; } - if(monery.startsWith("¥")){ + if (monery.startsWith("¥")) { String substring = monery.substring(1); BigDecimal decimal = new BigDecimal(substring); - log.info("收款:{},付款人:{},付款备注:{}",decimal.stripTrailingZeros().toPlainString(),receiver_username,remark); + log.info("收款:{},付款人:{},付款备注:{}", decimal.stripTrailingZeros().toPlainString(), receiver_username, remark); return false; } } @@ -163,52 +171,50 @@ public class WxMsgHandle { /** * 解析收款信息1段 * 会自动进行收款 + * * @param chatMsg * @return boolean true则 继续解析,false则不需要解析了 */ - public static boolean 解析收款信息1段(PrivateChatMsg chatMsg){ + public static boolean 解析收款信息1段(PrivateChatMsg chatMsg) { try { String content = chatMsg.getContent(); Document document = XmlUtil.parseXml(content); Node paysubtype = document.getElementsByTagName("paysubtype").item(0); - if("1".equals(paysubtype.getTextContent().trim())){ + if ("1".equals(paysubtype.getTextContent().trim())) { // 手机发出去的 String textContent = document.getElementsByTagName("receiver_username").item(0).getTextContent(); - if(!InitWeChat.WXID_MAP.contains(textContent)){ + if (!InitWeChat.WXID_MAP.contains(textContent)) { // 如果不是机器人收款,则认为不需要解析了,大概率是机器人自己发出去的 return false; } Node transcationid = document.getDocumentElement().getElementsByTagName("transcationid").item(0); Node transferid = document.getDocumentElement().getElementsByTagName("transferid").item(0); - HttpSyncUtil.exec(HttpAsyncUtil.Type.确认收款, new JsonObject().put("wxid",chatMsg.getFromUser()) - .put("transcationId",transcationid.getTextContent()) - .put("transferId",transferid.getTextContent())); + HttpSyncUtil.exec(HttpAsyncUtil.Type.确认收款, new JsonObject().put("wxid", chatMsg.getFromUser()) + .put("transcationId", transcationid.getTextContent()) + .put("transferId", transferid.getTextContent())); return false; } - } catch (Exception e) { - log.error(e); + } catch (Exception e) { + log.error(e); } return true; } - - public interface Handle{ - Object handle(PrivateChatMsg chatMsg); + public static void exec(PrivateChatMsg chatMsg) { + Handle handle = map.get(chatMsg.getType()); + if (handle != null) { + handle.handle(chatMsg); + } } - - - public void add(Handle handle, WxMsgType...type){ + public void add(Handle handle, WxMsgType... type) { for (WxMsgType integer : type) { map.put(integer.getType(), handle); } } - public static void exec(PrivateChatMsg chatMsg){ - Handle handle = map.get(chatMsg.getType()); - if (handle != null) { - handle.handle(chatMsg); - } + public interface Handle { + Object handle(PrivateChatMsg chatMsg); } } diff --git a/java_client/src/main/java/com/example/wxhk/tcp/vertx/ArrHandle.java b/java_client/src/main/java/com/example/wxhk/tcp/vertx/ArrHandle.java index 39add74..d9fa2f6 100644 --- a/java_client/src/main/java/com/example/wxhk/tcp/vertx/ArrHandle.java +++ b/java_client/src/main/java/com/example/wxhk/tcp/vertx/ArrHandle.java @@ -15,40 +15,51 @@ import java.util.concurrent.TimeUnit; /** * 消息处理 + * * @author wt * @date 2023/05/31 */ @Component public class ArrHandle { - protected static final Log log = Log.get(); - public static final ThreadPoolExecutor sub = new ThreadPoolExecutor(1, 10, 30, TimeUnit.MINUTES, new LinkedBlockingQueue<>(), new NamedThreadFactory("sub", false)); + public static final ThreadPoolExecutor sub = new ThreadPoolExecutor(1, 10, 30, TimeUnit.MINUTES, new LinkedBlockingQueue<>(), new NamedThreadFactory("sub", false)); + public static final ThreadLocal chatMsgThreadLocal = new InheritableThreadLocal<>(); + protected static final Log log = Log.get(); + /** + * 得到当前正在处理的消息 + * + * @return {@link PrivateChatMsg} + */ + public static PrivateChatMsg getPriMsg() { + return chatMsgThreadLocal.get(); + } - @PostConstruct - public void exec(){ - for (int i = 0; i < sub.getCorePoolSize(); i++) { - sub.submit(() -> { - while (!Thread.currentThread().isInterrupted()){ - try { - JsonObject take = VertxTcp.LINKED_BLOCKING_QUEUE.take(); - log.info("{}",take.encode()); - - PrivateChatMsg privateChatMsg = take.mapTo(PrivateChatMsg.class); - if("weixin".equals(privateChatMsg.getFromUser())){ - String s = HttpSendUtil.获取当前登陆微信id(); - InitWeChat.WXID_MAP.add(s); - continue; - } - WxMsgHandle.exec(privateChatMsg); - } catch (Exception e) { - log.error(e); + @PostConstruct + public void exec() { + for (int i = 0; i < sub.getCorePoolSize(); i++) { + sub.submit(() -> { + while (!Thread.currentThread().isInterrupted()) { + try { + JsonObject take = VertxTcp.LINKED_BLOCKING_QUEUE.take(); + log.info("{}", take.encode()); + PrivateChatMsg privateChatMsg = take.mapTo(PrivateChatMsg.class); + chatMsgThreadLocal.set(privateChatMsg); + if ("weixin".equals(privateChatMsg.getFromUser())) { + String s = HttpSendUtil.获取当前登陆微信id(); + InitWeChat.WXID_MAP.add(s); + continue; } + WxMsgHandle.exec(privateChatMsg); + chatMsgThreadLocal.remove(); + } catch (Exception e) { + log.error(e); } - log.error("退出线程了"); - }); - } - + } + log.error("退出线程了"); + }); } + } + } diff --git a/java_client/src/main/java/com/example/wxhk/tcp/vertx/InitWeChat.java b/java_client/src/main/java/com/example/wxhk/tcp/vertx/InitWeChat.java index 649eaf3..9c5eab5 100644 --- a/java_client/src/main/java/com/example/wxhk/tcp/vertx/InitWeChat.java +++ b/java_client/src/main/java/com/example/wxhk/tcp/vertx/InitWeChat.java @@ -31,9 +31,8 @@ import java.io.IOException; public class InitWeChat implements CommandLineRunner { public final static Log log = Log.get(); - + public static final ConcurrentHashSet WXID_MAP = new ConcurrentHashSet<>(); public static String wxPath; - public static Integer wxPort; public static Integer vertxPort; /** @@ -41,9 +40,6 @@ public class InitWeChat implements CommandLineRunner { */ public static File DLL_PATH; - public static final ConcurrentHashSet WXID_MAP=new ConcurrentHashSet<>(); - - public static void 注入dll(String wxPid) throws IOException { String format = StrUtil.format("cmd /C c.exe -I {} -p {}\\wxhelper.dll -m {}", wxPid, DLL_PATH.getAbsolutePath(), wxPid); Process exec = Runtime.getRuntime().exec(format, null, DLL_PATH); @@ -138,15 +134,15 @@ public class InitWeChat implements CommandLineRunner { 注入dll(wxPid); } ThreadUtil.execute(() -> { - while (!Thread.currentThread().isInterrupted()){ + while (!Thread.currentThread().isInterrupted()) { JsonObject exec = HttpSyncUtil.exec(HttpAsyncUtil.Type.检查微信登陆, new JsonObject()); - if(exec.getInteger("code").equals(1)){ + if (exec.getInteger("code").equals(1)) { JsonObject dl = HttpSyncUtil.exec(HttpAsyncUtil.Type.获取登录信息, new JsonObject()); JsonObject jsonObject = dl.getJsonObject("data"); String wx = jsonObject.getString("wxid"); WXID_MAP.add(wx); if (log.isDebugEnabled()) { - log.debug("检测到微信登陆:{}",wx); + log.debug("检测到微信登陆:{}", wx); } break; } diff --git a/java_client/src/main/java/com/example/wxhk/tcp/vertx/VertxTcp.java b/java_client/src/main/java/com/example/wxhk/tcp/vertx/VertxTcp.java index aad3656..4a9bd8b 100644 --- a/java_client/src/main/java/com/example/wxhk/tcp/vertx/VertxTcp.java +++ b/java_client/src/main/java/com/example/wxhk/tcp/vertx/VertxTcp.java @@ -19,21 +19,20 @@ import java.util.concurrent.LinkedBlockingQueue; /** * 接受微信hook信息 + * * @author wt * @date 2023/05/26 */ @Component @Order() public class VertxTcp extends AbstractVerticle implements CommandLineRunner { - protected static final Log log = Log.get(); - NetServer netServer; public final static LinkedBlockingQueue LINKED_BLOCKING_QUEUE = new LinkedBlockingQueue<>(); - - + protected static final Log log = Log.get(); + NetServer netServer; @Override public void start(Promise startPromise) throws Exception { - netServer = vertx.createNetServer(new NetServerOptions() + netServer = vertx.createNetServer(new NetServerOptions() .setPort(InitWeChat.getVertxPort()) .setIdleTimeout(0) .setLogActivity(false) @@ -63,9 +62,9 @@ public class VertxTcp extends AbstractVerticle implements CommandLineRunner { listen.onComplete(event -> { boolean succeeded = event.succeeded(); if (succeeded) { - HttpAsyncUtil.exec(HttpAsyncUtil.Type.开启hook, new JsonObject().put("port", "8080").put("ip", "127.0.0.1")); + HttpAsyncUtil.exec(HttpAsyncUtil.Type.开启hook, new JsonObject().put("port", InitWeChat.getVertxPort().toString()).put("ip", "127.0.0.1")); startPromise.complete(); - }else{ + } else { startPromise.fail(event.cause()); } @@ -74,6 +73,6 @@ public class VertxTcp extends AbstractVerticle implements CommandLineRunner { @Override public void run(String... args) throws Exception { - WxhkApplication.vertx.deployVerticle(this,new DeploymentOptions().setWorkerPoolSize(6)); + WxhkApplication.vertx.deployVerticle(this, new DeploymentOptions().setWorkerPoolSize(6)); } } diff --git a/java_client/src/main/java/com/example/wxhk/util/HttpAsyncUtil.java b/java_client/src/main/java/com/example/wxhk/util/HttpAsyncUtil.java index 49d9015..b8d2ba0 100644 --- a/java_client/src/main/java/com/example/wxhk/util/HttpAsyncUtil.java +++ b/java_client/src/main/java/com/example/wxhk/util/HttpAsyncUtil.java @@ -19,9 +19,9 @@ import org.dromara.hutool.log.Log; * @date 2023/05/25 */ public class HttpAsyncUtil { - protected static final Log log = Log.get(); - public static final WebClient client = WebClient.create(WxhkApplication.vertx,new WebClientOptions().setDefaultHost("localhost").setDefaultPort(InitWeChat.wxPort) + public static final WebClient client = WebClient.create(WxhkApplication.vertx, new WebClientOptions().setDefaultHost("localhost").setDefaultPort(InitWeChat.wxPort) .setConnectTimeout(10000).setMaxPoolSize(10).setPoolEventLoopSize(10)); + protected static final Log log = Log.get(); public static Future> exec(Type type, JsonObject object) { return client.post(InitWeChat.wxPort, "localhost", "/api/?type=" + type.getType()) @@ -29,7 +29,7 @@ public class HttpAsyncUtil { .onSuccess(event -> { if (log.isDebugEnabled()) { - log.debug("type:{},{}",type.getType(), event.bodyAsJsonObject()); + log.debug("type:{},{}", type.getType(), event.bodyAsJsonObject()); } } ); @@ -65,12 +65,12 @@ public class HttpAsyncUtil { ; String type; - public String getType() { - return type; - } - Type(String type) { this.type = type; } + + public String getType() { + return type; + } } } diff --git a/java_client/src/main/java/com/example/wxhk/util/HttpSendUtil.java b/java_client/src/main/java/com/example/wxhk/util/HttpSendUtil.java index 8a815ea..6381a84 100644 --- a/java_client/src/main/java/com/example/wxhk/util/HttpSendUtil.java +++ b/java_client/src/main/java/com/example/wxhk/util/HttpSendUtil.java @@ -1,6 +1,8 @@ package com.example.wxhk.util; import com.example.wxhk.model.PrivateChatMsg; +import com.example.wxhk.model.request.SendMsg; +import com.example.wxhk.tcp.vertx.ArrHandle; import com.example.wxhk.tcp.vertx.InitWeChat; import io.vertx.core.json.JsonObject; import org.dromara.hutool.core.util.XmlUtil; @@ -10,46 +12,75 @@ import org.w3c.dom.Node; /** * 常见方法 + * * @author wt * @date 2023/05/29 */ public class HttpSendUtil { - protected static final Log log = Log.get(); - public static JsonObject 通过好友请求(PrivateChatMsg msg){ + protected static final Log log = Log.get(); + + public static JsonObject 通过好友请求(PrivateChatMsg msg) { Document document = XmlUtil.parseXml(msg.getContent()); String encryptusername = document.getDocumentElement().getAttribute("encryptusername"); String ticket = document.getDocumentElement().getAttribute("ticket"); return HttpSyncUtil.exec(HttpAsyncUtil.Type.通过好友申请, new JsonObject().put("v3", encryptusername).put("v4", ticket).put("permission", "0")); } - public static JsonObject 确认收款(PrivateChatMsg msg){ + + public static JsonObject 确认收款(PrivateChatMsg msg) { try { String content = msg.getContent(); Document document = XmlUtil.parseXml(content); Node paysubtype = document.getElementsByTagName("paysubtype").item(0); - if("1".equals(paysubtype.getTextContent().trim())){ + if ("1".equals(paysubtype.getTextContent().trim())) { // 手机发出去的 String textContent = document.getElementsByTagName("receiver_username").item(0).getTextContent(); - if(!InitWeChat.WXID_MAP.contains(textContent)){ - return new JsonObject().put("spick",true); + if (!InitWeChat.WXID_MAP.contains(textContent)) { + return new JsonObject().put("spick", true); } Node transcationid = document.getDocumentElement().getElementsByTagName("transcationid").item(0); Node transferid = document.getDocumentElement().getElementsByTagName("transferid").item(0); - return HttpSyncUtil.exec(HttpAsyncUtil.Type.确认收款, new JsonObject().put("wxid",msg.getFromUser()) - .put("transcationId",transcationid.getTextContent()) - .put("transferId",transferid.getTextContent())); + return HttpSyncUtil.exec(HttpAsyncUtil.Type.确认收款, new JsonObject().put("wxid", msg.getFromUser()) + .put("transcationId", transcationid.getTextContent()) + .put("transferId", transferid.getTextContent())); } // 如果是确认接受收款,则跳过 return new JsonObject(); - } catch (Exception e) { + } catch (Exception e) { throw new RuntimeException(e); } } - public static String 获取当前登陆微信id(){ + public static JsonObject 发送文本(String wxid,String msg){ + return HttpSyncUtil.exec(HttpAsyncUtil.Type.发送文本, JsonObject.mapFrom(new SendMsg().setMsg(msg).setWxid(wxid))); + } + public static JsonObject 发送文本(String msg){ + return 发送文本(ArrHandle.getPriMsg().getFromUser(),msg); + } + public static JsonObject 发送at文本(String chatRoomId,String wxids,String msg){ + return HttpSyncUtil.exec(HttpAsyncUtil.Type.发送at文本, JsonObject.mapFrom(new SendMsg().setMsg(msg).setWxids(wxids).setChatRoomId(chatRoomId))); + } + public static JsonObject 发送at文本(String wxids,String msg){ + return 发送at文本(ArrHandle.getPriMsg().getFromGroup(),wxids,msg); + } + public static JsonObject 发送图片(String wxid,String msg){ + return HttpSyncUtil.exec(HttpAsyncUtil.Type.发送图片, JsonObject.mapFrom(new SendMsg().setImagePath(msg).setWxid(wxid))); + } + public static JsonObject 发送图片(String msg){ + return 发送图片(ArrHandle.getPriMsg().getFromUser(),msg); + } + public static JsonObject 发送文件(String wxid,String msg){ + return HttpSyncUtil.exec(HttpAsyncUtil.Type.发送文件, JsonObject.mapFrom(new SendMsg().setFilePath(msg).setWxid(wxid))); + } + public static JsonObject 发送文件(String msg){ + return 发送文件(ArrHandle.getPriMsg().getFromUser(),msg); + } + + + public static String 获取当前登陆微信id() { JsonObject exec = HttpSyncUtil.exec(HttpAsyncUtil.Type.获取登录信息, new JsonObject()); return exec.getJsonObject("data").getString("wxid"); } diff --git a/java_client/src/main/java/com/example/wxhk/util/HttpSyncUtil.java b/java_client/src/main/java/com/example/wxhk/util/HttpSyncUtil.java index d5a2a63..21686ac 100644 --- a/java_client/src/main/java/com/example/wxhk/util/HttpSyncUtil.java +++ b/java_client/src/main/java/com/example/wxhk/util/HttpSyncUtil.java @@ -16,18 +16,20 @@ import org.dromara.hutool.log.Log; * @date 2023/05/25 */ public class HttpSyncUtil { + protected static final Log log = Log.get(); static final ClientEngine engine; - protected static final Log log = Log.get(); + static { ClientConfig clientConfig = ClientConfig.of() .setTimeout(30 * 1000); engine = ClientEngineFactory.createEngine(clientConfig); } - public static JsonObject exec(HttpAsyncUtil.Type type,JsonObject obj){ + + public static JsonObject exec(HttpAsyncUtil.Type type, JsonObject obj) { String post = engine.send(Request.of("http://localhost:" + InitWeChat.wxPort + "/api/?type=" + type.getType()).method(Method.POST).body(obj.encode())).bodyStr(); if (log.isDebugEnabled()) { - log.debug("type:{},{}",type.getType(),post); + log.debug("type:{},{}", type.getType(), post); } return new JsonObject(post); }