mirror of
https://github.com/rhunk/SnapEnhance.git
synced 2025-05-20 16:17:08 +02:00
feat: add friend source spoof
This commit is contained in:
parent
c791fbbd00
commit
dded6acff0
@ -366,6 +366,10 @@
|
||||
"no_friend_score_delay": {
|
||||
"name": "No Friend Score Delay",
|
||||
"description": "Removes the delay when viewing a friends score"
|
||||
},
|
||||
"add_friend_source_spoof": {
|
||||
"name": "Add Friend Source Spoof",
|
||||
"description": "Spoofs the source of a friend request"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -461,6 +465,13 @@
|
||||
"ngs_community_icon_container": "Community / Stories",
|
||||
"ngs_spotlight_icon_container": "Spotlight",
|
||||
"ngs_search_icon_container": "Search"
|
||||
},
|
||||
"add_friend_source_spoof": {
|
||||
"added_by_username": "By Username",
|
||||
"added_by_mention": "By Mention",
|
||||
"added_by_group_chat": "By Group Chat",
|
||||
"added_by_qr_code": "By QR Code",
|
||||
"added_by_community": "By Community"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -14,6 +14,7 @@ import me.rhunk.snapmapper.impl.CallbackMapper
|
||||
import me.rhunk.snapmapper.impl.CompositeConfigurationProviderMapper
|
||||
import me.rhunk.snapmapper.impl.DefaultMediaItemMapper
|
||||
import me.rhunk.snapmapper.impl.EnumMapper
|
||||
import me.rhunk.snapmapper.impl.FriendRelationshipChangerMapper
|
||||
import me.rhunk.snapmapper.impl.FriendsFeedEventDispatcherMapper
|
||||
import me.rhunk.snapmapper.impl.MediaQualityLevelProviderMapper
|
||||
import me.rhunk.snapmapper.impl.OperaPageViewControllerMapper
|
||||
@ -41,7 +42,8 @@ class MappingsWrapper : FileLoaderWrapper(BridgeFileType.MAPPINGS, "{}".toByteAr
|
||||
StoryBoostStateMapper::class,
|
||||
FriendsFeedEventDispatcherMapper::class,
|
||||
CompositeConfigurationProviderMapper::class,
|
||||
ScoreUpdateMapper::class
|
||||
ScoreUpdateMapper::class,
|
||||
FriendRelationshipChangerMapper::class,
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -12,4 +12,11 @@ class Experimental : ConfigContainer() {
|
||||
val meoPasscodeBypass = boolean("meo_passcode_bypass")
|
||||
val unlimitedMultiSnap = boolean("unlimited_multi_snap") { addNotices(FeatureNotice.MAY_BAN)}
|
||||
val noFriendScoreDelay = boolean("no_friend_score_delay")
|
||||
val addFriendSourceSpoof = unique("add_friend_source_spoof",
|
||||
"added_by_username",
|
||||
"added_by_mention",
|
||||
"added_by_group_chat",
|
||||
"added_by_qr_code",
|
||||
"added_by_community",
|
||||
) { addNotices(FeatureNotice.MAY_BAN) }
|
||||
}
|
@ -49,6 +49,9 @@ class DatabaseAccess(private val context: ModContext) : Manager {
|
||||
query: (SQLiteDatabase) -> T?
|
||||
): T? {
|
||||
synchronized(databaseLock) {
|
||||
if (!database.isOpen) {
|
||||
return null
|
||||
}
|
||||
return runCatching {
|
||||
query(database)
|
||||
}.onFailure {
|
||||
|
@ -3,7 +3,7 @@ package me.rhunk.snapenhance.features
|
||||
import me.rhunk.snapenhance.ModContext
|
||||
|
||||
abstract class Feature(
|
||||
val nameKey: String,
|
||||
val featureKey: String,
|
||||
val loadParams: Int = FeatureLoadParams.INIT_SYNC
|
||||
) {
|
||||
lateinit var context: ModContext
|
||||
|
@ -0,0 +1,55 @@
|
||||
package me.rhunk.snapenhance.features.impl.experiments
|
||||
|
||||
import me.rhunk.snapenhance.features.Feature
|
||||
import me.rhunk.snapenhance.features.FeatureLoadParams
|
||||
import me.rhunk.snapenhance.hook.HookStage
|
||||
import me.rhunk.snapenhance.hook.hook
|
||||
|
||||
class AddFriendSourceSpoof : Feature("AddFriendSourceSpoof", loadParams = FeatureLoadParams.ACTIVITY_CREATE_ASYNC) {
|
||||
override fun asyncOnActivityCreate() {
|
||||
val friendRelationshipChangerMapping = context.mappings.getMappedMap("FriendRelationshipChanger")
|
||||
|
||||
findClass(friendRelationshipChangerMapping["class"].toString())
|
||||
.hook(friendRelationshipChangerMapping["addFriendMethod"].toString(), HookStage.BEFORE) { param ->
|
||||
val spoofedSource = context.config.experimental.addFriendSourceSpoof.getNullable() ?: return@hook
|
||||
|
||||
context.log.verbose("addFriendMethod: ${param.args().toList()}", featureKey)
|
||||
|
||||
fun setEnum(index: Int, value: String) {
|
||||
val enumData = param.arg<Any>(index)
|
||||
enumData::class.java.enumConstants.first { it.toString() == value }.let {
|
||||
param.setArg(index, it)
|
||||
}
|
||||
}
|
||||
|
||||
when (spoofedSource) {
|
||||
"added_by_group_chat" -> {
|
||||
setEnum(1, "PROFILE")
|
||||
setEnum(2, "GROUP_PROFILE")
|
||||
setEnum(3, "ADDED_BY_GROUP_CHAT")
|
||||
}
|
||||
"added_by_username" -> {
|
||||
setEnum(1, "SEARCH")
|
||||
setEnum(2, "SEARCH")
|
||||
setEnum(3, "ADDED_BY_USERNAME")
|
||||
}
|
||||
"added_by_qr_code" -> {
|
||||
setEnum(1, "PROFILE")
|
||||
setEnum(2, "PROFILE")
|
||||
setEnum(3, "ADDED_BY_QR_CODE")
|
||||
}
|
||||
"added_by_mention" -> {
|
||||
setEnum(1, "CONTEXT_CARDS")
|
||||
setEnum(2, "CONTEXT_CARD")
|
||||
setEnum(3, "ADDED_BY_MENTION")
|
||||
}
|
||||
"added_by_community" -> {
|
||||
setEnum(1, "PROFILE")
|
||||
setEnum(2, "PROFILE")
|
||||
setEnum(3, "ADDED_BY_COMMUNITY")
|
||||
}
|
||||
else -> return@hook
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -9,6 +9,7 @@ import me.rhunk.snapenhance.features.impl.ConfigurationOverride
|
||||
import me.rhunk.snapenhance.features.impl.Messaging
|
||||
import me.rhunk.snapenhance.features.impl.downloader.MediaDownloader
|
||||
import me.rhunk.snapenhance.features.impl.downloader.ProfilePictureDownloader
|
||||
import me.rhunk.snapenhance.features.impl.experiments.AddFriendSourceSpoof
|
||||
import me.rhunk.snapenhance.features.impl.experiments.AmoledDarkMode
|
||||
import me.rhunk.snapenhance.features.impl.experiments.AppPasscode
|
||||
import me.rhunk.snapenhance.features.impl.experiments.DeviceSpooferHook
|
||||
@ -93,6 +94,7 @@ class FeatureManager(private val context: ModContext) : Manager {
|
||||
register(GooglePlayServicesDialogs::class)
|
||||
register(NoFriendScoreDelay::class)
|
||||
register(ProfilePictureDownloader::class)
|
||||
register(AddFriendSourceSpoof::class)
|
||||
|
||||
initializeFeatures()
|
||||
}
|
||||
@ -103,8 +105,8 @@ class FeatureManager(private val context: ModContext) : Manager {
|
||||
runCatching {
|
||||
action(feature)
|
||||
}.onFailure {
|
||||
Logger.xposedLog("Failed to init feature ${feature.nameKey}", it)
|
||||
context.longToast("Failed to init feature ${feature.nameKey}")
|
||||
context.log.error("Failed to init feature ${feature.featureKey}", it)
|
||||
context.longToast("Failed to load feature ${feature.featureKey}! Check logcat for more details.")
|
||||
}
|
||||
}
|
||||
if (!isAsync) {
|
||||
|
@ -0,0 +1,27 @@
|
||||
package me.rhunk.snapmapper.impl
|
||||
|
||||
import me.rhunk.snapmapper.AbstractClassMapper
|
||||
import me.rhunk.snapmapper.MapperContext
|
||||
import me.rhunk.snapmapper.ext.findConstString
|
||||
import me.rhunk.snapmapper.ext.getClassName
|
||||
import me.rhunk.snapmapper.ext.isEnum
|
||||
|
||||
class FriendRelationshipChangerMapper : AbstractClassMapper() {
|
||||
override fun run(context: MapperContext) {
|
||||
for (classDef in context.classes) {
|
||||
classDef.methods.firstOrNull { it.name == "<init>" }?.implementation?.findConstString("FriendRelationshipChangerImpl")?.takeIf { it } ?: continue
|
||||
val addFriendMethod = classDef.methods.first {
|
||||
it.parameterTypes.size > 4 &&
|
||||
context.getClass(it.parameterTypes[1])?.isEnum() == true &&
|
||||
context.getClass(it.parameterTypes[2])?.isEnum() == true &&
|
||||
context.getClass(it.parameterTypes[3])?.isEnum() == true &&
|
||||
it.parameters[4].type == "Ljava/lang/String;"
|
||||
}
|
||||
|
||||
context.addMapping("FriendRelationshipChanger",
|
||||
"class" to classDef.getClassName(),
|
||||
"addFriendMethod" to addFriendMethod.name
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
@ -24,6 +24,7 @@ class TestMappings {
|
||||
FriendsFeedEventDispatcherMapper::class,
|
||||
CompositeConfigurationProviderMapper::class,
|
||||
ScoreUpdateMapper::class,
|
||||
FriendRelationshipChangerMapper::class,
|
||||
)
|
||||
|
||||
val gson = GsonBuilder().setPrettyPrinting().create()
|
||||
|
Loading…
x
Reference in New Issue
Block a user