Skip to content

Commit 8d444d3

Browse files
committed
Fixed building issues
1 parent 39f3200 commit 8d444d3

File tree

9 files changed

+82
-35
lines changed

9 files changed

+82
-35
lines changed

.github/workflows/release.yml

+3-8
Original file line numberDiff line numberDiff line change
@@ -43,20 +43,15 @@ jobs:
4343
run: |
4444
echo "${{ secrets.keystore }}" | base64 -d > $GITHUB_WORKSPACE/signing-key.jks
4545
chmod +x ./gradlew
46-
./gradlew assembleRelease \
46+
./gradlew packageReleaseUniversalApk \
4747
-Pandroid.injected.signing.store.file=$GITHUB_WORKSPACE/signing-key.jks \
4848
-Pandroid.injected.signing.store.password=${{ secrets.keystore_password }} \
4949
-Pandroid.injected.signing.key.alias=${{ secrets.key_alias }} \
5050
-Pandroid.injected.signing.key.password=${{ secrets.key_password }}
5151
5252
- name: Find and Rename APK
5353
run: |
54-
APK_PATH=$(find . -name "*release*.apk" | head -n 1)
55-
if [ -z "$APK_PATH" ]; then
56-
echo "No APK file found"
57-
exit 1
58-
fi
59-
mv "$APK_PATH" ./app-release.apk
54+
mv app/build/outputs/apk_from_bundle/release/app-release-universal.apk ./app-release.apk
6055
cp ./app-release.apk ./BunnyXposed-${{ steps.extract_version.outputs.version }}.apk
6156
echo "APKs renamed and copied"
6257
@@ -84,4 +79,4 @@ jobs:
8479
--generate-notes \
8580
$PRERELEASE_FLAG \
8681
$DRAFT_FLAG \
87-
./*.apk
82+
./*.apk

.idea/deploymentTargetSelector.xml

+8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/vcs.xml

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

UPDATING.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ How to update to latest upstream repo:
22

33
First Time:
44

5-
- git remote add public https://github.com/pyoncord/BunnyXPosed
5+
- git remote add public https://github.com/felitendo/FelocordXPosed
66

77
Then:
88

app/src/main/kotlin/io/github/felitendo/xposed/FontsModule.kt

+3-8
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,19 @@ package io.github.felitendo.xposed
55

66
import android.content.res.AssetManager
77
import android.os.Build
8-
import android.graphics.Color
98
import android.graphics.Typeface
109
import android.graphics.Typeface.CustomFallbackBuilder
1110
import android.graphics.fonts.Font
1211
import android.graphics.fonts.FontFamily
1312
import android.util.Log
14-
import android.webkit.URLUtil
1513
import de.robv.android.xposed.XC_MethodReplacement
16-
import de.robv.android.xposed.XposedBridge
1714
import de.robv.android.xposed.XposedHelpers
1815
import de.robv.android.xposed.callbacks.XC_LoadPackage
1916
import kotlinx.serialization.Serializable
2017
import kotlinx.serialization.decodeFromString
2118
import kotlinx.serialization.json.*
2219
import java.io.IOException
2320
import java.io.File
24-
import java.net.HttpURLConnection
25-
import java.net.URL
2621
import kotlinx.coroutines.*
2722

2823
import io.ktor.client.*
@@ -67,7 +62,7 @@ class FontsModule: PyonModule() {
6762
val assetManager: AssetManager = param.args[2] as AssetManager
6863
return createAssetTypeface(fontFamilyName, style, assetManager)
6964
}
70-
});
65+
})
7166

7267
val fontDefFile = File(appInfo.dataDir, "files/felitendo/fonts.json")
7368
if (!fontDefFile.exists()) return@with
@@ -144,7 +139,7 @@ class FontsModule: PyonModule() {
144139
// ignore
145140
}
146141

147-
for (fontRootPath in arrayOf(fontsAbsPath, FONTS_ASSET_PATH).filter { it != null }) {
142+
for (fontRootPath in arrayOf(fontsAbsPath, FONTS_ASSET_PATH).filterNotNull()) {
148143
for (fileExtension in FILE_EXTENSIONS) {
149144
val fileName = java.lang.StringBuilder()
150145
.append(fontRootPath)
@@ -220,7 +215,7 @@ class FontsModule: PyonModule() {
220215

221216
// Lastly, after all those checks above, this is the original RN logic for
222217
// getting the typeface.
223-
for (fontRootPath in arrayOf(fontsAbsPath, FONTS_ASSET_PATH).filter { it != null }) {
218+
for (fontRootPath in arrayOf(fontsAbsPath, FONTS_ASSET_PATH).filterNotNull()) {
224219
for (fileExtension in FILE_EXTENSIONS) {
225220
val fileName = java.lang.StringBuilder()
226221
.append(fontRootPath)

app/src/main/kotlin/io/github/felitendo/xposed/Main.kt

+57-9
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
package io.github.felitendo.xposed
22

3+
import android.app.Activity
34
import android.content.res.AssetManager
45
import android.content.res.Resources
56
import android.util.Log
7+
import android.os.Bundle
8+
import android.widget.Toast
69
import de.robv.android.xposed.IXposedHookLoadPackage
710
import de.robv.android.xposed.XC_MethodHook
811
import de.robv.android.xposed.XposedBridge
@@ -50,10 +53,33 @@ class Main : IXposedHookLoadPackage {
5053
return Json.encodeToString(obj)
5154
}
5255

53-
override fun handleLoadPackage(param: XC_LoadPackage.LoadPackageParam) = with (param) {
54-
val catalystInstanceImpl = runCatching {
55-
classLoader.loadClass("com.facebook.react.bridge.CatalystInstanceImpl")
56-
}.getOrElse { return@with }
56+
override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam) {
57+
val reactActivity = runCatching {
58+
lpparam.classLoader.loadClass("com.discord.react_activities.ReactActivity")
59+
}.getOrElse { return } // Package is not our the target app, return
60+
61+
var activity: Activity? = null;
62+
val onActivityCreateCallback = mutableSetOf<(activity: Activity) -> Unit>()
63+
64+
XposedBridge.hookMethod(reactActivity.getDeclaredMethod("onCreate", Bundle::class.java), object : XC_MethodHook() {
65+
override fun beforeHookedMethod(param: MethodHookParam) {
66+
activity = param.thisObject as Activity;
67+
onActivityCreateCallback.forEach { cb -> cb(activity!!) }
68+
onActivityCreateCallback.clear()
69+
}
70+
})
71+
72+
init(lpparam) { cb ->
73+
if (activity != null) cb(activity!!)
74+
else onActivityCreateCallback.add(cb)
75+
}
76+
}
77+
78+
private fun init(
79+
param: XC_LoadPackage.LoadPackageParam,
80+
onActivityCreate: ((activity: Activity) -> Unit) -> Unit
81+
) = with (param) {
82+
val catalystInstanceImpl = classLoader.loadClass("com.facebook.react.bridge.CatalystInstanceImpl")
5783

5884
for (module in pyonModules) module.onInit(param)
5985

@@ -94,6 +120,7 @@ class Main : IXposedHookLoadPackage {
94120
customLoadUrl = CustomLoadUrl(
95121
enabled = false,
96122
url = "http://localhost:4040/felitendo.js"
123+
url = "" // Not used
97124
)
98125
)
99126
}
@@ -102,8 +129,9 @@ class Main : IXposedHookLoadPackage {
102129
val httpJob = scope.async(Dispatchers.IO) {
103130
try {
104131
val client = HttpClient(CIO) {
132+
expectSuccess = true
105133
install(HttpTimeout) {
106-
requestTimeoutMillis = if (bundle.exists()) 3000 else HttpTimeout.INFINITE_TIMEOUT_MS
134+
requestTimeoutMillis = if (bundle.exists()) 5000 else 10000
107135
}
108136
install(UserAgent) { agent = "FelocordXposed" }
109137
}
@@ -112,6 +140,10 @@ class Main : IXposedHookLoadPackage {
112140
if (config.customLoadUrl.enabled) config.customLoadUrl.url
113141
else "https://raw.githubusercontent.com/Felocord/builds/main/felocord.js"
114142

143+
else "https://raw.githubusercontent.com/felitendo/detta-builds/main/felocord.min.js"
144+
145+
Log.e("Felocord", "Fetching JS bundle from $url")
146+
115147
val response: HttpResponse = client.get(url) {
116148
headers {
117149
if (etag.exists() && bundle.exists()) {
@@ -120,14 +152,30 @@ class Main : IXposedHookLoadPackage {
120152
}
121153
}
122154

123-
if (response.status == HttpStatusCode.OK) {
124-
bundle.writeBytes(response.body())
125-
if (response.headers["Etag"] != null) etag.writeText(response.headers["Etag"]!!)
126-
else if (etag.exists()) etag.delete()
155+
bundle.writeBytes(response.body())
156+
if (response.headers["Etag"] != null) {
157+
etag.writeText(response.headers["Etag"]!!)
158+
}
159+
else if (etag.exists()) {
160+
// This is called when server does not return an E-tag, so clear em
161+
etag.delete()
127162
}
128163

129164
return@async
165+
} catch (e: RedirectResponseException) {
166+
if (e.response.status != HttpStatusCode.NotModified) throw e;
167+
Log.e("Felocord", "Server responded with status code 304 - no changes to file")
130168
} catch (e: Throwable) {
169+
onActivityCreate { activity ->
170+
activity.runOnUiThread {
171+
Toast.makeText(
172+
activity.applicationContext,
173+
"Failed to fetch JS bundle, Felocord may not load!",
174+
Toast.LENGTH_SHORT
175+
).show()
176+
}
177+
}
178+
131179
Log.e("Felocord", "Failed to download bundle", e)
132180
}
133181
}

app/src/main/kotlin/io/github/felitendo/xposed/SysColorsModule.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ data class SysColors(
1818

1919
class SysColorsModule : PyonModule() {
2020
private lateinit var context: Context
21-
fun isSupported() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
21+
private fun isSupported() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
2222

2323
override fun buildJson(builder: JsonObjectBuilder) {
2424
context = AndroidAppHelper.currentApplication()
@@ -43,7 +43,7 @@ class SysColorsModule : PyonModule() {
4343
}
4444
}
4545

46-
fun convertToColor(id: Int): String {
46+
private fun convertToColor(id: Int): String {
4747
val clr = if (isSupported()) ContextCompat.getColor(context, id) else 0
4848
return String.format("#%06X", 0xFFFFFF and clr)
4949
}

app/src/main/kotlin/io/github/felitendo/xposed/ThemeModule.kt

+6-6
Original file line numberDiff line numberDiff line change
@@ -58,14 +58,14 @@ class ThemeModule : PyonModule() {
5858
hookTheme()
5959
}
6060

61-
fun File.isValidish(): Boolean {
61+
private fun File.isValidish(): Boolean {
6262
if (!this.exists()) return false
6363

6464
val text = this.readText()
65-
return !text.isBlank() && text != "{}" && text != "null"
65+
return text.isNotBlank() && text != "{}" && text != "null"
6666
}
6767

68-
fun getTheme(): Theme? {
68+
private fun getTheme(): Theme? {
6969
val filesDir = File(param.appInfo.dataDir, "files").apply { mkdirs() }
7070
val pyonDir = File(filesDir, "felitendo").apply { mkdirs() }
7171
val themeFile = File(pyonDir, "current-theme.json")
@@ -139,12 +139,12 @@ class ThemeModule : PyonModule() {
139139
}
140140

141141
// Convert 0xRRGGBBAA to 0XAARRGGBB
142-
fun hexStringToColorInt(hexString: String): Int {
142+
private fun hexStringToColorInt(hexString: String): Int {
143143
val parsed = Color.parseColor(hexString)
144-
return parsed.takeIf { hexString.length == 7 } ?: parsed and 0xFFFFFF or (parsed ushr 24)
144+
return parsed.takeIf { hexString.length == 7 } ?: (parsed and 0xFFFFFF or (parsed ushr 24))
145145
}
146146

147-
fun hookThemeMethod(themeClass: Class<*>, methodName: String, themeValue: Int) {
147+
private fun hookThemeMethod(themeClass: Class<*>, methodName: String, themeValue: Int) {
148148
try {
149149
themeClass.getDeclaredMethod(methodName).let { method ->
150150
// Log.i("Hooking $methodName -> ${themeValue.toString(16)}")

build.gradle.kts

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ allprojects {
1919
repositories {
2020
google()
2121
mavenCentral()
22+
maven(url = "https://api.xposed.info/")
2223
// See comment in buildscript repos
2324
jcenter()
2425
}

0 commit comments

Comments
 (0)