fix: Prevent snap replay & fix remove audio note duration & transcription(thanks to RSR)
This commit is contained in:
@@ -2,7 +2,6 @@ package me.eternal.purrfectsnap.core.features.impl.messaging
|
||||
|
||||
import me.eternal.purrfectsnap.common.data.NotificationType
|
||||
import me.eternal.purrfectsnap.common.util.protobuf.ProtoEditor
|
||||
import me.eternal.purrfectsnap.common.util.protobuf.ProtoReader
|
||||
import me.eternal.purrfectsnap.core.event.events.impl.NativeUnaryCallEvent
|
||||
import me.eternal.purrfectsnap.core.event.events.impl.UnaryCallEvent
|
||||
import me.eternal.purrfectsnap.core.event.events.impl.SendMessageWithContentEvent
|
||||
@@ -27,42 +26,12 @@ class PreventMessageSending : Feature("Prevent message sending") {
|
||||
}.toByteArray()
|
||||
}
|
||||
|
||||
fun handleCreateContentMessage(uri: String, buffer: ByteArray): Boolean {
|
||||
if (uri != "/messagingcoreservice.MessagingCoreService/CreateContentMessage") return false
|
||||
val reader = ProtoReader(buffer)
|
||||
// check for missed audio/video call in MessageContent (field 4)
|
||||
val contentReader = reader.followPath(4) ?: return false
|
||||
|
||||
// try both possible field IDs based on SnapEnums and ContentType.java
|
||||
val contentType = contentReader.getVarInt(2)
|
||||
|
||||
val isMissedAudio = contentType == 13L || contentType == 18L
|
||||
val isMissedVideo = contentType == 12L || contentType == 17L
|
||||
|
||||
if (isMissedAudio && preventMessageSending.contains("abandon_audio")) return true
|
||||
if (isMissedVideo && preventMessageSending.contains("abandon_video")) return true
|
||||
|
||||
return false
|
||||
context.event.subscribe(NativeUnaryCallEvent::class, { preventMessageSending.contains("snap_replay") }) { event ->
|
||||
handleUpdateContentMessage(event.uri, event.buffer)?.let { event.buffer = it }
|
||||
}
|
||||
|
||||
context.event.subscribe(NativeUnaryCallEvent::class) { event ->
|
||||
val uri = event.uri
|
||||
if (!uri.startsWith("/messagingcoreservice.MessagingCoreService/")) return@subscribe
|
||||
|
||||
if (handleCreateContentMessage(uri, event.buffer)) {
|
||||
event.canceled = true
|
||||
}
|
||||
handleUpdateContentMessage(uri, event.buffer)?.let { event.buffer = it }
|
||||
}
|
||||
|
||||
context.event.subscribe(UnaryCallEvent::class) { event ->
|
||||
val uri = event.uri
|
||||
if (!uri.startsWith("/messagingcoreservice.MessagingCoreService/")) return@subscribe
|
||||
|
||||
if (handleCreateContentMessage(uri, event.buffer)) {
|
||||
event.canceled = true
|
||||
}
|
||||
handleUpdateContentMessage(uri, event.buffer)?.let { event.buffer = it }
|
||||
context.event.subscribe(UnaryCallEvent::class, { preventMessageSending.contains("snap_replay") }) { event ->
|
||||
handleUpdateContentMessage(event.uri, event.buffer)?.let { event.buffer = it }
|
||||
}
|
||||
|
||||
context.classCache.conversationManager.hook("updateMessage", HookStage.BEFORE) { param ->
|
||||
@@ -75,7 +44,7 @@ class PreventMessageSending : Feature("Prevent message sending") {
|
||||
param.setResult(null)
|
||||
}
|
||||
|
||||
if ((messageUpdate == "REPLAY" || messageUpdate == "replay") && preventMessageSending.contains("snap_replay")) {
|
||||
if (messageUpdate == "REPLAY" && preventMessageSending.contains("snap_replay")) {
|
||||
param.setResult(null)
|
||||
}
|
||||
}
|
||||
@@ -85,6 +54,7 @@ class PreventMessageSending : Feature("Prevent message sending") {
|
||||
val associatedType = NotificationType.fromContentType(contentType ?: return@subscribe) ?: return@subscribe
|
||||
|
||||
if (preventMessageSending.contains(associatedType.key)) {
|
||||
context.log.verbose("Preventing message sending for $associatedType")
|
||||
event.canceled = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,6 +159,63 @@ class SendOverride : Feature("Send Override") {
|
||||
if (configOverrideType == null && stripMediaMetadata.isEmpty()) return
|
||||
|
||||
context.event.subscribe(MediaUploadEvent::class) { event ->
|
||||
// Handle audio notes separately since they don't have path 11, 5
|
||||
if (stripMediaMetadata.isNotEmpty() &&
|
||||
(event.localMessageContent.contentType == ContentType.NOTE ||
|
||||
stripMediaMetadata.contains("remove_audio_note_duration") ||
|
||||
stripMediaMetadata.contains("remove_audio_note_transcript_capability"))) {
|
||||
event.onMediaUploaded { result ->
|
||||
if (result.messageContent.contentType == ContentType.NOTE) {
|
||||
val contentReader = ProtoReader(result.messageContent.content!!)
|
||||
result.messageContent.content = ProtoEditor(result.messageContent.content!!).apply {
|
||||
// Check which path structure exists - try both to be safe
|
||||
val hasFullPath = contentReader.followPath(4, 4, 6, 1, 1) != null
|
||||
val hasDirectPath = contentReader.followPath(6, 1, 1) != null
|
||||
|
||||
if (stripMediaMetadata.contains("remove_audio_note_duration")) {
|
||||
// Audio note duration is at field 13 (confirmed from MessageDecoder line 94 and MessageSender line 27)
|
||||
if (hasFullPath) {
|
||||
edit(4, 4, 6, 1, 1) {
|
||||
remove(13)
|
||||
}
|
||||
}
|
||||
if (hasDirectPath || !hasFullPath) {
|
||||
edit(6, 1, 1) {
|
||||
remove(13)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (stripMediaMetadata.contains("remove_audio_note_transcript_capability")) {
|
||||
// Remove locale string (field 3) which may be used for transcript capability
|
||||
// Also try other potential fields
|
||||
if (hasFullPath) {
|
||||
edit(4, 4, 6, 1, 1) {
|
||||
remove(2) // potential transcript-related field
|
||||
remove(3) // locale string (may affect transcript capability)
|
||||
remove(4) // potential transcript-related field
|
||||
}
|
||||
edit(4, 4, 6, 1) {
|
||||
remove(2) // possible transcript capability flag at parent level
|
||||
remove(3) // locale at parent level
|
||||
}
|
||||
}
|
||||
if (hasDirectPath || !hasFullPath) {
|
||||
edit(6, 1, 1) {
|
||||
remove(2) // potential transcript-related field
|
||||
remove(3) // locale string (may affect transcript capability)
|
||||
remove(4) // potential transcript-related field
|
||||
}
|
||||
edit(6, 1) {
|
||||
remove(2) // possible transcript capability flag at parent level
|
||||
remove(3) // locale at parent level (field 3 at 6,1 is locale per MessageSender)
|
||||
}
|
||||
}
|
||||
}
|
||||
}.toByteArray()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ProtoReader(event.localMessageContent.content!!).followPath(11, 5)?.let { snapDocPlayback ->
|
||||
event.onMediaUploaded { result ->
|
||||
result.messageContent.content = ProtoEditor(result.messageContent.content!!).apply {
|
||||
@@ -213,18 +270,6 @@ class SendOverride : Feature("Send Override") {
|
||||
}
|
||||
}
|
||||
}
|
||||
ContentType.NOTE -> {
|
||||
if (stripMediaMetadata.contains("remove_audio_note_duration")) {
|
||||
edit(6, 1, 1) {
|
||||
remove(13)
|
||||
}
|
||||
}
|
||||
if (stripMediaMetadata.contains("remove_audio_note_transcript_capability")) {
|
||||
edit(6, 1) {
|
||||
remove(3)
|
||||
}
|
||||
}
|
||||
}
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user