mirror of
https://github.com/whitechi73/OpenShamrock.git
synced 2024-08-14 13:12:17 +08:00
ShamrockPublic
: アクティブな一時チャットを許可する
Signed-off-by: WhiteChi <whitechi73@outlook.com>
This commit is contained in:
parent
c30e3db1a1
commit
259de3d3aa
@ -0,0 +1,28 @@
|
|||||||
|
package com.tencent.mobileqq.troop.api;
|
||||||
|
|
||||||
|
import mqq.app.api.IRuntimeService;
|
||||||
|
import com.tencent.mobileqq.data.troop.TroopMemberInfo;
|
||||||
|
|
||||||
|
public interface ITroopMemberNameService extends IRuntimeService {
|
||||||
|
String getTroopMemberColorNick(String str, String str2);
|
||||||
|
|
||||||
|
String getTroopMemberName(TroopMemberInfo troopMemberInfo);
|
||||||
|
|
||||||
|
String getTroopMemberName(String str, String str2);
|
||||||
|
|
||||||
|
String getTroopMemberName(String str, String str2, String str3, String str4);
|
||||||
|
|
||||||
|
String getTroopMemberName(String str, String str2, boolean z, boolean z2);
|
||||||
|
|
||||||
|
//void getTroopMemberNameAsync(String str, String str2, a aVar);
|
||||||
|
|
||||||
|
String getTroopMemberNameInUI(String str, String str2);
|
||||||
|
|
||||||
|
String getTroopMemberNameRemarkFirst(String str, String str2);
|
||||||
|
|
||||||
|
String getTroopMemberNameWithoutRemark(String str, String str2);
|
||||||
|
|
||||||
|
String getTroopMemberNick(String str, String str2);
|
||||||
|
|
||||||
|
String getTroopMemberNickByTroopCode(String str, String str2);
|
||||||
|
}
|
@ -1,7 +1,9 @@
|
|||||||
package com.tencent.qqnt.kernel.api.impl;
|
package com.tencent.qqnt.kernel.api.impl;
|
||||||
|
|
||||||
import com.tencent.qqnt.kernel.nativeinterface.IKernelMsgListener;
|
import com.tencent.qqnt.kernel.nativeinterface.IKernelMsgListener;
|
||||||
|
import com.tencent.qqnt.kernel.nativeinterface.IOperateCallback;
|
||||||
import com.tencent.qqnt.kernel.nativeinterface.RichMediaFilePathInfo;
|
import com.tencent.qqnt.kernel.nativeinterface.RichMediaFilePathInfo;
|
||||||
|
import com.tencent.qqnt.kernel.nativeinterface.TempChatPrepareInfo;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
@ -18,4 +20,8 @@ public class MsgService {
|
|||||||
public String getRichMediaFilePathForMobileQQSend(@NotNull RichMediaFilePathInfo richMediaFilePathInfo) {
|
public String getRichMediaFilePathForMobileQQSend(@NotNull RichMediaFilePathInfo richMediaFilePathInfo) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void prepareTempChat(TempChatPrepareInfo tempChatPrepareInfo, IOperateCallback cb) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,20 +56,14 @@ public final class TempChatPrepareInfo {
|
|||||||
return "TempChatPrepareInfo{chatType=" + this.chatType + ",peerUid=" + this.peerUid + ",peerNickname=" + this.peerNickname + ",fromGroupCode=" + this.fromGroupCode + ",sig=" + this.sig + ",selfUid=" + this.selfUid + ",selfPhone=" + this.selfPhone + ",gameSession=" + this.gameSession + ",}";
|
return "TempChatPrepareInfo{chatType=" + this.chatType + ",peerUid=" + this.peerUid + ",peerNickname=" + this.peerNickname + ",fromGroupCode=" + this.fromGroupCode + ",sig=" + this.sig + ",selfUid=" + this.selfUid + ",selfPhone=" + this.selfPhone + ",gameSession=" + this.gameSession + ",}";
|
||||||
}
|
}
|
||||||
|
|
||||||
public TempChatPrepareInfo(int i2, String str, String str2, String str3, byte[] bArr, String str4, String str5, TempChatGameSession tempChatGameSession) {
|
public TempChatPrepareInfo(int chatType, String peerId, String nickName, String fromGroup, byte[] sig, String selfUid, String selfPhone, TempChatGameSession session) {
|
||||||
this.peerUid = "";
|
this.chatType = chatType;
|
||||||
this.peerNickname = "";
|
this.peerUid = peerId;
|
||||||
this.fromGroupCode = "";
|
this.peerNickname = nickName;
|
||||||
this.sig = new byte[0];
|
this.fromGroupCode = fromGroup;
|
||||||
this.selfUid = "";
|
this.sig = sig;
|
||||||
this.selfPhone = "";
|
this.selfUid = selfUid;
|
||||||
this.chatType = i2;
|
this.selfPhone = selfPhone;
|
||||||
this.peerUid = str;
|
this.gameSession = session;
|
||||||
this.peerNickname = str2;
|
|
||||||
this.fromGroupCode = str3;
|
|
||||||
this.sig = bArr;
|
|
||||||
this.selfUid = str4;
|
|
||||||
this.selfPhone = str5;
|
|
||||||
this.gameSession = tempChatGameSession;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -81,6 +81,10 @@ public abstract class AppRuntime {
|
|||||||
return !"0".equals(getCurrentAccountUin()) ? getCurrentAccountUin() : "";
|
return !"0".equals(getCurrentAccountUin()) ? getCurrentAccountUin() : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getCurrentUid() {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
public long getLongAccountUin() {
|
public long getLongAccountUin() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,24 @@
|
|||||||
package moe.fuqiuluo.qqinterface.servlet
|
package moe.fuqiuluo.qqinterface.servlet
|
||||||
|
|
||||||
import com.tencent.mobileqq.qroute.QRoute
|
import com.tencent.mobileqq.qroute.QRoute
|
||||||
|
import com.tencent.mobileqq.troop.api.ITroopMemberNameService
|
||||||
|
import com.tencent.qqnt.kernel.api.IKernelService
|
||||||
import com.tencent.qqnt.kernel.nativeinterface.IOperateCallback
|
import com.tencent.qqnt.kernel.nativeinterface.IOperateCallback
|
||||||
|
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.kernel.nativeinterface.TempChatGameSession
|
||||||
|
import com.tencent.qqnt.kernel.nativeinterface.TempChatPrepareInfo
|
||||||
import com.tencent.qqnt.msg.api.IMsgService
|
import com.tencent.qqnt.msg.api.IMsgService
|
||||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||||
import kotlinx.coroutines.withTimeoutOrNull
|
import kotlinx.coroutines.withTimeoutOrNull
|
||||||
import kotlinx.serialization.json.JsonArray
|
import kotlinx.serialization.json.JsonArray
|
||||||
import moe.fuqiuluo.shamrock.helper.MessageHelper
|
import moe.fuqiuluo.shamrock.helper.ContactHelper
|
||||||
|
import moe.fuqiuluo.shamrock.helper.Level
|
||||||
import moe.fuqiuluo.shamrock.helper.LogCenter
|
import moe.fuqiuluo.shamrock.helper.LogCenter
|
||||||
|
import moe.fuqiuluo.shamrock.helper.MessageHelper
|
||||||
|
import moe.fuqiuluo.shamrock.tools.EMPTY_BYTE_ARRAY
|
||||||
import moe.fuqiuluo.shamrock.xposed.helper.NTServiceFetcher
|
import moe.fuqiuluo.shamrock.xposed.helper.NTServiceFetcher
|
||||||
|
import moe.fuqiuluo.shamrock.xposed.helper.msgService
|
||||||
import kotlin.coroutines.resume
|
import kotlin.coroutines.resume
|
||||||
import kotlin.coroutines.suspendCoroutine
|
import kotlin.coroutines.suspendCoroutine
|
||||||
|
|
||||||
@ -18,6 +27,27 @@ internal object MsgSvc: BaseSvc() {
|
|||||||
return Result.failure(Exception("Not implemented"))
|
return Result.failure(Exception("Not implemented"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun prepareTempChatFromGroup(
|
||||||
|
groupId: String,
|
||||||
|
peerId: String
|
||||||
|
): Result<Unit> {
|
||||||
|
LogCenter.log("主动临时消息,创建临时会话。", Level.INFO)
|
||||||
|
val msgService = app.getRuntimeService(IKernelService::class.java, "all").msgService
|
||||||
|
?: return Result.failure(Exception("获取消息服务失败"))
|
||||||
|
msgService.prepareTempChat(TempChatPrepareInfo(
|
||||||
|
MsgConstant.KCHATTYPETEMPC2CFROMGROUP,
|
||||||
|
ContactHelper.getUidByUinAsync(peerId = peerId.toLong()),
|
||||||
|
app.getRuntimeService(ITroopMemberNameService::class.java, "all")
|
||||||
|
.getTroopMemberNameRemarkFirst(groupId, peerId),
|
||||||
|
groupId, EMPTY_BYTE_ARRAY, app.currentUid, "", TempChatGameSession()
|
||||||
|
)) { code, reason ->
|
||||||
|
if (code != 0) {
|
||||||
|
LogCenter.log("临时会话创建失败: $code, $reason", Level.ERROR)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Result.success(Unit)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 正常获取
|
* 正常获取
|
||||||
*/
|
*/
|
||||||
@ -139,6 +169,17 @@ internal object MsgSvc: BaseSvc() {
|
|||||||
): Pair<Long, Int> {
|
): Pair<Long, Int> {
|
||||||
//LogCenter.log(message.toString(), Level.ERROR)
|
//LogCenter.log(message.toString(), Level.ERROR)
|
||||||
//callback.msgHash = result.second 什么垃圾代码,万一cb比你快,你不就寄了?
|
//callback.msgHash = result.second 什么垃圾代码,万一cb比你快,你不就寄了?
|
||||||
|
|
||||||
|
// 主动临时消息
|
||||||
|
when(chatType) {
|
||||||
|
MsgConstant.KCHATTYPETEMPC2CFROMGROUP -> {
|
||||||
|
prepareTempChatFromGroup(fromId, peedId).onFailure {
|
||||||
|
LogCenter.log("主动临时消息,创建临时会话失败。", Level.ERROR)
|
||||||
|
return -1L to 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return MessageHelper.sendMessageWithoutMsgId(chatType, peedId, message, MessageCallback(peedId, 0), fromId)
|
return MessageHelper.sendMessageWithoutMsgId(chatType, peedId, message, MessageCallback(peedId, 0), fromId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,6 +44,7 @@ internal object MessageHelper {
|
|||||||
if(callback is MsgSvc.MessageCallback) {
|
if(callback is MsgSvc.MessageCallback) {
|
||||||
callback.msgHash = uniseq.first
|
callback.msgHash = uniseq.first
|
||||||
}
|
}
|
||||||
|
|
||||||
service.sendMsg(
|
service.sendMsg(
|
||||||
generateContact(chatType, peerId, fromId),
|
generateContact(chatType, peerId, fromId),
|
||||||
uniseq.second,
|
uniseq.second,
|
||||||
|
@ -81,10 +81,13 @@ internal object SendMessage: IActionHandler() {
|
|||||||
MsgSvc.sendToAio(chatType, peerId, msg, fromId = fromId)
|
MsgSvc.sendToAio(chatType, peerId, msg, fromId = fromId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (result.first <= 0) {
|
||||||
|
return logic("send message failed", echo = echo)
|
||||||
|
}
|
||||||
return ok(MessageResult(
|
return ok(MessageResult(
|
||||||
msgId = result.second,
|
msgId = result.second,
|
||||||
time = result.first * 0.001
|
time = result.first * 0.001
|
||||||
), echo)
|
), echo = echo)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 消息段格式消息
|
// 消息段格式消息
|
||||||
@ -95,6 +98,9 @@ internal object SendMessage: IActionHandler() {
|
|||||||
// return logic("contact is not found", echo = echo)
|
// return logic("contact is not found", echo = echo)
|
||||||
//}
|
//}
|
||||||
val result = MsgSvc.sendToAio(chatType, peerId, message, fromId = fromId)
|
val result = MsgSvc.sendToAio(chatType, peerId, message, fromId = fromId)
|
||||||
|
if (result.first <= 0) {
|
||||||
|
return logic("send message failed", echo = echo)
|
||||||
|
}
|
||||||
return ok(MessageResult(
|
return ok(MessageResult(
|
||||||
msgId = result.second,
|
msgId = result.second,
|
||||||
time = result.first * 0.001
|
time = result.first * 0.001
|
||||||
|
@ -12,10 +12,23 @@ internal object SendPrivateMessage: IActionHandler() {
|
|||||||
return if (session.isString("message")) {
|
return if (session.isString("message")) {
|
||||||
val autoEscape = session.getBooleanOrDefault("auto_escape", false)
|
val autoEscape = session.getBooleanOrDefault("auto_escape", false)
|
||||||
val message = session.getString("message")
|
val message = session.getString("message")
|
||||||
SendMessage(chatTYpe, userId, message, autoEscape, echo = session.echo, fromId = groupId ?: userId)
|
SendMessage.invoke(
|
||||||
|
chatType = chatTYpe,
|
||||||
|
peerId = userId,
|
||||||
|
message = message,
|
||||||
|
autoEscape = autoEscape,
|
||||||
|
echo = session.echo,
|
||||||
|
fromId = groupId ?: userId
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
val message = session.getArray("message")
|
val message = session.getArray("message")
|
||||||
SendMessage(chatTYpe, userId, message, session.echo, fromId = groupId ?: userId)
|
SendMessage(
|
||||||
|
chatType = chatTYpe,
|
||||||
|
peerId = userId,
|
||||||
|
message = message,
|
||||||
|
echo = session.echo,
|
||||||
|
fromId = groupId ?: userId
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,13 +42,13 @@ fun Routing.messageAction() {
|
|||||||
}
|
}
|
||||||
post {
|
post {
|
||||||
val msgType = fetchPostOrThrow("message_type")
|
val msgType = fetchPostOrThrow("message_type")
|
||||||
val peerIdKey = if(msgType == "group") "group_id" else "user_id"
|
|
||||||
val chatType = MessageHelper.obtainMessageTypeByDetailType(msgType)
|
val chatType = MessageHelper.obtainMessageTypeByDetailType(msgType)
|
||||||
|
val peerId = fetchPostOrThrow(if(msgType == "group") "group_id" else "user_id")
|
||||||
call.respondText(if (isJsonData() && !isJsonString("message")) {
|
call.respondText(if (isJsonData() && !isJsonString("message")) {
|
||||||
SendMessage(chatType, fetchPostOrThrow(peerIdKey), fetchPostJsonArray("message"))
|
SendMessage(chatType, peerId, fetchPostJsonArray("message"))
|
||||||
} else {
|
} else {
|
||||||
val autoEscape = fetchPostOrNull("auto_escape")?.toBooleanStrict() ?: false
|
val autoEscape = fetchPostOrNull("auto_escape")?.toBooleanStrict() ?: false
|
||||||
SendMessage(chatType, fetchPostOrThrow(peerIdKey), fetchPostOrThrow("message"), autoEscape)
|
SendMessage(chatType, peerId, fetchPostOrThrow("message"), autoEscape)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,8 @@ import io.ktor.http.parseUrlEncodedParameters
|
|||||||
import io.ktor.server.request.httpMethod
|
import io.ktor.server.request.httpMethod
|
||||||
import io.ktor.server.routing.route
|
import io.ktor.server.routing.route
|
||||||
import kotlinx.serialization.json.JsonElement
|
import kotlinx.serialization.json.JsonElement
|
||||||
|
import moe.fuqiuluo.shamrock.helper.Level
|
||||||
|
import moe.fuqiuluo.shamrock.helper.LogCenter
|
||||||
import moe.fuqiuluo.shamrock.remote.entries.CommonResult
|
import moe.fuqiuluo.shamrock.remote.entries.CommonResult
|
||||||
import moe.fuqiuluo.shamrock.remote.entries.EmptyObject
|
import moe.fuqiuluo.shamrock.remote.entries.EmptyObject
|
||||||
import moe.fuqiuluo.shamrock.remote.entries.Status
|
import moe.fuqiuluo.shamrock.remote.entries.Status
|
||||||
@ -88,7 +90,7 @@ suspend fun ApplicationCall.fetchPostOrThrow(key: String): String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun ApplicationCall.isJsonData(): Boolean {
|
fun ApplicationCall.isJsonData(): Boolean {
|
||||||
return ContentType.Application.Json == request.contentType()
|
return ContentType.Application.Json == request.contentType() || ContentType.Application.ProblemJson == request.contentType()
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun ApplicationCall.fetchPostOrNull(key: String): String? {
|
suspend fun ApplicationCall.fetchPostOrNull(key: String): String? {
|
||||||
@ -102,6 +104,7 @@ suspend fun ApplicationCall.fetchPostOrNull(key: String): String? {
|
|||||||
if (isJsonData()) {
|
if (isJsonData()) {
|
||||||
Json.parseToJsonElement(receiveText()).jsonObject.also {
|
Json.parseToJsonElement(receiveText()).jsonObject.also {
|
||||||
attributes.put(jsonKey, it)
|
attributes.put(jsonKey, it)
|
||||||
|
attributes.put(isJsonKey, true)
|
||||||
}[key].asStringOrNull
|
}[key].asStringOrNull
|
||||||
} else if (
|
} else if (
|
||||||
ContentType.Application.FormUrlEncoded == request.contentType()
|
ContentType.Application.FormUrlEncoded == request.contentType()
|
||||||
@ -113,7 +116,7 @@ suspend fun ApplicationCall.fetchPostOrNull(key: String): String? {
|
|||||||
receiveTextAsUnknown(key)
|
receiveTextAsUnknown(key)
|
||||||
}
|
}
|
||||||
}.getOrElse {
|
}.getOrElse {
|
||||||
receiveTextAsUnknown(key)
|
throw IllegalArgumentException("JSON数据格式不合法")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,6 +180,7 @@ suspend fun PipelineContext<Unit, ApplicationCall>.isJsonString(key: String): Bo
|
|||||||
} else {
|
} else {
|
||||||
Json.parseToJsonElement(call.receiveText()).jsonObject.also {
|
Json.parseToJsonElement(call.receiveText()).jsonObject.also {
|
||||||
call.attributes.put(jsonKey, it)
|
call.attributes.put(jsonKey, it)
|
||||||
|
call.attributes.put(isJsonKey, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return data[key] is JsonPrimitive
|
return data[key] is JsonPrimitive
|
||||||
@ -245,6 +249,7 @@ suspend fun PipelineContext<Unit, ApplicationCall>.fetchPostJsonArray(key: Strin
|
|||||||
} else {
|
} else {
|
||||||
Json.parseToJsonElement(call.receiveText()).jsonObject.also {
|
Json.parseToJsonElement(call.receiveText()).jsonObject.also {
|
||||||
call.attributes.put(jsonKey, it)
|
call.attributes.put(jsonKey, it)
|
||||||
|
call.attributes.put(isJsonKey, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return data[key].asJsonArray
|
return data[key].asJsonArray
|
||||||
|
Loading…
x
Reference in New Issue
Block a user