refactor: core package

This commit is contained in:
rhunk
2023-09-09 15:35:26 +02:00
parent 249569468c
commit 7b5a411a5d
77 changed files with 143 additions and 141 deletions

View File

@ -3,6 +3,7 @@ package me.rhunk.snapenhance
import android.content.SharedPreferences
import android.util.Log
import com.google.gson.GsonBuilder
import me.rhunk.snapenhance.core.LogLevel
import java.io.File
import java.io.OutputStream
import java.io.RandomAccessFile

View File

@ -3,7 +3,7 @@ package me.rhunk.snapenhance.bridge
import android.app.Service
import android.content.Intent
import android.os.IBinder
import me.rhunk.snapenhance.LogLevel
import me.rhunk.snapenhance.core.LogLevel
import me.rhunk.snapenhance.RemoteSideContext
import me.rhunk.snapenhance.SharedContextHolder
import me.rhunk.snapenhance.core.bridge.types.BridgeFileType
@ -14,7 +14,7 @@ import me.rhunk.snapenhance.core.database.objects.FriendInfo
import me.rhunk.snapenhance.core.messaging.MessagingFriendInfo
import me.rhunk.snapenhance.core.messaging.MessagingGroupInfo
import me.rhunk.snapenhance.download.DownloadProcessor
import me.rhunk.snapenhance.util.SerializableDataObject
import me.rhunk.snapenhance.core.util.SerializableDataObject
import kotlin.system.measureTimeMillis
class BridgeService : Service() {

View File

@ -26,7 +26,7 @@ import me.rhunk.snapenhance.core.download.data.DownloadRequest
import me.rhunk.snapenhance.core.download.data.DownloadStage
import me.rhunk.snapenhance.core.download.data.InputMedia
import me.rhunk.snapenhance.core.download.data.MediaEncryptionKeyPair
import me.rhunk.snapenhance.util.download.RemoteMediaResolver
import me.rhunk.snapenhance.core.util.download.RemoteMediaResolver
import java.io.File
import java.io.InputStream
import java.net.HttpURLConnection

View File

@ -6,9 +6,9 @@ import android.database.sqlite.SQLiteDatabase
import me.rhunk.snapenhance.core.download.data.DownloadMetadata
import me.rhunk.snapenhance.core.download.data.DownloadStage
import me.rhunk.snapenhance.core.download.data.MediaDownloadSource
import me.rhunk.snapenhance.util.SQLiteDatabaseHelper
import me.rhunk.snapenhance.util.ktx.getIntOrNull
import me.rhunk.snapenhance.util.ktx.getStringOrNull
import me.rhunk.snapenhance.core.util.SQLiteDatabaseHelper
import me.rhunk.snapenhance.core.util.ktx.getIntOrNull
import me.rhunk.snapenhance.core.util.ktx.getStringOrNull
class DownloadTaskManager {
private lateinit var taskDatabase: SQLiteDatabase

View File

@ -4,9 +4,9 @@ import com.arthenica.ffmpegkit.FFmpegKit
import com.arthenica.ffmpegkit.FFmpegSession
import com.arthenica.ffmpegkit.Level
import kotlinx.coroutines.suspendCancellableCoroutine
import me.rhunk.snapenhance.LogLevel
import me.rhunk.snapenhance.core.LogLevel
import me.rhunk.snapenhance.LogManager
import me.rhunk.snapenhance.Logger
import me.rhunk.snapenhance.core.Logger
import me.rhunk.snapenhance.core.config.impl.DownloaderConfig
import java.io.File
import java.util.concurrent.Executors

View File

@ -7,10 +7,10 @@ import me.rhunk.snapenhance.core.messaging.FriendStreaks
import me.rhunk.snapenhance.core.messaging.MessagingFriendInfo
import me.rhunk.snapenhance.core.messaging.MessagingGroupInfo
import me.rhunk.snapenhance.core.messaging.MessagingRuleType
import me.rhunk.snapenhance.util.SQLiteDatabaseHelper
import me.rhunk.snapenhance.util.ktx.getInteger
import me.rhunk.snapenhance.util.ktx.getLongOrNull
import me.rhunk.snapenhance.util.ktx.getStringOrNull
import me.rhunk.snapenhance.core.util.SQLiteDatabaseHelper
import me.rhunk.snapenhance.core.util.ktx.getInteger
import me.rhunk.snapenhance.core.util.ktx.getLongOrNull
import me.rhunk.snapenhance.core.util.ktx.getStringOrNull
import java.util.concurrent.Executors

View File

@ -15,7 +15,7 @@ import me.rhunk.snapenhance.RemoteSideContext
import me.rhunk.snapenhance.SharedContextHolder
import me.rhunk.snapenhance.bridge.ForceStartActivity
import me.rhunk.snapenhance.ui.util.ImageRequestHelper
import me.rhunk.snapenhance.util.snap.BitmojiSelfie
import me.rhunk.snapenhance.core.util.snap.BitmojiSelfie
class StreaksReminder(
private val remoteSideContext: RemoteSideContext? = null

View File

@ -53,8 +53,8 @@ import androidx.compose.ui.window.Dialog
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import me.rhunk.snapenhance.Constants
import me.rhunk.snapenhance.LogChannels
import me.rhunk.snapenhance.LogLevel
import me.rhunk.snapenhance.core.LogChannels
import me.rhunk.snapenhance.core.LogLevel
import me.rhunk.snapenhance.LogReader
import me.rhunk.snapenhance.RemoteSideContext
import me.rhunk.snapenhance.action.EnumAction

View File

@ -47,7 +47,7 @@ import me.rhunk.snapenhance.RemoteSideContext
import me.rhunk.snapenhance.core.bridge.BridgeClient
import me.rhunk.snapenhance.core.messaging.MessagingFriendInfo
import me.rhunk.snapenhance.core.messaging.MessagingGroupInfo
import me.rhunk.snapenhance.util.snap.SnapWidgetBroadcastReceiverHelper
import me.rhunk.snapenhance.core.util.snap.SnapWidgetBroadcastReceiverHelper
class AddFriendDialog(
private val context: RemoteSideContext,

View File

@ -31,7 +31,7 @@ import me.rhunk.snapenhance.RemoteSideContext
import me.rhunk.snapenhance.core.messaging.MessagingRuleType
import me.rhunk.snapenhance.core.messaging.SocialScope
import me.rhunk.snapenhance.ui.util.BitmojiImage
import me.rhunk.snapenhance.util.snap.BitmojiSelfie
import me.rhunk.snapenhance.core.util.snap.BitmojiSelfie
class ScopeContent(
private val context: RemoteSideContext,

View File

@ -57,7 +57,7 @@ import me.rhunk.snapenhance.ui.manager.Section
import me.rhunk.snapenhance.ui.util.AlertDialogs
import me.rhunk.snapenhance.ui.util.BitmojiImage
import me.rhunk.snapenhance.ui.util.pagerTabIndicatorOffset
import me.rhunk.snapenhance.util.snap.BitmojiSelfie
import me.rhunk.snapenhance.core.util.snap.BitmojiSelfie
class SocialSection : Section() {
private lateinit var friendList: List<MessagingFriendInfo>

View File

@ -1,14 +1,10 @@
package me.rhunk.snapenhance.ui.setup.screens.impl
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Button
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
@ -21,7 +17,6 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import me.rhunk.snapenhance.Logger
import me.rhunk.snapenhance.ui.setup.screens.SetupScreen
import me.rhunk.snapenhance.ui.util.AlertDialogs

View File

@ -4,7 +4,7 @@ import android.content.Intent
import androidx.activity.ComponentActivity
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import me.rhunk.snapenhance.Logger
import me.rhunk.snapenhance.core.Logger
typealias ActivityLauncherCallback = (resultCode: Int, intent: Intent?) -> Unit

View File

@ -9,15 +9,15 @@ import me.rhunk.snapenhance.core.eventbus.events.impl.NetworkApiRequestEvent
import me.rhunk.snapenhance.core.eventbus.events.impl.OnSnapInteractionEvent
import me.rhunk.snapenhance.core.eventbus.events.impl.SendMessageWithContentEvent
import me.rhunk.snapenhance.core.eventbus.events.impl.SnapWidgetBroadcastReceiveEvent
import me.rhunk.snapenhance.core.util.ktx.getObjectField
import me.rhunk.snapenhance.core.util.ktx.setObjectField
import me.rhunk.snapenhance.core.util.snap.SnapWidgetBroadcastReceiverHelper
import me.rhunk.snapenhance.data.wrapper.impl.MessageContent
import me.rhunk.snapenhance.data.wrapper.impl.MessageDestinations
import me.rhunk.snapenhance.data.wrapper.impl.SnapUUID
import me.rhunk.snapenhance.hook.HookStage
import me.rhunk.snapenhance.hook.hook
import me.rhunk.snapenhance.manager.Manager
import me.rhunk.snapenhance.util.ktx.getObjectField
import me.rhunk.snapenhance.util.ktx.setObjectField
import me.rhunk.snapenhance.util.snap.SnapWidgetBroadcastReceiverHelper
class EventDispatcher(
private val context: ModContext

View File

@ -11,19 +11,20 @@ import android.widget.Toast
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import kotlinx.coroutines.asCoroutineDispatcher
import me.rhunk.snapenhance.core.Logger
import me.rhunk.snapenhance.core.bridge.BridgeClient
import me.rhunk.snapenhance.core.bridge.wrapper.LocaleWrapper
import me.rhunk.snapenhance.core.bridge.wrapper.MappingsWrapper
import me.rhunk.snapenhance.core.config.ModConfig
import me.rhunk.snapenhance.core.database.DatabaseAccess
import me.rhunk.snapenhance.core.eventbus.EventBus
import me.rhunk.snapenhance.core.util.download.HttpServer
import me.rhunk.snapenhance.data.MessageSender
import me.rhunk.snapenhance.features.Feature
import me.rhunk.snapenhance.manager.impl.ActionManager
import me.rhunk.snapenhance.manager.impl.FeatureManager
import me.rhunk.snapenhance.nativelib.NativeConfig
import me.rhunk.snapenhance.nativelib.NativeLib
import me.rhunk.snapenhance.util.download.HttpServer
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
import kotlin.reflect.KClass

View File

@ -8,16 +8,17 @@ import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
import me.rhunk.snapenhance.bridge.SyncCallback
import me.rhunk.snapenhance.core.BuildConfig
import me.rhunk.snapenhance.core.Logger
import me.rhunk.snapenhance.core.bridge.BridgeClient
import me.rhunk.snapenhance.core.eventbus.events.impl.SnapWidgetBroadcastReceiveEvent
import me.rhunk.snapenhance.core.eventbus.events.impl.UnaryCallEvent
import me.rhunk.snapenhance.core.messaging.MessagingFriendInfo
import me.rhunk.snapenhance.core.messaging.MessagingGroupInfo
import me.rhunk.snapenhance.core.util.ktx.getApplicationInfoCompat
import me.rhunk.snapenhance.data.SnapClassCache
import me.rhunk.snapenhance.hook.HookStage
import me.rhunk.snapenhance.hook.Hooker
import me.rhunk.snapenhance.hook.hook
import me.rhunk.snapenhance.util.ktx.getApplicationInfoCompat
import kotlin.time.ExperimentalTime
import kotlin.time.measureTime

View File

@ -11,17 +11,17 @@ import kotlinx.coroutines.Job
import kotlinx.coroutines.joinAll
import kotlinx.coroutines.launch
import kotlinx.coroutines.suspendCancellableCoroutine
import me.rhunk.snapenhance.Logger
import me.rhunk.snapenhance.action.AbstractAction
import me.rhunk.snapenhance.core.Logger
import me.rhunk.snapenhance.core.database.objects.FriendFeedEntry
import me.rhunk.snapenhance.core.util.CallbackBuilder
import me.rhunk.snapenhance.core.util.export.ExportFormat
import me.rhunk.snapenhance.core.util.export.MessageExporter
import me.rhunk.snapenhance.data.ContentType
import me.rhunk.snapenhance.data.wrapper.impl.Message
import me.rhunk.snapenhance.data.wrapper.impl.SnapUUID
import me.rhunk.snapenhance.features.impl.Messaging
import me.rhunk.snapenhance.ui.ViewAppearanceHelper
import me.rhunk.snapenhance.util.CallbackBuilder
import me.rhunk.snapenhance.util.export.ExportFormat
import me.rhunk.snapenhance.util.export.MessageExporter
import java.io.File
import kotlin.math.absoluteValue

View File

@ -1,4 +1,4 @@
package me.rhunk.snapenhance
package me.rhunk.snapenhance.core
import android.annotation.SuppressLint
import android.util.Log

View File

@ -3,7 +3,7 @@ package me.rhunk.snapenhance.core.bridge.wrapper
import android.content.Context
import com.google.gson.JsonObject
import com.google.gson.JsonParser
import me.rhunk.snapenhance.Logger
import me.rhunk.snapenhance.core.Logger
import me.rhunk.snapenhance.core.bridge.BridgeClient
import me.rhunk.snapenhance.data.LocalePair
import java.util.Locale

View File

@ -5,7 +5,7 @@ import com.google.gson.GsonBuilder
import com.google.gson.JsonElement
import com.google.gson.JsonParser
import me.rhunk.snapenhance.Constants
import me.rhunk.snapenhance.Logger
import me.rhunk.snapenhance.core.Logger
import me.rhunk.snapenhance.core.bridge.FileLoaderWrapper
import me.rhunk.snapenhance.core.bridge.types.BridgeFileType
import me.rhunk.snapmapper.Mapper

View File

@ -2,7 +2,7 @@ package me.rhunk.snapenhance.core.bridge.wrapper
import android.content.ContentValues
import android.database.sqlite.SQLiteDatabase
import me.rhunk.snapenhance.util.SQLiteDatabaseHelper
import me.rhunk.snapenhance.core.util.SQLiteDatabaseHelper
import java.io.File
class MessageLoggerWrapper(

View File

@ -2,8 +2,8 @@ package me.rhunk.snapenhance.core.database
import android.annotation.SuppressLint
import android.database.sqlite.SQLiteDatabase
import me.rhunk.snapenhance.Logger
import me.rhunk.snapenhance.ModContext
import me.rhunk.snapenhance.core.Logger
import me.rhunk.snapenhance.core.database.objects.ConversationMessage
import me.rhunk.snapenhance.core.database.objects.FriendFeedEntry
import me.rhunk.snapenhance.core.database.objects.FriendInfo

View File

@ -4,12 +4,12 @@ import android.annotation.SuppressLint
import android.database.Cursor
import me.rhunk.snapenhance.Constants
import me.rhunk.snapenhance.core.database.DatabaseObject
import me.rhunk.snapenhance.core.util.ktx.getBlobOrNull
import me.rhunk.snapenhance.core.util.ktx.getInteger
import me.rhunk.snapenhance.core.util.ktx.getLong
import me.rhunk.snapenhance.core.util.ktx.getStringOrNull
import me.rhunk.snapenhance.core.util.protobuf.ProtoReader
import me.rhunk.snapenhance.data.ContentType
import me.rhunk.snapenhance.util.ktx.getBlobOrNull
import me.rhunk.snapenhance.util.ktx.getInteger
import me.rhunk.snapenhance.util.ktx.getLong
import me.rhunk.snapenhance.util.ktx.getStringOrNull
import me.rhunk.snapenhance.util.protobuf.ProtoReader
@Suppress("ArrayInDataClass")
data class ConversationMessage(

View File

@ -3,10 +3,10 @@ package me.rhunk.snapenhance.core.database.objects
import android.annotation.SuppressLint
import android.database.Cursor
import me.rhunk.snapenhance.core.database.DatabaseObject
import me.rhunk.snapenhance.util.ktx.getIntOrNull
import me.rhunk.snapenhance.util.ktx.getInteger
import me.rhunk.snapenhance.util.ktx.getLong
import me.rhunk.snapenhance.util.ktx.getStringOrNull
import me.rhunk.snapenhance.core.util.ktx.getIntOrNull
import me.rhunk.snapenhance.core.util.ktx.getInteger
import me.rhunk.snapenhance.core.util.ktx.getLong
import me.rhunk.snapenhance.core.util.ktx.getStringOrNull
data class FriendFeedEntry(
var id: Int = 0,

View File

@ -3,10 +3,10 @@ package me.rhunk.snapenhance.core.database.objects
import android.annotation.SuppressLint
import android.database.Cursor
import me.rhunk.snapenhance.core.database.DatabaseObject
import me.rhunk.snapenhance.util.SerializableDataObject
import me.rhunk.snapenhance.util.ktx.getInteger
import me.rhunk.snapenhance.util.ktx.getLong
import me.rhunk.snapenhance.util.ktx.getStringOrNull
import me.rhunk.snapenhance.core.util.SerializableDataObject
import me.rhunk.snapenhance.core.util.ktx.getInteger
import me.rhunk.snapenhance.core.util.ktx.getLong
import me.rhunk.snapenhance.core.util.ktx.getStringOrNull
data class FriendInfo(
var id: Int = 0,

View File

@ -3,8 +3,8 @@ package me.rhunk.snapenhance.core.database.objects
import android.annotation.SuppressLint
import android.database.Cursor
import me.rhunk.snapenhance.core.database.DatabaseObject
import me.rhunk.snapenhance.util.ktx.getInteger
import me.rhunk.snapenhance.util.ktx.getStringOrNull
import me.rhunk.snapenhance.core.util.ktx.getInteger
import me.rhunk.snapenhance.core.util.ktx.getStringOrNull
data class StoryEntry(
var id: Int = 0,

View File

@ -3,8 +3,8 @@ package me.rhunk.snapenhance.core.database.objects
import android.annotation.SuppressLint
import android.database.Cursor
import me.rhunk.snapenhance.core.database.DatabaseObject
import me.rhunk.snapenhance.util.ktx.getInteger
import me.rhunk.snapenhance.util.ktx.getStringOrNull
import me.rhunk.snapenhance.core.util.ktx.getInteger
import me.rhunk.snapenhance.core.util.ktx.getStringOrNull
class UserConversationLink(
var userId: String? = null,

View File

@ -1,6 +1,6 @@
package me.rhunk.snapenhance.core.messaging
import me.rhunk.snapenhance.util.SerializableDataObject
import me.rhunk.snapenhance.core.util.SerializableDataObject
enum class RuleState(

View File

@ -1,4 +1,4 @@
package me.rhunk.snapenhance.util
package me.rhunk.snapenhance.core.util
import de.robv.android.xposed.XC_MethodHook
import me.rhunk.snapenhance.hook.HookAdapter

View File

@ -1,4 +1,4 @@
package me.rhunk.snapenhance.util
package me.rhunk.snapenhance.core.util
import java.lang.reflect.Field
import java.lang.reflect.Method

View File

@ -1,8 +1,8 @@
package me.rhunk.snapenhance.util
package me.rhunk.snapenhance.core.util
import android.annotation.SuppressLint
import android.database.sqlite.SQLiteDatabase
import me.rhunk.snapenhance.Logger
import me.rhunk.snapenhance.core.Logger
object SQLiteDatabaseHelper {
@SuppressLint("Range")

View File

@ -1,4 +1,4 @@
package me.rhunk.snapenhance.util
package me.rhunk.snapenhance.core.util
import com.google.gson.Gson
import com.google.gson.GsonBuilder

View File

@ -1,11 +1,11 @@
package me.rhunk.snapenhance.util.download
package me.rhunk.snapenhance.core.util.download
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import me.rhunk.snapenhance.Logger
import me.rhunk.snapenhance.core.Logger
import java.io.BufferedReader
import java.io.InputStream
import java.io.InputStreamReader

View File

@ -1,7 +1,7 @@
package me.rhunk.snapenhance.util.download
package me.rhunk.snapenhance.core.util.download
import me.rhunk.snapenhance.Constants
import me.rhunk.snapenhance.Logger
import me.rhunk.snapenhance.core.Logger
import okhttp3.OkHttpClient
import okhttp3.Request
import java.io.ByteArrayInputStream

View File

@ -1,4 +1,4 @@
package me.rhunk.snapenhance.util.export
package me.rhunk.snapenhance.core.util.export
import android.os.Environment
import android.util.Base64InputStream
@ -11,14 +11,14 @@ import me.rhunk.snapenhance.ModContext
import me.rhunk.snapenhance.core.BuildConfig
import me.rhunk.snapenhance.core.database.objects.FriendFeedEntry
import me.rhunk.snapenhance.core.database.objects.FriendInfo
import me.rhunk.snapenhance.core.util.protobuf.ProtoReader
import me.rhunk.snapenhance.core.util.snap.EncryptionHelper
import me.rhunk.snapenhance.core.util.snap.MediaDownloaderHelper
import me.rhunk.snapenhance.data.ContentType
import me.rhunk.snapenhance.data.FileType
import me.rhunk.snapenhance.data.MediaReferenceType
import me.rhunk.snapenhance.data.wrapper.impl.Message
import me.rhunk.snapenhance.data.wrapper.impl.SnapUUID
import me.rhunk.snapenhance.util.protobuf.ProtoReader
import me.rhunk.snapenhance.util.snap.EncryptionHelper
import me.rhunk.snapenhance.util.snap.MediaDownloaderHelper
import java.io.File
import java.io.FileOutputStream
import java.io.InputStream

View File

@ -1,4 +1,4 @@
package me.rhunk.snapenhance.util.ktx
package me.rhunk.snapenhance.core.util.ktx
import android.content.pm.PackageManager
import android.content.pm.PackageManager.ApplicationInfoFlags

View File

@ -1,4 +1,4 @@
package me.rhunk.snapenhance.util.ktx
package me.rhunk.snapenhance.core.util.ktx
import android.database.Cursor

View File

@ -1,4 +1,4 @@
package me.rhunk.snapenhance.util.ktx
package me.rhunk.snapenhance.core.util.ktx
import de.robv.android.xposed.XposedHelpers

View File

@ -1,4 +1,4 @@
package me.rhunk.snapenhance.util.protobuf
package me.rhunk.snapenhance.core.util.protobuf
typealias WireCallback = EditorContext.() -> Unit

View File

@ -1,4 +1,4 @@
package me.rhunk.snapenhance.util.protobuf
package me.rhunk.snapenhance.core.util.protobuf
data class Wire(val id: Int, val type: WireType, val value: Any)

View File

@ -1,4 +1,4 @@
package me.rhunk.snapenhance.util.protobuf
package me.rhunk.snapenhance.core.util.protobuf
import java.io.ByteArrayOutputStream

View File

@ -1,4 +1,4 @@
package me.rhunk.snapenhance.util.protobuf;
package me.rhunk.snapenhance.core.util.protobuf;
enum class WireType(val value: Int) {
VARINT(0),

View File

@ -1,4 +1,4 @@
package me.rhunk.snapenhance.util.snap
package me.rhunk.snapenhance.core.util.snap
object BitmojiSelfie {
enum class BitmojiSelfieType(

View File

@ -1,8 +1,8 @@
package me.rhunk.snapenhance.util.snap
package me.rhunk.snapenhance.core.util.snap
import me.rhunk.snapenhance.Constants
import me.rhunk.snapenhance.core.util.protobuf.ProtoReader
import me.rhunk.snapenhance.data.ContentType
import me.rhunk.snapenhance.util.protobuf.ProtoReader
import java.io.InputStream
import java.util.Base64
import javax.crypto.Cipher
@ -12,7 +12,11 @@ import javax.crypto.spec.SecretKeySpec
object EncryptionHelper {
fun getEncryptionKeys(contentType: ContentType, messageProto: ProtoReader, isArroyo: Boolean): Pair<ByteArray, ByteArray>? {
val mediaEncryptionInfo = MediaDownloaderHelper.getMessageMediaEncryptionInfo(messageProto, contentType, isArroyo) ?: return null
val mediaEncryptionInfo = MediaDownloaderHelper.getMessageMediaEncryptionInfo(
messageProto,
contentType,
isArroyo
) ?: return null
val encryptionProtoIndex = if (mediaEncryptionInfo.contains(Constants.ENCRYPTION_PROTO_INDEX_V2)) {
Constants.ENCRYPTION_PROTO_INDEX_V2
} else {

View File

@ -1,11 +1,11 @@
package me.rhunk.snapenhance.util.snap
package me.rhunk.snapenhance.core.util.snap
import me.rhunk.snapenhance.Constants
import me.rhunk.snapenhance.core.download.data.SplitMediaAssetType
import me.rhunk.snapenhance.core.util.download.RemoteMediaResolver
import me.rhunk.snapenhance.core.util.protobuf.ProtoReader
import me.rhunk.snapenhance.data.ContentType
import me.rhunk.snapenhance.data.FileType
import me.rhunk.snapenhance.util.download.RemoteMediaResolver
import me.rhunk.snapenhance.util.protobuf.ProtoReader
import java.io.ByteArrayInputStream
import java.io.FileNotFoundException
import java.io.InputStream

View File

@ -1,4 +1,4 @@
package me.rhunk.snapenhance.util.snap
package me.rhunk.snapenhance.core.util.snap
import android.graphics.Bitmap
import android.graphics.BitmapFactory

View File

@ -1,4 +1,4 @@
package me.rhunk.snapenhance.util.snap
package me.rhunk.snapenhance.core.util.snap
import android.content.Intent
import me.rhunk.snapenhance.Constants

View File

@ -1,6 +1,6 @@
package me.rhunk.snapenhance.data
import me.rhunk.snapenhance.Logger
import me.rhunk.snapenhance.core.Logger
import java.io.File
import java.io.InputStream

View File

@ -1,12 +1,12 @@
package me.rhunk.snapenhance.data
import me.rhunk.snapenhance.ModContext
import me.rhunk.snapenhance.core.util.CallbackBuilder
import me.rhunk.snapenhance.core.util.protobuf.ProtoWriter
import me.rhunk.snapenhance.data.wrapper.AbstractWrapper
import me.rhunk.snapenhance.data.wrapper.impl.MessageDestinations
import me.rhunk.snapenhance.data.wrapper.impl.SnapUUID
import me.rhunk.snapenhance.features.impl.Messaging
import me.rhunk.snapenhance.util.CallbackBuilder
import me.rhunk.snapenhance.util.protobuf.ProtoWriter
class MessageSender(
private val context: ModContext,

View File

@ -1,7 +1,7 @@
package me.rhunk.snapenhance.data.wrapper
import de.robv.android.xposed.XposedHelpers
import me.rhunk.snapenhance.util.CallbackBuilder
import me.rhunk.snapenhance.core.util.CallbackBuilder
import kotlin.reflect.KProperty
abstract class AbstractWrapper(

View File

@ -1,8 +1,8 @@
package me.rhunk.snapenhance.data.wrapper.impl
import me.rhunk.snapenhance.core.util.ktx.getObjectField
import me.rhunk.snapenhance.data.MessageState
import me.rhunk.snapenhance.data.wrapper.AbstractWrapper
import me.rhunk.snapenhance.util.ktx.getObjectField
class Message(obj: Any?) : AbstractWrapper(obj) {
val orderKey get() = instanceNonNull().getObjectField("mOrderKey") as Long

View File

@ -1,9 +1,9 @@
package me.rhunk.snapenhance.data.wrapper.impl
import me.rhunk.snapenhance.core.util.ktx.getObjectField
import me.rhunk.snapenhance.core.util.ktx.setObjectField
import me.rhunk.snapenhance.data.ContentType
import me.rhunk.snapenhance.data.wrapper.AbstractWrapper
import me.rhunk.snapenhance.util.ktx.getObjectField
import me.rhunk.snapenhance.util.ktx.setObjectField
class MessageContent(obj: Any?) : AbstractWrapper(obj) {
var content

View File

@ -1,7 +1,7 @@
package me.rhunk.snapenhance.data.wrapper.impl
import me.rhunk.snapenhance.core.util.ktx.getObjectField
import me.rhunk.snapenhance.data.wrapper.AbstractWrapper
import me.rhunk.snapenhance.util.ktx.getObjectField
class MessageDescriptor(obj: Any?) : AbstractWrapper(obj) {
val messageId: Long get() = instanceNonNull().getObjectField("mMessageId") as Long

View File

@ -1,8 +1,8 @@
package me.rhunk.snapenhance.data.wrapper.impl
import me.rhunk.snapenhance.core.util.ktx.getObjectField
import me.rhunk.snapenhance.core.util.ktx.setObjectField
import me.rhunk.snapenhance.data.wrapper.AbstractWrapper
import me.rhunk.snapenhance.util.ktx.getObjectField
import me.rhunk.snapenhance.util.ktx.setObjectField
@Suppress("UNCHECKED_CAST")
class MessageDestinations(obj: Any) : AbstractWrapper(obj){

View File

@ -1,8 +1,8 @@
package me.rhunk.snapenhance.data.wrapper.impl
import me.rhunk.snapenhance.core.util.ktx.getObjectField
import me.rhunk.snapenhance.data.PlayableSnapState
import me.rhunk.snapenhance.data.wrapper.AbstractWrapper
import me.rhunk.snapenhance.util.ktx.getObjectField
class MessageMetadata(obj: Any?) : AbstractWrapper(obj){
val createdAt: Long get() = instanceNonNull().getObjectField("mCreatedAt") as Long

View File

@ -1,8 +1,8 @@
package me.rhunk.snapenhance.data.wrapper.impl
import me.rhunk.snapenhance.SnapEnhance
import me.rhunk.snapenhance.core.util.ktx.getObjectField
import me.rhunk.snapenhance.data.wrapper.AbstractWrapper
import me.rhunk.snapenhance.util.ktx.getObjectField
import java.nio.ByteBuffer
import java.util.UUID

View File

@ -1,7 +1,7 @@
package me.rhunk.snapenhance.data.wrapper.impl
import me.rhunk.snapenhance.core.util.ktx.getObjectField
import me.rhunk.snapenhance.data.wrapper.AbstractWrapper
import me.rhunk.snapenhance.util.ktx.getObjectField
class UserIdToReaction(obj: Any?) : AbstractWrapper(obj) {
val userId = SnapUUID(instanceNonNull().getObjectField("mUserId"))

View File

@ -1,8 +1,8 @@
package me.rhunk.snapenhance.data.wrapper.impl.media
import android.os.Parcelable
import me.rhunk.snapenhance.core.util.ktx.getObjectField
import me.rhunk.snapenhance.data.wrapper.AbstractWrapper
import me.rhunk.snapenhance.util.ktx.getObjectField
import java.lang.reflect.Field

View File

@ -1,7 +1,7 @@
package me.rhunk.snapenhance.data.wrapper.impl.media.opera
import me.rhunk.snapenhance.core.util.ReflectionHelper
import me.rhunk.snapenhance.data.wrapper.AbstractWrapper
import me.rhunk.snapenhance.util.ReflectionHelper
class Layer(obj: Any?) : AbstractWrapper(obj) {
val paramMap: ParamMap

View File

@ -1,8 +1,8 @@
package me.rhunk.snapenhance.data.wrapper.impl.media.opera
import de.robv.android.xposed.XposedHelpers
import me.rhunk.snapenhance.core.util.ReflectionHelper
import me.rhunk.snapenhance.data.wrapper.AbstractWrapper
import me.rhunk.snapenhance.util.ReflectionHelper
import java.lang.reflect.Field
import java.util.concurrent.ConcurrentHashMap

View File

@ -1,8 +1,8 @@
package me.rhunk.snapenhance.data.wrapper.impl.media.opera
import me.rhunk.snapenhance.core.util.ReflectionHelper
import me.rhunk.snapenhance.core.util.ktx.getObjectField
import me.rhunk.snapenhance.data.wrapper.AbstractWrapper
import me.rhunk.snapenhance.util.ReflectionHelper
import me.rhunk.snapenhance.util.ktx.getObjectField
import java.lang.reflect.Field
import java.util.concurrent.ConcurrentHashMap

View File

@ -1,11 +1,11 @@
package me.rhunk.snapenhance.features.impl
import de.robv.android.xposed.XposedHelpers
import me.rhunk.snapenhance.core.util.ktx.setObjectField
import me.rhunk.snapenhance.features.Feature
import me.rhunk.snapenhance.features.FeatureLoadParams
import me.rhunk.snapenhance.hook.HookStage
import me.rhunk.snapenhance.hook.hook
import me.rhunk.snapenhance.util.ktx.setObjectField
class ConfigurationOverride : Feature("Configuration Override", loadParams = FeatureLoadParams.INIT_SYNC) {
override fun init() {

View File

@ -1,6 +1,7 @@
package me.rhunk.snapenhance.features.impl
import me.rhunk.snapenhance.core.eventbus.events.impl.OnSnapInteractionEvent
import me.rhunk.snapenhance.core.util.ktx.getObjectField
import me.rhunk.snapenhance.data.wrapper.impl.SnapUUID
import me.rhunk.snapenhance.features.Feature
import me.rhunk.snapenhance.features.FeatureLoadParams
@ -8,7 +9,6 @@ import me.rhunk.snapenhance.features.impl.spying.StealthMode
import me.rhunk.snapenhance.hook.HookStage
import me.rhunk.snapenhance.hook.Hooker
import me.rhunk.snapenhance.hook.hook
import me.rhunk.snapenhance.util.ktx.getObjectField
class Messaging : Feature("Messaging", loadParams = FeatureLoadParams.ACTIVITY_CREATE_SYNC or FeatureLoadParams.INIT_ASYNC or FeatureLoadParams.INIT_SYNC) {
lateinit var conversationManager: Any

View File

@ -16,6 +16,13 @@ import me.rhunk.snapenhance.core.download.data.MediaDownloadSource
import me.rhunk.snapenhance.core.download.data.SplitMediaAssetType
import me.rhunk.snapenhance.core.download.data.toKeyPair
import me.rhunk.snapenhance.core.messaging.MessagingRuleType
import me.rhunk.snapenhance.core.util.download.RemoteMediaResolver
import me.rhunk.snapenhance.core.util.ktx.getObjectField
import me.rhunk.snapenhance.core.util.protobuf.ProtoReader
import me.rhunk.snapenhance.core.util.snap.BitmojiSelfie
import me.rhunk.snapenhance.core.util.snap.EncryptionHelper
import me.rhunk.snapenhance.core.util.snap.MediaDownloaderHelper
import me.rhunk.snapenhance.core.util.snap.PreviewUtils
import me.rhunk.snapenhance.data.ContentType
import me.rhunk.snapenhance.data.FileType
import me.rhunk.snapenhance.data.wrapper.impl.media.MediaInfo
@ -31,13 +38,6 @@ import me.rhunk.snapenhance.hook.HookAdapter
import me.rhunk.snapenhance.hook.HookStage
import me.rhunk.snapenhance.hook.Hooker
import me.rhunk.snapenhance.ui.ViewAppearanceHelper
import me.rhunk.snapenhance.util.download.RemoteMediaResolver
import me.rhunk.snapenhance.util.ktx.getObjectField
import me.rhunk.snapenhance.util.protobuf.ProtoReader
import me.rhunk.snapenhance.util.snap.BitmojiSelfie
import me.rhunk.snapenhance.util.snap.EncryptionHelper
import me.rhunk.snapenhance.util.snap.MediaDownloaderHelper
import me.rhunk.snapenhance.util.snap.PreviewUtils
import java.nio.file.Paths
import java.text.SimpleDateFormat
import java.util.Locale

View File

@ -5,12 +5,12 @@ import android.widget.Button
import android.widget.RelativeLayout
import me.rhunk.snapenhance.core.eventbus.events.impl.AddViewEvent
import me.rhunk.snapenhance.core.eventbus.events.impl.NetworkApiRequestEvent
import me.rhunk.snapenhance.core.util.protobuf.ProtoReader
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.ui.ViewAppearanceHelper
import me.rhunk.snapenhance.util.protobuf.ProtoReader
import java.nio.ByteBuffer
class ProfilePictureDownloader : Feature("ProfilePictureDownloader", loadParams = FeatureLoadParams.ACTIVITY_CREATE_ASYNC) {

View File

@ -1,10 +1,10 @@
package me.rhunk.snapenhance.features.impl.experiments
import me.rhunk.snapenhance.core.util.ktx.setObjectField
import me.rhunk.snapenhance.features.Feature
import me.rhunk.snapenhance.features.FeatureLoadParams
import me.rhunk.snapenhance.hook.HookStage
import me.rhunk.snapenhance.hook.hookConstructor
import me.rhunk.snapenhance.util.ktx.setObjectField
class UnlimitedMultiSnap : Feature("UnlimitedMultiSnap", loadParams = FeatureLoadParams.ACTIVITY_CREATE_ASYNC) {
override fun asyncOnActivityCreate() {

View File

@ -2,9 +2,9 @@ package me.rhunk.snapenhance.features.impl.spying
import kotlinx.coroutines.runBlocking
import me.rhunk.snapenhance.core.eventbus.events.impl.NetworkApiRequestEvent
import me.rhunk.snapenhance.core.util.download.HttpServer
import me.rhunk.snapenhance.features.Feature
import me.rhunk.snapenhance.features.FeatureLoadParams
import me.rhunk.snapenhance.util.download.HttpServer
import kotlin.coroutines.suspendCoroutine
class AnonymousStoryViewing : Feature("Anonymous Story Viewing", loadParams = FeatureLoadParams.ACTIVITY_CREATE_ASYNC) {

View File

@ -1,7 +1,9 @@
package me.rhunk.snapenhance.features.impl.tweaks
import me.rhunk.snapenhance.Logger
import me.rhunk.snapenhance.core.Logger
import me.rhunk.snapenhance.core.messaging.MessagingRuleType
import me.rhunk.snapenhance.core.util.CallbackBuilder
import me.rhunk.snapenhance.core.util.ktx.getObjectField
import me.rhunk.snapenhance.data.MessageState
import me.rhunk.snapenhance.data.wrapper.impl.Message
import me.rhunk.snapenhance.data.wrapper.impl.SnapUUID
@ -12,8 +14,6 @@ import me.rhunk.snapenhance.features.impl.spying.MessageLogger
import me.rhunk.snapenhance.features.impl.spying.StealthMode
import me.rhunk.snapenhance.hook.HookStage
import me.rhunk.snapenhance.hook.Hooker
import me.rhunk.snapenhance.util.CallbackBuilder
import me.rhunk.snapenhance.util.ktx.getObjectField
import java.util.concurrent.Executors
class AutoSave : MessagingRuleFeature("Auto Save", MessagingRuleType.AUTO_SAVE, loadParams = FeatureLoadParams.ACTIVITY_CREATE_ASYNC) {

View File

@ -8,13 +8,13 @@ import android.hardware.camera2.CameraCharacteristics
import android.hardware.camera2.CameraCharacteristics.Key
import android.hardware.camera2.CameraManager
import android.util.Range
import me.rhunk.snapenhance.core.util.ktx.setObjectField
import me.rhunk.snapenhance.data.wrapper.impl.ScSize
import me.rhunk.snapenhance.features.Feature
import me.rhunk.snapenhance.features.FeatureLoadParams
import me.rhunk.snapenhance.hook.HookStage
import me.rhunk.snapenhance.hook.hook
import me.rhunk.snapenhance.hook.hookConstructor
import me.rhunk.snapenhance.util.ktx.setObjectField
class CameraTweaks : Feature("Camera Tweaks", loadParams = FeatureLoadParams.ACTIVITY_CREATE_SYNC) {
companion object {

View File

@ -1,11 +1,11 @@
package me.rhunk.snapenhance.features.impl.tweaks
import me.rhunk.snapenhance.core.util.ktx.getObjectField
import me.rhunk.snapenhance.core.util.ktx.setEnumField
import me.rhunk.snapenhance.features.Feature
import me.rhunk.snapenhance.features.FeatureLoadParams
import me.rhunk.snapenhance.hook.HookStage
import me.rhunk.snapenhance.hook.hookConstructor
import me.rhunk.snapenhance.util.ktx.getObjectField
import me.rhunk.snapenhance.util.ktx.setEnumField
class DisableReplayInFF : Feature("DisableReplayInFF", loadParams = FeatureLoadParams.ACTIVITY_CREATE_ASYNC) {
override fun asyncOnActivityCreate() {

View File

@ -12,9 +12,16 @@ import android.os.Bundle
import android.os.UserHandle
import de.robv.android.xposed.XposedBridge
import de.robv.android.xposed.XposedHelpers
import me.rhunk.snapenhance.Logger
import me.rhunk.snapenhance.core.Logger
import me.rhunk.snapenhance.core.download.data.SplitMediaAssetType
import me.rhunk.snapenhance.core.eventbus.events.impl.SnapWidgetBroadcastReceiveEvent
import me.rhunk.snapenhance.core.util.CallbackBuilder
import me.rhunk.snapenhance.core.util.ktx.setObjectField
import me.rhunk.snapenhance.core.util.protobuf.ProtoReader
import me.rhunk.snapenhance.core.util.snap.EncryptionHelper
import me.rhunk.snapenhance.core.util.snap.MediaDownloaderHelper
import me.rhunk.snapenhance.core.util.snap.PreviewUtils
import me.rhunk.snapenhance.core.util.snap.SnapWidgetBroadcastReceiverHelper
import me.rhunk.snapenhance.data.ContentType
import me.rhunk.snapenhance.data.MediaReferenceType
import me.rhunk.snapenhance.data.wrapper.impl.Message
@ -26,13 +33,6 @@ import me.rhunk.snapenhance.features.impl.downloader.MediaDownloader
import me.rhunk.snapenhance.hook.HookStage
import me.rhunk.snapenhance.hook.Hooker
import me.rhunk.snapenhance.hook.hook
import me.rhunk.snapenhance.util.CallbackBuilder
import me.rhunk.snapenhance.util.ktx.setObjectField
import me.rhunk.snapenhance.util.protobuf.ProtoReader
import me.rhunk.snapenhance.util.snap.EncryptionHelper
import me.rhunk.snapenhance.util.snap.MediaDownloaderHelper
import me.rhunk.snapenhance.util.snap.PreviewUtils
import me.rhunk.snapenhance.util.snap.SnapWidgetBroadcastReceiverHelper
class Notifications : Feature("Notifications", loadParams = FeatureLoadParams.INIT_SYNC) {
companion object{

View File

@ -1,9 +1,9 @@
package me.rhunk.snapenhance.features.impl.tweaks
import me.rhunk.snapenhance.core.eventbus.events.impl.NetworkApiRequestEvent
import me.rhunk.snapenhance.core.util.snap.BitmojiSelfie
import me.rhunk.snapenhance.features.Feature
import me.rhunk.snapenhance.features.FeatureLoadParams
import me.rhunk.snapenhance.util.snap.BitmojiSelfie
class OldBitmojiSelfie : Feature("OldBitmojiSelfie", loadParams = FeatureLoadParams.INIT_SYNC) {
override fun init() {

View File

@ -3,13 +3,13 @@ package me.rhunk.snapenhance.features.impl.tweaks
import me.rhunk.snapenhance.Constants
import me.rhunk.snapenhance.core.eventbus.events.impl.SendMessageWithContentEvent
import me.rhunk.snapenhance.core.eventbus.events.impl.UnaryCallEvent
import me.rhunk.snapenhance.core.util.protobuf.ProtoEditor
import me.rhunk.snapenhance.core.util.protobuf.ProtoReader
import me.rhunk.snapenhance.data.ContentType
import me.rhunk.snapenhance.data.MessageSender
import me.rhunk.snapenhance.features.Feature
import me.rhunk.snapenhance.features.FeatureLoadParams
import me.rhunk.snapenhance.ui.ViewAppearanceHelper
import me.rhunk.snapenhance.util.protobuf.ProtoEditor
import me.rhunk.snapenhance.util.protobuf.ProtoReader
class SendOverride : Feature("Send Override", loadParams = FeatureLoadParams.INIT_SYNC) {
private var isLastSnapSavable = false

View File

@ -1,20 +1,20 @@
package me.rhunk.snapenhance.features.impl.tweaks
import me.rhunk.snapenhance.core.util.protobuf.ProtoEditor
import me.rhunk.snapenhance.core.util.protobuf.ProtoReader
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
import me.rhunk.snapenhance.util.protobuf.ProtoReader
import me.rhunk.snapenhance.hook.hookConstructor
class UnlimitedSnapViewTime :
Feature("UnlimitedSnapViewTime", loadParams = FeatureLoadParams.ACTIVITY_CREATE_SYNC) {
override fun onActivityCreate() {
val state by context.config.messaging.unlimitedSnapViewTime
Hooker.hookConstructor(context.classCache.message, HookStage.AFTER, { state }) { param ->
context.classCache.message.hookConstructor(HookStage.AFTER, { state }) { param ->
val message = Message(param.thisObject())
if (message.messageState != MessageState.COMMITTED) return@hookConstructor
if (message.messageContent.contentType != ContentType.SNAP) return@hookConstructor

View File

@ -1,14 +1,14 @@
package me.rhunk.snapenhance.features.impl.ui
import me.rhunk.snapenhance.core.bridge.types.BridgeFileType
import me.rhunk.snapenhance.core.util.ktx.getObjectField
import me.rhunk.snapenhance.core.util.ktx.setObjectField
import me.rhunk.snapenhance.data.wrapper.impl.SnapUUID
import me.rhunk.snapenhance.features.BridgeFileFeature
import me.rhunk.snapenhance.features.FeatureLoadParams
import me.rhunk.snapenhance.hook.HookStage
import me.rhunk.snapenhance.hook.hook
import me.rhunk.snapenhance.hook.hookConstructor
import me.rhunk.snapenhance.util.ktx.getObjectField
import me.rhunk.snapenhance.util.ktx.setObjectField
class PinConversations : BridgeFileFeature("PinConversations", BridgeFileType.PINNED_CONVERSATIONS, loadParams = FeatureLoadParams.ACTIVITY_CREATE_SYNC) {
override fun onActivityCreate() {

View File

@ -1,7 +1,7 @@
package me.rhunk.snapenhance.manager.impl
import me.rhunk.snapenhance.Logger
import me.rhunk.snapenhance.ModContext
import me.rhunk.snapenhance.core.Logger
import me.rhunk.snapenhance.features.Feature
import me.rhunk.snapenhance.features.FeatureLoadParams
import me.rhunk.snapenhance.features.impl.ConfigurationOverride
@ -34,8 +34,8 @@ import me.rhunk.snapenhance.features.impl.tweaks.OldBitmojiSelfie
import me.rhunk.snapenhance.features.impl.tweaks.SendOverride
import me.rhunk.snapenhance.features.impl.tweaks.SnapchatPlus
import me.rhunk.snapenhance.features.impl.tweaks.UnlimitedSnapViewTime
import me.rhunk.snapenhance.features.impl.ui.PinConversations
import me.rhunk.snapenhance.features.impl.ui.ClientBootstrapOverride
import me.rhunk.snapenhance.features.impl.ui.PinConversations
import me.rhunk.snapenhance.features.impl.ui.UITweaks
import me.rhunk.snapenhance.manager.Manager
import me.rhunk.snapenhance.ui.menu.impl.MenuViewInjector

View File

@ -14,6 +14,7 @@ import android.widget.Switch
import me.rhunk.snapenhance.core.database.objects.ConversationMessage
import me.rhunk.snapenhance.core.database.objects.FriendInfo
import me.rhunk.snapenhance.core.database.objects.UserConversationLink
import me.rhunk.snapenhance.core.util.snap.BitmojiSelfie
import me.rhunk.snapenhance.data.ContentType
import me.rhunk.snapenhance.features.MessagingRuleFeature
import me.rhunk.snapenhance.features.impl.Messaging
@ -22,7 +23,6 @@ import me.rhunk.snapenhance.features.impl.spying.StealthMode
import me.rhunk.snapenhance.features.impl.tweaks.AutoSave
import me.rhunk.snapenhance.ui.ViewAppearanceHelper
import me.rhunk.snapenhance.ui.menu.AbstractMenu
import me.rhunk.snapenhance.util.snap.BitmojiSelfie
import java.net.HttpURLConnection
import java.net.URL
import java.text.DateFormat