mirror of
https://github.com/whitechi73/OpenShamrock.git
synced 2024-08-14 13:12:17 +08:00
Shamrock
: fix #190
This commit is contained in:
parent
48b720bdd7
commit
4b5932b319
@ -1,10 +1,32 @@
|
|||||||
package com.tencent.qqnt.kernel.nativeinterface;
|
package com.tencent.qqnt.kernel.nativeinterface;
|
||||||
|
|
||||||
/* compiled from: P */
|
public final class DeviceType {
|
||||||
/* loaded from: classes4.dex */
|
private static final DeviceType[] $VALUES;
|
||||||
public enum DeviceType {
|
public static final DeviceType KCOMPUTER;
|
||||||
KUNKNOWN,
|
public static final DeviceType KPAD;
|
||||||
KPHONE,
|
public static final DeviceType KPHONE;
|
||||||
KPAD,
|
public static final DeviceType KUNKNOWN;
|
||||||
KCOMPUTER
|
|
||||||
|
static {
|
||||||
|
DeviceType deviceType = new DeviceType("KUNKNOWN", 0);
|
||||||
|
KUNKNOWN = deviceType;
|
||||||
|
DeviceType deviceType2 = new DeviceType("KPHONE", 1);
|
||||||
|
KPHONE = deviceType2;
|
||||||
|
DeviceType deviceType3 = new DeviceType("KPAD", 2);
|
||||||
|
KPAD = deviceType3;
|
||||||
|
DeviceType deviceType4 = new DeviceType("KCOMPUTER", 3);
|
||||||
|
KCOMPUTER = deviceType4;
|
||||||
|
$VALUES = new DeviceType[]{deviceType, deviceType2, deviceType3, deviceType4};
|
||||||
|
}
|
||||||
|
|
||||||
|
DeviceType(String str, int i2) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DeviceType valueOf(String str) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DeviceType[] values() {
|
||||||
|
return (DeviceType[]) $VALUES.clone();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,100 @@
|
|||||||
|
package com.tencent.qqnt.kernel.nativeinterface;
|
||||||
|
|
||||||
|
public class InitSessionConfig {
|
||||||
|
|
||||||
|
String a2;
|
||||||
|
String appid;
|
||||||
|
String clientVer;
|
||||||
|
String d2;
|
||||||
|
String d2Key;
|
||||||
|
String defaultFileDownloadPath;
|
||||||
|
InitSessionDesktopPathConfig desktopPathConfig;
|
||||||
|
DeviceType deviceType;
|
||||||
|
String extDataPath;
|
||||||
|
String gproDBName;
|
||||||
|
String machineId;
|
||||||
|
InitSessionMobilePathConfig mobilePathConfig;
|
||||||
|
String platVer;
|
||||||
|
PlatformType platform;
|
||||||
|
RDeliveryConfig rdeliveryConfig;
|
||||||
|
String selfUid;
|
||||||
|
long selfUin;
|
||||||
|
String sysPath;
|
||||||
|
String userPath;
|
||||||
|
|
||||||
|
public String getA2() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAppid() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getClientVer() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getD2() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getD2Key() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDefaultFileDownloadPath() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public InitSessionDesktopPathConfig getDesktopPathConfig() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DeviceType getDeviceType() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getExtDataPath() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getGproDBName() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMachineId() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public InitSessionMobilePathConfig getMobilePathConfig() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPlatVer() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PlatformType getPlatform() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RDeliveryConfig getRdeliveryConfig() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSelfUid() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getSelfUin() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSysPath() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUserPath() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
package com.tencent.qqnt.kernel.nativeinterface;
|
||||||
|
|
||||||
|
public class InitSessionDesktopPathConfig {
|
||||||
|
String accountPath;
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
package com.tencent.qqnt.kernel.nativeinterface;
|
||||||
|
|
||||||
|
public final class InitSessionMobilePathConfig {
|
||||||
|
String mobileQqFilePath;
|
||||||
|
String mobileQqMarketPath;
|
||||||
|
String mobileQqPicPath;
|
||||||
|
String mobileQqPttPath;
|
||||||
|
String mobileQqVideoPath;
|
||||||
|
|
||||||
|
public InitSessionMobilePathConfig() {
|
||||||
|
this.mobileQqPicPath = "";
|
||||||
|
this.mobileQqVideoPath = "";
|
||||||
|
this.mobileQqPttPath = "";
|
||||||
|
this.mobileQqFilePath = "";
|
||||||
|
this.mobileQqMarketPath = "";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
package com.tencent.qqnt.kernel.nativeinterface;
|
||||||
|
|
||||||
|
public final class PlatformType {
|
||||||
|
private static final /* synthetic */ PlatformType[] $VALUES;
|
||||||
|
public static final PlatformType KANDROID;
|
||||||
|
public static final PlatformType KIOS;
|
||||||
|
public static final PlatformType KMAC;
|
||||||
|
public static final PlatformType KUNKNOWN;
|
||||||
|
public static final PlatformType KWINDOWS;
|
||||||
|
|
||||||
|
static {
|
||||||
|
PlatformType platformType = new PlatformType("KUNKNOWN", 0);
|
||||||
|
KUNKNOWN = platformType;
|
||||||
|
PlatformType platformType2 = new PlatformType("KANDROID", 1);
|
||||||
|
KANDROID = platformType2;
|
||||||
|
PlatformType platformType3 = new PlatformType("KIOS", 2);
|
||||||
|
KIOS = platformType3;
|
||||||
|
PlatformType platformType4 = new PlatformType("KWINDOWS", 3);
|
||||||
|
KWINDOWS = platformType4;
|
||||||
|
PlatformType platformType5 = new PlatformType("KMAC", 4);
|
||||||
|
KMAC = platformType5;
|
||||||
|
$VALUES = new PlatformType[]{platformType, platformType2, platformType3, platformType4, platformType5};
|
||||||
|
}
|
||||||
|
|
||||||
|
PlatformType(String str, int i2) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PlatformType valueOf(String str) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PlatformType[] values() {
|
||||||
|
return (PlatformType[]) $VALUES.clone();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
package com.tencent.qqnt.kernel.nativeinterface;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
public final class RDeliveryConfig implements IKernelModel {
|
||||||
|
String appId;
|
||||||
|
String appKey;
|
||||||
|
String appVersion;
|
||||||
|
String bundleId;
|
||||||
|
ArrayList<String> fixedAfterHitKeys;
|
||||||
|
String language;
|
||||||
|
String logicEnvironment;
|
||||||
|
String osVersion;
|
||||||
|
int platform;
|
||||||
|
String sdkVersion;
|
||||||
|
String serverUrl;
|
||||||
|
int systemId;
|
||||||
|
String userId;
|
||||||
|
}
|
@ -20,7 +20,6 @@ internal class WebSocketClientService(
|
|||||||
|
|
||||||
init {
|
init {
|
||||||
startHeartbeatTimer()
|
startHeartbeatTimer()
|
||||||
initTransmitter()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun submitFlowJob(job: Job) {
|
override fun submitFlowJob(job: Job) {
|
||||||
|
@ -45,6 +45,7 @@ internal abstract class WebSocketClientServlet(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var firstOpen = true
|
||||||
private val sendLock = Mutex()
|
private val sendLock = Mutex()
|
||||||
|
|
||||||
override fun allowTransmit(): Boolean {
|
override fun allowTransmit(): Boolean {
|
||||||
@ -89,7 +90,12 @@ internal abstract class WebSocketClientServlet(
|
|||||||
|
|
||||||
//startHeartbeatTimer()
|
//startHeartbeatTimer()
|
||||||
pushMetaLifecycle()
|
pushMetaLifecycle()
|
||||||
//initTransmitter()
|
if (firstOpen) {
|
||||||
|
firstOpen = false
|
||||||
|
} else {
|
||||||
|
cancelFlowJobs()
|
||||||
|
}
|
||||||
|
initTransmitter()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onClose(code: Int, reason: String?, remote: Boolean) {
|
override fun onClose(code: Int, reason: String?, remote: Boolean) {
|
||||||
|
@ -498,43 +498,42 @@ internal object PrimitiveListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun onGroupRecall(time: Long, pb: ProtoMap) {
|
private suspend fun onGroupRecall(time: Long, pb: ProtoMap) {
|
||||||
var detail = pb[1, 3, 2]
|
var detail = pb[1, 3, 2]
|
||||||
if (detail !is ProtoMap) {
|
if (detail !is ProtoMap) {
|
||||||
try {
|
|
||||||
val readPacket = ByteReadPacket(detail.asByteArray)
|
|
||||||
readPacket.discardExact(4)
|
|
||||||
readPacket.discardExact(1)
|
|
||||||
detail = ProtoUtils.decodeFromByteArray(readPacket.readBytes(readPacket.readShort().toInt()))
|
|
||||||
readPacket.release()
|
|
||||||
} catch (e: Exception) {
|
|
||||||
LogCenter.log("onGroupRecall error: ${e.stackTraceToString()}", Level.WARN)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var groupCode:Long
|
|
||||||
try {
|
try {
|
||||||
groupCode = detail[4].asULong
|
val readPacket = ByteReadPacket(detail.asByteArray)
|
||||||
}catch (e: ClassCastException){
|
readPacket.discardExact(4)
|
||||||
groupCode = detail[4].asList.value[0].asULong
|
readPacket.discardExact(1)
|
||||||
|
detail = ProtoUtils.decodeFromByteArray(readPacket.readBytes(readPacket.readShort().toInt()))
|
||||||
|
readPacket.release()
|
||||||
|
} catch (e: Exception) {
|
||||||
|
LogCenter.log("onGroupRecall error: ${e.stackTraceToString()}", Level.WARN)
|
||||||
}
|
}
|
||||||
val operatorUid = detail[11, 1].asUtf8String
|
}
|
||||||
val targetUid = detail[11, 3, 6].asUtf8String
|
val groupCode:Long = try {
|
||||||
val msgSeq = detail[11, 3, 1].asLong
|
detail[4].asULong
|
||||||
val tipText = if (detail.has(11, 9)) detail[11, 9, 2].asUtf8String else ""
|
}catch (e: ClassCastException){
|
||||||
val mapping = MessageHelper.getMsgMappingBySeq(MsgConstant.KCHATTYPEGROUP, msgSeq.toInt())
|
detail[4].asList.value[0].asULong
|
||||||
if (mapping == null) {
|
}
|
||||||
LogCenter.log("由于缺失消息映射关系(seq = $msgSeq),消息撤回事件无法推送!", Level.WARN)
|
val operatorUid = detail[11, 1].asUtf8String
|
||||||
return
|
val targetUid = detail[11, 3, 6].asUtf8String
|
||||||
}
|
val msgSeq = detail[11, 3, 1].asLong
|
||||||
val msgHash = mapping.msgHashId
|
val tipText = if (detail.has(11, 9)) detail[11, 9, 2].asUtf8String else ""
|
||||||
val operator = ContactHelper.getUinByUidAsync(operatorUid).toLong()
|
val mapping = MessageHelper.getMsgMappingBySeq(MsgConstant.KCHATTYPEGROUP, msgSeq.toInt())
|
||||||
val target = ContactHelper.getUinByUidAsync(targetUid).toLong()
|
if (mapping == null) {
|
||||||
LogCenter.log("群消息撤回($groupCode): $operator -> $target, seq = $msgSeq, hash = $msgHash, tip = $tipText")
|
LogCenter.log("由于缺失消息映射关系(seq = $msgSeq),消息撤回事件无法推送!", Level.WARN)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val msgHash = mapping.msgHashId
|
||||||
|
val operator = ContactHelper.getUinByUidAsync(operatorUid).toLong()
|
||||||
|
val target = ContactHelper.getUinByUidAsync(targetUid).toLong()
|
||||||
|
LogCenter.log("群消息撤回($groupCode): $operator -> $target, seq = $msgSeq, hash = $msgHash, tip = $tipText")
|
||||||
|
|
||||||
if (!GlobalEventTransmitter.GroupNoticeTransmitter
|
if (!GlobalEventTransmitter.GroupNoticeTransmitter
|
||||||
.transGroupMsgRecall(time, operator, target, groupCode, msgHash, tipText)
|
.transGroupMsgRecall(time, operator, target, groupCode, msgHash, tipText)
|
||||||
) {
|
) {
|
||||||
LogCenter.log("群消息撤回推送失败!", Level.WARN)
|
LogCenter.log("群消息撤回推送失败!", Level.WARN)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun onGroupApply(time: Long, pb: ProtoMap) {
|
private suspend fun onGroupApply(time: Long, pb: ProtoMap) {
|
||||||
|
@ -1,22 +1,32 @@
|
|||||||
|
@file:Suppress("UNUSED_VARIABLE", "LocalVariableName")
|
||||||
package moe.fuqiuluo.shamrock.xposed.actions
|
package moe.fuqiuluo.shamrock.xposed.actions
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.tencent.common.config.pad.DeviceType
|
import com.tencent.common.config.pad.DeviceType
|
||||||
|
import com.tencent.qqnt.kernel.nativeinterface.InitSessionConfig
|
||||||
|
import com.tencent.qqnt.kernel.nativeinterface.PlatformType
|
||||||
import de.robv.android.xposed.XC_MethodHook
|
import de.robv.android.xposed.XC_MethodHook
|
||||||
import de.robv.android.xposed.XposedBridge
|
import de.robv.android.xposed.XposedBridge
|
||||||
import moe.fuqiuluo.shamrock.remote.service.config.ShamrockConfig
|
import moe.fuqiuluo.shamrock.remote.service.config.ShamrockConfig
|
||||||
import moe.fuqiuluo.shamrock.tools.FuzzySearchClass
|
import moe.fuqiuluo.shamrock.tools.FuzzySearchClass
|
||||||
import moe.fuqiuluo.shamrock.utils.PlatformUtils
|
import moe.fuqiuluo.shamrock.utils.PlatformUtils
|
||||||
import moe.fuqiuluo.shamrock.helper.LogCenter
|
import moe.fuqiuluo.shamrock.helper.LogCenter
|
||||||
|
import moe.fuqiuluo.shamrock.tools.afterHook
|
||||||
|
import moe.fuqiuluo.shamrock.tools.hookMethod
|
||||||
import moe.fuqiuluo.shamrock.xposed.loader.LuoClassloader
|
import moe.fuqiuluo.shamrock.xposed.loader.LuoClassloader
|
||||||
|
|
||||||
internal class ForceTablet: IAction {
|
internal class ForceTablet: IAction {
|
||||||
override fun invoke(ctx: Context) {
|
override fun invoke(ctx: Context) {
|
||||||
if (!PlatformUtils.isMqqPackage()) return
|
//if (!PlatformUtils.isMqqPackage()) return
|
||||||
if (ShamrockConfig.forceTablet()) {
|
if (ShamrockConfig.forceTablet()) {
|
||||||
if (PlatformUtils.isMainProcess()) {
|
if (PlatformUtils.isMainProcess()) {
|
||||||
LogCenter.log("强制协议类型 (PAD)", toast = true)
|
LogCenter.log("强制协议类型 (PAD)", toast = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val returnTablet = afterHook {
|
||||||
|
it.result = DeviceType.TABLET
|
||||||
|
}
|
||||||
|
|
||||||
FuzzySearchClass.findAllClassByMethod(
|
FuzzySearchClass.findAllClassByMethod(
|
||||||
LuoClassloader.hostClassLoader, "com.tencent.common.config.pad"
|
LuoClassloader.hostClassLoader, "com.tencent.common.config.pad"
|
||||||
) { _, method ->
|
) { _, method ->
|
||||||
@ -24,13 +34,32 @@ internal class ForceTablet: IAction {
|
|||||||
}.forEach { clazz ->
|
}.forEach { clazz ->
|
||||||
//log("Inject to tablet mode in ${clazz.name}")
|
//log("Inject to tablet mode in ${clazz.name}")
|
||||||
val method = clazz.declaredMethods.first { it.returnType == DeviceType::class.java }
|
val method = clazz.declaredMethods.first { it.returnType == DeviceType::class.java }
|
||||||
XposedBridge.hookMethod(method, object: XC_MethodHook() {
|
XposedBridge.hookMethod(method, returnTablet)
|
||||||
override fun afterHookedMethod(param: MethodHookParam) {
|
}
|
||||||
//log("Original deviceMode = ${param.result}, but change to TABLET.")
|
|
||||||
param.result = DeviceType.TABLET
|
val PadUtil = LuoClassloader.load("com.tencent.common.config.pad.PadUtil")
|
||||||
}
|
PadUtil?.declaredMethods?.filter {
|
||||||
|
it.returnType == DeviceType::class.java
|
||||||
|
}?.forEach {
|
||||||
|
XposedBridge.hookMethod(it, returnTablet)
|
||||||
|
}
|
||||||
|
|
||||||
|
val deviceTypeField = InitSessionConfig::class.java.declaredFields.firstOrNull {
|
||||||
|
it.type == com.tencent.qqnt.kernel.nativeinterface.DeviceType::class.java
|
||||||
|
}
|
||||||
|
if (deviceTypeField != null) {
|
||||||
|
XposedBridge.hookAllConstructors(InitSessionConfig::class.java, afterHook {
|
||||||
|
if (!deviceTypeField.isAccessible) deviceTypeField.isAccessible = true
|
||||||
|
deviceTypeField.set(it.thisObject, com.tencent.qqnt.kernel.nativeinterface.DeviceType.KPAD)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
InitSessionConfig::class.java.hookMethod("getDeviceType").after {
|
||||||
|
it.result = com.tencent.qqnt.kernel.nativeinterface.DeviceType.KPAD
|
||||||
|
}
|
||||||
|
|
||||||
|
//InitSessionConfig::class.java.hookMethod("getPlatform").after {
|
||||||
|
// it.result = PlatformType.KMAC
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user