常见的方法和请求

This commit is contained in:
王涛 2023-06-01 09:57:03 +08:00
parent 003ceca7d6
commit 391011b696
25 changed files with 489 additions and 116 deletions

View File

@ -1,5 +1,6 @@
环境为jdk17
执行之后会在当前项目所处磁盘根路径生成一个exec文件夹,然后会把src/main/resources/exec下的文件放在那避免因为路径问题出错
java_client/src/main/resources/exec/c.exe 为注入器,只不过把名字改短了,更新的话换成最新版,改个名字就行, wxhelper.dll同理
项目启动之后,会生成一个tcp服务端,用来接受hook信息,然后把接收的信息放在队列中,之后用一个线程去循环处理消息.
具体实现可以看

View File

@ -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;
}
}

View File

@ -0,0 +1,11 @@
package com.example.wxhk.infe;
/**
* http接口请求的基础接口
*
* @author wt
* @date 2023/06/01
*/
public interface SendMsg extends java.io.Serializable{
}

View File

@ -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;
/**
* 类型
*/

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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多个用逗号隔开,@所有人则是<b>notify@all</b>
*/
String wxids;
String msg;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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多个用逗号隔开,@所有人则是<b>notify@all</b>
*/
String wxids;
/**
* 发送图片接口
* "imagePath": "C:/Users/123.png"
*/
String imagePath;
/**
* 发送文件路径
* "filePath": "C:/Users/123.txt"
*/
String filePath;
/**
* 通过 手机或qq查询信息
*/
String keyword;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -18,23 +18,31 @@ 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<Integer, Handle> map = new ConcurrentHashMap<>(32);
public static ConcurrentHashMap<String, String> cache = new ConcurrentHashMap<>();
protected static final Log log = Log.get();
public static ConcurrentHashMap<String, String> cache = new ConcurrentHashMap<>();
public WxMsgHandle() {
add(chatMsg -> {
if(Objects.equals(chatMsg.getIsSendMsg(), 1) && Objects.equals(chatMsg.getIsSendByPhone(), 1)){
log.info("手机端对:{}发出:{}",chatMsg.getFromUser(),chatMsg.getContent());
return 1;
},WxMsgType.私聊信息);// 好友请求
}
return 1;
}, WxMsgType.私聊信息);
add(chatMsg -> {
if("filehelper".equals(chatMsg.getFromUser())){
log.info("文件助手:{},",chatMsg.getContent());
}
return 1;
}, WxMsgType.收到转账之后或者文件助手等信息);
add(chatMsg -> {
HttpSendUtil.通过好友请求(chatMsg);
return 1;
@ -55,7 +63,6 @@ public class WxMsgHandle {
}, WxMsgType.扫码触发);
}
/**
@ -130,6 +137,7 @@ public class WxMsgHandle {
}
return true;
}
public static boolean 解析收款信息2段(PrivateChatMsg chatMsg) {
try {
Document document = XmlUtil.parseXml(chatMsg.getContent());
@ -163,6 +171,7 @@ public class WxMsgHandle {
/**
* 解析收款信息1段
* <b>会自动进行收款</b>
*
* @param chatMsg
* @return boolean true则 继续解析,false则不需要解析了
*/
@ -192,12 +201,12 @@ public class WxMsgHandle {
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) {
for (WxMsgType integer : type) {
@ -205,10 +214,7 @@ public class WxMsgHandle {
}
}
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);
}
}

View File

@ -15,15 +15,25 @@ 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 ThreadLocal<PrivateChatMsg> chatMsgThreadLocal = new InheritableThreadLocal<>();
protected static final Log log = Log.get();
/**
* 得到当前正在处理的消息
*
* @return {@link PrivateChatMsg}
*/
public static PrivateChatMsg getPriMsg() {
return chatMsgThreadLocal.get();
}
@PostConstruct
public void exec() {
@ -33,14 +43,15 @@ public class ArrHandle {
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);
}

View File

@ -31,9 +31,8 @@ import java.io.IOException;
public class InitWeChat implements CommandLineRunner {
public final static Log log = Log.get();
public static final ConcurrentHashSet<String> 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<String> 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);

View File

@ -19,17 +19,16 @@ import java.util.concurrent.LinkedBlockingQueue;
/**
* 接受微信hook信息
*
* @author wt
* @date 2023/05/26
*/
@Component
@Order()
public class VertxTcp extends AbstractVerticle implements CommandLineRunner {
public final static LinkedBlockingQueue<JsonObject> LINKED_BLOCKING_QUEUE = new LinkedBlockingQueue<>();
protected static final Log log = Log.get();
NetServer netServer;
public final static LinkedBlockingQueue<JsonObject> LINKED_BLOCKING_QUEUE = new LinkedBlockingQueue<>();
@Override
public void start(Promise<Void> startPromise) throws Exception {
@ -63,7 +62,7 @@ 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 {
startPromise.fail(event.cause());

View File

@ -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)
.setConnectTimeout(10000).setMaxPoolSize(10).setPoolEventLoopSize(10));
protected static final Log log = Log.get();
public static Future<HttpResponse<Buffer>> exec(Type type, JsonObject object) {
return client.post(InitWeChat.wxPort, "localhost", "/api/?type=" + type.getType())
@ -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;
}
}
}

View File

@ -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,18 +12,21 @@ 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) {
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) {
try {
String content = msg.getContent();
@ -49,6 +54,32 @@ public class HttpSendUtil {
}
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");

View File

@ -16,14 +16,16 @@ import org.dromara.hutool.log.Log;
* @date 2023/05/25
*/
public class HttpSyncUtil {
static final ClientEngine engine;
protected static final Log log = Log.get();
static final ClientEngine engine;
static {
ClientConfig clientConfig = ClientConfig.of()
.setTimeout(30 * 1000);
engine = ClientEngineFactory.createEngine(clientConfig);
}
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()) {