diff --git a/qqinterface/src/main/java/com/tencent/mobileqq/pb/PBField.java b/qqinterface/src/main/java/com/tencent/mobileqq/pb/PBField.java index 9ce5d9c..23377c4 100644 --- a/qqinterface/src/main/java/com/tencent/mobileqq/pb/PBField.java +++ b/qqinterface/src/main/java/com/tencent/mobileqq/pb/PBField.java @@ -21,6 +21,10 @@ public abstract class PBField { return new PBBytesField(byteStringMicro, false); } + public static PBFloatField initFloat(float paramFloat) { + return new PBFloatField(paramFloat, false); + } + public static PBBoolField initBool(boolean z) { return new PBBoolField(z, false); } diff --git a/qqinterface/src/main/java/com/tencent/mobileqq/pb/PBFloatField.java b/qqinterface/src/main/java/com/tencent/mobileqq/pb/PBFloatField.java new file mode 100644 index 0000000..34195ad --- /dev/null +++ b/qqinterface/src/main/java/com/tencent/mobileqq/pb/PBFloatField.java @@ -0,0 +1,13 @@ +package com.tencent.mobileqq.pb; + +public class PBFloatField extends PBPrimitiveField { + public PBFloatField(float i2, boolean z) { + } + + public int get() { + return 0; + } + + public void set(int i2) { + } +} diff --git a/qqinterface/src/main/java/tencent/im/oidb/cmd0xeb7/oidb_0xeb7.java b/qqinterface/src/main/java/tencent/im/oidb/cmd0xeb7/oidb_0xeb7.java new file mode 100644 index 0000000..d4e47e9 --- /dev/null +++ b/qqinterface/src/main/java/tencent/im/oidb/cmd0xeb7/oidb_0xeb7.java @@ -0,0 +1,245 @@ +package tencent.im.oidb.cmd0xeb7; + +import com.tencent.mobileqq.pb.MessageMicro; +import com.tencent.mobileqq.pb.PBEnumField; +import com.tencent.mobileqq.pb.PBField; +import com.tencent.mobileqq.pb.PBFloatField; +import com.tencent.mobileqq.pb.PBInt32Field; +import com.tencent.mobileqq.pb.PBInt64Field; +import com.tencent.mobileqq.pb.PBRepeatField; +import com.tencent.mobileqq.pb.PBRepeatMessageField; +import com.tencent.mobileqq.pb.PBStringField; + +public class oidb_0xeb7 { + public static class ReqBody extends MessageMicro { + static final MessageMicro.FieldMap __fieldMap__ = MessageMicro.initFieldMap(new int[] { 10, 18 }, new String[] { "signInStatusReq", "signInWriteReq" }, new Object[] { null, null }, ReqBody.class); + + public StSignInStatusReq signInStatusReq = new StSignInStatusReq(); + + public StSignInWriteReq signInWriteReq = new StSignInWriteReq(); + } + + + public static class RspBody extends MessageMicro + { + static final MessageMicro.FieldMap __fieldMap__ = MessageMicro.initFieldMap(new int[] { 10, 18 }, new String[] { "signInStatusRsp", "signInWriteRsp" }, new Object[] { null, null }, RspBody.class); + public StSignInStatusRsp signInStatusRsp = new StSignInStatusRsp(); + public StSignInWriteRsp signInWriteRsp = new StSignInWriteRsp(); + } + + + public static class StSignInWriteRsp + extends MessageMicro + { + static final MessageMicro.FieldMap __fieldMap__ = MessageMicro.initFieldMap(new int[] { 10, 18, 26 }, new String[] { "ret", "doneInfo", "groupScore" }, new Object[] { null, null, null }, StSignInWriteRsp.class); + public SignInStatusDoneInfo doneInfo = new SignInStatusDoneInfo(); + public SignInStatusGroupScore groupScore = new SignInStatusGroupScore(); + public Ret ret = new Ret(); + } + + public static class StSignInStatusRsp + extends MessageMicro + { + static final MessageMicro.FieldMap __fieldMap__ = MessageMicro.initFieldMap(new int[] { 10, 18, 26, 34, 42, 50, 58, 66 }, new String[] { "ret", "base", "yesterday", "notInfo", "doneInfo", "groupScore", "mantleUrl", "backgroundUrl" }, new Object[] { null, null, null, null, null, null, "", "" }, StSignInStatusRsp.class); + public final PBStringField backgroundUrl = PBField.initString(""); + public SignInStatusBase base = new SignInStatusBase(); + public SignInStatusDoneInfo doneInfo = new SignInStatusDoneInfo(); + public SignInStatusGroupScore groupScore = new SignInStatusGroupScore(); + public final PBStringField mantleUrl = PBField.initString(""); + public SignInStatusNotInfo notInfo = new SignInStatusNotInfo(); + public Ret ret = new Ret(); + public SignInStatusYesterdayFirst yesterday = new SignInStatusYesterdayFirst(); + } + + public static class SignInStatusYesterdayFirst + extends MessageMicro + { + static final MessageMicro.FieldMap __fieldMap__ = MessageMicro.initFieldMap(new int[] { 10, 18, 26 }, new String[] { "yesterdayFirstUid", "yesterdayWord", "yesterdayNick" }, new Object[] { "", "", "" }, SignInStatusYesterdayFirst.class); + public final PBStringField yesterdayFirstUid = PBField.initString(""); + public final PBStringField yesterdayNick = PBField.initString(""); + public final PBStringField yesterdayWord = PBField.initString(""); + } + + public static class SignInStatusNotInfo + extends MessageMicro + { + static final MessageMicro.FieldMap __fieldMap__ = MessageMicro.initFieldMap(new int[] { 10, 18, 26 }, new String[] { "buttonWord", "signDescWordLeft", "signDescWordRight" }, new Object[] { "", "", "" }, SignInStatusNotInfo.class); + public final PBStringField buttonWord = PBField.initString(""); + public final PBStringField signDescWordLeft = PBField.initString(""); + public final PBStringField signDescWordRight = PBField.initString(""); + } + + public static class SignInStatusGroupScore + extends MessageMicro + { + static final MessageMicro.FieldMap __fieldMap__ = MessageMicro.initFieldMap(new int[] { 10, 18 }, new String[] { "groupScoreWord", "scoreUrl" }, new Object[] { "", "" }, SignInStatusGroupScore.class); + public final PBStringField groupScoreWord = PBField.initString(""); + public final PBStringField scoreUrl = PBField.initString(""); + } + + public static class SignInStatusDoneInfo + extends MessageMicro + { + static final MessageMicro.FieldMap __fieldMap__ = MessageMicro.initFieldMap(new int[] { 10, 18, 26, 34 }, new String[] { "leftTitleWrod", "rightDescWord", "belowPortraitWords", "recordUrl" }, new Object[] { "", "", "", "" }, SignInStatusDoneInfo.class); + public final PBRepeatField belowPortraitWords = PBField.initRepeat(PBField.initString("")); + public final PBStringField leftTitleWrod = PBField.initString(""); + public final PBStringField recordUrl = PBField.initString(""); + public final PBStringField rightDescWord = PBField.initString(""); + } + + public static class StSignInRecordDaySigned extends MessageMicro { + static final MessageMicro.FieldMap __fieldMap__ = MessageMicro.initFieldMap(new int[] { 13, 16, 26, 34 }, new String[] { "daySignedRatio", "dayTotalSignedUid", "daySignedPage", "daySignedUrl" }, new Object[] { Float.valueOf(0.0F), Integer.valueOf(0), null, "" }, StSignInRecordDaySigned.class); + + public StDaySignedPage daySignedPage = new StDaySignedPage(); + + public final PBFloatField daySignedRatio = PBField.initFloat(0.0F); + + public final PBStringField daySignedUrl = PBField.initString(""); + + public final PBInt32Field dayTotalSignedUid = PBField.initInt32(0); + } + + + public static class SignInStatusBase extends MessageMicro { + static final MessageMicro.FieldMap __fieldMap__ = MessageMicro.initFieldMap(new int[] { 8, 16 }, new String[] { "status", "currentTimeStamp" }, new Object[] { Integer.valueOf(0), Long.valueOf(0L) }, SignInStatusBase.class); + + public final PBInt64Field currentTimeStamp = PBField.initInt64(0L); + + public final PBEnumField status = PBField.initEnum(0); + } + + + public static class StSignInRecordRsp extends MessageMicro { + static final MessageMicro.FieldMap __fieldMap__ = MessageMicro.initFieldMap(new int[] { 10, 18, 26, 34, 42, 50 }, new String[] { "ret", "base", "userRecord", "daySigned", "kingRecord", "level" }, new Object[] { null, null, null, null, null, null }, StSignInRecordRsp.class); + + public SignInStatusBase base = new SignInStatusBase(); + + public StSignInRecordDaySigned daySigned = new StSignInRecordDaySigned(); + + public StSignInRecordKing kingRecord = new StSignInRecordKing(); + + public StViewGroupLevel level = new StViewGroupLevel(); + + public Ret ret = new Ret(); + + public StSignInRecordUser userRecord = new StSignInRecordUser(); + } + + public static class Ret extends MessageMicro { + static final MessageMicro.FieldMap __fieldMap__ = MessageMicro.initFieldMap(new int[] { 8, 18 }, new String[] { "code", "msg" }, new Object[] { Integer.valueOf(0), "" }, Ret.class); + + public final PBEnumField code = PBField.initEnum(0); + + public final PBStringField msg = PBField.initString(""); + } + + + public static class StSignInRecordUser extends MessageMicro { + static final MessageMicro.FieldMap __fieldMap__; + + public final PBInt64Field continueSignedDays = PBField.initInt64(0L); + + public final PBInt64Field earliestSignedTimeStamp = PBField.initInt64(0L); + + public final PBStringField groupName = PBField.initString(""); + + public final PBRepeatField historySignedDays = PBField.initRepeat(PBField.initString("")); + + public final PBInt32Field totalSignedDays = PBField.initInt32(0); + + static { + Long long_ = Long.valueOf(0L); + __fieldMap__ = MessageMicro.initFieldMap(new int[] { 16, 24, 32, 42, 50 }, new String[] { "totalSignedDays", "earliestSignedTimeStamp", "continueSignedDays", "historySignedDays", "groupName" }, new Object[] { Integer.valueOf(0), long_, long_, "", "" }, StSignInRecordUser.class); + } + } + + public static class StDaySignedInfo extends MessageMicro { + static final MessageMicro.FieldMap __fieldMap__ = MessageMicro.initFieldMap(new int[] { 10, 18, 24, 32 }, new String[] { "uid", "uidGroupNick", "signedTimeStamp", "signInRank" }, new Object[] { "", "", Long.valueOf(0L), Integer.valueOf(0) }, StDaySignedInfo.class); + + public final PBInt32Field signInRank = PBField.initInt32(0); + + public final PBInt64Field signedTimeStamp = PBField.initInt64(0L); + + public final PBStringField uid = PBField.initString(""); + + public final PBStringField uidGroupNick = PBField.initString(""); + } + + public static class StDaySignedPage extends MessageMicro { + static final MessageMicro.FieldMap __fieldMap__; + + public final PBRepeatMessageField infos = PBField.initRepeatMessage(StDaySignedInfo.class); + + public final PBInt32Field offset = PBField.initInt32(0); + + public final PBInt32Field total = PBField.initInt32(0); + + static { + Integer integer = Integer.valueOf(0); + __fieldMap__ = MessageMicro.initFieldMap(new int[] { 10, 16, 24 }, new String[] { "infos", "offset", "total" }, new Object[] { null, integer, integer }, StDaySignedPage.class); + } + } + + public static class StKingSignedInfo extends MessageMicro { + static final MessageMicro.FieldMap __fieldMap__ = MessageMicro.initFieldMap(new int[] { 10, 18, 24, 32 }, new String[] { "uid", "groupNick", "signedTimeStamp", "signedCount" }, new Object[] { "", "", Long.valueOf(0L), Integer.valueOf(0) }, StKingSignedInfo.class); + + public final PBStringField groupNick = PBField.initString(""); + + public final PBInt32Field signedCount = PBField.initInt32(0); + + public final PBInt64Field signedTimeStamp = PBField.initInt64(0L); + + public final PBStringField uid = PBField.initString(""); + } + + public static class StSignInStatusReq extends MessageMicro { + static final MessageMicro.FieldMap __fieldMap__ = MessageMicro.initFieldMap(new int[] { 10, 18, 24, 34 }, new String[] { "uid", "groupId", "scene", "clientVersion" }, new Object[] { "", "", Integer.valueOf(0), "" }, StSignInStatusReq.class); + + public final PBStringField clientVersion = PBField.initString(""); + + public final PBStringField groupId = PBField.initString(""); + + public final PBEnumField scene = PBField.initEnum(0); + + public final PBStringField uid = PBField.initString(""); + } + + + public static class StSignInWriteReq extends MessageMicro { + static final MessageMicro.FieldMap __fieldMap__ = MessageMicro.initFieldMap(new int[] { 10, 18, 26 }, new String[] { "uid", "groupId", "clientVersion" }, new Object[] { "", "", "" }, StSignInWriteReq.class); + + public final PBStringField clientVersion = PBField.initString(""); + + public final PBStringField groupId = PBField.initString(""); + + public final PBStringField uid = PBField.initString(""); + } + + public static class StViewGroupLevel extends MessageMicro { + static final MessageMicro.FieldMap __fieldMap__ = MessageMicro.initFieldMap(new int[] { 10, 18 }, new String[] { "title", "url" }, new Object[] { "", "" }, StViewGroupLevel.class); + + public final PBStringField title = PBField.initString(""); + + public final PBStringField url = PBField.initString(""); + } + + + public static class StSignInRecordKing extends MessageMicro { + static final MessageMicro.FieldMap __fieldMap__ = MessageMicro.initFieldMap(new int[] { 10, 18, 26, 34 }, new String[] { "yesterdayFirst", "topSignedTotal", "topSignedContinue", "kingUrl" }, new Object[] { null, null, null, "" }, StSignInRecordKing.class); + + public final PBStringField kingUrl = PBField.initString(""); + + public final PBRepeatMessageField topSignedContinue = PBField.initRepeatMessage(StKingSignedInfo.class); + + public final PBRepeatMessageField topSignedTotal = PBField.initRepeatMessage(StKingSignedInfo.class); + + public StKingSignedInfo yesterdayFirst = new StKingSignedInfo(); + } + + +} + + + + + diff --git a/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/GroupSvc.kt b/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/GroupSvc.kt index 2664cd0..d664660 100644 --- a/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/GroupSvc.kt +++ b/xposed/src/main/java/moe/fuqiuluo/qqinterface/servlet/GroupSvc.kt @@ -47,6 +47,7 @@ import moe.fuqiuluo.proto.ProtoUtils import moe.fuqiuluo.proto.asInt import moe.fuqiuluo.proto.asUtf8String import moe.fuqiuluo.proto.protobufOf +import moe.fuqiuluo.qqinterface.servlet.TicketSvc.getUin import moe.fuqiuluo.qqinterface.servlet.entries.ProhibitedMemberInfo import moe.fuqiuluo.shamrock.helper.Level import moe.fuqiuluo.shamrock.helper.LogCenter @@ -67,13 +68,16 @@ import moe.fuqiuluo.shamrock.tools.ifNullOrEmpty import moe.fuqiuluo.shamrock.tools.putBuf32Long import moe.fuqiuluo.shamrock.tools.slice import moe.fuqiuluo.shamrock.utils.FileUtils +import moe.fuqiuluo.shamrock.utils.PlatformUtils import moe.fuqiuluo.shamrock.xposed.helper.AppRuntimeFetcher import moe.fuqiuluo.shamrock.xposed.helper.NTServiceFetcher +import mqq.app.MobileQQ import tencent.im.group.group_member_info import tencent.im.oidb.cmd0x899.oidb_0x899 import tencent.im.oidb.cmd0x89a.oidb_0x89a import tencent.im.oidb.cmd0x8a0.oidb_0x8a0 import tencent.im.oidb.cmd0x8fc.Oidb_0x8fc +import tencent.im.oidb.cmd0xeb7.oidb_0xeb7 import tencent.im.oidb.oidb_sso import tencent.im.troop.honor.troop_honor import java.lang.reflect.Method @@ -950,4 +954,27 @@ internal object GroupSvc: BaseSvc() { Result.failure(Exception(body.jsonObject["em"].asStringOrNull)) } } + + suspend fun groupSign(groupId: Long): Result { + val req = oidb_0xeb7.ReqBody() + val signInWriteReq = oidb_0xeb7.StSignInWriteReq() + signInWriteReq.groupId.set(groupId.toString()) + signInWriteReq.uid.set(getUin()) + var version = PlatformUtils.getClientVersion(MobileQQ.getContext()) + version = version.replace("android", "").trimStart() + signInWriteReq.clientVersion.set(version) + req.signInWriteReq.set(signInWriteReq) + val buffer = sendOidbAW("OidbSvc.0xeb7", 3767, 1, req.toByteArray()) + return if (buffer == null) { + Result.failure(Exception("操作失败")) + } else { + val body = oidb_sso.OIDBSSOPkg() + body.mergeFrom(buffer.slice(4)) + val rsp = oidb_0xeb7.RspBody() + rsp.mergeFrom(body.bytes_bodybuffer.get().toByteArray()) + val doneInfo = rsp.signInWriteRsp.doneInfo + LogCenter.log(rsp.toString(), Level.DEBUG) + Result.success("${doneInfo.leftTitleWrod.get()} ${doneInfo.rightDescWord.get()} ${doneInfo.belowPortraitWords.get().joinToString(" ")}") + } + } } \ No newline at end of file diff --git a/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/action/ActionManager.kt b/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/action/ActionManager.kt index bdbe629..15a0d1f 100644 --- a/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/action/ActionManager.kt +++ b/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/action/ActionManager.kt @@ -31,7 +31,7 @@ internal object ActionManager { // GroupActions ModifyTroopName, LeaveTroop, KickTroopMember, BanTroopMember, SetGroupWholeBan, SetGroupAdmin, ModifyTroopMemberName, SetGroupUnique, GetTroopHonor, GroupPoke, SetEssenceMessage, DeleteEssenceMessage, - GetGroupSystemMsg, GetProhibitedMemberList, GetEssenceMessageList, GetGroupNotice, SendGroupNotice, + GetGroupSystemMsg, GetProhibitedMemberList, GetEssenceMessageList, GetGroupNotice, SendGroupNotice, SendGroupSign, // MSG ACTIONS SendMessage, DeleteMessage, GetMsg, GetForwardMsg, SendPrivateForwardMessage, SendGroupMessage, SendPrivateMessage, diff --git a/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/action/handlers/SendGroupSign.kt b/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/action/handlers/SendGroupSign.kt new file mode 100644 index 0000000..b2619e8 --- /dev/null +++ b/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/action/handlers/SendGroupSign.kt @@ -0,0 +1,30 @@ +package moe.fuqiuluo.shamrock.remote.action.handlers + +import com.tencent.qqnt.kernel.nativeinterface.MsgConstant +import kotlinx.serialization.json.JsonElement +import moe.fuqiuluo.qqinterface.servlet.GroupSvc +import moe.fuqiuluo.qqinterface.servlet.MsgSvc +import moe.fuqiuluo.shamrock.helper.Level +import moe.fuqiuluo.shamrock.helper.LogCenter +import moe.fuqiuluo.shamrock.remote.action.ActionSession +import moe.fuqiuluo.shamrock.remote.action.IActionHandler +import moe.fuqiuluo.shamrock.tools.EmptyJsonString + +internal object SendGroupSign: IActionHandler() { + override suspend fun internalHandle(session: ActionSession): String { + val groupId = session.getLong("group_id") + return invoke(groupId, session.echo) + } + + suspend operator fun invoke(groupId: Long, echo: JsonElement = EmptyJsonString): String { + val ret = GroupSvc.groupSign(groupId) + return if (ret.isSuccess) { + ok(ret.getOrNull() ?: "", echo) + } else { + logic(ret.exceptionOrNull()?.message ?: "", echo) + } + } + + override val requiredParams: Array = arrayOf("group_id") + override fun path(): String = "send_group_sign" +} \ No newline at end of file diff --git a/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/api/GroupAction.kt b/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/api/GroupAction.kt index dca2097..b2fa491 100644 --- a/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/api/GroupAction.kt +++ b/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/api/GroupAction.kt @@ -140,4 +140,9 @@ fun Routing.troopAction() { call.respondText(SendGroupNotice(groupId, text, image), ContentType.Application.Json) } + getOrPost("/send_group_sign") { + val groupId = fetchOrThrow("group_id").toLong() + call.respondText(SendGroupSign(groupId), ContentType.Application.Json) + } + } \ No newline at end of file