mirror of
https://github.com/rhunk/SnapEnhance.git
synced 2025-05-21 00:27:09 +02:00
feat: add friend source spoof
This commit is contained in:
parent
c791fbbd00
commit
dded6acff0
@ -366,6 +366,10 @@
|
|||||||
"no_friend_score_delay": {
|
"no_friend_score_delay": {
|
||||||
"name": "No Friend Score Delay",
|
"name": "No Friend Score Delay",
|
||||||
"description": "Removes the delay when viewing a friends score"
|
"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_community_icon_container": "Community / Stories",
|
||||||
"ngs_spotlight_icon_container": "Spotlight",
|
"ngs_spotlight_icon_container": "Spotlight",
|
||||||
"ngs_search_icon_container": "Search"
|
"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.CompositeConfigurationProviderMapper
|
||||||
import me.rhunk.snapmapper.impl.DefaultMediaItemMapper
|
import me.rhunk.snapmapper.impl.DefaultMediaItemMapper
|
||||||
import me.rhunk.snapmapper.impl.EnumMapper
|
import me.rhunk.snapmapper.impl.EnumMapper
|
||||||
|
import me.rhunk.snapmapper.impl.FriendRelationshipChangerMapper
|
||||||
import me.rhunk.snapmapper.impl.FriendsFeedEventDispatcherMapper
|
import me.rhunk.snapmapper.impl.FriendsFeedEventDispatcherMapper
|
||||||
import me.rhunk.snapmapper.impl.MediaQualityLevelProviderMapper
|
import me.rhunk.snapmapper.impl.MediaQualityLevelProviderMapper
|
||||||
import me.rhunk.snapmapper.impl.OperaPageViewControllerMapper
|
import me.rhunk.snapmapper.impl.OperaPageViewControllerMapper
|
||||||
@ -41,7 +42,8 @@ class MappingsWrapper : FileLoaderWrapper(BridgeFileType.MAPPINGS, "{}".toByteAr
|
|||||||
StoryBoostStateMapper::class,
|
StoryBoostStateMapper::class,
|
||||||
FriendsFeedEventDispatcherMapper::class,
|
FriendsFeedEventDispatcherMapper::class,
|
||||||
CompositeConfigurationProviderMapper::class,
|
CompositeConfigurationProviderMapper::class,
|
||||||
ScoreUpdateMapper::class
|
ScoreUpdateMapper::class,
|
||||||
|
FriendRelationshipChangerMapper::class,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,4 +12,11 @@ class Experimental : ConfigContainer() {
|
|||||||
val meoPasscodeBypass = boolean("meo_passcode_bypass")
|
val meoPasscodeBypass = boolean("meo_passcode_bypass")
|
||||||
val unlimitedMultiSnap = boolean("unlimited_multi_snap") { addNotices(FeatureNotice.MAY_BAN)}
|
val unlimitedMultiSnap = boolean("unlimited_multi_snap") { addNotices(FeatureNotice.MAY_BAN)}
|
||||||
val noFriendScoreDelay = boolean("no_friend_score_delay")
|
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?
|
query: (SQLiteDatabase) -> T?
|
||||||
): T? {
|
): T? {
|
||||||
synchronized(databaseLock) {
|
synchronized(databaseLock) {
|
||||||
|
if (!database.isOpen) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
return runCatching {
|
return runCatching {
|
||||||
query(database)
|
query(database)
|
||||||
}.onFailure {
|
}.onFailure {
|
||||||
|
@ -3,7 +3,7 @@ package me.rhunk.snapenhance.features
|
|||||||
import me.rhunk.snapenhance.ModContext
|
import me.rhunk.snapenhance.ModContext
|
||||||
|
|
||||||
abstract class Feature(
|
abstract class Feature(
|
||||||
val nameKey: String,
|
val featureKey: String,
|
||||||
val loadParams: Int = FeatureLoadParams.INIT_SYNC
|
val loadParams: Int = FeatureLoadParams.INIT_SYNC
|
||||||
) {
|
) {
|
||||||
lateinit var context: ModContext
|
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.Messaging
|
||||||
import me.rhunk.snapenhance.features.impl.downloader.MediaDownloader
|
import me.rhunk.snapenhance.features.impl.downloader.MediaDownloader
|
||||||
import me.rhunk.snapenhance.features.impl.downloader.ProfilePictureDownloader
|
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.AmoledDarkMode
|
||||||
import me.rhunk.snapenhance.features.impl.experiments.AppPasscode
|
import me.rhunk.snapenhance.features.impl.experiments.AppPasscode
|
||||||
import me.rhunk.snapenhance.features.impl.experiments.DeviceSpooferHook
|
import me.rhunk.snapenhance.features.impl.experiments.DeviceSpooferHook
|
||||||
@ -93,6 +94,7 @@ class FeatureManager(private val context: ModContext) : Manager {
|
|||||||
register(GooglePlayServicesDialogs::class)
|
register(GooglePlayServicesDialogs::class)
|
||||||
register(NoFriendScoreDelay::class)
|
register(NoFriendScoreDelay::class)
|
||||||
register(ProfilePictureDownloader::class)
|
register(ProfilePictureDownloader::class)
|
||||||
|
register(AddFriendSourceSpoof::class)
|
||||||
|
|
||||||
initializeFeatures()
|
initializeFeatures()
|
||||||
}
|
}
|
||||||
@ -103,8 +105,8 @@ class FeatureManager(private val context: ModContext) : Manager {
|
|||||||
runCatching {
|
runCatching {
|
||||||
action(feature)
|
action(feature)
|
||||||
}.onFailure {
|
}.onFailure {
|
||||||
Logger.xposedLog("Failed to init feature ${feature.nameKey}", it)
|
context.log.error("Failed to init feature ${feature.featureKey}", it)
|
||||||
context.longToast("Failed to init feature ${feature.nameKey}")
|
context.longToast("Failed to load feature ${feature.featureKey}! Check logcat for more details.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!isAsync) {
|
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,
|
FriendsFeedEventDispatcherMapper::class,
|
||||||
CompositeConfigurationProviderMapper::class,
|
CompositeConfigurationProviderMapper::class,
|
||||||
ScoreUpdateMapper::class,
|
ScoreUpdateMapper::class,
|
||||||
|
FriendRelationshipChangerMapper::class,
|
||||||
)
|
)
|
||||||
|
|
||||||
val gson = GsonBuilder().setPrettyPrinting().create()
|
val gson = GsonBuilder().setPrettyPrinting().create()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user