-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add feature to show message content in notifications.
- Loading branch information
Showing
8 changed files
with
220 additions
and
12 deletions.
There are no files selected for viewing
Binary file not shown.
43 changes: 43 additions & 0 deletions
43
app/src/main/java/xyz/rodit/snapmod/arroyo/ArroyoReader.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package xyz.rodit.snapmod.arroyo | ||
|
||
import android.content.Context | ||
import android.database.sqlite.SQLiteDatabase | ||
import xyz.rodit.snapmod.logging.log | ||
import xyz.rodit.snapmod.util.ProtoReader | ||
import java.io.File | ||
|
||
class ArroyoReader(private val context: Context) { | ||
|
||
fun getMessageContent(conversationId: String, messageId: String): String? { | ||
try { | ||
val db: SQLiteDatabase = | ||
SQLiteDatabase.openDatabase( | ||
File(context.filesDir, "../databases/arroyo.db").path, | ||
null, | ||
0 | ||
) | ||
val cursor = | ||
db.rawQuery( | ||
"SELECT message_content FROM conversation_message WHERE client_conversation_id='$conversationId' AND server_message_id=$messageId", | ||
null | ||
) | ||
if (cursor.moveToFirst()) { | ||
var parts = ProtoReader(cursor.getBlob(0)).read() | ||
var container = parts.firstOrNull { it.index == 4 }?.value ?: return null | ||
parts = ProtoReader(container).read() | ||
container = parts.firstOrNull { it.index == 4 }?.value ?: return null | ||
parts = ProtoReader(container).read() | ||
container = parts.firstOrNull { it.index == 2 }?.value ?: return null | ||
parts = ProtoReader(container).read() | ||
container = parts.firstOrNull { it.index == 1 }?.value ?: return null | ||
return String(container) | ||
} else { | ||
log.debug("No result in db.") | ||
} | ||
} catch (e: Exception) { | ||
log.error("Error reading arroyo db", e) | ||
} | ||
|
||
return null | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
26 changes: 26 additions & 0 deletions
26
app/src/main/java/xyz/rodit/snapmod/notifications/ShowMessageContent.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package xyz.rodit.snapmod.notifications | ||
|
||
import xyz.rodit.snapmod.arroyo.ArroyoReader | ||
import xyz.rodit.snapmod.features.Feature | ||
import xyz.rodit.snapmod.features.FeatureContext | ||
import xyz.rodit.snapmod.mappings.NotificationData | ||
import xyz.rodit.snapmod.mappings.NotificationHandler | ||
import xyz.rodit.snapmod.util.before | ||
|
||
class ShowMessageContent(context: FeatureContext) : Feature(context) { | ||
|
||
private val arroyoReader = ArroyoReader(context.appContext) | ||
|
||
override fun performHooks() { | ||
NotificationHandler.handle.before(context, "show_notification_content") { | ||
val data = NotificationData.wrap(NotificationHandler.wrap(it.thisObject).data) | ||
val bundle = data.bundle | ||
val conversationId = bundle.getString("arroyo_convo_id") | ||
val messageId = bundle.getString("arroyo_message_id") | ||
if (conversationId.isNullOrBlank() || messageId.isNullOrBlank()) return@before | ||
|
||
val content = arroyoReader.getMessageContent(conversationId, messageId) ?: return@before | ||
bundle.putString("ab_cnotif_body", content) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
package xyz.rodit.snapmod.util | ||
|
||
import xyz.rodit.snapmod.logging.log | ||
import java.math.BigInteger | ||
|
||
private val BIGINT_2 = BigInteger.valueOf(2) | ||
private const val TYPE_VAR_INT = 0 | ||
private const val TYPE_STRING = 2 | ||
|
||
internal inline infix fun Byte.and(other: Int): Int = toInt() and other | ||
|
||
internal inline infix fun Byte.shl(other: Int): Int = toInt() shl other | ||
|
||
class ProtoReader(private val data: ByteArray) { | ||
|
||
private var position = 0 | ||
private var checkpoint = 0 | ||
|
||
fun read(): List<ProtoPart> { | ||
val parts = mutableListOf<ProtoPart>() | ||
|
||
while (position < data.size) { | ||
checkpoint = position | ||
|
||
val varInt = internalReadVarint32() | ||
val type = varInt and 0b111 | ||
val index = varInt shr 3 | ||
|
||
var value = ByteArray(0) | ||
|
||
if (type == TYPE_VAR_INT) { | ||
value = internalReadVarint32().toString().toByteArray() | ||
} else if (type == TYPE_STRING) { | ||
val length = internalReadVarint32() | ||
value = ByteArray(length) | ||
data.copyInto(value, 0, position, position + length) | ||
position += length | ||
} else { | ||
log.error("Unknown protobuf type $type") | ||
} | ||
|
||
parts.add(ProtoPart(index, type, value)) | ||
} | ||
|
||
return parts | ||
} | ||
|
||
private fun readByte(): Byte { | ||
return data[position++] | ||
} | ||
|
||
private fun internalReadVarint32(): Int { | ||
var tmp = readByte() | ||
if (tmp >= 0) { | ||
return tmp.toInt() | ||
} | ||
var result = tmp and 0x7f | ||
tmp = readByte() | ||
if (tmp >= 0) { | ||
result = result or (tmp shl 7) | ||
} else { | ||
result = result or (tmp and 0x7f shl 7) | ||
tmp = readByte() | ||
if (tmp >= 0) { | ||
result = result or (tmp shl 14) | ||
} else { | ||
result = result or (tmp and 0x7f shl 14) | ||
tmp = readByte() | ||
if (tmp >= 0) { | ||
result = result or (tmp shl 21) | ||
} else { | ||
result = result or (tmp and 0x7f shl 21) | ||
tmp = readByte() | ||
result = result or (tmp shl 28) | ||
if (tmp < 0) { | ||
for (i in 0..4) { | ||
if (readByte() >= 0) { | ||
return result | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
return result | ||
} | ||
} | ||
|
||
data class ProtoPart(val index: Int, val type: Int, val value: ByteArray) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters