Compare commits

...

12 Commits

Author SHA1 Message Date
伏秋洛
40ffa2b71b
Update bug.md 2024-07-21 21:40:04 +08:00
fuqiuluo
cca2cbbbd7 Version Restriction Notice 2024-07-19 03:35:45 +08:00
fuqiuluo
40d2911135 修复资源rkey获取异常 2024-07-16 17:47:39 +08:00
fuqiuluo
823d9911a0 fix #338 2024-07-16 17:11:48 +08:00
fuqiuluo
4adbc12a0b fix /get_group_root_files 2024-07-08 09:53:15 +08:00
fuqiuluo
114fbfdd23 fix /get_group_root_files 2024-07-08 09:44:26 +08:00
fuqiuluo
0a563d60a1 fix crash in QQ9.0.71 2024-07-08 09:17:56 +08:00
fuqiuluo
5fb1d0aeb9 fix ping-pong 2024-07-08 09:11:49 +08:00
fuqiuluo
012ecaa85d fix #335 2024-07-08 08:55:49 +08:00
fuqiuluo
7ea127a279 update shamrock 2024-07-08 08:15:05 +08:00
ikechan8370
02f83a3c48
fix: remove debug log 2024-07-07 15:26:30 +08:00
ikechan8370
4016c05882 fix: 9.0.71 compatible issues (part of) 2024-07-07 15:04:30 +08:00
67 changed files with 1636 additions and 321 deletions

View File

@ -20,7 +20,8 @@ labels: bug
## 系统信息 ## 系统信息
- Shamrock 版本: - Shamrock 版本:
- QQ 版本:
- Android 版本: - Android 版本:
- LSPosed 框架版本: - LSPosed 框架版本:
- 设备的制造商和型号: - 设备的制造商和型号:

View File

