commit fff8221b7cb95f9f5a95426a117bc820b9a39486
parent b5c1dd0678d061d8419f034761aa597e592074e4
Author: rhunk <101876869+rhunk@users.noreply.github.com>
Date: Fri, 26 May 2023 14:43:57 +0200
feat: unlimited snap view time
Diffstat:
6 files changed, 85 insertions(+), 0 deletions(-)
diff --git a/app/src/main/assets/lang/en_US.json b/app/src/main/assets/lang/en_US.json
@@ -20,6 +20,7 @@
"hide_bitmoji_presence": "Hide Bitmoji Presence",
"show_message_content": "Show Message Content",
"message_logger": "Message Logger",
+ "unlimited_snap_view_time": "Unlimited Snap View Time",
"auto_download_snaps": "Auto Download Snaps",
"auto_download_stories": "Auto Download Stories",
"auto_download_public_stories": "Auto Download Public Stories",
diff --git a/app/src/main/kotlin/me/rhunk/snapenhance/config/ConfigProperty.kt b/app/src/main/kotlin/me/rhunk/snapenhance/config/ConfigProperty.kt
@@ -36,6 +36,7 @@ enum class ConfigProperty(
false
),
MESSAGE_LOGGER("property.message_logger", "description.message_logger", ConfigCategory.SPY, false),
+ UNLIMITED_SNAP_VIEW_TIME("property.unlimited_snap_view_time", "description.unlimited_snap_view_time", ConfigCategory.SPY, false),
AUTO_DOWNLOAD_SNAPS(
"property.auto_download_snaps",
diff --git a/app/src/main/kotlin/me/rhunk/snapenhance/features/impl/extras/UnlimitedSnapViewTime.kt b/app/src/main/kotlin/me/rhunk/snapenhance/features/impl/extras/UnlimitedSnapViewTime.kt
@@ -0,0 +1,31 @@
+package me.rhunk.snapenhance.features.impl.extras
+
+import me.rhunk.snapenhance.config.ConfigProperty
+import me.rhunk.snapenhance.data.ContentType
+import me.rhunk.snapenhance.data.MessageState
+import me.rhunk.snapenhance.data.wrapper.impl.Message
+import me.rhunk.snapenhance.features.Feature
+import me.rhunk.snapenhance.features.FeatureLoadParams
+import me.rhunk.snapenhance.hook.HookStage
+import me.rhunk.snapenhance.hook.Hooker
+import me.rhunk.snapenhance.util.protobuf.ProtoEditor
+
+class UnlimitedSnapViewTime :
+ Feature("UnlimitedSnapViewTime", loadParams = FeatureLoadParams.ACTIVITY_CREATE_SYNC) {
+ override fun onActivityCreate() {
+ Hooker.hookConstructor(context.classCache.message, HookStage.AFTER, {
+ context.config.bool(ConfigProperty.UNLIMITED_SNAP_VIEW_TIME)
+ }) { param ->
+ val message = Message(param.thisObject())
+ if (message.messageState != MessageState.COMMITTED) return@hookConstructor
+ if (message.messageContent.contentType != ContentType.SNAP) return@hookConstructor
+
+ message.messageContent.content = ProtoEditor(message.messageContent.content).apply {
+ edit(11, 5, 2) {
+ writeConstant(5, 0)
+ writeBuffer(6, byteArrayOf())
+ }
+ }.toByteArray()
+ }
+ }
+}
diff --git a/app/src/main/kotlin/me/rhunk/snapenhance/manager/impl/FeatureManager.kt b/app/src/main/kotlin/me/rhunk/snapenhance/manager/impl/FeatureManager.kt
@@ -13,6 +13,7 @@ import me.rhunk.snapenhance.features.impl.extras.AutoSave
import me.rhunk.snapenhance.features.impl.extras.ExternalMediaAsSnap
import me.rhunk.snapenhance.features.impl.extras.Notifications
import me.rhunk.snapenhance.features.impl.extras.SnapchatPlus
+import me.rhunk.snapenhance.features.impl.extras.UnlimitedSnapViewTime
import me.rhunk.snapenhance.features.impl.privacy.DisableMetrics
import me.rhunk.snapenhance.features.impl.privacy.PreventMessageSending
import me.rhunk.snapenhance.features.impl.spy.AnonymousStoryViewing
@@ -64,6 +65,7 @@ class FeatureManager(private val context: ModContext) : Manager {
register(AntiAutoDownload::class)
register(ExternalMediaAsSnap::class)
register(AntiAutoSave::class)
+ register(UnlimitedSnapViewTime::class)
initializeFeatures()
}
diff --git a/app/src/main/kotlin/me/rhunk/snapenhance/util/protobuf/ProtoEditor.kt b/app/src/main/kotlin/me/rhunk/snapenhance/util/protobuf/ProtoEditor.kt
@@ -0,0 +1,41 @@
+package me.rhunk.snapenhance.util.protobuf
+
+class ProtoEditor(
+ private var buffer: ByteArray
+) {
+ fun edit(vararg path: Int, callback: ProtoWriter.() -> Unit) {
+ val writer = ProtoWriter()
+ callback(writer)
+ buffer = writeAtPath(path, 0, ProtoReader(buffer), writer.toByteArray())
+ }
+
+ private fun writeAtPath(path: IntArray, currentIndex: Int, rootReader: ProtoReader, bufferToWrite: ByteArray): ByteArray {
+ if (currentIndex == path.size) {
+ return bufferToWrite
+ }
+ val id = path[currentIndex]
+ val output = ProtoWriter()
+ val wires = mutableMapOf<Int, ByteArray>()
+
+ rootReader.list { tag, value ->
+ if (tag == id) {
+ val childReader = rootReader.readPath(id)
+ if (childReader == null) {
+ wires[tag] = value
+ return@list
+ }
+ wires[tag] = writeAtPath(path, currentIndex + 1, childReader, bufferToWrite)
+ return@list
+ }
+ wires[tag] = value
+ }
+
+ wires.forEach { (tag, value) ->
+ output.writeBuffer(tag, value)
+ }
+
+ return output.toByteArray()
+ }
+
+ fun toByteArray() = buffer
+}+
\ No newline at end of file
diff --git a/app/src/main/kotlin/me/rhunk/snapenhance/util/protobuf/ProtoReader.kt b/app/src/main/kotlin/me/rhunk/snapenhance/util/protobuf/ProtoReader.kt
@@ -113,6 +113,14 @@ class ProtoReader(private val buffer: ByteArray) {
}
}
+ fun list(reader: (id: Int, data: ByteArray) -> Unit) {
+ values.forEach { (id, wires) ->
+ wires.forEachIndexed { index, _ ->
+ reader(id, wires[index].value as ByteArray)
+ }
+ }
+ }
+
fun eachExists(id: Int, reader: ProtoReader.(index: Int) -> Unit) {
if (!exists(id)) {
return