@ -23,9 +23,13 @@
> Riru可能导致封禁请减少使用。 > Riru可能导致封禁请减少使用。
> 如有违反法律,请联系删除。 > 如有违反法律,请联系删除。
> 请勿在任何平台宣传,宣扬,转发本项目,请勿恶意修改企业安装包造成相关企业产生损失,如有违背,必将追责到底。 > 请勿在任何平台宣传,宣扬,转发本项目,请勿恶意修改企业安装包造成相关企业产生损失,如有违背,必将追责到底。
>
> 社区地址:[discord](https://discord.gg/MKR2wz863h)
## 兼容|迁移|替代 说明 ## 兼容|迁移|替代 说明
仅支持QQ9.0.70以上的版本,低版本问题将不再修复与处理。
- 一键移植:本项目基于 go-cqhttp 的文档进行开发实现。 - 一键移植:本项目基于 go-cqhttp 的文档进行开发实现。
- 平行部署:可多平台部署。 - 平行部署:可多平台部署。

View File

@ -17,7 +17,7 @@ android {
minSdk = 27 minSdk = 27
targetSdk = 34 targetSdk = 34
versionCode = getVersionCode() versionCode = getVersionCode()
versionName = "1.1.0" + ".r${getGitCommitCount()}." + getVersionName() versionName = "1.1.1" + ".r${getGitCommitCount()}." + getVersionName()
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables { vectorDrawables {

View File

@ -162,7 +162,7 @@ private fun FunctionCard(
Function( Function(
title = "主动RPC", title = "主动RPC",
desc = "Kritor协议实现RPC", desc = "Kritor协议实现RPC由Shamrock放出rpc服务",
isSwitch = ShamrockConfig[ctx, ActiveRPC] isSwitch = ShamrockConfig[ctx, ActiveRPC]
) { ) {
ShamrockConfig[ctx, ActiveRPC] = it ShamrockConfig[ctx, ActiveRPC] = it
@ -171,7 +171,7 @@ private fun FunctionCard(
Function( Function(
title = "被动RPC", title = "被动RPC",
desc = "Kritor协议实现RPC", desc = "Kritor协议实现RPC由客户端提供反向的rpc服务",
isSwitch = ShamrockConfig[ctx, PassiveRPC] isSwitch = ShamrockConfig[ctx, PassiveRPC]
) { ) {
ShamrockConfig[ctx, PassiveRPC] = it ShamrockConfig[ctx, PassiveRPC] = it

@ -1 +1 @@
Subproject commit 27669a8f5704a8876658a47cc976f1fb3e9cc2f4 Subproject commit 3dec747a8ec60aa80d5d7b55bb26244706c769be

View File

@ -8,7 +8,9 @@ import moe.fuqiuluo.symbols.Protobuf
data class TrpcOidb( data class TrpcOidb(
@ProtoNumber(1) val cmd: Int = Int.MIN_VALUE, @ProtoNumber(1) val cmd: Int = Int.MIN_VALUE,
@ProtoNumber(2) val service: Int = Int.MIN_VALUE, @ProtoNumber(2) val service: Int = Int.MIN_VALUE,
@ProtoNumber(4) val buffer: ByteArray, @ProtoNumber(3) val result: UInt? = null,
@ProtoNumber(4) val buffer: ByteArray? = null,
@ProtoNumber(5) val msg: String? = null,
//@ProtoNumber(11) val traceParams: Map<String, String> = mapOf(), //@ProtoNumber(11) val traceParams: Map<String, String> = mapOf(),
@ProtoNumber(12) val flag: Int = Int.MIN_VALUE, @ProtoNumber(12) val flag: Int = Int.MIN_VALUE,
): Protobuf<TrpcOidb> ): Protobuf<TrpcOidb>

View File

@ -94,7 +94,8 @@ data class DeleteReq(
@Serializable @Serializable
data class DownloadRkeyReq( data class DownloadRkeyReq(
@ProtoNumber(1) val types: List<Int> @ProtoNumber(1) val types: List<Int>,
@ProtoNumber(2) val downloadType: Int
) )
@Serializable @Serializable

View File

@ -52,11 +52,11 @@ data class DownloadRkeyRsp(
@Serializable @Serializable
data class RKeyInfo( data class RKeyInfo(
@ProtoNumber(1) val rkey: String?, @ProtoNumber(1) val rkey: String,
@ProtoNumber(2) val rkeyTtlSec: ULong?, @ProtoNumber(2) val rkeyTtlSec: ULong?,
@ProtoNumber(3) val storeId: UInt = 0u, @ProtoNumber(3) val storeId: UInt = 0u,
@ProtoNumber(4) val rkeyCreateTime: UInt?, @ProtoNumber(4) val rkeyCreateTime: UInt?,
@ProtoNumber(4) val type: UInt?, @ProtoNumber(4) val type: UInt,
) )
@Serializable @Serializable

View File

@ -1,7 +1,9 @@
package com.tencent.qphone.base.util; package com.tencent.qphone.base.util;
public abstract class CodecWarpper { public abstract class CodecWarpper {
public abstract void onResponse(int i2, Object obj, int i3); // public abstract void onResponse(int i2, Object obj, int i3);
public abstract void onInvalidData(int i2, int i3, String str);
public abstract void onResponse(int i2, Object obj, int i3, byte[] bArr); public abstract void onResponse(int i2, Object obj, int i3, byte[] bArr);

View File

@ -1,7 +1,7 @@
package com.tencent.qqnt.aio.api; package com.tencent.qqnt.aio.api;
import com.tencent.mobileqq.qroute.QRouteApi; import com.tencent.mobileqq.qroute.QRouteApi;
import com.tencent.qqnt.kernel.nativeinterface.Contact; import com.tencent.qqnt.kernelpublic.nativeinterface.Contact;
import com.tencent.qqnt.kernel.nativeinterface.IOperateCallback; import com.tencent.qqnt.kernel.nativeinterface.IOperateCallback;
public interface IAIOFileTransfer extends QRouteApi { public interface IAIOFileTransfer extends QRouteApi {

View File

@ -0,0 +1,4 @@
package com.tencent.qqnt.kernel.api.impl;
public class GroupService {
}

View File

@ -1,5 +1,7 @@
package com.tencent.qqnt.kernel.nativeinterface; package com.tencent.qqnt.kernel.nativeinterface;
import com.tencent.qqnt.kernelpublic.nativeinterface.Contact;
import java.util.ArrayList; import java.util.ArrayList;

View File

@ -0,0 +1,4 @@
package com.tencent.qqnt.kernel.nativeinterface;
public class GProGuildTopFeedMsg {
}

View File

@ -1,5 +1,7 @@
package com.tencent.qqnt.kernel.nativeinterface; package com.tencent.qqnt.kernel.nativeinterface;
import com.tencent.qqnt.kernelpublic.nativeinterface.Contact;
import java.util.ArrayList; import java.util.ArrayList;

View File

@ -0,0 +1,36 @@
package com.tencent.qqnt.kernel.nativeinterface;
import java.util.ArrayList;
public class GroupMemberCommonListResult {
public long groupCode;
public int identifyFlag;
public long startUin;
public ArrayList<MemberCommonInfo> memberList = new ArrayList<>();
public String strErrorInfo = "";
public long getGroupCode() {
return this.groupCode;
}
public int getIdentifyFlag() {
return this.identifyFlag;
}
public ArrayList<MemberCommonInfo> getMemberList() {
return this.memberList;
}
public long getStartUin() {
return this.startUin;
}
public String getStrErrorInfo() {
return this.strErrorInfo;
}
public String toString() {
return "GroupMemberCommonListResult{groupCode=" + this.groupCode + ",startUin=" + this.startUin + ",identifyFlag=" + this.identifyFlag + ",memberList=" + this.memberList + ",strErrorInfo=" + this.strErrorInfo + ",}";
}
}

View File

@ -0,0 +1,101 @@
package com.tencent.qqnt.kernel.nativeinterface;
import java.util.ArrayList;
public class GroupMemberCommonReq {
public long groupCode;
public int sourceType;
public String startUin = "";
public String identifyFlag = "";
public ArrayList<Long> uinList = new ArrayList<>();
public MemberCommonInfoFilter memberCommonFilter = new MemberCommonInfoFilter();
public String memberNum = "";
public String filterMethod = "";
public String onlineFlag = "";
public String realSpecialTitleFlag = "";
public String getFilterMethod() {
return this.filterMethod;
}
public long getGroupCode() {
return this.groupCode;
}
public String getIdentifyFlag() {
return this.identifyFlag;
}
public MemberCommonInfoFilter getMemberCommonFilter() {
return this.memberCommonFilter;
}
public String getMemberNum() {
return this.memberNum;
}
public String getOnlineFlag() {
return this.onlineFlag;
}
public String getRealSpecialTitleFlag() {
return this.realSpecialTitleFlag;
}
public int getSourceType() {
return this.sourceType;
}
public String getStartUin() {
return this.startUin;
}
public ArrayList<Long> getUinList() {
return this.uinList;
}
public void setFilterMethod(String str) {
this.filterMethod = str;
}
public void setGroupCode(long j2) {
this.groupCode = j2;
}
public void setIdentifyFlag(String str) {
this.identifyFlag = str;
}
public void setMemberCommonFilter(MemberCommonInfoFilter memberCommonInfoFilter) {
this.memberCommonFilter = memberCommonInfoFilter;
}
public void setMemberNum(String str) {
this.memberNum = str;
}
public void setOnlineFlag(String str) {
this.onlineFlag = str;
}
public void setRealSpecialTitleFlag(String str) {
this.realSpecialTitleFlag = str;
}
public void setSourceType(int i2) {
this.sourceType = i2;
}
public void setStartUin(String str) {
this.startUin = str;
}
public void setUinList(ArrayList<Long> arrayList) {
this.uinList = arrayList;
}
public String toString() {
return "GroupMemberCommonReq{groupCode=" + this.groupCode + ",startUin=" + this.startUin + ",identifyFlag=" + this.identifyFlag + ",uinList=" + this.uinList + ",memberCommonFilter=" + this.memberCommonFilter + ",memberNum=" + this.memberNum + ",filterMethod=" + this.filterMethod + ",onlineFlag=" + this.onlineFlag + ",realSpecialTitleFlag=" + this.realSpecialTitleFlag + ",sourceType=" + this.sourceType + ",}";
}
}

View File

@ -0,0 +1,81 @@
package com.tencent.qqnt.kernel.nativeinterface;
import java.util.ArrayList;
public class GroupMemberExtListResult {
public long dataTime;
public long endUin;
public long groupCode;
public int levelNameSeq;
public int memberInfoSeq;
public int sysShowFlag;
public int timeToUpdate;
public int userShowFlag;
public int userShowFlagNew;
public ArrayList<MemberExtInfo> memberLevelInfo = new ArrayList<>();
public ArrayList<MemberLevelName> msgLevelName = new ArrayList<>();
public String strOwnerName = "";
public String strAdminName = "";
public ArrayList<MemberLevelName> msgLevelNameNew = new ArrayList<>();
public long getDataTime() {
return this.dataTime;
}
public long getEndUin() {
return this.endUin;
}
public long getGroupCode() {
return this.groupCode;
}
public int getLevelNameSeq() {
return this.levelNameSeq;
}
public int getMemberInfoSeq() {
return this.memberInfoSeq;
}
public ArrayList<MemberExtInfo> getMemberLevelInfo() {
return this.memberLevelInfo;
}
public ArrayList<MemberLevelName> getMsgLevelName() {
return this.msgLevelName;
}
public ArrayList<MemberLevelName> getMsgLevelNameNew() {
return this.msgLevelNameNew;
}
public String getStrAdminName() {
return this.strAdminName;
}
public String getStrOwnerName() {
return this.strOwnerName;
}
public int getSysShowFlag() {
return this.sysShowFlag;
}
public int getTimeToUpdate() {
return this.timeToUpdate;
}
public int getUserShowFlag() {
return this.userShowFlag;
}
public int getUserShowFlagNew() {
return this.userShowFlagNew;
}
public String toString() {
return "GroupMemberExtListResult{groupCode=" + this.groupCode + ",memberLevelInfo=" + this.memberLevelInfo + ",msgLevelName=" + this.msgLevelName + ",endUin=" + this.endUin + ",dataTime=" + this.dataTime + ",userShowFlag=" + this.userShowFlag + ",sysShowFlag=" + this.sysShowFlag + ",timeToUpdate=" + this.timeToUpdate + ",strOwnerName=" + this.strOwnerName + ",strAdminName=" + this.strAdminName + ",levelNameSeq=" + this.levelNameSeq + ",userShowFlagNew=" + this.userShowFlagNew + ",msgLevelNameNew=" + this.msgLevelNameNew + ",memberInfoSeq=" + this.memberInfoSeq + ",}";
}
}

View File

@ -0,0 +1,101 @@
package com.tencent.qqnt.kernel.nativeinterface;
import java.util.ArrayList;
public class GroupMemberExtReq {
public long groupCode;
public int sourceType;
public String beginUin = "";
public String dataTime = "";
public ArrayList<Long> uinList = new ArrayList<>();
public MemberExtInfoFilter memberExtFilter = new MemberExtInfoFilter();
public String seq = "";
public String uinNum = "";
public String groupType = "";
public String richCardNameVer = "";
public String getBeginUin() {
return this.beginUin;
}
public String getDataTime() {
return this.dataTime;
}
public long getGroupCode() {
return this.groupCode;
}
public String getGroupType() {
return this.groupType;
}
public MemberExtInfoFilter getMemberExtFilter() {
return this.memberExtFilter;
}
public String getRichCardNameVer() {
return this.richCardNameVer;
}
public String getSeq() {
return this.seq;
}
public int getSourceType() {
return this.sourceType;
}
public ArrayList<Long> getUinList() {
return this.uinList;
}
public String getUinNum() {
return this.uinNum;
}
public void setBeginUin(String str) {
this.beginUin = str;
}
public void setDataTime(String str) {
this.dataTime = str;
}
public void setGroupCode(long j2) {
this.groupCode = j2;
}
public void setGroupType(String str) {
this.groupType = str;
}
public void setMemberExtFilter(MemberExtInfoFilter memberExtInfoFilter) {
this.memberExtFilter = memberExtInfoFilter;
}
public void setRichCardNameVer(String str) {
this.richCardNameVer = str;
}
public void setSeq(String str) {
this.seq = str;
}
public void setSourceType(int i2) {
this.sourceType = i2;
}
public void setUinList(ArrayList<Long> arrayList) {
this.uinList = arrayList;
}
public void setUinNum(String str) {
this.uinNum = str;
}
public String toString() {
return "GroupMemberExtReq{groupCode=" + this.groupCode + ",beginUin=" + this.beginUin + ",dataTime=" + this.dataTime + ",uinList=" + this.uinList + ",memberExtFilter=" + this.memberExtFilter + ",seq=" + this.seq + ",uinNum=" + this.uinNum + ",groupType=" + this.groupType + ",richCardNameVer=" + this.richCardNameVer + ",sourceType=" + this.sourceType + ",}";
}
}

View File

@ -0,0 +1,32 @@
package com.tencent.qqnt.kernel.nativeinterface;
import java.util.ArrayList;
import java.util.HashMap;
public class GroupMemberListResult {
public boolean finish;
public boolean hasRobot;
public ArrayList<GroupMemberInfoListId> ids = new ArrayList<>();
public HashMap<String, MemberInfo> infos = new HashMap<>();
public boolean getFinish() {
return this.finish;
}
public boolean getHasRobot() {
return this.hasRobot;
}
public ArrayList<GroupMemberInfoListId> getIds() {
return this.ids;
}
public HashMap<String, MemberInfo> getInfos() {
return this.infos;
}
public String toString() {
return "GroupMemberListResult{ids=" + this.ids + ",infos=" + this.infos + ",finish=" + this.finish + ",hasRobot=" + this.hasRobot + ",}";
}
}

View File

@ -0,0 +1,6 @@
package com.tencent.qqnt.kernel.nativeinterface;
public interface IGroupMemberCommonCallback {
void onResult(int i2, String str, GroupMemberCommonListResult groupMemberCommonListResult);
}

View File

@ -0,0 +1,5 @@
package com.tencent.qqnt.kernel.nativeinterface;
public interface IGroupMemberExtCallback {
void onResult(int i2, String str, GroupMemberExtListResult groupMemberExtListResult);
}

View File

@ -0,0 +1,6 @@
package com.tencent.qqnt.kernel.nativeinterface;
public interface IGroupMemberListCallback {
void onResult(int result, String str, GroupMemberListResult groupMemberListResult);
}

View File

@ -1,7 +1,25 @@
package com.tencent.qqnt.kernel.nativeinterface; package com.tencent.qqnt.kernel.nativeinterface;
import java.util.ArrayList;
public interface IKernelGroupService { public interface IKernelGroupService {
void getTransferableMemberInfo(long uin, IGetTransferableMemberCallback cb); void getTransferableMemberInfo(long uin, IGetTransferableMemberCallback cb);
long addKernelGroupListener(IKernelGroupListener ln); long addKernelGroupListener(IKernelGroupListener ln);
void getAllMemberList(long groupCode, boolean refresh, IGroupMemberListCallback iGroupMemberListCallback);
void getMemberCommonInfo(GroupMemberCommonReq groupMemberCommonReq, IGroupMemberCommonCallback iGroupMemberCommonCallback);
void getMemberExtInfo(GroupMemberExtReq groupMemberExtReq, IGroupMemberExtCallback iGroupMemberExtCallback);
void getMemberInfo(long j2, ArrayList<String> arrayList, boolean z, IOperateCallback iOperateCallback);
void getMemberInfoForMqq(long groupCode, ArrayList<String> uids, boolean z, IGroupMemberListCallback iGroupMemberListCallback);
void getNextMemberList(String sceneId, GroupMemberInfoListId groupMemberInfoListId, int i2, IGroupMemberListCallback iGroupMemberListCallback);
void getPrevMemberList(String sceneId, GroupMemberInfoListId groupMemberInfoListId, int i2, IGroupMemberListCallback iGroupMemberListCallback);
} }

View File

@ -1,5 +1,7 @@
package com.tencent.qqnt.kernel.nativeinterface; package com.tencent.qqnt.kernel.nativeinterface;
import com.tencent.qqnt.kernelpublic.nativeinterface.Contact;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
@ -16,7 +18,7 @@ public interface IKernelMsgListener {
void onCustomWithdrawConfigUpdate(CustomWithdrawConfig customWithdrawConfig); void onCustomWithdrawConfigUpdate(CustomWithdrawConfig customWithdrawConfig);
void onDraftUpdate(Contact contact, ArrayList<MsgElement> arrayList, long j2); void onDraftUpdate(Contact contact, ArrayList<MsgElement> arrayList, long j);
void onEmojiDownloadComplete(EmojiNotifyInfo emojiNotifyInfo); void onEmojiDownloadComplete(EmojiNotifyInfo emojiNotifyInfo);
@ -30,7 +32,7 @@ public interface IKernelMsgListener {
void onFirstViewGroupGuildMapping(ArrayList<FirstViewGroupGuildInfo> arrayList); void onFirstViewGroupGuildMapping(ArrayList<FirstViewGroupGuildInfo> arrayList);
void onGrabPasswordRedBag(int i2, String str, int i3, RecvdOrder recvdOrder, MsgRecord msgRecord); void onGrabPasswordRedBag(int i, String str, int i2, RecvdOrder recvdOrder, MsgRecord msgRecord);
void onGroupFileInfoAdd(GroupItem groupItem); void onGroupFileInfoAdd(GroupItem groupItem);
@ -48,6 +50,8 @@ public interface IKernelMsgListener {
void onGuildNotificationAbstractUpdate(GuildNotificationAbstractInfo guildNotificationAbstractInfo); void onGuildNotificationAbstractUpdate(GuildNotificationAbstractInfo guildNotificationAbstractInfo);
void onGuildTopFeedUpdate(GProGuildTopFeedMsg gProGuildTopFeedMsg);
void onHitCsRelatedEmojiResult(DownloadRelateEmojiResultInfo downloadRelateEmojiResultInfo); void onHitCsRelatedEmojiResult(DownloadRelateEmojiResultInfo downloadRelateEmojiResultInfo);
void onHitEmojiKeywordResult(HitRelatedEmojiWordsResult hitRelatedEmojiWordsResult); void onHitEmojiKeywordResult(HitRelatedEmojiWordsResult hitRelatedEmojiWordsResult);
@ -62,7 +66,7 @@ public interface IKernelMsgListener {
void onLineDev(ArrayList<DevInfo> arrayList); void onLineDev(ArrayList<DevInfo> arrayList);
void onLogLevelChanged(long j2); void onLogLevelChanged(long j);
void onMsgAbstractUpdate(ArrayList<MsgAbstract> arrayList); void onMsgAbstractUpdate(ArrayList<MsgAbstract> arrayList);
@ -76,14 +80,16 @@ public interface IKernelMsgListener {
void onMsgInfoListUpdate(ArrayList<MsgRecord> arrayList); void onMsgInfoListUpdate(ArrayList<MsgRecord> arrayList);
void onMsgQRCodeStatusChanged(int i2); void onMsgQRCodeStatusChanged(int i);
void onMsgRecall(int i2, String str, long j2); void onMsgRecall(int i, String str, long j);
void onMsgSecurityNotify(MsgRecord msgRecord); void onMsgSecurityNotify(MsgRecord msgRecord);
void onMsgSettingUpdate(MsgSetting msgSetting); void onMsgSettingUpdate(MsgSetting msgSetting);
void onMsgWithRichLinkInfoUpdate(ArrayList<MsgRecord> arrayList);
void onNtFirstViewMsgSyncEnd(); void onNtFirstViewMsgSyncEnd();
void onNtMsgSyncEnd(); void onNtMsgSyncEnd();
@ -92,11 +98,11 @@ public interface IKernelMsgListener {
void onReadFeedEventUpdate(FirstViewDirectMsgNotifyInfo firstViewDirectMsgNotifyInfo); void onReadFeedEventUpdate(FirstViewDirectMsgNotifyInfo firstViewDirectMsgNotifyInfo);
void onRecvGroupGuildFlag(int i2); void onRecvGroupGuildFlag(int i);
void onRecvMsg(ArrayList<MsgRecord> arrayList); void onRecvMsg(ArrayList<MsgRecord> arrayList);
void onRecvMsgSvrRspTransInfo(long j2, Contact contact, int i2, int i3, String str, byte[] bArr); void onRecvMsgSvrRspTransInfo(long j, Contact contact, int i, int i2, String str, byte[] bArr);
void onRecvOnlineFileMsg(ArrayList<MsgRecord> arrayList); void onRecvOnlineFileMsg(ArrayList<MsgRecord> arrayList);
@ -104,7 +110,9 @@ public interface IKernelMsgListener {
void onRecvSysMsg(ArrayList<Byte> arrayList); void onRecvSysMsg(ArrayList<Byte> arrayList);
void onRecvUDCFlag(int i2); void onRecvUDCFlag(int i);
void onRedTouchChanged();
void onRichMediaDownloadComplete(FileTransNotifyInfo fileTransNotifyInfo); void onRichMediaDownloadComplete(FileTransNotifyInfo fileTransNotifyInfo);
@ -114,9 +122,9 @@ public interface IKernelMsgListener {
void onSearchGroupFileInfoUpdate(SearchGroupFileResult searchGroupFileResult); void onSearchGroupFileInfoUpdate(SearchGroupFileResult searchGroupFileResult);
void onSendMsgError(long j2, Contact contact, int i2, String str); void onSendMsgError(long j, Contact contact, int i, String str);
void onSysMsgNotification(int i2, long j2, long j3, ArrayList<Byte> arrayList); void onSysMsgNotification(int i, long j, long j2, boolean z, ArrayList<Byte> arrayList);
void onTempChatInfoUpdate(TempChatInfo tempChatInfo); void onTempChatInfoUpdate(TempChatInfo tempChatInfo);
@ -128,9 +136,11 @@ public interface IKernelMsgListener {
void onUserOnlineStatusChanged(boolean z); void onUserOnlineStatusChanged(boolean z);
void onUserSecQualityChanged(QueryUserSecQualityRsp queryUserSecQualityRsp);
void onUserTabStatusChanged(ArrayList<TabStatusInfo> arrayList); void onUserTabStatusChanged(ArrayList<TabStatusInfo> arrayList);
void onlineStatusBigIconDownloadPush(int i2, long j2, String str); void onlineStatusBigIconDownloadPush(int i, long j, String str);
void onlineStatusSmallIconDownloadPush(int i2, long j2, String str); void onlineStatusSmallIconDownloadPush(int i, long j, String str);
} }

View File

@ -1,5 +1,7 @@
package com.tencent.qqnt.kernel.nativeinterface; package com.tencent.qqnt.kernel.nativeinterface;
import com.tencent.qqnt.kernelpublic.nativeinterface.Contact;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.ArrayList; import java.util.ArrayList;

View File

@ -1,5 +1,7 @@
package com.tencent.qqnt.kernel.nativeinterface; package com.tencent.qqnt.kernel.nativeinterface;
import com.tencent.qqnt.kernelpublic.nativeinterface.Contact;
import java.util.ArrayList; import java.util.ArrayList;
public interface IKernelRichMediaService { public interface IKernelRichMediaService {

View File

@ -0,0 +1,63 @@
package com.tencent.qqnt.kernel.nativeinterface;
public class MemberCommonInfo {
public long memberUin;
public int privilege;
public int shutUpTime;
public int uinFlag;
public int uinFlagExt;
public int uinMobileFlag;
public long getMemberUin() {
return this.memberUin;
}
public int getPrivilege() {
return this.privilege;
}
public int getShutUpTime() {
return this.shutUpTime;
}
public int getUinFlag() {
return this.uinFlag;
}
public int getUinFlagExt() {
return this.uinFlagExt;
}
public int getUinMobileFlag() {
return this.uinMobileFlag;
}
public void setMemberUin(long j2) {
this.memberUin = j2;
}
public void setPrivilege(int i2) {
this.privilege = i2;
}
public void setShutUpTime(int i2) {
this.shutUpTime = i2;
}
public void setUinFlag(int i2) {
this.uinFlag = i2;
}
public void setUinFlagExt(int i2) {
this.uinFlagExt = i2;
}
public void setUinMobileFlag(int i2) {
this.uinMobileFlag = i2;
}
public String toString() {
return "MemberCommonInfo{memberUin=" + this.memberUin + ",uinFlag=" + this.uinFlag + ",uinFlagExt=" + this.uinFlagExt + ",uinMobileFlag=" + this.uinMobileFlag + ",shutUpTime=" + this.shutUpTime + ",privilege=" + this.privilege + ",}";
}
}

View File

@ -0,0 +1,63 @@
package com.tencent.qqnt.kernel.nativeinterface;
public class MemberCommonInfoFilter {
public int memberUin;
public int privilege;
public int shutUpTime;
public int uinFlag;
public int uinFlagExt;
public int uinMobileFlag;
public int getMemberUin() {
return this.memberUin;
}
public int getPrivilege() {
return this.privilege;
}
public int getShutUpTime() {
return this.shutUpTime;
}
public int getUinFlag() {
return this.uinFlag;
}
public int getUinFlagExt() {
return this.uinFlagExt;
}
public int getUinMobileFlag() {
return this.uinMobileFlag;
}
public void setMemberUin(int i2) {
this.memberUin = i2;
}
public void setPrivilege(int i2) {
this.privilege = i2;
}
public void setShutUpTime(int i2) {
this.shutUpTime = i2;
}
public void setUinFlag(int i2) {
this.uinFlag = i2;
}
public void setUinFlagExt(int i2) {
this.uinFlagExt = i2;
}
public void setUinMobileFlag(int i2) {
this.uinMobileFlag = i2;
}
public String toString() {
return "MemberCommonInfoFilter{memberUin=" + this.memberUin + ",uinFlag=" + this.uinFlag + ",uinFlagExt=" + this.uinFlagExt + ",uinMobileFlag=" + this.uinMobileFlag + ",shutUpTime=" + this.shutUpTime + ",privilege=" + this.privilege + ",}";
}
}

View File

@ -0,0 +1,110 @@
package com.tencent.qqnt.kernel.nativeinterface;
import java.util.ArrayList;
public class MemberExtInfo {
public int activeDay;
public int cmdUinFlagExt3Grocery;
public int level;
public int point;
public long specialTitleExpireTime;
public long uin;
public String strName = "";
public String nickName = "";
public String specialTitle = "";
public byte[] msgNeedField = new byte[0];
public ArrayList<MemberIcon> memberIconList = new ArrayList<>();
public int getActiveDay() {
return this.activeDay;
}
public int getCmdUinFlagExt3Grocery() {
return this.cmdUinFlagExt3Grocery;
}
public int getLevel() {
return this.level;
}
public ArrayList<MemberIcon> getMemberIconList() {
return this.memberIconList;
}
public byte[] getMsgNeedField() {
return this.msgNeedField;
}
public String getNickName() {
return this.nickName;
}
public int getPoint() {
return this.point;
}
public String getSpecialTitle() {
return this.specialTitle;
}
public long getSpecialTitleExpireTime() {
return this.specialTitleExpireTime;
}
public String getStrName() {
return this.strName;
}
public long getUin() {
return this.uin;
}
public void setActiveDay(int i2) {
this.activeDay = i2;
}
public void setCmdUinFlagExt3Grocery(int i2) {
this.cmdUinFlagExt3Grocery = i2;
}
public void setLevel(int i2) {
this.level = i2;
}
public void setMemberIconList(ArrayList<MemberIcon> arrayList) {
this.memberIconList = arrayList;
}
public void setMsgNeedField(byte[] bArr) {
this.msgNeedField = bArr;
}
public void setNickName(String str) {
this.nickName = str;
}
public void setPoint(int i2) {
this.point = i2;
}
public void setSpecialTitle(String str) {
this.specialTitle = str;
}
public void setSpecialTitleExpireTime(long j2) {
this.specialTitleExpireTime = j2;
}
public void setStrName(String str) {
this.strName = str;
}
public void setUin(long j2) {
this.uin = j2;
}
public String toString() {
return "MemberExtInfo{uin=" + this.uin + ",point=" + this.point + ",activeDay=" + this.activeDay + ",level=" + this.level + ",strName=" + this.strName + ",nickName=" + this.nickName + ",specialTitle=" + this.specialTitle + ",specialTitleExpireTime=" + this.specialTitleExpireTime + ",msgNeedField=" + this.msgNeedField + ",cmdUinFlagExt3Grocery=" + this.cmdUinFlagExt3Grocery + ",memberIconList=" + this.memberIconList + ",}";
}
}

View File

@ -0,0 +1,171 @@
package com.tencent.qqnt.kernel.nativeinterface;
public class MemberExtInfoFilter {
public int cmdUinFlagExt3Grocery;
public int dataTime;
public int levelName;
public int levelNameNew;
public int memberIcon;
public int memberInfoSeq;
public int memberLevelInfoActiveDay;
public int memberLevelInfoLevel;
public int memberLevelInfoName;
public int memberLevelInfoPoint;
public int memberLevelInfoUin;
public int msgNeedField;
public int nickName;
public int specialTitle;
public int sysShowFlag;
public int timeToUpdate;
public int userShowFlag;
public int userShowFlagNew;
public int getCmdUinFlagExt3Grocery() {
return this.cmdUinFlagExt3Grocery;
}
public int getDataTime() {
return this.dataTime;
}
public int getLevelName() {
return this.levelName;
}
public int getLevelNameNew() {
return this.levelNameNew;
}
public int getMemberIcon() {
return this.memberIcon;
}
public int getMemberInfoSeq() {
return this.memberInfoSeq;
}
public int getMemberLevelInfoActiveDay() {
return this.memberLevelInfoActiveDay;
}
public int getMemberLevelInfoLevel() {
return this.memberLevelInfoLevel;
}
public int getMemberLevelInfoName() {
return this.memberLevelInfoName;
}
public int getMemberLevelInfoPoint() {
return this.memberLevelInfoPoint;
}
public int getMemberLevelInfoUin() {
return this.memberLevelInfoUin;
}
public int getMsgNeedField() {
return this.msgNeedField;
}
public int getNickName() {
return this.nickName;
}
public int getSpecialTitle() {
return this.specialTitle;
}
public int getSysShowFlag() {
return this.sysShowFlag;
}
public int getTimeToUpdate() {
return this.timeToUpdate;
}
public int getUserShowFlag() {
return this.userShowFlag;
}
public int getUserShowFlagNew() {
return this.userShowFlagNew;
}
public void setCmdUinFlagExt3Grocery(int i2) {
this.cmdUinFlagExt3Grocery = i2;
}
public void setDataTime(int i2) {
this.dataTime = i2;
}
public void setLevelName(int i2) {
this.levelName = i2;
}
public void setLevelNameNew(int i2) {
this.levelNameNew = i2;
}
public void setMemberIcon(int i2) {
this.memberIcon = i2;
}
public void setMemberInfoSeq(int i2) {
this.memberInfoSeq = i2;
}
public void setMemberLevelInfoActiveDay(int i2) {
this.memberLevelInfoActiveDay = i2;
}
public void setMemberLevelInfoLevel(int i2) {
this.memberLevelInfoLevel = i2;
}
public void setMemberLevelInfoName(int i2) {
this.memberLevelInfoName = i2;
}
public void setMemberLevelInfoPoint(int i2) {
this.memberLevelInfoPoint = i2;
}
public void setMemberLevelInfoUin(int i2) {
this.memberLevelInfoUin = i2;
}
public void setMsgNeedField(int i2) {
this.msgNeedField = i2;
}
public void setNickName(int i2) {
this.nickName = i2;
}
public void setSpecialTitle(int i2) {
this.specialTitle = i2;
}
public void setSysShowFlag(int i2) {
this.sysShowFlag = i2;
}
public void setTimeToUpdate(int i2) {
this.timeToUpdate = i2;
}
public void setUserShowFlag(int i2) {
this.userShowFlag = i2;
}
public void setUserShowFlagNew(int i2) {
this.userShowFlagNew = i2;
}
public String toString() {
return "MemberExtInfoFilter{memberLevelInfoUin=" + this.memberLevelInfoUin + ",memberLevelInfoPoint=" + this.memberLevelInfoPoint + ",memberLevelInfoActiveDay=" + this.memberLevelInfoActiveDay + ",memberLevelInfoLevel=" + this.memberLevelInfoLevel + ",memberLevelInfoName=" + this.memberLevelInfoName + ",levelName=" + this.levelName + ",dataTime=" + this.dataTime + ",userShowFlag=" + this.userShowFlag + ",sysShowFlag=" + this.sysShowFlag + ",timeToUpdate=" + this.timeToUpdate + ",nickName=" + this.nickName + ",specialTitle=" + this.specialTitle + ",levelNameNew=" + this.levelNameNew + ",userShowFlagNew=" + this.userShowFlagNew + ",msgNeedField=" + this.msgNeedField + ",cmdUinFlagExt3Grocery=" + this.cmdUinFlagExt3Grocery + ",memberIcon=" + this.memberIcon + ",memberInfoSeq=" + this.memberInfoSeq + ",}";
}
}

View File

@ -0,0 +1,29 @@
package com.tencent.qqnt.kernel.nativeinterface;
public class MemberIcon {
public int bizId;
public byte[] exInfo = new byte[0];
public long expireTime;
public int resId;
public int getBizId() {
return this.bizId;
}
public byte[] getExInfo() {
return this.exInfo;
}
public long getExpireTime() {
return this.expireTime;
}
public int getResId() {
return this.resId;
}
public String toString() {
return "MemberIcon{resId=" + this.resId + ",expireTime=" + this.expireTime + ",bizId=" + this.bizId + ",exInfo=" + this.exInfo + ",}";
}
}

View File

@ -1,51 +1,146 @@
package com.tencent.qqnt.kernel.nativeinterface; package com.tencent.qqnt.kernel.nativeinterface;
public final class MemberInfo implements IKernelModel { import com.tencent.qqnt.kernelpublic.nativeinterface.MemberRole;
String avatarPath;
String cardName;
int cardType;
boolean isDelete;
boolean isSpecialConcerned;
String nick;
String qid;
String remark;
MemberRole role;
long serialVersionUID;
int shutUpTime;
String uid;
long uin;
public MemberInfo() { public final class MemberInfo implements IKernelModel {
this.serialVersionUID = 1L; public int bigClubFlag;
this.uid = ""; public int bigClubLevel;
this.qid = ""; public int cardNameId;
this.nick = ""; public int cardType;
this.remark = ""; public int creditLevel;
this.cardName = ""; public int globalGroupLevel;
this.role = MemberRole.values()[0]; public int globalGroupPoint;
this.avatarPath = ""; public boolean isDelete;
public boolean isRobot;
public boolean isSpecialConcerned;
public boolean isSpecialShielded;
public int joinTime;
public int lastSpeakTime;
public int memberFlag;
public int memberFlagExt;
public int memberFlagExt2;
public int memberLevel;
public int memberMobileFlag;
public int memberTitleId;
public int mssVipType;
public int richFlag;
public int shutUpTime;
public long specialTitleExpireTime;
public long uin;
public int userShowFlag;
public int userShowFlagNew;
long serialVersionUID = 1;
public String uid = "";
public String qid = "";
public String nick = "";
public String remark = "";
public String cardName = "";
public MemberRole role = MemberRole.values()[0];
public String avatarPath = "";
public byte[] groupHonor = new byte[0];
public String memberSpecialTitle = "";
public String autoRemark = "";
public String getAutoRemark() {
return this.autoRemark;
} }
public String getAvatarPath() { public String getAvatarPath() {
return this.avatarPath; return this.avatarPath;
} }
public int getBigClubFlag() {
return this.bigClubFlag;
}
public int getBigClubLevel() {
return this.bigClubLevel;
}
public String getCardName() { public String getCardName() {
return this.cardName; return this.cardName;
} }
public int getCardNameId() {
return this.cardNameId;
}
public int getCardType() { public int getCardType() {
return this.cardType; return this.cardType;
} }
public int getCreditLevel() {
return this.creditLevel;
}
public int getGlobalGroupLevel() {
return this.globalGroupLevel;
}
public int getGlobalGroupPoint() {
return this.globalGroupPoint;
}
public byte[] getGroupHonor() {
return this.groupHonor;
}
public boolean getIsDelete() { public boolean getIsDelete() {
return this.isDelete; return this.isDelete;
} }
public boolean getIsRobot() {
return this.isRobot;
}
public boolean getIsSpecialConcerned() { public boolean getIsSpecialConcerned() {
return this.isSpecialConcerned; return this.isSpecialConcerned;
} }
public boolean getIsSpecialShielded() {
return this.isSpecialShielded;
}
public int getJoinTime() {
return this.joinTime;
}
public int getLastSpeakTime() {
return this.lastSpeakTime;
}
public int getMemberFlag() {
return this.memberFlag;
}
public int getMemberFlagExt() {
return this.memberFlagExt;
}
public int getMemberFlagExt2() {
return this.memberFlagExt2;
}
public int getMemberLevel() {
return this.memberLevel;
}
public int getMemberMobileFlag() {
return this.memberMobileFlag;
}
public String getMemberSpecialTitle() {
return this.memberSpecialTitle;
}
public int getMemberTitleId() {
return this.memberTitleId;
}
public int getMssVipType() {
return this.mssVipType;
}
public String getNick() { public String getNick() {
return this.nick; return this.nick;
} }
@ -58,6 +153,10 @@ public final class MemberInfo implements IKernelModel {
return this.remark; return this.remark;
} }
public int getRichFlag() {
return this.richFlag;
}
public MemberRole getRole() { public MemberRole getRole() {
return this.role; return this.role;
} }
@ -66,6 +165,10 @@ public final class MemberInfo implements IKernelModel {
return this.shutUpTime; return this.shutUpTime;
} }
public long getSpecialTitleExpireTime() {
return this.specialTitleExpireTime;
}
public String getUid() { public String getUid() {
return this.uid; return this.uid;
} }
@ -74,26 +177,114 @@ public final class MemberInfo implements IKernelModel {
return this.uin; return this.uin;
} }
public int getUserShowFlag() {
return this.userShowFlag;
}
public int getUserShowFlagNew() {
return this.userShowFlagNew;
}
public void setAutoRemark(String str) {
this.autoRemark = str;
}
public void setAvatarPath(String str) { public void setAvatarPath(String str) {
this.avatarPath = str; this.avatarPath = str;
} }
public void setBigClubFlag(int i2) {
this.bigClubFlag = i2;
}
public void setBigClubLevel(int i2) {
this.bigClubLevel = i2;
}
public void setCardName(String str) { public void setCardName(String str) {
this.cardName = str; this.cardName = str;
} }
public void setCardNameId(int i2) {
this.cardNameId = i2;
}
public void setCardType(int i2) { public void setCardType(int i2) {
this.cardType = i2; this.cardType = i2;
} }
public void setCreditLevel(int i2) {
this.creditLevel = i2;
}
public void setGlobalGroupLevel(int i2) {
this.globalGroupLevel = i2;
}
public void setGlobalGroupPoint(int i2) {
this.globalGroupPoint = i2;
}
public void setGroupHonor(byte[] bArr) {
this.groupHonor = bArr;
}
public void setIsDelete(boolean z) { public void setIsDelete(boolean z) {
this.isDelete = z; this.isDelete = z;
} }
public void setIsRobot(boolean z) {
this.isRobot = z;
}
public void setIsSpecialConcerned(boolean z) { public void setIsSpecialConcerned(boolean z) {
this.isSpecialConcerned = z; this.isSpecialConcerned = z;
} }
public void setIsSpecialShielded(boolean z) {
this.isSpecialShielded = z;
}
public void setJoinTime(int i2) {
this.joinTime = i2;
}
public void setLastSpeakTime(int i2) {
this.lastSpeakTime = i2;
}
public void setMemberFlag(int i2) {
this.memberFlag = i2;
}
public void setMemberFlagExt(int i2) {
this.memberFlagExt = i2;
}
public void setMemberFlagExt2(int i2) {
this.memberFlagExt2 = i2;
}
public void setMemberLevel(int i2) {
this.memberLevel = i2;
}
public void setMemberMobileFlag(int i2) {
this.memberMobileFlag = i2;
}
public void setMemberSpecialTitle(String str) {
this.memberSpecialTitle = str;
}
public void setMemberTitleId(int i2) {
this.memberTitleId = i2;
}
public void setMssVipType(int i2) {
this.mssVipType = i2;
}
public void setNick(String str) { public void setNick(String str) {
this.nick = str; this.nick = str;
} }
@ -106,6 +297,10 @@ public final class MemberInfo implements IKernelModel {
this.remark = str; this.remark = str;
} }
public void setRichFlag(int i2) {
this.richFlag = i2;
}
public void setRole(MemberRole memberRole) { public void setRole(MemberRole memberRole) {
this.role = memberRole; this.role = memberRole;
} }
@ -114,6 +309,10 @@ public final class MemberInfo implements IKernelModel {
this.shutUpTime = i2; this.shutUpTime = i2;
} }
public void setSpecialTitleExpireTime(long j2) {
this.specialTitleExpireTime = j2;
}
public void setUid(String str) { public void setUid(String str) {
this.uid = str; this.uid = str;
} }
@ -122,30 +321,16 @@ public final class MemberInfo implements IKernelModel {
this.uin = j2; this.uin = j2;
} }
public String toString() { public void setUserShowFlag(int i2) {
return "MemberInfo{uid=" + this.uid + ",qid=" + this.qid + ",uin=" + this.uin + ",nick=" + this.nick + ",remark=" + this.remark + ",cardType=" + this.cardType + ",cardName=" + this.cardName + ",role=" + this.role + ",avatarPath=" + this.avatarPath + ",shutUpTime=" + this.shutUpTime + ",isDelete=" + this.isDelete + ",isSpecialConcerned=" + this.isSpecialConcerned + ",}"; this.userShowFlag = i2;
} }
public MemberInfo(String str, String str2, long j2, String str3, String str4, int i2, String str5, MemberRole memberRole, String str6, int i3, boolean z, boolean z2) { public void setUserShowFlagNew(int i2) {
this.serialVersionUID = 1L; this.userShowFlagNew = i2;
this.uid = "";
this.qid = "";
this.nick = "";
this.remark = "";
this.cardName = "";
this.role = MemberRole.values()[0];
this.avatarPath = "";
this.uid = str;
this.qid = str2;
this.uin = j2;
this.nick = str3;
this.remark = str4;
this.cardType = i2;
this.cardName = str5;
this.role = memberRole;
this.avatarPath = str6;
this.shutUpTime = i3;
this.isDelete = z;
this.isSpecialConcerned = z2;
} }
public String toString() {
return "MemberInfo{uid=" + this.uid + ",qid=" + this.qid + ",uin=" + this.uin + ",nick=" + this.nick + ",remark=" + this.remark + ",cardType=" + this.cardType + ",cardName=" + this.cardName + ",role=" + this.role + ",avatarPath=" + this.avatarPath + ",shutUpTime=" + this.shutUpTime + ",isDelete=" + this.isDelete + ",isSpecialConcerned=" + this.isSpecialConcerned + ",isRobot=" + this.isRobot + ",groupHonor=" + this.groupHonor + ",memberLevel=" + this.memberLevel + ",globalGroupLevel=" + this.globalGroupLevel + ",globalGroupPoint=" + this.globalGroupPoint + ",memberTitleId=" + this.memberTitleId + ",memberSpecialTitle=" + this.memberSpecialTitle + ",specialTitleExpireTime=" + this.specialTitleExpireTime + ",userShowFlag=" + this.userShowFlag + ",userShowFlagNew=" + this.userShowFlagNew + ",richFlag=" + this.richFlag + ",mssVipType=" + this.mssVipType + ",bigClubLevel=" + this.bigClubLevel + ",bigClubFlag=" + this.bigClubFlag + ",autoRemark=" + this.autoRemark + ",creditLevel=" + this.creditLevel + ",joinTime=" + this.joinTime + ",lastSpeakTime=" + this.lastSpeakTime + ",memberFlag=" + this.memberFlag + ",memberFlagExt=" + this.memberFlagExt + ",memberMobileFlag=" + this.memberMobileFlag + ",memberFlagExt2=" + this.memberFlagExt2 + ",isSpecialShielded=" + this.isSpecialShielded + ",cardNameId=" + this.cardNameId + ",}";
}
} }

View File

@ -0,0 +1,19 @@
package com.tencent.qqnt.kernel.nativeinterface;
public class MemberLevelName {
public int level;
public String strName = "";
public int getLevel() {
return this.level;
}
public String getStrName() {
return this.strName;
}
public String toString() {
return "MemberLevelName{level=" + this.level + ",strName=" + this.strName + ",}";
}
}

View File

@ -1,5 +1,7 @@
package com.tencent.qqnt.kernel.nativeinterface; package com.tencent.qqnt.kernel.nativeinterface;
import com.tencent.qqnt.kernelpublic.nativeinterface.Contact;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;

View File

@ -0,0 +1,4 @@
package com.tencent.qqnt.kernel.nativeinterface;
public class QueryUserSecQualityRsp {
}

View File

@ -1,6 +1,7 @@
package com.tencent.qqnt.kernel.nativeinterface; package com.tencent.qqnt.kernel.nativeinterface;
import com.tencent.qqnt.kernelpublic.nativeinterface.Contact;
public final class UnreadCntInfo { public final class UnreadCntInfo {
UnreadCnt allUnreadCnt; UnreadCnt allUnreadCnt;

View File

@ -1,4 +1,6 @@
package com.tencent.qqnt.kernel.nativeinterface; package com.tencent.qqnt.kernelpublic.nativeinterface;
import com.tencent.qqnt.kernel.nativeinterface.IKernelModel;
import java.io.Serializable; import java.io.Serializable;

View File

@ -0,0 +1,9 @@
package com.tencent.qqnt.kernelpublic.nativeinterface;
public enum MemberRole {
UNSPECIFIED,
STRANGER,
MEMBER,
ADMIN,
OWNER
}

View File

@ -2,6 +2,7 @@ package com.tencent.qqnt.msg.api;
import com.tencent.mobileqq.qroute.QRouteApi; import com.tencent.mobileqq.qroute.QRouteApi;
import com.tencent.qqnt.kernel.nativeinterface.*; import com.tencent.qqnt.kernel.nativeinterface.*;
import com.tencent.qqnt.kernelpublic.nativeinterface.Contact;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@ -9,7 +10,6 @@ import org.jetbrains.annotations.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import kotlin.Pair;
import kotlinx.coroutines.flow.Flow; import kotlinx.coroutines.flow.Flow;
public interface IMsgService extends QRouteApi { public interface IMsgService extends QRouteApi {

View File

@ -156,8 +156,8 @@ internal object FriendService : FriendServiceGrpcKt.FriendServiceCoroutineImplBa
val bundle = Bundle() val bundle = Bundle()
val service = QQInterfaces.app val service = QQInterfaces.app
.getRuntimeService(IProfileProtocolService::class.java, "all") .getRuntimeService(IProfileProtocolService::class.java, "all")
if (request.hasNickName()) { if (request.hasNick()) {
bundle.putString(IProfileProtocolConst.KEY_NICK, request.nickName) bundle.putString(IProfileProtocolConst.KEY_NICK, request.nick)
} }
if (request.hasCompany()) { if (request.hasCompany()) {
bundle.putString(IProfileProtocolConst.KEY_COMPANY, request.company) bundle.putString(IProfileProtocolConst.KEY_COMPANY, request.company)

View File

@ -3,6 +3,7 @@ package kritor.service
import io.grpc.Status import io.grpc.Status
import io.grpc.StatusRuntimeException import io.grpc.StatusRuntimeException
import io.kritor.file.* import io.kritor.file.*
import moe.fuqiuluo.shamrock.tools.decodeToOidb
import moe.fuqiuluo.shamrock.tools.slice import moe.fuqiuluo.shamrock.tools.slice
import moe.fuqiuluo.symbols.decodeProtobuf import moe.fuqiuluo.symbols.decodeProtobuf
import protobuf.auto.toByteArray import protobuf.auto.toByteArray
@ -33,8 +34,7 @@ internal object GroupFileService : GroupFileServiceGrpcKt.GroupFileServiceCorout
if (fromServiceMsg.wupBuffer == null) { if (fromServiceMsg.wupBuffer == null) {
throw StatusRuntimeException(Status.INTERNAL.withDescription("oidb request failed")) throw StatusRuntimeException(Status.INTERNAL.withDescription("oidb request failed"))
} }
val oidbPkg = oidb_sso.OIDBSSOPkg() val oidbPkg = fromServiceMsg.decodeToOidb()
oidbPkg.mergeFrom(fromServiceMsg.wupBuffer.slice(4))
val rsp = oidbPkg.bytes_bodybuffer.get() val rsp = oidbPkg.bytes_bodybuffer.get()
.toByteArray() .toByteArray()
.decodeProtobuf<Oidb0x6d7RespBody>() .decodeProtobuf<Oidb0x6d7RespBody>()
@ -61,8 +61,7 @@ internal object GroupFileService : GroupFileServiceGrpcKt.GroupFileServiceCorout
if (fromServiceMsg.wupBuffer == null) { if (fromServiceMsg.wupBuffer == null) {
throw StatusRuntimeException(Status.INTERNAL.withDescription("oidb request failed")) throw StatusRuntimeException(Status.INTERNAL.withDescription("oidb request failed"))
} }
val oidbPkg = oidb_sso.OIDBSSOPkg() val oidbPkg = fromServiceMsg.decodeToOidb()
oidbPkg.mergeFrom(fromServiceMsg.wupBuffer.slice(4))
val rsp = oidbPkg.bytes_bodybuffer.get().toByteArray().decodeProtobuf<Oidb0x6d7RespBody>() val rsp = oidbPkg.bytes_bodybuffer.get().toByteArray().decodeProtobuf<Oidb0x6d7RespBody>()
if (rsp.deleteFolder?.retCode != 0) { if (rsp.deleteFolder?.retCode != 0) {
throw StatusRuntimeException(Status.INTERNAL.withDescription("unable to delete folder: ${rsp.deleteFolder?.retCode}")) throw StatusRuntimeException(Status.INTERNAL.withDescription("unable to delete folder: ${rsp.deleteFolder?.retCode}"))
@ -86,8 +85,7 @@ internal object GroupFileService : GroupFileServiceGrpcKt.GroupFileServiceCorout
if (fromServiceMsg.wupBuffer == null) { if (fromServiceMsg.wupBuffer == null) {
throw StatusRuntimeException(Status.INTERNAL.withDescription("oidb request failed")) throw StatusRuntimeException(Status.INTERNAL.withDescription("oidb request failed"))
} }
val oidbPkg = oidb_sso.OIDBSSOPkg() val oidbPkg = fromServiceMsg.decodeToOidb()
oidbPkg.mergeFrom(fromServiceMsg.wupBuffer.slice(4))
val rsp = oidb_0x6d6.RspBody().apply { val rsp = oidb_0x6d6.RspBody().apply {
mergeFrom(oidbPkg.bytes_bodybuffer.get().toByteArray()) mergeFrom(oidbPkg.bytes_bodybuffer.get().toByteArray())
} }
@ -112,8 +110,7 @@ internal object GroupFileService : GroupFileServiceGrpcKt.GroupFileServiceCorout
if (fromServiceMsg.wupBuffer == null) { if (fromServiceMsg.wupBuffer == null) {
throw StatusRuntimeException(Status.INTERNAL.withDescription("oidb request failed")) throw StatusRuntimeException(Status.INTERNAL.withDescription("oidb request failed"))
} }
val oidbPkg = oidb_sso.OIDBSSOPkg() val oidbPkg = fromServiceMsg.decodeToOidb()
oidbPkg.mergeFrom(fromServiceMsg.wupBuffer.slice(4))
val rsp = oidbPkg.bytes_bodybuffer.get().toByteArray().decodeProtobuf<Oidb0x6d7RespBody>() val rsp = oidbPkg.bytes_bodybuffer.get().toByteArray().decodeProtobuf<Oidb0x6d7RespBody>()
if (rsp.renameFolder?.retCode != 0) { if (rsp.renameFolder?.retCode != 0) {
throw StatusRuntimeException(Status.INTERNAL.withDescription("unable to rename folder: ${rsp.renameFolder?.retCode}")) throw StatusRuntimeException(Status.INTERNAL.withDescription("unable to rename folder: ${rsp.renameFolder?.retCode}"))

View File

@ -8,6 +8,7 @@ import moe.fuqiuluo.shamrock.helper.TroopHonorHelper.decodeHonor
import moe.fuqiuluo.shamrock.tools.ifNullOrEmpty import moe.fuqiuluo.shamrock.tools.ifNullOrEmpty
import qq.service.contact.ContactHelper import qq.service.contact.ContactHelper
import qq.service.group.GroupHelper import qq.service.group.GroupHelper
import tencent.im.troop.honor.troop_honor
internal object GroupService : GroupServiceGrpcKt.GroupServiceCoroutineImplBase() { internal object GroupService : GroupServiceGrpcKt.GroupServiceCoroutineImplBase() {
@Grpc("GroupService", "BanMember") @Grpc("GroupService", "BanMember")
@ -258,12 +259,12 @@ internal object GroupService : GroupServiceGrpcKt.GroupServiceCoroutineImplBase(
.ifNullOrEmpty { memberInfo.friendnick } ?: "" .ifNullOrEmpty { memberInfo.friendnick } ?: ""
age = memberInfo.age.toInt() age = memberInfo.age.toInt()
uniqueTitle = memberInfo.mUniqueTitle ?: "" uniqueTitle = memberInfo.mUniqueTitle ?: ""
uniqueTitleExpireTime = memberInfo.mUniqueTitleExpire uniqueTitleExpireTime = memberInfo.mUniqueTitleExpire.toLong()
card = memberInfo.troopnick.ifNullOrEmpty { memberInfo.friendnick } ?: "" card = memberInfo.troopnick.ifNullOrEmpty { memberInfo.friendnick } ?: ""
joinTime = memberInfo.join_time joinTime = memberInfo.join_time
lastActiveTime = memberInfo.last_active_time lastActiveTime = memberInfo.last_active_time
level = memberInfo.level level = memberInfo.level
shutUpTimestamp = memberInfo.gagTimeStamp shutUpTime = memberInfo.gagTimeStamp
distance = memberInfo.distance distance = memberInfo.distance
addAllHonors((memberInfo.honorList ?: "") addAllHonors((memberInfo.honorList ?: "")
@ -279,7 +280,7 @@ internal object GroupService : GroupServiceGrpcKt.GroupServiceCoroutineImplBase(
@Grpc("GroupService", "GetGroupMemberList") @Grpc("GroupService", "GetGroupMemberList")
override suspend fun getGroupMemberList(request: GetGroupMemberListRequest): GetGroupMemberListResponse { override suspend fun getGroupMemberList(request: GetGroupMemberListRequest): GetGroupMemberListResponse {
val memberList = GroupHelper.getGroupMemberList( val memberList = GroupHelper.getGroupMemberList(
request.groupId.toString(), request.groupId,
if (request.hasRefresh()) request.refresh else false if (request.hasRefresh()) request.refresh else false
).onFailure { ).onFailure {
throw StatusRuntimeException( throw StatusRuntimeException(
@ -287,30 +288,28 @@ internal object GroupService : GroupServiceGrpcKt.GroupServiceCoroutineImplBase(
) )
}.getOrThrow() }.getOrThrow()
return GetGroupMemberListResponse.newBuilder().apply { return GetGroupMemberListResponse.newBuilder().apply {
memberList.forEach { memberInfo -> memberList.values.forEach { memberInfo ->
this.addGroupMembersInfo(GroupMemberInfo.newBuilder().apply { this.addGroupMembersInfo(GroupMemberInfo.newBuilder().apply {
uid = ContactHelper.getUidByUinAsync(memberInfo.memberuin?.toLong() ?: 0) uid = memberInfo.uid
uin = memberInfo.memberuin?.toLong() ?: 0 uin = memberInfo.uin
nick = memberInfo.troopnick nick = memberInfo.nick ?: ""
.ifNullOrEmpty { memberInfo.hwName } age = 0
.ifNullOrEmpty { memberInfo.troopColorNick } uniqueTitle = memberInfo.memberSpecialTitle ?: ""
.ifNullOrEmpty { memberInfo.friendnick } ?: "" uniqueTitleExpireTime = memberInfo.specialTitleExpireTime
age = memberInfo.age.toInt() card = memberInfo.cardName.ifNullOrEmpty { memberInfo.nick } ?: ""
uniqueTitle = memberInfo.mUniqueTitle ?: "" joinTime = memberInfo.joinTime.toLong()
uniqueTitleExpireTime = memberInfo.mUniqueTitleExpire lastActiveTime = memberInfo.lastSpeakTime.toLong()
card = memberInfo.troopnick.ifNullOrEmpty { memberInfo.friendnick } ?: "" level = memberInfo.memberLevel
joinTime = memberInfo.join_time shutUpTime = memberInfo.shutUpTime.toLong()
lastActiveTime = memberInfo.last_active_time
level = memberInfo.level
shutUpTimestamp = memberInfo.gagTimeStamp
distance = memberInfo.distance distance = 0
addAllHonors((memberInfo.honorList ?: "") addAllHonors(memberInfo.groupHonor.let { bytes ->
.split("|") val honor = troop_honor.GroupUserCardHonor()
.filter { it.isNotBlank() } honor.mergeFrom(bytes)
.map { it.toInt() }) honor.id.get()
})
unfriendly = false unfriendly = false
cardChangeable = GroupHelper.isAdmin(request.groupId.toString()) cardChangeable = memberInfo.role == com.tencent.qqnt.kernelpublic.nativeinterface.MemberRole.ADMIN
}) })
} }
}.build() }.build()
@ -328,7 +327,7 @@ internal object GroupService : GroupServiceGrpcKt.GroupServiceCoroutineImplBase(
this.addProhibitedUsersInfo(ProhibitedUserInfo.newBuilder().apply { this.addProhibitedUsersInfo(ProhibitedUserInfo.newBuilder().apply {
uid = ContactHelper.getUidByUinAsync(it.memberUin) uid = ContactHelper.getUidByUinAsync(it.memberUin)
uin = it.memberUin uin = it.memberUin
prohibitedTime = it.shutuptimestap prohibitedTime = it.shutuptimestap.toLong()
}) })
} }
}.build() }.build()
@ -361,7 +360,7 @@ internal object GroupService : GroupServiceGrpcKt.GroupServiceCoroutineImplBase(
maxMemberCount = groupInfo.maxMember maxMemberCount = groupInfo.maxMember
memberCount = groupInfo.memberCount memberCount = groupInfo.memberCount
groupDesc = groupInfo.groupDesc groupDesc = groupInfo.groupDesc
createTime = groupInfo.createTime.toInt() createTime = groupInfo.createTime
groupFlag = groupInfo.groupFlag groupFlag = groupInfo.groupFlag
groupFlagExt = groupInfo.groupFlagExt groupFlagExt = groupInfo.groupFlagExt
}.build() }.build()
@ -371,24 +370,25 @@ internal object GroupService : GroupServiceGrpcKt.GroupServiceCoroutineImplBase(
@Grpc("GroupService", "GetGroupHonor") @Grpc("GroupService", "GetGroupHonor")
override suspend fun getGroupHonor(request: GetGroupHonorRequest): GetGroupHonorResponse { override suspend fun getGroupHonor(request: GetGroupHonorRequest): GetGroupHonorResponse {
return GetGroupHonorResponse.newBuilder().apply { return GetGroupHonorResponse.newBuilder().apply {
GroupHelper.getGroupMemberList(request.groupId.toString(), true).onFailure { GroupHelper.getGroupMemberList(request.groupId, true).onFailure {
throw StatusRuntimeException( throw StatusRuntimeException(
Status.INTERNAL.withDescription("unable to get group member list").withCause(it) Status.INTERNAL.withDescription("unable to get group member list").withCause(it)
) )
}.onSuccess { memberList -> }.onSuccess { memberList ->
memberList.forEach { member -> memberList.values.forEach { member ->
(member.honorList ?: "").split("|") member.groupHonor.let { bytes ->
.filter { it.isNotBlank() } val honor = troop_honor.GroupUserCardHonor()
.map { it.toInt() }.forEach { honor.mergeFrom(bytes)
val honor = decodeHonor(member.memberuin.toLong(), it, member.mHonorRichFlag) honor.id.get()
}.forEach {
val honor = decodeHonor(member.uin, it, 0)
if (honor != null) { if (honor != null) {
addGroupHonorsInfo(GroupHonorInfo.newBuilder().apply { addGroupHonorsInfo(GroupHonorInfo.newBuilder().apply {
uid = ContactHelper.getUidByUinAsync(member.memberuin.toLong()) uid = member.uid
uin = member.memberuin.toLong() uin = member.uin
nick = member.troopnick nick = member.nick.ifEmpty {
.ifNullOrEmpty { member.hwName } member.cardName
.ifNullOrEmpty { member.troopColorNick } } ?: ""
.ifNullOrEmpty { member.friendnick } ?: ""
honorName = honor.honorName honorName = honor.honorName
avatar = honor.honorIconUrl avatar = honor.honorIconUrl
id = honor.honorId id = honor.honorId

View File

@ -1,7 +1,7 @@
package kritor.service package kritor.service
import com.tencent.mobileqq.qroute.QRoute import com.tencent.mobileqq.qroute.QRoute
import com.tencent.qqnt.kernel.nativeinterface.Contact import com.tencent.qqnt.kernelpublic.nativeinterface.Contact
import com.tencent.qqnt.kernel.nativeinterface.MsgConstant import com.tencent.qqnt.kernel.nativeinterface.MsgConstant
import com.tencent.qqnt.kernel.nativeinterface.MsgRecord import com.tencent.qqnt.kernel.nativeinterface.MsgRecord
import com.tencent.qqnt.msg.api.IMsgService import com.tencent.qqnt.msg.api.IMsgService
@ -103,7 +103,12 @@ internal object MessageService : MessageServiceGrpcKt.MessageServiceCoroutineImp
Scene.STRANGER -> MsgConstant.KCHATTYPETEMPC2CFROMUNKNOWN Scene.STRANGER -> MsgConstant.KCHATTYPETEMPC2CFROMUNKNOWN
Scene.UNRECOGNIZED -> throw StatusRuntimeException(Status.INVALID_ARGUMENT.withDescription("Unrecognized scene")) Scene.UNRECOGNIZED -> throw StatusRuntimeException(Status.INVALID_ARGUMENT.withDescription("Unrecognized scene"))
} }
service.clearMsgRecords(Contact(chatType, contact.peer, contact.subPeer), null) service.clearMsgRecords(
Contact(
chatType,
contact.peer,
contact.subPeer
), null)
return SetMessageReadResponse.newBuilder().build() return SetMessageReadResponse.newBuilder().build()
} }
@ -310,7 +315,7 @@ internal object MessageService : MessageServiceGrpcKt.MessageServiceCoroutineImp
throw StatusRuntimeException(Status.INTERNAL.withCause(it)) throw StatusRuntimeException(Status.INTERNAL.withCause(it))
}.getOrThrow().map { detail -> }.getOrThrow().map { detail ->
PushMessageBody.newBuilder().apply { PushMessageBody.newBuilder().apply {
this.time = detail.time this.time = detail.time.toLong()
this.messageId = detail.qqMsgId.toString() this.messageId = detail.qqMsgId.toString()
this.messageSeq = detail.msgSeq this.messageSeq = detail.msgSeq
this.contact = io.kritor.common.Contact.newBuilder().apply { this.contact = io.kritor.common.Contact.newBuilder().apply {
@ -330,7 +335,7 @@ internal object MessageService : MessageServiceGrpcKt.MessageServiceCoroutineImp
this.uid = detail.sender.uid this.uid = detail.sender.uid
}.build() }.build()
detail.message?.elements?.toKritorResponseMessages( detail.message?.elements?.toKritorResponseMessages(
com.tencent.qqnt.kernel.nativeinterface.Contact( Contact(
detail.msgType, detail.msgType,
detail.peerId.toString(), detail.peerId.toString(),
null null
@ -393,10 +398,10 @@ internal object MessageService : MessageServiceGrpcKt.MessageServiceCoroutineImp
this.messageId = it.msgId.toString() this.messageId = it.msgId.toString()
} }
this.messageSeq = it.messageSeq this.messageSeq = it.messageSeq
this.messageTime = it.senderTime.toInt() this.messageTime = it.senderTime
this.senderNick = it.senderNick this.senderNick = it.senderNick
this.senderUin = it.senderId this.senderUin = it.senderId
this.operationTime = it.operatorTime.toInt() this.operationTime = it.operatorTime
this.operatorNick = it.operatorNick this.operatorNick = it.operatorNick
this.operatorUin = it.operatorId this.operatorUin = it.operatorId
this.jsonElements = it.messageContent.toString() this.jsonElements = it.messageContent.toString()

View File

@ -20,6 +20,7 @@ private val configKeys = setOf(
ResourceGroup, ResourceGroup,
RPCAddress, RPCAddress,
RPCPort, RPCPort,
AliveReply,
) )
internal object ShamrockConfig: Properties() { internal object ShamrockConfig: Properties() {

View File

@ -42,7 +42,7 @@ internal object GlobalEventTransmitter : QQInterfaces() {
elements: ArrayList<MsgElement>, elements: ArrayList<MsgElement>,
): Boolean { ): Boolean {
transMessageEvent(record, PushMessageBody.newBuilder().apply { transMessageEvent(record, PushMessageBody.newBuilder().apply {
this.time = record.msgTime.toInt() this.time = record.msgTime
this.messageId = record.msgId.toString() this.messageId = record.msgId.toString()
this.messageSeq = record.msgSeq this.messageSeq = record.msgSeq
this.contact = Contact.newBuilder().apply { this.contact = Contact.newBuilder().apply {
@ -65,7 +65,7 @@ internal object GlobalEventTransmitter : QQInterfaces() {
elements: ArrayList<MsgElement>, elements: ArrayList<MsgElement>,
): Boolean { ): Boolean {
transMessageEvent(record, PushMessageBody.newBuilder().apply { transMessageEvent(record, PushMessageBody.newBuilder().apply {
this.time = record.msgTime.toInt() this.time = record.msgTime
this.messageId = record.msgId.toString() this.messageId = record.msgId.toString()
this.messageSeq = record.msgSeq this.messageSeq = record.msgSeq
this.contact = Contact.newBuilder().apply { this.contact = Contact.newBuilder().apply {
@ -90,7 +90,7 @@ internal object GlobalEventTransmitter : QQInterfaces() {
fromNick: String, fromNick: String,
): Boolean { ): Boolean {
transMessageEvent(record, PushMessageBody.newBuilder().apply { transMessageEvent(record, PushMessageBody.newBuilder().apply {
this.time = record.msgTime.toInt() this.time = record.msgTime
this.messageId = record.msgId.toString() this.messageId = record.msgId.toString()
this.messageSeq = record.msgSeq this.messageSeq = record.msgSeq
this.contact = Contact.newBuilder().apply { this.contact = Contact.newBuilder().apply {
@ -113,7 +113,7 @@ internal object GlobalEventTransmitter : QQInterfaces() {
elements: ArrayList<MsgElement>, elements: ArrayList<MsgElement>,
): Boolean { ): Boolean {
transMessageEvent(record, PushMessageBody.newBuilder().apply { transMessageEvent(record, PushMessageBody.newBuilder().apply {
this.time = record.msgTime.toInt() this.time = record.msgTime
this.messageId = record.msgId.toString() this.messageId = record.msgId.toString()
this.messageSeq = record.msgSeq this.messageSeq = record.msgSeq
this.contact = Contact.newBuilder().apply { this.contact = Contact.newBuilder().apply {
@ -152,16 +152,16 @@ internal object GlobalEventTransmitter : QQInterfaces() {
): Boolean { ): Boolean {
pushNotice(NoticeEvent.newBuilder().apply { pushNotice(NoticeEvent.newBuilder().apply {
this.type = NoticeEvent.NoticeType.PRIVATE_FILE_UPLOADED this.type = NoticeEvent.NoticeType.PRIVATE_FILE_UPLOADED
this.time = msgTime.toInt() this.time = msgTime
this.privateFileUploaded = PrivateFileUploadedNotice.newBuilder().apply { this.privateFileUploaded = PrivateFileUploadedNotice.newBuilder().apply {
this.fileId = fileId this.fileId = fileId
this.fileName = fileName this.fileName = fileName
this.operatorUid = senderUid this.operatorUid = senderUid
this.operatorUin = senderUin this.operatorUin = senderUin
this.fileSize = fileSize this.fileSize = fileSize
this.expireTime = expireTime.toInt() this.expireTime = expireTime
this.fileSubId = fileSubId this.fileSubId = fileSubId.toInt() // todo(这玩意真的是一个数字?)
this.url = url this.fileUrl = url
}.build() }.build()
}.build()) }.build())
return true return true
@ -183,7 +183,7 @@ internal object GlobalEventTransmitter : QQInterfaces() {
): Boolean { ): Boolean {
pushNotice(NoticeEvent.newBuilder().apply { pushNotice(NoticeEvent.newBuilder().apply {
this.type = NoticeEvent.NoticeType.GROUP_FILE_UPLOADED this.type = NoticeEvent.NoticeType.GROUP_FILE_UPLOADED
this.time = msgTime.toInt() this.time = msgTime
this.groupFileUploaded = GroupFileUploadedNotice.newBuilder().apply { this.groupFileUploaded = GroupFileUploadedNotice.newBuilder().apply {
this.groupId = groupId this.groupId = groupId
this.operatorUid = senderUid this.operatorUid = senderUid
@ -191,7 +191,7 @@ internal object GlobalEventTransmitter : QQInterfaces() {
this.fileId = uuid this.fileId = uuid
this.fileName = fileName this.fileName = fileName
this.fileSize = fileSize this.fileSize = fileSize
this.busId = bizId this.fileSubId = bizId
this.fileUrl = url this.fileUrl = url
}.build() }.build()
}.build()) }.build())
@ -212,7 +212,7 @@ internal object GlobalEventTransmitter : QQInterfaces() {
): Boolean { ): Boolean {
pushNotice(NoticeEvent.newBuilder().apply { pushNotice(NoticeEvent.newBuilder().apply {
this.type = NoticeEvent.NoticeType.GROUP_SIGN_IN this.type = NoticeEvent.NoticeType.GROUP_SIGN_IN
this.time = time.toInt() this.time = time
this.groupSignIn = GroupSignInNotice.newBuilder().apply { this.groupSignIn = GroupSignInNotice.newBuilder().apply {
this.groupId = groupCode this.groupId = groupCode
this.targetUid = ContactHelper.getUidByUinAsync(target) this.targetUid = ContactHelper.getUidByUinAsync(target)
@ -235,7 +235,7 @@ internal object GlobalEventTransmitter : QQInterfaces() {
): Boolean { ): Boolean {
pushNotice(NoticeEvent.newBuilder().apply { pushNotice(NoticeEvent.newBuilder().apply {
this.type = NoticeEvent.NoticeType.GROUP_POKE this.type = NoticeEvent.NoticeType.GROUP_POKE
this.time = time.toInt() this.time = time
this.groupPoke = GroupPokeNotice.newBuilder().apply { this.groupPoke = GroupPokeNotice.newBuilder().apply {
this.groupId = groupCode this.groupId = groupCode
this.action = action this.action = action
@ -261,7 +261,7 @@ internal object GlobalEventTransmitter : QQInterfaces() {
): Boolean { ): Boolean {
pushNotice(NoticeEvent.newBuilder().apply { pushNotice(NoticeEvent.newBuilder().apply {
this.type = NoticeEvent.NoticeType.GROUP_MEMBER_INCREASE this.type = NoticeEvent.NoticeType.GROUP_MEMBER_INCREASE
this.time = time.toInt() this.time = time
this.groupMemberIncrease = GroupMemberIncreasedNotice.newBuilder().apply { this.groupMemberIncrease = GroupMemberIncreasedNotice.newBuilder().apply {
this.groupId = groupCode this.groupId = groupCode
this.operatorUid = operatorUid this.operatorUid = operatorUid
@ -285,7 +285,7 @@ internal object GlobalEventTransmitter : QQInterfaces() {
): Boolean { ): Boolean {
pushNotice(NoticeEvent.newBuilder().apply { pushNotice(NoticeEvent.newBuilder().apply {
this.type = NoticeEvent.NoticeType.GROUP_MEMBER_DECREASE this.type = NoticeEvent.NoticeType.GROUP_MEMBER_DECREASE
this.time = time.toInt() this.time = time
this.groupMemberDecrease = GroupMemberDecreasedNotice.newBuilder().apply { this.groupMemberDecrease = GroupMemberDecreasedNotice.newBuilder().apply {
this.groupId = groupCode this.groupId = groupCode
this.operatorUid = operatorUid this.operatorUid = operatorUid
@ -307,7 +307,7 @@ internal object GlobalEventTransmitter : QQInterfaces() {
): Boolean { ): Boolean {
pushNotice(NoticeEvent.newBuilder().apply { pushNotice(NoticeEvent.newBuilder().apply {
this.type = NoticeEvent.NoticeType.GROUP_ADMIN_CHANGED this.type = NoticeEvent.NoticeType.GROUP_ADMIN_CHANGED
this.time = msgTime.toInt() this.time = msgTime
this.groupAdminChanged = GroupAdminChangedNotice.newBuilder().apply { this.groupAdminChanged = GroupAdminChangedNotice.newBuilder().apply {
this.groupId = groupCode this.groupId = groupCode
this.targetUid = targetUid this.targetUid = targetUid
@ -327,7 +327,7 @@ internal object GlobalEventTransmitter : QQInterfaces() {
): Boolean { ): Boolean {
pushNotice(NoticeEvent.newBuilder().apply { pushNotice(NoticeEvent.newBuilder().apply {
this.type = NoticeEvent.NoticeType.GROUP_WHOLE_BAN this.type = NoticeEvent.NoticeType.GROUP_WHOLE_BAN
this.time = msgTime.toInt() this.time = msgTime
this.groupWholeBan = GroupWholeBanNotice.newBuilder().apply { this.groupWholeBan = GroupWholeBanNotice.newBuilder().apply {
this.groupId = groupCode this.groupId = groupCode
this.isBan = isOpen this.isBan = isOpen
@ -349,7 +349,7 @@ internal object GlobalEventTransmitter : QQInterfaces() {
): Boolean { ): Boolean {
pushNotice(NoticeEvent.newBuilder().apply { pushNotice(NoticeEvent.newBuilder().apply {
this.type = NoticeEvent.NoticeType.GROUP_MEMBER_BAN this.type = NoticeEvent.NoticeType.GROUP_MEMBER_BAN
this.time = msgTime.toInt() this.time = msgTime
this.groupMemberBan = GroupMemberBanNotice.newBuilder().apply { this.groupMemberBan = GroupMemberBanNotice.newBuilder().apply {
this.groupId = groupCode this.groupId = groupCode
this.operatorUid = operatorUid this.operatorUid = operatorUid
@ -376,7 +376,7 @@ internal object GlobalEventTransmitter : QQInterfaces() {
): Boolean { ): Boolean {
pushNotice(NoticeEvent.newBuilder().apply { pushNotice(NoticeEvent.newBuilder().apply {
this.type = NoticeEvent.NoticeType.GROUP_RECALL this.type = NoticeEvent.NoticeType.GROUP_RECALL
this.time = time.toInt() this.time = time
this.groupRecall = GroupRecallNotice.newBuilder().apply { this.groupRecall = GroupRecallNotice.newBuilder().apply {
this.groupId = groupCode this.groupId = groupCode
this.operatorUid = operatorUid this.operatorUid = operatorUid
@ -398,7 +398,7 @@ internal object GlobalEventTransmitter : QQInterfaces() {
): Boolean { ): Boolean {
pushNotice(NoticeEvent.newBuilder().apply { pushNotice(NoticeEvent.newBuilder().apply {
this.type = NoticeEvent.NoticeType.GROUP_CARD_CHANGED this.type = NoticeEvent.NoticeType.GROUP_CARD_CHANGED
this.time = time.toInt() this.time = time
this.groupCardChanged = GroupCardChangedNotice.newBuilder().apply { this.groupCardChanged = GroupCardChangedNotice.newBuilder().apply {
this.groupId = groupId this.groupId = groupId
this.targetUin = targetId this.targetUin = targetId
@ -416,7 +416,7 @@ internal object GlobalEventTransmitter : QQInterfaces() {
): Boolean { ): Boolean {
pushNotice(NoticeEvent.newBuilder().apply { pushNotice(NoticeEvent.newBuilder().apply {
this.type = NoticeEvent.NoticeType.GROUP_MEMBER_UNIQUE_TITLE_CHANGED this.type = NoticeEvent.NoticeType.GROUP_MEMBER_UNIQUE_TITLE_CHANGED
this.time = time.toInt() this.time = time
this.groupMemberUniqueTitleChanged = GroupUniqueTitleChangedNotice.newBuilder().apply { this.groupMemberUniqueTitleChanged = GroupUniqueTitleChangedNotice.newBuilder().apply {
this.groupId = groupId this.groupId = groupId
this.targetUid = ContactHelper.getUidByUinAsync(targetUin) this.targetUid = ContactHelper.getUidByUinAsync(targetUin)
@ -437,7 +437,7 @@ internal object GlobalEventTransmitter : QQInterfaces() {
): Boolean { ): Boolean {
pushNotice(NoticeEvent.newBuilder().apply { pushNotice(NoticeEvent.newBuilder().apply {
this.type = NoticeEvent.NoticeType.GROUP_ESSENCE_CHANGED this.type = NoticeEvent.NoticeType.GROUP_ESSENCE_CHANGED
this.time = time.toInt() this.time = time
this.groupEssenceChanged = GroupEssenceMessageNotice.newBuilder().apply { this.groupEssenceChanged = GroupEssenceMessageNotice.newBuilder().apply {
this.groupId = groupId this.groupId = groupId
this.messageId = msgId.toString() this.messageId = msgId.toString()
@ -465,7 +465,7 @@ internal object GlobalEventTransmitter : QQInterfaces() {
): Boolean { ): Boolean {
pushNotice(NoticeEvent.newBuilder().apply { pushNotice(NoticeEvent.newBuilder().apply {
this.type = NoticeEvent.NoticeType.PRIVATE_POKE this.type = NoticeEvent.NoticeType.PRIVATE_POKE
this.time = msgTime.toInt() this.time = msgTime
this.privatePoke = PrivatePokeNotice.newBuilder().apply { this.privatePoke = PrivatePokeNotice.newBuilder().apply {
this.action = action ?: "" this.action = action ?: ""
this.operatorUid = ContactHelper.getUidByUinAsync(operator) this.operatorUid = ContactHelper.getUidByUinAsync(operator)
@ -480,7 +480,7 @@ internal object GlobalEventTransmitter : QQInterfaces() {
suspend fun transPrivateRecall(time: Long, operator: Long, msgId: Long, tipText: String): Boolean { suspend fun transPrivateRecall(time: Long, operator: Long, msgId: Long, tipText: String): Boolean {
pushNotice(NoticeEvent.newBuilder().apply { pushNotice(NoticeEvent.newBuilder().apply {
this.type = NoticeEvent.NoticeType.PRIVATE_RECALL this.type = NoticeEvent.NoticeType.PRIVATE_RECALL
this.time = time.toInt() this.time = time
this.privateRecall = PrivateRecallNotice.newBuilder().apply { this.privateRecall = PrivateRecallNotice.newBuilder().apply {
this.operatorUin = operator this.operatorUin = operator
this.messageId = msgId.toString() this.messageId = msgId.toString()
@ -499,7 +499,7 @@ internal object GlobalEventTransmitter : QQInterfaces() {
suspend fun transFriendApp(time: Long, applierUid: String, operator: Long, tipText: String, flag: String): Boolean { suspend fun transFriendApp(time: Long, applierUid: String, operator: Long, tipText: String, flag: String): Boolean {
pushRequest(RequestEvent.newBuilder().apply { pushRequest(RequestEvent.newBuilder().apply {
this.type = RequestEvent.RequestType.FRIEND_APPLY this.type = RequestEvent.RequestType.FRIEND_APPLY
this.time = time.toInt() this.time = time
this.requestId = flag this.requestId = flag
this.friendApply = FriendApplyRequest.newBuilder().apply { this.friendApply = FriendApplyRequest.newBuilder().apply {
this.applierUid = applierUid this.applierUid = applierUid
@ -520,7 +520,7 @@ internal object GlobalEventTransmitter : QQInterfaces() {
): Boolean { ): Boolean {
pushRequest(RequestEvent.newBuilder().apply { pushRequest(RequestEvent.newBuilder().apply {
this.type = RequestEvent.RequestType.GROUP_APPLY this.type = RequestEvent.RequestType.GROUP_APPLY
this.time = time.toInt() this.time = time
this.requestId = flag this.requestId = flag
this.groupApply = GroupApplyRequest.newBuilder().apply { this.groupApply = GroupApplyRequest.newBuilder().apply {
this.applierUid = applierUid this.applierUid = applierUid
@ -541,7 +541,7 @@ internal object GlobalEventTransmitter : QQInterfaces() {
): Boolean { ): Boolean {
pushRequest(RequestEvent.newBuilder().apply { pushRequest(RequestEvent.newBuilder().apply {
this.type = RequestEvent.RequestType.GROUP_APPLY this.type = RequestEvent.RequestType.GROUP_APPLY
this.time = time.toInt() this.time = time
this.requestId = flag this.requestId = flag
this.invitedGroup = InvitedJoinGroupRequest.newBuilder().apply { this.invitedGroup = InvitedJoinGroupRequest.newBuilder().apply {
this.inviterUid = inviterUid this.inviterUid = inviterUid

View File

@ -0,0 +1,33 @@
package moe.fuqiuluo.shamrock.tools
import com.tencent.qphone.base.remote.FromServiceMsg
import moe.fuqiuluo.shamrock.helper.Level
import moe.fuqiuluo.shamrock.helper.LogCenter
import moe.fuqiuluo.shamrock.utils.DeflateTools
import moe.fuqiuluo.symbols.decodeProtobuf
import protobuf.oidb.TrpcOidb
import tencent.im.oidb.oidb_sso
fun FromServiceMsg.decodeToOidb(): oidb_sso.OIDBSSOPkg {
return kotlin.runCatching {
oidb_sso.OIDBSSOPkg().mergeFrom(wupBuffer.slice(4).let {
if (it[0] == 0x78.toByte()) DeflateTools.uncompress(it) else it
})
}.getOrElse {
oidb_sso.OIDBSSOPkg().mergeFrom(wupBuffer.let {
if (it[0] == 0x78.toByte()) DeflateTools.uncompress(it) else it
})
}
}
fun FromServiceMsg.decodeToTrpcOidb(): TrpcOidb {
return kotlin.runCatching {
wupBuffer.slice(4).let {
if (it[0] == 0x78.toByte()) DeflateTools.uncompress(it) else it
}.decodeProtobuf<TrpcOidb>()
}.getOrElse {
wupBuffer.let {
if (it[0] == 0x78.toByte()) DeflateTools.uncompress(it) else it
}.decodeProtobuf<TrpcOidb>()
}
}

View File

@ -6,17 +6,21 @@ import android.content.Context
import android.content.Context.BATTERY_SERVICE import android.content.Context.BATTERY_SERVICE
import android.content.Intent import android.content.Intent
import android.content.IntentFilter import android.content.IntentFilter
import android.content.pm.ApplicationInfo
import android.content.pm.PackageInfo import android.content.pm.PackageInfo
import android.os.BatteryManager import android.os.BatteryManager
import android.os.Build import android.os.Build
import android.os.Process import android.os.Process
import android.provider.Settings import android.provider.Settings
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import moe.fuqiuluo.shamrock.tools.ShamrockVersion
import mqq.app.MobileQQ import mqq.app.MobileQQ
import kotlin.random.Random import kotlin.random.Random
internal object PlatformUtils { internal object PlatformUtils {
const val QQ_9_0_8_VER = 5540 const val QQ_9_0_8_VER = 5540
const val QQ_9_0_65_VER = 6566
fun getQUA(): String { fun getQUA(): String {
return "V1_AND_SQ_${getQQVersion(MobileQQ.getContext())}_${getQQVersionCode()}_YYB_D" return "V1_AND_SQ_${getQQVersion(MobileQQ.getContext())}_${getQQVersionCode()}_YYB_D"
@ -69,6 +73,15 @@ internal object PlatformUtils {
return MobileQQ.getMobileQQ().qqProcessName == "com.tencent.tim" return MobileQQ.getMobileQQ().qqProcessName == "com.tencent.tim"
} }
fun isApkInDebug(context: Context): Boolean {
try {
val info = context.applicationInfo
return (info.flags and ApplicationInfo.FLAG_DEBUGGABLE) != 0
} catch (e: Exception) {
return false
}
}
fun killProcess(context: Context, processName: String) { fun killProcess(context: Context, processName: String) {
for (processInfo in (context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager).runningAppProcesses) { for (processInfo in (context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager).runningAppProcesses) {
if (processInfo.processName == processName) { if (processInfo.processName == processName) {

View File

@ -5,7 +5,7 @@ import androidx.exifinterface.media.ExifInterface
import com.tencent.mobileqq.qroute.QRoute import com.tencent.mobileqq.qroute.QRoute
import com.tencent.qqnt.aio.adapter.api.IAIOPttApi import com.tencent.qqnt.aio.adapter.api.IAIOPttApi
import com.tencent.qqnt.kernel.nativeinterface.CommonFileInfo import com.tencent.qqnt.kernel.nativeinterface.CommonFileInfo
import com.tencent.qqnt.kernel.nativeinterface.Contact import com.tencent.qqnt.kernelpublic.nativeinterface.Contact
import com.tencent.qqnt.kernel.nativeinterface.FileTransNotifyInfo import com.tencent.qqnt.kernel.nativeinterface.FileTransNotifyInfo
import com.tencent.qqnt.kernel.nativeinterface.MsgConstant import com.tencent.qqnt.kernel.nativeinterface.MsgConstant
import com.tencent.qqnt.kernel.nativeinterface.MsgElement import com.tencent.qqnt.kernel.nativeinterface.MsgElement
@ -20,9 +20,12 @@ import kotlinx.coroutines.suspendCancellableCoroutine
import kotlinx.coroutines.withTimeoutOrNull import kotlinx.coroutines.withTimeoutOrNull
import moe.fuqiuluo.shamrock.config.ResourceGroup import moe.fuqiuluo.shamrock.config.ResourceGroup
import moe.fuqiuluo.shamrock.config.ShamrockConfig import moe.fuqiuluo.shamrock.config.ShamrockConfig
import moe.fuqiuluo.shamrock.helper.LogCenter
import moe.fuqiuluo.shamrock.tools.decodeToTrpcOidb
import moe.fuqiuluo.shamrock.tools.hex2ByteArray import moe.fuqiuluo.shamrock.tools.hex2ByteArray
import moe.fuqiuluo.shamrock.tools.ifNullOrEmpty import moe.fuqiuluo.shamrock.tools.ifNullOrEmpty
import moe.fuqiuluo.shamrock.tools.slice import moe.fuqiuluo.shamrock.tools.slice
import moe.fuqiuluo.shamrock.tools.toHexString
import moe.fuqiuluo.shamrock.utils.AudioUtils import moe.fuqiuluo.shamrock.utils.AudioUtils
import moe.fuqiuluo.shamrock.utils.FileUtils import moe.fuqiuluo.shamrock.utils.FileUtils
import moe.fuqiuluo.shamrock.utils.MediaType import moe.fuqiuluo.shamrock.utils.MediaType
@ -34,6 +37,8 @@ import protobuf.oidb.cmd0x11c5.CodecConfigReq
import protobuf.oidb.cmd0x11c5.CommonHead import protobuf.oidb.cmd0x11c5.CommonHead
import protobuf.oidb.cmd0x11c5.DownloadExt import protobuf.oidb.cmd0x11c5.DownloadExt
import protobuf.oidb.cmd0x11c5.DownloadReq import protobuf.oidb.cmd0x11c5.DownloadReq
import protobuf.oidb.cmd0x11c5.DownloadRkeyReq
import protobuf.oidb.cmd0x11c5.DownloadRkeyRsp
import protobuf.oidb.cmd0x11c5.FileInfo import protobuf.oidb.cmd0x11c5.FileInfo
import protobuf.oidb.cmd0x11c5.FileType import protobuf.oidb.cmd0x11c5.FileType
import protobuf.oidb.cmd0x11c5.IndexNode import protobuf.oidb.cmd0x11c5.IndexNode
@ -283,6 +288,44 @@ internal object NtV2RichMediaSvc: QQInterfaces() {
return Result.success(result) return Result.success(result)
} }
suspend fun getTempNtRKey(): Result<DownloadRkeyRsp> {
runCatching {
val req = NtV2RichMediaReq(
head = MultiMediaReqHead(
commonHead = CommonHead(
requestId = requestIdSeq.incrementAndGet().toULong(),
cmd = 202u
),
sceneInfo = SceneInfo(
requestType = 2u,
businessType = 1u,
sceneType = 0u,
),
clientMeta = ClientMeta(2u)
),
downloadRkey = DownloadRkeyReq(
types = listOf(10, 20),
downloadType = 2
)
).toByteArray()
val fromServiceMsg = sendOidbAW("OidbSvcTrpcTcp.0x9067_202", 0x9067, 202, req, true)
if (fromServiceMsg == null || fromServiceMsg.wupBuffer == null) {
return Result.failure(Exception("failed to fetch NtTempRKey: ${fromServiceMsg?.wupBuffer?.toHexString()}"))
}
val trpc = fromServiceMsg.decodeToTrpcOidb()
if (trpc.buffer == null) {
return Result.failure(Exception("failed to fetch NtTempRKey: ${trpc.msg}"))
}
trpc.buffer?.decodeProtobuf<NtV2RichMediaRsp>()?.downloadRkeyRsp?.let {
return Result.success(it)
}
}.onFailure {
return Result.failure(it)
}
return Result.failure(Exception("failed to fetch NtTempRKey"))
}
/** /**
* 获取NT图片的RKEY * 获取NT图片的RKEY
*/ */
@ -351,9 +394,14 @@ internal object NtV2RichMediaSvc: QQInterfaces() {
).toByteArray() ).toByteArray()
val fromServiceMsg = sendOidbAW("OidbSvcTrpcTcp.0x11c5_200", 4549, 200, req, true) val fromServiceMsg = sendOidbAW("OidbSvcTrpcTcp.0x11c5_200", 4549, 200, req, true)
if (fromServiceMsg == null || fromServiceMsg.wupBuffer == null) { if (fromServiceMsg == null || fromServiceMsg.wupBuffer == null) {
return Result.failure(Exception("unable to get multimedia pic info: ${fromServiceMsg?.wupBuffer}")) return Result.failure(Exception("unable to get multimedia pic info: ${fromServiceMsg?.wupBuffer?.toHexString()}"))
} }
fromServiceMsg.wupBuffer.slice(4).decodeProtobuf<TrpcOidb>().buffer.decodeProtobuf<NtV2RichMediaRsp>().download?.rkeyParam?.let { val trpc = fromServiceMsg.decodeToTrpcOidb()
if (trpc.buffer == null) {
return Result.failure(Exception("unable to get multimedia pic info: ${trpc.msg}"))
}
trpc.buffer?.decodeProtobuf<NtV2RichMediaRsp>()?.download?.rkeyParam?.let {
return Result.success(it) return Result.success(it)
} }
}.onFailure { }.onFailure {
@ -446,8 +494,11 @@ internal object NtV2RichMediaSvc: QQInterfaces() {
if (fromServiceMsg == null || fromServiceMsg.wupBuffer == null) { if (fromServiceMsg == null || fromServiceMsg.wupBuffer == null) {
return Result.failure(Exception("unable to request upload nt pic")) return Result.failure(Exception("unable to request upload nt pic"))
} }
val rspBuffer = fromServiceMsg.wupBuffer.slice(4).decodeProtobuf<TrpcOidb>().buffer val trpc = fromServiceMsg.decodeToTrpcOidb()
val rsp = rspBuffer.decodeProtobuf<NtV2RichMediaRsp>() if (trpc.buffer == null) {
return Result.failure(Exception("unable to request upload nt pic: ${trpc.msg}"))
}
val rsp = trpc.buffer!!.decodeProtobuf<NtV2RichMediaRsp>()
if (rsp.upload == null) { if (rsp.upload == null) {
return Result.failure(Exception("unable to request upload nt pic: ${rsp.head}")) return Result.failure(Exception("unable to request upload nt pic: ${rsp.head}"))
} }
@ -502,4 +553,4 @@ internal object NtV2RichMediaSvc: QQInterfaces() {
) )
} }
} }
} }

View File

@ -6,11 +6,16 @@ import com.tencent.mobileqq.transfile.FileMsg
import com.tencent.mobileqq.transfile.api.IProtoReqManager import com.tencent.mobileqq.transfile.api.IProtoReqManager
import com.tencent.mobileqq.transfile.protohandler.RichProto import com.tencent.mobileqq.transfile.protohandler.RichProto
import com.tencent.mobileqq.transfile.protohandler.RichProtoProc import com.tencent.mobileqq.transfile.protohandler.RichProtoProc
import com.tencent.qqnt.kernel.nativeinterface.Image
import com.tencent.qqnt.kernel.nativeinterface.MsgConstant
import com.tencent.qqnt.kernel.nativeinterface.MsgRecord
import com.tencent.qqnt.kernel.nativeinterface.PicElement
import kotlinx.coroutines.suspendCancellableCoroutine import kotlinx.coroutines.suspendCancellableCoroutine
import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.ExperimentalSerializationApi
import moe.fuqiuluo.shamrock.helper.Level import moe.fuqiuluo.shamrock.helper.Level
import moe.fuqiuluo.shamrock.helper.LogCenter import moe.fuqiuluo.shamrock.helper.LogCenter
import moe.fuqiuluo.shamrock.tools.slice import moe.fuqiuluo.shamrock.tools.decodeToOidb
import moe.fuqiuluo.shamrock.tools.ifNullOrEmpty
import moe.fuqiuluo.shamrock.tools.toHexString import moe.fuqiuluo.shamrock.tools.toHexString
import moe.fuqiuluo.shamrock.utils.PlatformUtils import moe.fuqiuluo.shamrock.utils.PlatformUtils
import moe.fuqiuluo.symbols.decodeProtobuf import moe.fuqiuluo.symbols.decodeProtobuf
@ -28,7 +33,6 @@ import qq.service.contact.ContactHelper
import tencent.im.cs.cmd0x346.cmd0x346 import tencent.im.cs.cmd0x346.cmd0x346
import tencent.im.oidb.cmd0x6d6.oidb_0x6d6 import tencent.im.oidb.cmd0x6d6.oidb_0x6d6
import tencent.im.oidb.cmd0xe37.cmd0xe37 import tencent.im.oidb.cmd0xe37.cmd0xe37
import tencent.im.oidb.oidb_sso
import kotlin.coroutines.resume import kotlin.coroutines.resume
private const val GPRO_PIC = "gchat.qpic.cn" private const val GPRO_PIC = "gchat.qpic.cn"
@ -53,8 +57,7 @@ internal object RichProtoSvc: QQInterfaces() {
if (fromServiceMsg == null || fromServiceMsg.wupBuffer == null) { if (fromServiceMsg == null || fromServiceMsg.wupBuffer == null) {
return "" return ""
} }
val body = oidb_sso.OIDBSSOPkg() val body = fromServiceMsg.decodeToOidb()
body.mergeFrom(fromServiceMsg.wupBuffer.slice(4))
body.bytes_bodybuffer body.bytes_bodybuffer
.get().toByteArray() .get().toByteArray()
.decodeProtobuf<Oidb0xfc2RspBody>() .decodeProtobuf<Oidb0xfc2RspBody>()
@ -82,8 +85,7 @@ internal object RichProtoSvc: QQInterfaces() {
if (fromServiceMsg == null || fromServiceMsg.wupBuffer == null) { if (fromServiceMsg == null || fromServiceMsg.wupBuffer == null) {
return "" return ""
} }
val body = oidb_sso.OIDBSSOPkg() val body = fromServiceMsg.decodeToOidb()
body.mergeFrom(fromServiceMsg.wupBuffer.slice(4))
val result = oidb_0x6d6.RspBody().mergeFrom(body.bytes_bodybuffer.get().toByteArray()) val result = oidb_0x6d6.RspBody().mergeFrom(body.bytes_bodybuffer.get().toByteArray())
if (body.uint32_result.get() != 0 if (body.uint32_result.get() != 0
|| result.download_file_rsp.int32_ret_code.get() != 0) { || result.download_file_rsp.int32_ret_code.get() != 0) {
@ -130,8 +132,7 @@ internal object RichProtoSvc: QQInterfaces() {
} }
return "" return ""
} else { } else {
val body = oidb_sso.OIDBSSOPkg() val body = fromServiceMsg.decodeToOidb()
body.mergeFrom(fromServiceMsg.wupBuffer.slice(4))
val result = cmd0x346.RspBody().mergeFrom(cmd0xe37.Resp0xe37().mergeFrom( val result = cmd0x346.RspBody().mergeFrom(cmd0xe37.Resp0xe37().mergeFrom(
body.bytes_bodybuffer.get().toByteArray() body.bytes_bodybuffer.get().toByteArray()
).bytes_cmd_0x346_rsp_body.get().toByteArray()) ).bytes_cmd_0x346_rsp_body.get().toByteArray())
@ -152,6 +153,75 @@ internal object RichProtoSvc: QQInterfaces() {
} }
} }
suspend fun getTempPicDownloadUrl(
chatType: Int,
originalUrl: String,
md5: String,
image: PicElement,
storeId: Int = 0,
peer: String? = null,
subPeer: String? = null,
): String {
val isNtServer = originalUrl.startsWith("/download")
if (isNtServer) {
val tmpRKey = NtV2RichMediaSvc.getTempNtRKey()
if (tmpRKey.isSuccess) {
val tmpRKeyRsp = tmpRKey.getOrThrow()
val tmpRKeyMap = hashMapOf<UInt, String>()
tmpRKeyRsp.rkeys?.forEach { rKeyInfo ->
tmpRKeyMap[rKeyInfo.type] = rKeyInfo.rkey
}
val rkey = tmpRKeyMap[when(chatType) {
MsgConstant.KCHATTYPEDISC, MsgConstant.KCHATTYPEGROUP -> 10u
MsgConstant.KCHATTYPEC2C -> 20u
MsgConstant.KCHATTYPEGUILD -> 10u
else -> 0u
}]
if (rkey != null) {
return "https://$MULTIMEDIA_DOMAIN$originalUrl$rkey"
}
}
}
return when (chatType) {
MsgConstant.KCHATTYPEDISC, MsgConstant.KCHATTYPEGROUP -> getGroupPicDownUrl(
originalUrl = originalUrl,
md5 = md5,
fileId = image.fileUuid,
width = image.picWidth.toUInt(),
height = image.picHeight.toUInt(),
sha = "",
fileSize = image.fileSize.toULong(),
peer = peer ?: "0"
)
MsgConstant.KCHATTYPEC2C -> getC2CPicDownUrl(
originalUrl = originalUrl,
md5 = md5,
fileId = image.fileUuid,
width = image.picWidth.toUInt(),
height = image.picHeight.toUInt(),
sha = "",
fileSize = image.fileSize.toULong(),
peer = peer ?: "0",
storeId = storeId
)
MsgConstant.KCHATTYPEGUILD -> getGuildPicDownUrl(
originalUrl = originalUrl,
md5 = md5,
fileId = image.fileUuid,
width = image.picWidth.toUInt(),
height = image.picHeight.toUInt(),
sha = "",
fileSize = image.fileSize.toULong(),
peer = peer ?: "0",
subPeer = subPeer ?: "0"
)
else -> throw UnsupportedOperationException("Not supported chat type: $chatType")
}
}
suspend fun getGroupPicDownUrl( suspend fun getGroupPicDownUrl(
originalUrl: String, originalUrl: String,
md5: String, md5: String,

View File

@ -1,6 +1,6 @@
package qq.service.contact package qq.service.contact
import com.tencent.qqnt.kernel.nativeinterface.Contact import com.tencent.qqnt.kernelpublic.nativeinterface.Contact
import com.tencent.qqnt.kernel.nativeinterface.MsgConstant import com.tencent.qqnt.kernel.nativeinterface.MsgConstant
import io.kritor.common.Scene import io.kritor.common.Scene

View File

@ -11,6 +11,7 @@ import com.tencent.protofile.join_group_link.join_group_link
import kotlinx.coroutines.suspendCancellableCoroutine import kotlinx.coroutines.suspendCancellableCoroutine
import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock import kotlinx.coroutines.sync.withLock
import moe.fuqiuluo.shamrock.tools.decodeToOidb
import moe.fuqiuluo.shamrock.tools.slice import moe.fuqiuluo.shamrock.tools.slice
import qq.service.internals.NTServiceFetcher import qq.service.internals.NTServiceFetcher
import qq.service.QQInterfaces import qq.service.QQInterfaces
@ -190,8 +191,7 @@ internal object ContactHelper: QQInterfaces() {
val fromServiceMsg = sendOidbAW("OidbSvcTrpcTcp.0x11ca_0", 4790, 0, reqBody.toByteArray()) val fromServiceMsg = sendOidbAW("OidbSvcTrpcTcp.0x11ca_0", 4790, 0, reqBody.toByteArray())
?: error("unable to fetch contact ark_json_text") ?: error("unable to fetch contact ark_json_text")
val body = oidb_sso.OIDBSSOPkg() val body = fromServiceMsg.decodeToOidb()
body.mergeFrom(fromServiceMsg.wupBuffer.slice(4))
val rsp = oidb_0x11b2.BusinessCardV3Rsp() val rsp = oidb_0x11b2.BusinessCardV3Rsp()
rsp.mergeFrom(body.bytes_bodybuffer.get().toByteArray()) rsp.mergeFrom(body.bytes_bodybuffer.get().toByteArray())
return rsp.signed_ark_msg.get() return rsp.signed_ark_msg.get()

View File

@ -1,5 +1,3 @@
@file:OptIn(ExperimentalStdlibApi::class)
package qq.service.file package qq.service.file
import com.tencent.mobileqq.pb.ByteStringMicro import com.tencent.mobileqq.pb.ByteStringMicro
@ -9,7 +7,9 @@ import io.kritor.file.*
import moe.fuqiuluo.shamrock.helper.Level import moe.fuqiuluo.shamrock.helper.Level
import moe.fuqiuluo.shamrock.helper.LogCenter import moe.fuqiuluo.shamrock.helper.LogCenter
import moe.fuqiuluo.shamrock.tools.EMPTY_BYTE_ARRAY import moe.fuqiuluo.shamrock.tools.EMPTY_BYTE_ARRAY
import moe.fuqiuluo.shamrock.tools.decodeToOidb
import moe.fuqiuluo.shamrock.tools.slice import moe.fuqiuluo.shamrock.tools.slice
import moe.fuqiuluo.shamrock.tools.toHexString
import moe.fuqiuluo.shamrock.utils.DeflateTools import moe.fuqiuluo.shamrock.utils.DeflateTools
import qq.service.QQInterfaces import qq.service.QQInterfaces
import tencent.im.oidb.cmd0x6d8.oidb_0x6d8 import tencent.im.oidb.cmd0x6d8.oidb_0x6d8
@ -31,12 +31,9 @@ internal object GroupFileHelper: QQInterfaces() {
val fileCnt: Int val fileCnt: Int
val limitCnt: Int val limitCnt: Int
if (fromServiceMsg.wupBuffer != null) { if (fromServiceMsg.wupBuffer != null) {
oidb_0x6d8.RspBody().mergeFrom( val oidb1 = fromServiceMsg.decodeToOidb()
oidb_sso.OIDBSSOPkg()
.mergeFrom(fromServiceMsg.wupBuffer.slice(4)) oidb_0x6d8.RspBody().mergeFrom(oidb1.bytes_bodybuffer.get().toByteArray()).group_file_cnt_rsp.apply {
.bytes_bodybuffer.get()
.toByteArray()
).group_file_cnt_rsp.apply {
fileCnt = uint32_all_file_count.get() fileCnt = uint32_all_file_count.get()
limitCnt = uint32_limit_count.get() limitCnt = uint32_limit_count.get()
} }
@ -53,11 +50,9 @@ internal object GroupFileHelper: QQInterfaces() {
val totalSpace: Long val totalSpace: Long
val usedSpace: Long val usedSpace: Long
if (fromServiceMsg2.isSuccess && fromServiceMsg2.wupBuffer != null) { if (fromServiceMsg2.isSuccess && fromServiceMsg2.wupBuffer != null) {
oidb_0x6d8.RspBody().mergeFrom( val oidb2 = fromServiceMsg2.decodeToOidb()
oidb_sso.OIDBSSOPkg()
.mergeFrom(fromServiceMsg2.wupBuffer.slice(4)) oidb_0x6d8.RspBody().mergeFrom(oidb2.bytes_bodybuffer.get().toByteArray()).group_space_rsp.apply {
.bytes_bodybuffer.get()
.toByteArray()).group_space_rsp.apply {
totalSpace = uint64_total_space.get() totalSpace = uint64_total_space.get()
usedSpace = uint64_used_space.get() usedSpace = uint64_used_space.get()
} }
@ -95,16 +90,14 @@ internal object GroupFileHelper: QQInterfaces() {
uint32_show_onlinedoc_folder.set(0) uint32_show_onlinedoc_folder.set(0)
}) })
}.toByteArray(), timeout = 15.seconds) ?: throw StatusRuntimeException(Status.INTERNAL.withDescription("unable to send oidb request")) }.toByteArray(), timeout = 30.seconds) ?: throw StatusRuntimeException(Status.INTERNAL.withDescription("unable to send oidb request"))
if (fromServiceMsg.wupBuffer == null) { if (fromServiceMsg.wupBuffer == null) {
throw StatusRuntimeException(Status.INTERNAL.withDescription("oidb request failed")) throw StatusRuntimeException(Status.INTERNAL.withDescription("oidb request failed"))
} }
val files = arrayListOf<File>() val files = arrayListOf<File>()
val folders = arrayListOf<Folder>() val folders = arrayListOf<Folder>()
if (fromServiceMsg.wupBuffer != null) { if (fromServiceMsg.wupBuffer != null) {
val oidb = oidb_sso.OIDBSSOPkg().mergeFrom(fromServiceMsg.wupBuffer.slice(4).let { val oidb = fromServiceMsg.decodeToOidb()
if (it[0] == 0x78.toByte()) DeflateTools.uncompress(it) else it
})
oidb_0x6d8.RspBody().mergeFrom(oidb.bytes_bodybuffer.get().toByteArray()) oidb_0x6d8.RspBody().mergeFrom(oidb.bytes_bodybuffer.get().toByteArray())
.file_list_info_rsp.apply { .file_list_info_rsp.apply {
@ -116,9 +109,9 @@ internal object GroupFileHelper: QQInterfaces() {
this.fileName = fileInfo.str_file_name.get() this.fileName = fileInfo.str_file_name.get()
this.fileSize = fileInfo.uint64_file_size.get() this.fileSize = fileInfo.uint64_file_size.get()
this.busId = fileInfo.uint32_bus_id.get() this.busId = fileInfo.uint32_bus_id.get()
this.uploadTime = fileInfo.uint32_upload_time.get() this.uploadTime = fileInfo.uint32_upload_time.get().toLong()
this.expireTime = fileInfo.uint32_dead_time.get() this.expireTime = fileInfo.uint32_dead_time.get().toLong()
this.modifyTime = fileInfo.uint32_modify_time.get() this.modifyTime = fileInfo.uint32_modify_time.get().toLong()
this.downloadTimes = fileInfo.uint32_download_times.get() this.downloadTimes = fileInfo.uint32_download_times.get()
this.uploader = fileInfo.uint64_uploader_uin.get() this.uploader = fileInfo.uint64_uploader_uin.get()
this.uploaderName = fileInfo.str_uploader_name.get() this.uploaderName = fileInfo.str_uploader_name.get()
@ -133,7 +126,7 @@ internal object GroupFileHelper: QQInterfaces() {
this.folderId = folderInfo.str_folder_id.get() this.folderId = folderInfo.str_folder_id.get()
this.folderName = folderInfo.str_folder_name.get() this.folderName = folderInfo.str_folder_name.get()
this.totalFileCount = folderInfo.uint32_total_file_count.get() this.totalFileCount = folderInfo.uint32_total_file_count.get()
this.createTime = folderInfo.uint32_create_time.get() this.createTime = folderInfo.uint32_create_time.get().toLong()
this.creator = folderInfo.uint64_create_uin.get() this.creator = folderInfo.uint64_create_uin.get()
this.creatorName = folderInfo.str_creator_name.get() this.creatorName = folderInfo.str_creator_name.get()
}.build()) }.build())

View File

@ -19,10 +19,13 @@ import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.withTimeoutOrNull import kotlinx.coroutines.withTimeoutOrNull
import moe.fuqiuluo.shamrock.helper.Level import moe.fuqiuluo.shamrock.helper.Level
import moe.fuqiuluo.shamrock.helper.LogCenter import moe.fuqiuluo.shamrock.helper.LogCenter
import moe.fuqiuluo.shamrock.tools.decodeToOidb
import qq.service.internals.NTServiceFetcher import qq.service.internals.NTServiceFetcher
import moe.fuqiuluo.shamrock.tools.ifNullOrEmpty import moe.fuqiuluo.shamrock.tools.ifNullOrEmpty
import moe.fuqiuluo.shamrock.tools.putBuf32Long import moe.fuqiuluo.shamrock.tools.putBuf32Long
import moe.fuqiuluo.shamrock.tools.slice import moe.fuqiuluo.shamrock.tools.slice
import moe.fuqiuluo.shamrock.utils.PlatformUtils
import moe.fuqiuluo.shamrock.utils.PlatformUtils.QQ_9_0_65_VER
import protobuf.auto.toByteArray import protobuf.auto.toByteArray
import protobuf.oidb.cmd0xf16.Oidb0xf16 import protobuf.oidb.cmd0xf16.Oidb0xf16
import protobuf.oidb.cmd0xf16.SetGroupRemarkReq import protobuf.oidb.cmd0xf16.SetGroupRemarkReq
@ -398,22 +401,46 @@ internal object GroupHelper: QQInterfaces() {
sendOidb("OidbSvc.0x89a_0", 2202, 0, reqBody.toByteArray()) sendOidb("OidbSvc.0x89a_0", 2202, 0, reqBody.toByteArray())
} }
suspend fun getGroupMemberList(groupId: String, refresh: Boolean): Result<List<TroopMemberInfo>> { suspend fun getGroupMemberList(groupId: Long, refresh: Boolean): Result<HashMap<String, MemberInfo>> {
val service = app.getRuntimeService(ITroopMemberInfoService::class.java, "all") val kernelService = NTServiceFetcher.kernelService
var memberList = service.getAllTroopMembers(groupId) val sessionService = kernelService.wrapperSession
if (refresh || memberList == null) { val service = sessionService.groupService
memberList = requestTroopMemberInfo(service, groupId).onFailure { val uids = suspendCancellableCoroutine { continuation ->
return Result.failure(Exception("获取群成员列表失败")) service.getAllMemberList(groupId, refresh) { _, _, groupMemberListResult ->
}.getOrThrow() continuation.resume(groupMemberListResult?.ids?.map {
} it.uid
})
getGroupInfo(groupId, true).onSuccess {
if(it.wMemberNum > memberList.size) {
return getGroupMemberList(groupId, true)
} }
} }
val memberMap = suspendCancellableCoroutine { continuation ->
service.getMemberInfoForMqq(groupId, ArrayList(uids ?: emptyList()), refresh) { _, _, groupMemberListResult ->
continuation.resume(groupMemberListResult.infos)
}
}
// val extInfo = suspendCancellableCoroutine { continuation ->
// service.getMemberExtInfo(GroupMemberExtReq().apply {
// this.groupCode = groupId
// this.beginUin = 0.toString()
// this.groupType = ""
// this.memberExtFilter = MemberExtInfoFilter().apply {
// this.memberLevelInfoName = 1
// this.memberLevelInfoUin = 1
// this.nickName = 1
// this.specialTitle = 1
// this.memberLevelInfoActiveDay = 1
// }
// this.richCardNameVer = "1"
// this.sourceType = 1
// this.uinList = ArrayList(memberMap.values.toList().map {
// it.uin
// })
// }) { _, _, groupMemberExtListResult ->
// continuation.resume(groupMemberExtListResult)
// }
// }
return Result.success(memberMap)
return Result.success(memberList)
} }
suspend fun getProhibitedMemberList(groupId: Long): Result<List<ProhibitedMemberInfo>> { suspend fun getProhibitedMemberList(groupId: Long): Result<List<ProhibitedMemberInfo>> {
@ -429,8 +456,7 @@ internal object GroupHelper: QQInterfaces() {
if (fromServiceMsg.wupBuffer == null) { if (fromServiceMsg.wupBuffer == null) {
return Result.failure(RuntimeException("[oidb] failed")) return Result.failure(RuntimeException("[oidb] failed"))
} }
val body = oidb_sso.OIDBSSOPkg() val body = fromServiceMsg.decodeToOidb()
body.mergeFrom(fromServiceMsg.wupBuffer.slice(4))
if(body.uint32_result.get() != 0) { if(body.uint32_result.get() != 0) {
return Result.failure(RuntimeException(body.str_error_msg.get())) return Result.failure(RuntimeException(body.str_error_msg.get()))
} }
@ -451,8 +477,7 @@ internal object GroupHelper: QQInterfaces() {
if (fromServiceMsg.wupBuffer == null) { if (fromServiceMsg.wupBuffer == null) {
return Result.failure(RuntimeException("[oidb] failed")) return Result.failure(RuntimeException("[oidb] failed"))
} }
val body = oidb_sso.OIDBSSOPkg() val body = fromServiceMsg.decodeToOidb()
body.mergeFrom(fromServiceMsg.wupBuffer.slice(4))
if(body.uint32_result.get() != 0) { if(body.uint32_result.get() != 0) {
return Result.failure(RuntimeException(body.str_error_msg.get())) return Result.failure(RuntimeException(body.str_error_msg.get()))
} }
@ -613,6 +638,9 @@ internal object GroupHelper: QQInterfaces() {
} }
private suspend fun requestTroopMemberInfo(service: ITroopMemberInfoService, groupId: String, memberUin: String, timeout: Long = 10_000): Result<TroopMemberInfo> { private suspend fun requestTroopMemberInfo(service: ITroopMemberInfoService, groupId: String, memberUin: String, timeout: Long = 10_000): Result<TroopMemberInfo> {
if(PlatformUtils.getQQVersionCode() >= QQ_9_0_65_VER) {
return Result.failure(Exception("当前版本不支持该API"))
}
val info = RefreshTroopMemberInfoLock.withLock { val info = RefreshTroopMemberInfoLock.withLock {
service.deleteTroopMember(groupId, memberUin) service.deleteTroopMember(groupId, memberUin)

View File

@ -3,14 +3,24 @@
package qq.service.internals package qq.service.internals
import com.tencent.qqnt.kernel.nativeinterface.MsgConstant import com.tencent.qqnt.kernel.nativeinterface.MsgConstant
import com.tencent.qqnt.kernel.nativeinterface.MsgElement
import com.tencent.qqnt.kernel.nativeinterface.MsgRecord import com.tencent.qqnt.kernel.nativeinterface.MsgRecord
import com.tencent.qqnt.kernel.nativeinterface.TextElement
import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import moe.fuqiuluo.shamrock.config.AliveReply
import moe.fuqiuluo.shamrock.config.get
import moe.fuqiuluo.shamrock.helper.Level import moe.fuqiuluo.shamrock.helper.Level
import moe.fuqiuluo.shamrock.helper.LogCenter import moe.fuqiuluo.shamrock.helper.LogCenter
import moe.fuqiuluo.shamrock.helper.db.ImageDB
import moe.fuqiuluo.shamrock.helper.db.ImageMapping
import moe.fuqiuluo.shamrock.internals.GlobalEventTransmitter import moe.fuqiuluo.shamrock.internals.GlobalEventTransmitter
import moe.fuqiuluo.shamrock.utils.PlatformUtils
import moe.fuqiuluo.shamrock.utils.PlatformUtils.QQ_9_0_8_VER
import qq.service.bdh.RichProtoSvc import qq.service.bdh.RichProtoSvc
import qq.service.file.GroupFileHelper
import qq.service.group.GroupHelper
import qq.service.kernel.SimpleKernelMsgListener import qq.service.kernel.SimpleKernelMsgListener
import qq.service.msg.MessageHelper import qq.service.msg.MessageHelper
@ -27,7 +37,83 @@ object AioListener : SimpleKernelMsgListener() {
} }
} }
private suspend fun debugTest(record: MsgRecord, text: String) {
if (record.chatType == MsgConstant.KCHATTYPEGROUP && text == ".shamrock.members") {
val contact = MessageHelper.generateContact(record)
GroupHelper.getGroupMemberList(record.peerUin, true).onSuccess {
MessageHelper.sendMessage(contact, arrayListOf(
MsgElement().apply {
elementType = MsgConstant.KELEMTYPETEXT
textElement = TextElement().apply {
content = "memberCount: ${it.size}"
}
}
), 3, MessageHelper.generateMsgId(record.chatType))
}.onFailure {
LogCenter.log("获取群成员列表失败: $it", Level.ERROR)
}
} else if (record.chatType == MsgConstant.KCHATTYPEGROUP && text == ".shamrock.root_files") {
val contact = MessageHelper.generateContact(record)
val files = GroupFileHelper.getGroupFiles(record.peerUin)
MessageHelper.sendMessage(contact, arrayListOf(
MsgElement().apply {
elementType = MsgConstant.KELEMTYPETEXT
textElement = TextElement().apply {
content = "foldersCount: ${files.foldersCount}\nfilesCount: ${files.filesCount}"
}
}
), 3, MessageHelper.generateMsgId(record.chatType))
} else if (record.chatType == MsgConstant.KCHATTYPEGROUP && text == ".shamrock.pic_url") {
val contact = MessageHelper.generateContact(record)
val pic = record.elements.filter {
it.elementType == MsgConstant.KELEMTYPEPIC
}.map {
val image = it.picElement
val md5 = (image.md5HexStr ?: image.fileName
.replace("{", "")
.replace("}", "")
.replace("-", "").split(".")[0])
.uppercase()
var storeId = 0
if (PlatformUtils.getQQVersionCode() > QQ_9_0_8_VER) {
storeId = image.storeID
}
val originalUrl = image.originImageUrl ?: ""
return@map RichProtoSvc.getTempPicDownloadUrl(record.chatType, originalUrl, md5, image, storeId)
}
MessageHelper.sendMessage(contact, arrayListOf(
MsgElement().apply {
elementType = MsgConstant.KELEMTYPETEXT
textElement = TextElement().apply {
content = "picUrl: \n${
pic.joinToString("\n")
}"
}
}
), 3, MessageHelper.generateMsgId(record.chatType))
}
}
private suspend fun onMsg(record: MsgRecord) { private suspend fun onMsg(record: MsgRecord) {
if (AliveReply.get()) {
val texts = record.elements.filter { it.elementType == MsgConstant.KELEMTYPETEXT }
val text = texts.joinToString { it.textElement.content }
if (texts.isNotEmpty() && text == "ping") {
val contact = MessageHelper.generateContact(record)
MessageHelper.sendMessage(contact, arrayListOf(
MsgElement().apply {
elementType = MsgConstant.KELEMTYPETEXT
textElement = TextElement().apply {
content = "pong"
}
}
), 3, MessageHelper.generateMsgId(record.chatType))
return
}
debugTest(record, text)
}
when (record.chatType) { when (record.chatType) {
MsgConstant.KCHATTYPEGROUP -> { MsgConstant.KCHATTYPEGROUP -> {
if (record.senderUin == 0L) return if (record.senderUin == 0L) return

View File

@ -216,8 +216,13 @@ internal object PrimitiveListener {
}.decodeProtobuf<GroupCommonTipsEvent>() }.decodeProtobuf<GroupCommonTipsEvent>()
} }
val groupId = event.groupCode.toLong() val groupId = event.groupCode.toLong()
if (event.uniqueTitleChangeDetail == null) {
return
}
val detail = event.uniqueTitleChangeDetail!!.first() val detail = event.uniqueTitleChangeDetail!!.first()
// todo 贴表情也走的 732 16 这里
//detail = if (detail[5] is ProtoList) { //detail = if (detail[5] is ProtoList) {
// (detail[5] as ProtoList).value[0] // (detail[5] as ProtoList).value[0]
//} else { //} else {
@ -396,7 +401,7 @@ internal object PrimitiveListener {
val targetUid = event.memberUid val targetUid = event.memberUid
val type = event.type val type = event.type
GroupHelper.getGroupMemberList(groupCode.toString(), true).onFailure { GroupHelper.getGroupMemberList(groupCode, true).onFailure {
LogCenter.log("新成员加入刷新群成员列表失败: $groupCode", Level.WARN) LogCenter.log("新成员加入刷新群成员列表失败: $groupCode", Level.WARN)
}.onSuccess { }.onSuccess {
LogCenter.log("新成员加入刷新群成员列表成功,群成员数量: ${it.size}", Level.INFO) LogCenter.log("新成员加入刷新群成员列表成功,群成员数量: ${it.size}", Level.INFO)
@ -433,7 +438,7 @@ internal object PrimitiveListener {
val type = event.type val type = event.type
val operatorUid = event.operatorUid val operatorUid = event.operatorUid
GroupHelper.getGroupMemberList(groupCode.toString(), true).onFailure { GroupHelper.getGroupMemberList(groupCode, true).onFailure {
LogCenter.log("新成员加入刷新群成员列表失败: $groupCode", Level.WARN) LogCenter.log("新成员加入刷新群成员列表失败: $groupCode", Level.WARN)
}.onSuccess { }.onSuccess {
LogCenter.log("新成员加入刷新群成员列表成功,群成员数量: ${it.size}", Level.INFO) LogCenter.log("新成员加入刷新群成员列表成功,群成员数量: ${it.size}", Level.INFO)

View File

@ -1,7 +1,7 @@
package qq.service.kernel package qq.service.kernel
import com.tencent.qqnt.kernel.nativeinterface.BroadcastHelperTransNotifyInfo import com.tencent.qqnt.kernel.nativeinterface.BroadcastHelperTransNotifyInfo
import com.tencent.qqnt.kernel.nativeinterface.Contact import com.tencent.qqnt.kernelpublic.nativeinterface.Contact
import com.tencent.qqnt.kernel.nativeinterface.ContactMsgBoxInfo import com.tencent.qqnt.kernel.nativeinterface.ContactMsgBoxInfo
import com.tencent.qqnt.kernel.nativeinterface.CustomWithdrawConfig import com.tencent.qqnt.kernel.nativeinterface.CustomWithdrawConfig
import com.tencent.qqnt.kernel.nativeinterface.DevInfo import com.tencent.qqnt.kernel.nativeinterface.DevInfo
@ -12,6 +12,7 @@ import com.tencent.qqnt.kernel.nativeinterface.FileTransNotifyInfo
import com.tencent.qqnt.kernel.nativeinterface.FirstViewDirectMsgNotifyInfo import com.tencent.qqnt.kernel.nativeinterface.FirstViewDirectMsgNotifyInfo
import com.tencent.qqnt.kernel.nativeinterface.FirstViewGroupGuildInfo import com.tencent.qqnt.kernel.nativeinterface.FirstViewGroupGuildInfo
import com.tencent.qqnt.kernel.nativeinterface.FreqLimitInfo import com.tencent.qqnt.kernel.nativeinterface.FreqLimitInfo
import com.tencent.qqnt.kernel.nativeinterface.GProGuildTopFeedMsg
import com.tencent.qqnt.kernel.nativeinterface.GroupFileListResult import com.tencent.qqnt.kernel.nativeinterface.GroupFileListResult
import com.tencent.qqnt.kernel.nativeinterface.GroupGuildNotifyInfo import com.tencent.qqnt.kernel.nativeinterface.GroupGuildNotifyInfo
import com.tencent.qqnt.kernel.nativeinterface.GroupItem import com.tencent.qqnt.kernel.nativeinterface.GroupItem
@ -27,6 +28,7 @@ import com.tencent.qqnt.kernel.nativeinterface.MsgAbstract
import com.tencent.qqnt.kernel.nativeinterface.MsgElement import com.tencent.qqnt.kernel.nativeinterface.MsgElement
import com.tencent.qqnt.kernel.nativeinterface.MsgRecord import com.tencent.qqnt.kernel.nativeinterface.MsgRecord
import com.tencent.qqnt.kernel.nativeinterface.MsgSetting import com.tencent.qqnt.kernel.nativeinterface.MsgSetting
import com.tencent.qqnt.kernel.nativeinterface.QueryUserSecQualityRsp
import com.tencent.qqnt.kernel.nativeinterface.RecvdOrder import com.tencent.qqnt.kernel.nativeinterface.RecvdOrder
import com.tencent.qqnt.kernel.nativeinterface.RelatedWordEmojiInfo import com.tencent.qqnt.kernel.nativeinterface.RelatedWordEmojiInfo
import com.tencent.qqnt.kernel.nativeinterface.SearchGroupFileResult import com.tencent.qqnt.kernel.nativeinterface.SearchGroupFileResult
@ -135,7 +137,10 @@ abstract class SimpleKernelMsgListener: IKernelMsgListener {
} }
override fun onHitCsRelatedEmojiResult(downloadRelateEmojiResultInfo: DownloadRelateEmojiResultInfo?) { override fun onGuildTopFeedUpdate(gProGuildTopFeedMsg: GProGuildTopFeedMsg?) {
}
override fun onHitCsRelatedEmojiResult(downloadRelateEmojiResultInfo: DownloadRelateEmojiResultInfo?) {
} }
@ -207,7 +212,10 @@ abstract class SimpleKernelMsgListener: IKernelMsgListener {
} }
override fun onNtFirstViewMsgSyncEnd() { override fun onMsgWithRichLinkInfoUpdate(arrayList: ArrayList<MsgRecord>?) {
}
override fun onNtFirstViewMsgSyncEnd() {
} }
@ -258,7 +266,10 @@ abstract class SimpleKernelMsgListener: IKernelMsgListener {
} }
override fun onRichMediaDownloadComplete(fileTransNotifyInfo: FileTransNotifyInfo?) { override fun onRedTouchChanged() {
}
override fun onRichMediaDownloadComplete(fileTransNotifyInfo: FileTransNotifyInfo?) {
} }
@ -278,7 +289,13 @@ abstract class SimpleKernelMsgListener: IKernelMsgListener {
} }
override fun onSysMsgNotification(i2: Int, j2: Long, j3: Long, arrayList: ArrayList<Byte>?) { override fun onSysMsgNotification(
i2: Int,
j2: Long,
j3: Long,
z: Boolean,
arrayList: ArrayList<Byte>?
) {
} }
@ -302,7 +319,10 @@ abstract class SimpleKernelMsgListener: IKernelMsgListener {
} }
override fun onUserTabStatusChanged(arrayList: ArrayList<TabStatusInfo>?) { override fun onUserSecQualityChanged(queryUserSecQualityRsp: QueryUserSecQualityRsp?) {
}
override fun onUserTabStatusChanged(arrayList: ArrayList<TabStatusInfo>?) {
} }

View File

@ -1,6 +1,6 @@
package qq.service.lightapp package qq.service.lightapp
import com.tencent.qqnt.kernel.nativeinterface.Contact import com.tencent.qqnt.kernelpublic.nativeinterface.Contact
import com.tencent.qqnt.kernel.nativeinterface.MsgConstant import com.tencent.qqnt.kernel.nativeinterface.MsgConstant
import qq.service.QQInterfaces import qq.service.QQInterfaces
import qq.service.contact.longPeer import qq.service.contact.longPeer

View File

@ -2,7 +2,7 @@ package qq.service.lightapp
import com.tencent.biz.map.trpcprotocol.LbsSendInfo import com.tencent.biz.map.trpcprotocol.LbsSendInfo
import com.tencent.proto.lbsshare.LBSShare import com.tencent.proto.lbsshare.LBSShare
import com.tencent.qqnt.kernel.nativeinterface.Contact import com.tencent.qqnt.kernelpublic.nativeinterface.Contact
import com.tencent.qqnt.kernel.nativeinterface.MsgConstant import com.tencent.qqnt.kernel.nativeinterface.MsgConstant
import moe.fuqiuluo.shamrock.helper.IllegalParamsException import moe.fuqiuluo.shamrock.helper.IllegalParamsException
import moe.fuqiuluo.shamrock.tools.slice import moe.fuqiuluo.shamrock.tools.slice

View File

@ -1,6 +1,6 @@
package qq.service.lightapp package qq.service.lightapp
import com.tencent.qqnt.kernel.nativeinterface.Contact import com.tencent.qqnt.kernelpublic.nativeinterface.Contact
import io.ktor.client.request.get import io.ktor.client.request.get
import io.ktor.client.statement.bodyAsText import io.ktor.client.statement.bodyAsText
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json

View File

@ -1,15 +1,12 @@
package qq.service.msg package qq.service.msg
import com.tencent.mobileqq.qroute.QRoute import com.tencent.mobileqq.qroute.QRoute
import com.tencent.qqnt.kernel.nativeinterface.Contact import com.tencent.qqnt.kernelpublic.nativeinterface.Contact
import com.tencent.qqnt.kernel.nativeinterface.MsgConstant import com.tencent.qqnt.kernel.nativeinterface.MsgConstant
import com.tencent.qqnt.kernel.nativeinterface.MsgRecord import com.tencent.qqnt.kernel.nativeinterface.MsgRecord
import com.tencent.qqnt.msg.api.IMsgService import com.tencent.qqnt.msg.api.IMsgService
import io.grpc.Status
import io.grpc.StatusRuntimeException
import io.kritor.common.ForwardElement import io.kritor.common.ForwardElement
import io.kritor.common.ForwardMessageBody import io.kritor.common.ForwardMessageBody
import io.kritor.common.Scene
import kotlinx.coroutines.suspendCancellableCoroutine import kotlinx.coroutines.suspendCancellableCoroutine
import kotlinx.coroutines.withTimeoutOrNull import kotlinx.coroutines.withTimeoutOrNull
import moe.fuqiuluo.shamrock.helper.Level import moe.fuqiuluo.shamrock.helper.Level
@ -21,7 +18,6 @@ import protobuf.auto.toByteArray
import protobuf.message.* import protobuf.message.*
import protobuf.message.longmsg.* import protobuf.message.longmsg.*
import qq.service.QQInterfaces import qq.service.QQInterfaces
import qq.service.contact.ContactHelper
import qq.service.msg.MessageHelper.getMultiMsg import qq.service.msg.MessageHelper.getMultiMsg
import qq.service.ticket.TicketHelper import qq.service.ticket.TicketHelper
import java.util.* import java.util.*

View File

@ -3,7 +3,7 @@ package qq.service.msg
import com.tencent.mobileqq.qroute.QRoute import com.tencent.mobileqq.qroute.QRoute
import com.tencent.mobileqq.troop.api.ITroopMemberNameService import com.tencent.mobileqq.troop.api.ITroopMemberNameService
import com.tencent.qqnt.kernel.api.IKernelService import com.tencent.qqnt.kernel.api.IKernelService
import com.tencent.qqnt.kernel.nativeinterface.Contact import com.tencent.qqnt.kernelpublic.nativeinterface.Contact
import com.tencent.qqnt.kernel.nativeinterface.MsgConstant import com.tencent.qqnt.kernel.nativeinterface.MsgConstant
import com.tencent.qqnt.kernel.nativeinterface.MsgElement import com.tencent.qqnt.kernel.nativeinterface.MsgElement
import com.tencent.qqnt.kernel.nativeinterface.MsgRecord import com.tencent.qqnt.kernel.nativeinterface.MsgRecord
@ -31,6 +31,7 @@ import moe.fuqiuluo.shamrock.tools.asJsonObject
import moe.fuqiuluo.shamrock.tools.asLong import moe.fuqiuluo.shamrock.tools.asLong
import moe.fuqiuluo.shamrock.tools.asString import moe.fuqiuluo.shamrock.tools.asString
import moe.fuqiuluo.shamrock.tools.asStringOrNull import moe.fuqiuluo.shamrock.tools.asStringOrNull
import moe.fuqiuluo.shamrock.tools.decodeToOidb
import moe.fuqiuluo.shamrock.tools.slice import moe.fuqiuluo.shamrock.tools.slice
import moe.fuqiuluo.shamrock.tools.toHexString import moe.fuqiuluo.shamrock.tools.toHexString
import moe.fuqiuluo.shamrock.utils.DeflateTools import moe.fuqiuluo.shamrock.utils.DeflateTools
@ -108,8 +109,7 @@ internal object MessageHelper: QQInterfaces() {
if (fromServiceMsg?.wupBuffer == null) { if (fromServiceMsg?.wupBuffer == null) {
return "no response" return "no response"
} }
val body = oidb_sso.OIDBSSOPkg() val body = fromServiceMsg.decodeToOidb()
body.mergeFrom(fromServiceMsg.wupBuffer.slice(4))
val result = oidb_0xeac.RspBody().mergeFrom(body.bytes_bodybuffer.get().toByteArray()) val result = oidb_0xeac.RspBody().mergeFrom(body.bytes_bodybuffer.get().toByteArray())
return if (result.wording.has()) { return if (result.wording.has()) {
LogCenter.log("设置群精华失败: ${result.wording.get()}", Level.WARN) LogCenter.log("设置群精华失败: ${result.wording.get()}", Level.WARN)
@ -129,8 +129,7 @@ internal object MessageHelper: QQInterfaces() {
if (fromServiceMsg?.wupBuffer == null) { if (fromServiceMsg?.wupBuffer == null) {
return "no response" return "no response"
} }
val body = oidb_sso.OIDBSSOPkg() val body = fromServiceMsg.decodeToOidb()
body.mergeFrom(fromServiceMsg.wupBuffer.slice(4))
val result = oidb_0xeac.RspBody().mergeFrom(body.bytes_bodybuffer.get().toByteArray()) val result = oidb_0xeac.RspBody().mergeFrom(body.bytes_bodybuffer.get().toByteArray())
return if (result.wording.has()) { return if (result.wording.has()) {
LogCenter.log("移除群精华失败: ${result.wording.get()}", Level.WARN) LogCenter.log("移除群精华失败: ${result.wording.get()}", Level.WARN)

View File

@ -78,7 +78,7 @@ private object MsgConvertor {
elem.type = ElementType.POKE elem.type = ElementType.POKE
elem.setPoke(PokeElement.newBuilder().apply { elem.setPoke(PokeElement.newBuilder().apply {
this.id = face.vaspokeId this.id = face.vaspokeId
this.type = face.pokeType this.pokeType = face.pokeType
this.strength = face.pokeStrength this.strength = face.pokeStrength
}) })
} else { } else {
@ -157,45 +157,21 @@ private object MsgConvertor {
elem.type = ElementType.IMAGE elem.type = ElementType.IMAGE
elem.setImage(ImageElement.newBuilder().apply { elem.setImage(ImageElement.newBuilder().apply {
this.file = ByteString.copyFromUtf8(md5) this.file = ByteString.copyFromUtf8(md5)
this.fileUrl = when (record.chatType) { this.fileUrl = RichProtoSvc.getTempPicDownloadUrl(record.chatType, originalUrl, md5, image, storeId,
MsgConstant.KCHATTYPEDISC, MsgConstant.KCHATTYPEGROUP -> RichProtoSvc.getGroupPicDownUrl( peer = when(record.chatType) {
originalUrl = originalUrl, MsgConstant.KCHATTYPEDISC, MsgConstant.KCHATTYPEGROUP -> record.peerUin.toString()
md5 = md5, MsgConstant.KCHATTYPEC2C -> record.senderUin.toString()
fileId = image.fileUuid, MsgConstant.KCHATTYPEGUILD -> record.channelId.ifNullOrEmpty { record.peerUin.toString() } ?: "0"
width = image.picWidth.toUInt(), else -> null
height = image.picHeight.toUInt(), },
sha = "", subPeer = when(record.chatType) {
fileSize = image.fileSize.toULong(), MsgConstant.KCHATTYPEDISC, MsgConstant.KCHATTYPEGROUP -> null
peer = record.peerUin.toString() MsgConstant.KCHATTYPEC2C -> null
) MsgConstant.KCHATTYPEGUILD -> record.guildId ?: "0"
else -> null
MsgConstant.KCHATTYPEC2C -> RichProtoSvc.getC2CPicDownUrl( }
originalUrl = originalUrl, )
md5 = md5, this.fileType =
fileId = image.fileUuid,
width = image.picWidth.toUInt(),
height = image.picHeight.toUInt(),
sha = "",
fileSize = image.fileSize.toULong(),
peer = record.senderUin.toString(),
storeId = storeId
)
MsgConstant.KCHATTYPEGUILD -> RichProtoSvc.getGuildPicDownUrl(
originalUrl = originalUrl,
md5 = md5,
fileId = image.fileUuid,
width = image.picWidth.toUInt(),
height = image.picHeight.toUInt(),
sha = "",
fileSize = image.fileSize.toULong(),
peer = record.channelId.ifNullOrEmpty { record.peerUin.toString() } ?: "0",
subPeer = record.guildId ?: "0"
)
else -> throw UnsupportedOperationException("Not supported chat type: ${record.chatType}")
}
this.type =
if (image.isFlashPic == true) ImageElement.ImageType.FLASH else if (image.original) ImageElement.ImageType.ORIGIN else ImageElement.ImageType.COMMON if (image.isFlashPic == true) ImageElement.ImageType.FLASH else if (image.original) ImageElement.ImageType.ORIGIN else ImageElement.ImageType.COMMON
this.subType = image.picSubType this.subType = image.picSubType
}) })

View File

@ -2,7 +2,7 @@
package qq.service.msg package qq.service.msg
import com.tencent.qqnt.kernel.nativeinterface.Contact import com.tencent.qqnt.kernelpublic.nativeinterface.Contact
import com.tencent.qqnt.kernel.nativeinterface.MsgConstant import com.tencent.qqnt.kernel.nativeinterface.MsgConstant
import io.kritor.common.* import io.kritor.common.*
import io.kritor.common.Element.ElementType import io.kritor.common.Element.ElementType
@ -65,7 +65,7 @@ suspend fun List<Elem>.toKritorResponseMessages(contact: Contact): ArrayList<Ele
this.type = ElementType.IMAGE this.type = ElementType.IMAGE
this.image = ImageElement.newBuilder().apply { this.image = ImageElement.newBuilder().apply {
this.fileMd5 = md5 this.fileMd5 = md5
this.type = if (customFace.origin == true) ImageType.ORIGIN else ImageType.COMMON this.fileType = if (customFace.origin == true) ImageType.ORIGIN else ImageType.COMMON
this.fileUrl = when (contact.chatType) { this.fileUrl = when (contact.chatType) {
MsgConstant.KCHATTYPEDISC, MsgConstant.KCHATTYPEGROUP -> RichProtoSvc.getGroupPicDownUrl( MsgConstant.KCHATTYPEDISC, MsgConstant.KCHATTYPEGROUP -> RichProtoSvc.getGroupPicDownUrl(
origUrl, origUrl,
@ -85,7 +85,7 @@ suspend fun List<Elem>.toKritorResponseMessages(contact: Contact): ArrayList<Ele
this.type = ElementType.IMAGE this.type = ElementType.IMAGE
this.image = ImageElement.newBuilder().apply { this.image = ImageElement.newBuilder().apply {
this.fileMd5 = md5 this.fileMd5 = md5
this.type = if (element.notOnlineImage?.original == true) ImageType.ORIGIN else ImageType.COMMON this.fileType = if (element.notOnlineImage?.original == true) ImageType.ORIGIN else ImageType.COMMON
this.fileUrl = when (contact.chatType) { this.fileUrl = when (contact.chatType) {
MsgConstant.KCHATTYPEDISC, MsgConstant.KCHATTYPEGROUP -> RichProtoSvc.getGroupPicDownUrl( MsgConstant.KCHATTYPEDISC, MsgConstant.KCHATTYPEGROUP -> RichProtoSvc.getGroupPicDownUrl(
origUrl, origUrl,

View File

@ -8,7 +8,7 @@ import com.tencent.mobileqq.qroute.QRoute
import com.tencent.qphone.base.remote.ToServiceMsg import com.tencent.qphone.base.remote.ToServiceMsg
import com.tencent.qqnt.aio.adapter.api.IAIOPttApi import com.tencent.qqnt.aio.adapter.api.IAIOPttApi
import com.tencent.qqnt.kernel.nativeinterface.* import com.tencent.qqnt.kernel.nativeinterface.*
import com.tencent.qqnt.kernel.nativeinterface.Contact import com.tencent.qqnt.kernelpublic.nativeinterface.Contact
import com.tencent.qqnt.kernel.nativeinterface.FaceElement import com.tencent.qqnt.kernel.nativeinterface.FaceElement
import com.tencent.qqnt.kernel.nativeinterface.MarkdownElement import com.tencent.qqnt.kernel.nativeinterface.MarkdownElement
import com.tencent.qqnt.kernel.nativeinterface.MarketFaceElement import com.tencent.qqnt.kernel.nativeinterface.MarketFaceElement
@ -254,8 +254,8 @@ object NtMsgConvertor {
} }
private suspend fun imageConvertor(contact: Contact, msgId: Long, sourceImage: Element): Result<MsgElement> { private suspend fun imageConvertor(contact: Contact, msgId: Long, sourceImage: Element): Result<MsgElement> {
val isOriginal = sourceImage.image.type == ImageType.ORIGIN val isOriginal = sourceImage.image.fileType == ImageType.ORIGIN
val isFlash = sourceImage.image.type == ImageType.FLASH val isFlash = sourceImage.image.fileType == ImageType.FLASH
val file = when (sourceImage.image.dataCase!!) { val file = when (sourceImage.image.dataCase!!) {
ImageElement.DataCase.FILE_NAME -> { ImageElement.DataCase.FILE_NAME -> {
val fileMd5 = sourceImage.image.fileName.replace(regex = "[{}\\-]".toRegex(), replacement = "") val fileMd5 = sourceImage.image.fileName.replace(regex = "[{}\\-]".toRegex(), replacement = "")
@ -638,7 +638,7 @@ object NtMsgConvertor {
face.faceText = "" face.faceText = ""
face.faceType = 5 face.faceType = 5
face.packId = null face.packId = null
face.pokeType = sourcePoke.poke.type face.pokeType = sourcePoke.poke.pokeType
face.spokeSummary = "" face.spokeSummary = ""
face.doubleHit = 0 face.doubleHit = 0
face.vaspokeId = sourcePoke.poke.id face.vaspokeId = sourcePoke.poke.id

View File

@ -1,7 +1,7 @@
package qq.service.msg package qq.service.msg
import com.tencent.mobileqq.qroute.QRoute import com.tencent.mobileqq.qroute.QRoute
import com.tencent.qqnt.kernel.nativeinterface.Contact import com.tencent.qqnt.kernelpublic.nativeinterface.Contact
import com.tencent.qqnt.kernel.nativeinterface.MsgConstant import com.tencent.qqnt.kernel.nativeinterface.MsgConstant
import com.tencent.qqnt.kernel.nativeinterface.MsgElement import com.tencent.qqnt.kernel.nativeinterface.MsgElement
import com.tencent.qqnt.msg.api.IMsgService import com.tencent.qqnt.msg.api.IMsgService
@ -73,7 +73,7 @@ private object ReqMsgConvertor {
if (face.faceType == 5) { if (face.faceType == 5) {
elem.setPoke(PokeElement.newBuilder().apply { elem.setPoke(PokeElement.newBuilder().apply {
this.id = face.vaspokeId this.id = face.vaspokeId
this.type = face.pokeType this.pokeType = face.pokeType
this.strength = face.pokeStrength this.strength = face.pokeStrength
}) })
} else { } else {
@ -136,45 +136,8 @@ private object ReqMsgConvertor {
val elem = Element.newBuilder() val elem = Element.newBuilder()
elem.setImage(ImageElement.newBuilder().apply { elem.setImage(ImageElement.newBuilder().apply {
this.fileMd5 = md5 this.fileMd5 = md5
this.fileUrl = when (contact.chatType) { this.fileUrl = RichProtoSvc.getTempPicDownloadUrl(contact.chatType, originalUrl, md5, image, storeId, contact.peerUid, contact.guildId)
MsgConstant.KCHATTYPEDISC, MsgConstant.KCHATTYPEGROUP -> RichProtoSvc.getGroupPicDownUrl( this.fileType =
originalUrl = originalUrl,
md5 = md5,
fileId = image.fileUuid,
width = image.picWidth.toUInt(),
height = image.picHeight.toUInt(),
sha = "",
fileSize = image.fileSize.toULong(),
peer = contact.longPeer().toString()
)
MsgConstant.KCHATTYPEC2C -> RichProtoSvc.getC2CPicDownUrl(
originalUrl = originalUrl,
md5 = md5,
fileId = image.fileUuid,
width = image.picWidth.toUInt(),
height = image.picHeight.toUInt(),
sha = "",
fileSize = image.fileSize.toULong(),
peer = contact.longPeer().toString(),
storeId = storeId
)
MsgConstant.KCHATTYPEGUILD -> RichProtoSvc.getGuildPicDownUrl(
originalUrl = originalUrl,
md5 = md5,
fileId = image.fileUuid,
width = image.picWidth.toUInt(),
height = image.picHeight.toUInt(),
sha = "",
fileSize = image.fileSize.toULong(),
peer = contact.longPeer().toString(),
subPeer = "0"
)
else -> throw UnsupportedOperationException("Not supported chat type: ${contact.chatType}")
}
this.type =
if (image.isFlashPic == true) ImageElement.ImageType.FLASH else if (image.original) ImageElement.ImageType.ORIGIN else ImageElement.ImageType.COMMON if (image.isFlashPic == true) ImageElement.ImageType.FLASH else if (image.original) ImageElement.ImageType.ORIGIN else ImageElement.ImageType.COMMON
this.subType = image.picSubType this.subType = image.picSubType
}) })

View File

@ -1,10 +1,9 @@
package qq.service.msg package qq.service.msg
import android.graphics.BitmapFactory import android.graphics.BitmapFactory
import android.util.Base64
import androidx.exifinterface.media.ExifInterface import androidx.exifinterface.media.ExifInterface
import com.tencent.mobileqq.qroute.QRoute import com.tencent.mobileqq.qroute.QRoute
import com.tencent.qqnt.kernel.nativeinterface.Contact import com.tencent.qqnt.kernelpublic.nativeinterface.Contact
import com.tencent.qqnt.kernel.nativeinterface.MsgConstant import com.tencent.qqnt.kernel.nativeinterface.MsgConstant
import com.tencent.qqnt.msg.api.IMsgService import com.tencent.qqnt.msg.api.IMsgService
import io.kritor.common.Element import io.kritor.common.Element
@ -184,7 +183,7 @@ suspend fun List<Element>.toRichText(contact: Contact): Result<Pair<String, Rich
summary.append("[回复消息]") summary.append("[回复消息]")
} }
Element.ElementType.IMAGE -> { Element.ElementType.IMAGE -> {
val type = it.image.type val type = it.image.fileType
val isOriginal = type == ImageElement.ImageType.ORIGIN val isOriginal = type == ImageElement.ImageType.ORIGIN
val file = when(it.image.dataCase!!) { val file = when(it.image.dataCase!!) {
ImageElement.DataCase.FILE_NAME -> { ImageElement.DataCase.FILE_NAME -> {
@ -392,7 +391,7 @@ suspend fun List<Element>.toRichText(contact: Contact): Result<Pair<String, Rich
commonElem = CommonElem( commonElem = CommonElem(
serviceType = 2, serviceType = 2,
elem = PokeExtra( elem = PokeExtra(
type = it.poke.type, type = it.poke.pokeType,
field7 = 0, field7 = 0,
field8 = 0 field8 = 0
).toByteArray(), ).toByteArray(),

View File

@ -10,6 +10,7 @@ import io.ktor.client.plugins.HttpTimeout
import io.ktor.client.request.get import io.ktor.client.request.get
import io.ktor.client.request.header import io.ktor.client.request.header
import moe.fuqiuluo.shamrock.tools.GlobalClient import moe.fuqiuluo.shamrock.tools.GlobalClient
import moe.fuqiuluo.shamrock.tools.decodeToOidb
import moe.fuqiuluo.shamrock.tools.slice import moe.fuqiuluo.shamrock.tools.slice
import mqq.app.MobileQQ import mqq.app.MobileQQ
import mqq.manager.TicketManager import mqq.manager.TicketManager
@ -140,8 +141,7 @@ internal object TicketHelper: QQInterfaces() {
val fromServiceMsg = sendOidbAW("OidbSvcTcp.0x102a", 4138, 0, req.toByteArray()) val fromServiceMsg = sendOidbAW("OidbSvcTcp.0x102a", 4138, 0, req.toByteArray())
?: return Result.failure(Exception("getLessPSKey failed")) ?: return Result.failure(Exception("getLessPSKey failed"))
if (fromServiceMsg.wupBuffer == null) return Result.failure(Exception("getLessPSKey failed: no response")) if (fromServiceMsg.wupBuffer == null) return Result.failure(Exception("getLessPSKey failed: no response"))
val body = oidb_sso.OIDBSSOPkg() val body = fromServiceMsg.decodeToOidb()
body.mergeFrom(fromServiceMsg.wupBuffer.slice(4))
val rsp = oidb_cmd0x102a.GetPSkeyResponse().mergeFrom(body.bytes_bodybuffer.get().toByteArray()) val rsp = oidb_cmd0x102a.GetPSkeyResponse().mergeFrom(body.bytes_bodybuffer.get().toByteArray())
return Result.success(rsp.private_keys.get()) return Result.success(rsp.private_keys.get())
} }