Compare commits

...

79 commits
v1.1.3 ... main

Author SHA1 Message Date
OTKUSteyler
2cc79c59d0
Update InjectShiggyXposedStep.kt
Some checks failed
Build Debug App / build (push) Failing after 7m12s
2026-09-07 05:40:27 +02:00
OTKUSteyler
3ba2f9a460
Merge branch 'kmmiio99o:main' into main 2026-06-09 13:55:29 +02:00
kmmiio99o
0045d3b2a4
chore: bump version 2026-06-09 11:27:20 +00:00
kmmiio99o
71fab34c98
fix: use locale-independent formatting for LSPatch output filename (#4)
Fixes installation failures on non-Latin locales by ensuring the LSPatch
output filename lookup uses Latin numerals regardless of device locale.

LSPatch uses String.format(Locale.getDefault(), ...) which produces
locale-specific numerals (e.g., Arabic numerals on Arabic locales),
but the filename lookup was using hardcoded Latin numerals, causing
a mismatch that resulted in "Invalid package" errors.

Fixes #XXXX
2026-06-09 11:22:11 +00:00
OTKUSteyler
fdf93c7b1e
Update README.md 2026-05-22 21:51:05 +02:00
OTKUSteyler
460375e4ac
Update README.md 2026-05-22 21:50:25 +02:00
OTKUSteyler
28fe88c157 Merge remote-tracking branch 'upstream/main' 2026-05-08 00:02:56 +02:00
kmmiio99o
eaad9755ea
chore: bump to 1.1.2 2026-05-07 16:02:23 +02:00
kmmiio99o
50d58dc4e1
feat: use JingMatrix lspatch 2026-05-07 16:01:23 +02:00
OTKUSteyler
62c5659245
Merge branch 'kmmiio99o:main' into main 2026-04-28 12:42:55 +02:00
CatPieLeaf
7411ceb7a7
chore: update LSPatch and use JingMatrix fork (#3) 2026-04-28 11:51:17 +02:00
OTKUSteyler
ac57f05cae
Merge branch 'kmmiio99o:main' into main 2026-04-02 06:28:15 +02:00
мекатів
dcc33736a3
feat(manifestpatcher): allow connecting over http (#2)
Co-authored-by: meqativ <meqativ@users.noreply.github.com>
2026-04-01 23:47:23 +02:00
OTKUSteyler
35dca04b37
Update ic_discord_aliucord.xml 2026-03-26 09:50:04 +01:00
OTKUSteyler
748bb9dc59
Update colors.xml 2026-03-26 07:44:12 +01:00
j
1fa78ab647
proper icon referencing 2026-03-04 10:23:30 +01:00
J
6a3c90d12b fix(icon/anydpi-v26): nuked the wrong icons, replaced with right icons 2026-03-02 17:25:42 +01:00
OTKUSteyler
a00a6fdf66
Update ic_discord_aliucord.xml 2026-03-02 16:39:17 +01:00
OTKUSteyler
17b40741ea
Update ic_launcher.xml 2026-03-02 01:41:36 +01:00
OTKUSteyler
5c17dc3f9d
Update colors.xml 2026-03-02 01:30:32 +01:00
OTKUSteyler
0cd04a473a
Delete app/src/main/res/ic_launcher_round.png 2026-03-02 01:07:26 +01:00
OTKUSteyler
f234785571
Delete app/src/main/res/ic_launcher.png 2026-03-02 01:07:18 +01:00
OTKUSteyler
98625b22b8
Update colors.xml 2026-03-01 22:35:35 +01:00
OTKUSteyler
15a81b53ac
Update strings.xml 2026-03-01 22:32:15 +01:00
OTKUSteyler
3c8f78ef68
Update ic_launcher_background.xml 2026-03-01 22:27:59 +01:00
OTKUSteyler
1725bb6f0d
Update colors.xml 2026-03-01 21:53:23 +01:00
OTKUSteyler
2b62ed13a3
Update colors.xml 2026-03-01 21:43:53 +01:00
OTKUSteyler
d414b9c20a
Update fun facts in strings.xml 2026-03-01 21:41:35 +01:00
OTKUSteyler
e331dbb030
Update strings.xml 2026-03-01 21:39:35 +01:00
OTKUSteyler
ecd5c55008
Add files via upload 2026-02-20 18:01:33 +01:00
OTKUSteyler
7b82e406a4
Add files via upload 2026-02-20 18:00:08 +01:00
OTKUSteyler
eee219a4d1
Add files via upload 2026-02-20 17:59:58 +01:00
OTKUSteyler
012ece1855
Add files via upload 2026-02-20 17:59:45 +01:00
OTKUSteyler
2b12b2fb4e
Add files via upload 2026-02-20 17:59:30 +01:00
OTKUSteyler
0c58003936 Add files via upload 2026-02-20 17:59:12 +01:00
OTKUSteyler
6a5114cad0
Add files via upload 2026-02-20 17:59:01 +01:00
OTKUSteyler
17cd3d552e
Update ic_rounded_shiggy.xml 2026-02-20 06:56:39 +01:00
OTKUSteyler
9aefa5fed7
Update ic_rounded_shiggy.xml 2026-02-19 22:57:24 +01:00
OTKUSteyler
5df4a74536
Add files via upload 2026-02-19 20:34:00 +01:00
OTKUSteyler
94720320d8
Add files via upload 2026-02-19 20:22:53 +01:00
OTKUSteyler
3f29feecec
Add files via upload 2026-02-19 20:22:38 +01:00
OTKUSteyler
3529f5f7c1
Add files via upload 2026-02-19 20:22:21 +01:00
OTKUSteyler
ad6e5eb850
Add files via upload 2026-02-19 20:21:48 +01:00
OTKUSteyler
546d97844e
Add files via upload 2026-02-19 20:21:06 +01:00
OTKUSteyler
d0aff56a91
Add files via upload 2026-02-19 20:10:42 +01:00
OTKUSteyler
665b60654e
Add files via upload 2026-02-19 20:10:34 +01:00
OTKUSteyler
6eebcdb494
Add files via upload 2026-02-19 20:10:26 +01:00
OTKUSteyler
f3f352977e
Add files via upload 2026-02-19 20:10:13 +01:00
OTKUSteyler
e0aac86ec2
Add files via upload 2026-02-19 20:09:29 +01:00
OTKUSteyler
1b29c8070b
Update ic_discord.xml 2026-02-17 01:06:53 +01:00
OTKUSteyler
f60c24a259
Update ic_discord_aliucord.xml 2026-02-17 01:06:07 +01:00
OTKUSteyler
bcf39e1e65
Update ic_discord.xml 2026-02-17 01:03:33 +01:00
OTKUSteyler
1dea909ef5
Update ic_rounded_shiggy.xml 2026-02-17 00:12:38 +01:00
OTKUSteyler
b90183d4a6
Update ic_rounded_shiggy.xml 2026-02-17 00:10:40 +01:00
OTKUSteyler
ca59a08cc2
Update ic_rounded_shiggy.xml 2026-02-17 00:08:57 +01:00
OTKUSteyler
28dc73b7ae
Update ic_rounded_shiggy.xml 2026-02-17 00:06:34 +01:00
OTKUSteyler
84677d92c2
Update ic_rounded_shiggy.xml 2026-02-17 00:05:14 +01:00
OTKUSteyler
57f7d8b3dc
Update ic_rounded_shiggy.xml 2026-02-17 00:03:07 +01:00
OTKUSteyler
3c1c423283
Update ic_rounded_shiggy.xml 2026-02-17 00:02:46 +01:00
OTKUSteyler
aa4a3a6847
Update ic_discord.xml 2026-02-16 23:47:00 +01:00
OTKUSteyler
fedb711333
Update ic_rounded_shiggy.xml 2026-02-16 23:43:46 +01:00
OTKUSteyler
4b7b0009fa
Update ic_discord.xml 2026-02-16 23:42:26 +01:00
OTKUSteyler
b033d53c5b
Update ic_discord.xml 2026-02-16 23:40:51 +01:00
OTKUSteyler
cb3021e2a2
Update ic_rounded_shiggy.xml 2026-02-15 23:36:53 +01:00
OTKUSteyler
82e69d5ab1
Update ic_rounded_shiggy.xml 2026-02-15 23:30:42 +01:00
OTKUSteyler
e499c7d228
Update ic_rounded_shiggy.xml 2026-02-15 23:30:13 +01:00
OTKUSteyler
2759b71df1
Update ic_discord.xml 2026-02-15 23:27:30 +01:00
OTKUSteyler
6663e4a912
Update ic_rounded_shiggy.xml 2026-02-15 23:26:53 +01:00
OTKUSteyler
1e4b846dbd
Update ic_rounded_shiggy.xml 2026-02-14 17:22:17 +01:00
OTKUSteyler
d6fd188dce
Update ic_rounded_shiggy.xml 2026-02-12 20:13:14 +01:00
OTKUSteyler
c5d9dc9821
Update ic_rounded_shiggy.xml 2026-02-11 23:16:00 +01:00
OTKUSteyler
45f14b92fe
Update ic_rounded_shiggy.xml 2026-02-11 23:01:32 +01:00
OTKUSteyler
79a215d318
Merge branch 'kmmiio99o:main' into main 2026-01-16 21:29:00 +00:00
kmmiio99o
8cf989a239
feat: Add basic implementation of Amoled mode in the manager and fix
some misspells

TODO:
- Fix instance card to also use Amoled when needed
2026-01-16 20:44:29 +01:00
OTKUSteyler
d07c8e953d
Merge branch 'kmmiio99o:main' into main 2026-01-10 16:32:35 +00:00
kmmiio99o
3c14917b2f
bump to 10_11_01 2026-01-10 17:21:38 +01:00
kmmiio99o
48b5e39f3a
feat: possible fix rate limiting and github being blocked in some
countries?
2026-01-10 17:21:14 +01:00
OTKUSteyler
eb41f0ec8e
Update DownloadShiggyXposedStep.kt 2025-11-26 09:54:16 +01:00
OTKUSteyler
5dcee025b6
Update README.md 2025-11-23 16:26:35 +01:00
36 changed files with 286 additions and 107 deletions

View file

@ -26,7 +26,7 @@ Goon Manager makes installing and managing Discord mods simple and safe. It's bu
<p><strong>Download & run</strong> — get a released APK from Releases and install with:</p> <p><strong>Download & run</strong> — get a released APK from Releases and install with:</p>
Get newest apk from [release list](https://github.com/OTKUSteyler/GoonManager/releases/tag/v1.1.2) and install it. Get newest apk from [release list](https://github.com/OTKUSteyler/GoonManager/releases/tag/v1.1.3) and install it.
<p><strong>Build from source</strong> — clone and assemble:</p> <p><strong>Build from source</strong> — clone and assemble:</p>
@ -127,3 +127,5 @@ Goon Manager is open source under the OSL License. See `LICENSE` for details.
<p align="center"> <p align="center">
<strong>Made with ❤️ for the GoonCord community — keep it playful, keep it safe.</strong> <strong>Made with ❤️ for the GoonCord community — keep it playful, keep it safe.</strong>
</p> </p>
![OTKUSteyler](https://count.getloli.com/@OTKUSteyler?name=OTKUSteyler&theme=miku&padding=7&offset=0&align=top&scale=1&pixelated=1&darkmode=1)

View file

@ -19,20 +19,20 @@ val gitHasLocalCommits = gitCurrentBranch?.let { providers.execIgnoreCode("git",
val gitHasHasLocalChanges = providers.execIgnoreCode("git", "status", "-s").isNotEmpty() val gitHasHasLocalChanges = providers.execIgnoreCode("git", "status", "-s").isNotEmpty()
android { android {
namespace = "dev.goon.manager" namespace = "dev.shiggy.manager"
compileSdk = 36 compileSdk = 37
defaultConfig { defaultConfig {
minSdk = 28 minSdk = 28
targetSdk = 36 targetSdk = 37
versionCode = 10_11_00 versionCode = 10_12_01
versionName = "1.1.1" versionName = "1.1.2"
vectorDrawables { vectorDrawables {
useSupportLibrary = true useSupportLibrary = true
} }
buildConfigField("String", "APPLICATION_NAME", "\"Goon Manager\"") buildConfigField("String", "APPLICATION_NAME", "\"Shiggy Manager\"")
buildConfigField("String", "TAG", "\"GoonManager\"") buildConfigField("String", "TAG", "\"ShiggyManager\"")
buildConfigField("String", "GITHUB_ORG", "\"ShiggyCord\"") buildConfigField("String", "GITHUB_ORG", "\"ShiggyCord\"")
buildConfigField("String", "SUPPORT_SERVER", "\"\"") buildConfigField("String", "SUPPORT_SERVER", "\"\"")

30
app/libs/convert-lspatch.sh Executable file
View file

@ -0,0 +1,30 @@
# Download LSPatch jar and convert it to an aar
# Jars cannot be used as a dependency without breaking R8 optimization
LSPATCH_URL="https://github.com/JingMatrix/LSPatch/releases/latest/download/lspatch.jar"
LSPATCH_FILE_NAME="lspatch"
function cleanup {
rm -rf $LSPATCH_FILE_NAME.jar META-INF AndroidManifest.xml classes.jar R.txt
}
cleanup
# download lspatch
curl -sSL -o $LSPATCH_FILE_NAME.jar $LSPATCH_URL
# prepare aar contents
unzip -q $LSPATCH_FILE_NAME.jar "META-INF/**"
mv $LSPATCH_FILE_NAME.jar classes.jar
touch R.txt
cat >AndroidManifest.xml <<EOF
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="org.lsposed.lspatch">
<uses-sdk android:minSdkVersion="28" android:targetSdkVersion="36" />
</manifest>
EOF
# add everything to aar
rm -f $LSPATCH_FILE_NAME.aar
zip -rq $LSPATCH_FILE_NAME.aar R.txt AndroidManifest.xml META-INF classes.jar
cleanup

Binary file not shown.

View file

@ -18,11 +18,11 @@
<application <application
android:name="com.aliucord.manager.ManagerApplication" android:name="com.aliucord.manager.ManagerApplication"
android:icon="@mipmap/ic_launcher" android:icon="@drawable/ic_launcher"
android:label="@string/app_name" android:label="@string/app_name"
android:largeHeap="true" android:largeHeap="true"
android:requestLegacyExternalStorage="true" android:requestLegacyExternalStorage="true"
android:roundIcon="@mipmap/ic_launcher_round" android:roundIcon="@drawable/ic_launcher_round"
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/Theme.AppCompat.NoActionBar" android:theme="@style/Theme.AppCompat.NoActionBar"
> >

View file

@ -42,6 +42,7 @@ class MainActivity : ComponentActivity() {
ManagerTheme( ManagerTheme(
theme = preferences.theme, theme = preferences.theme,
dynamicColor = preferences.dynamicColor, dynamicColor = preferences.dynamicColor,
amoled = preferences.amoled,
) { ) {
if (BuildConfig.RELEASE) { if (BuildConfig.RELEASE) {
UpdaterDialog() UpdaterDialog()

View file

@ -8,6 +8,7 @@ import com.aliucord.manager.ui.theme.Theme
@Stable @Stable
class PreferencesManager(preferences: SharedPreferences) : BasePreferenceManager(preferences) { class PreferencesManager(preferences: SharedPreferences) : BasePreferenceManager(preferences) {
var theme by enumPreference("theme", Theme.System) var theme by enumPreference("theme", Theme.System)
var amoled by booleanPreference("amoled", false)
var dynamicColor by booleanPreference("dynamic_color", true) var dynamicColor by booleanPreference("dynamic_color", true)
var devMode by booleanPreference("dev_mode", false) var devMode by booleanPreference("dev_mode", false)
var installer by enumPreference<InstallerSetting>("installer", InstallerSetting.PM) var installer by enumPreference<InstallerSetting>("installer", InstallerSetting.PM)

View file

@ -16,11 +16,13 @@ import io.ktor.client.request.prepareGet
import io.ktor.client.statement.bodyAsChannel import io.ktor.client.statement.bodyAsChannel
import io.ktor.http.HttpHeaders import io.ktor.http.HttpHeaders
import io.ktor.http.contentLength import io.ktor.http.contentLength
import io.ktor.http.isSuccess
import io.ktor.utils.io.readAvailable import io.ktor.utils.io.readAvailable
import kotlinx.coroutines.CancellationException import kotlinx.coroutines.CancellationException
import java.io.File import java.io.File
import java.io.IOException import java.io.IOException
import java.net.SocketTimeoutException import java.net.SocketTimeoutException
import java.net.URI
/** /**
* Handle downloading remote urls to a path with Ktor. * Handle downloading remote urls to a path with Ktor.
@ -39,55 +41,108 @@ class KtorDownloadManager(
.apply { exists() || createNewFile() } .apply { exists() || createNewFile() }
try { try {
val httpStmt = http.prepareGet(url) { val downloadUrl = rewriteRawGithubUrl(url)
header(HttpHeaders.CacheControl, "no-cache, no-store")
// Disable compression due to bug on emulators // Try the CDN first (jsDelivr), then an alternate raw proxy (raw.githack.com), and finally
// This header cannot be set with Android's DownloadManager // fall back to the original URL if all CDN attempts fail.
if (IS_PROBABLY_EMULATOR) { val rawGithack = try {
header(HttpHeaders.AcceptEncoding, null) when {
// direct raw.githubusercontent.com -> raw.githack.com
url.contains("raw.githubusercontent.com", ignoreCase = true) ->
url.replace("raw.githubusercontent.com", "raw.githack.com")
// github.com/.../raw/... -> convert to raw.githack.com/ORG/REPO/BRANCH/path
url.contains("/raw/", ignoreCase = true) && url.contains("github.com", ignoreCase = true) -> {
try {
val u = URI(url)
val segs = u.path.trimStart('/').split('/', limit = 6)
if (segs.size >= 5 && segs[2].equals("raw", ignoreCase = true)) {
"https://raw.githack.com/${segs[0]}/${segs[1]}/${segs.subList(3, segs.size).joinToString("/")}"
} else url
} catch (_: Throwable) {
url
}
}
else -> url
}
} catch (_: Throwable) {
url
}
val attempts = listOf(downloadUrl, rawGithack, url).distinct()
var lastException: Throwable? = null
var downloaded = false
for (attemptUrl in attempts) {
val httpStmt = http.prepareGet(attemptUrl) {
header(HttpHeaders.CacheControl, "no-cache, no-store")
// Disable compression due to bug on emulators
// This header cannot be set with Android's DownloadManager
if (IS_PROBABLY_EMULATOR) {
header(HttpHeaders.AcceptEncoding, null)
}
}
try {
httpStmt.execute { resp ->
if (!resp.status.isSuccess()) {
throw IOException("HTTP error ${resp.status.value} for $attemptUrl")
}
val channel = resp.bodyAsChannel()
val total = resp.contentLength() ?: 0
var retrieved = 0L
val buf = ByteArray(1024 * 1024 * 1)
var bufLen: Int
tmpOut.outputStream().use { stream ->
// Preallocate space for this file
if (total > 0 && Build.VERSION.SDK_INT >= 26) {
val storageManager = application.getSystemService<StorageManager>()!!
try {
storageManager.allocateBytes(stream.fd, total)
} catch (e: IOException) {
throw InsufficientStorageException(e.message)
}
}
while (!channel.isClosedForRead) {
bufLen = channel.readAvailable(buf)
if (bufLen <= 0) break
stream.write(buf, 0, bufLen)
stream.flush()
retrieved += bufLen
if (total > 0) {
if (retrieved > total)
throw IOException("Total bytes received exceeds header total!")
onProgressUpdate?.onUpdate(retrieved / total.toFloat())
} else {
onProgressUpdate?.onUpdate(null)
}
}
}
}
// If we reach here, the attempt succeeded
downloaded = true
break
} catch (e: CancellationException) {
// Propagate cancellations immediately
throw e
} catch (t: Throwable) {
// Record the last exception and try the next URL (if any)
lastException = t
} }
} }
httpStmt.execute { resp -> if (!downloaded) {
val channel = resp.bodyAsChannel() // No attempt succeeded, throw the last failure to be handled by outer catch blocks
val total = resp.contentLength() ?: 0 throw lastException ?: IOException("Failed to download resource from $url")
var retrieved = 0L
val buf = ByteArray(1024 * 1024 * 1)
var bufLen: Int
tmpOut.outputStream().use { stream ->
// Preallocate space for this file
if (total > 0 && Build.VERSION.SDK_INT >= 26) {
val storageManager = application.getSystemService<StorageManager>()!!
try {
storageManager.allocateBytes(stream.fd, total)
} catch (e: IOException) {
throw InsufficientStorageException(e.message)
}
}
while (!channel.isClosedForRead) {
bufLen = channel.readAvailable(buf)
if (bufLen <= 0) break
stream.write(buf, 0, bufLen)
stream.flush()
retrieved += bufLen
if (total > 0) {
if (retrieved > total)
throw IOException("Total bytes received exceeds header total!")
onProgressUpdate?.onUpdate(retrieved / total.toFloat())
} else {
onProgressUpdate?.onUpdate(null)
}
}
}
} }
} catch (_: CancellationException) { } catch (_: CancellationException) {
tmpOut.delete() tmpOut.delete()
@ -107,6 +162,17 @@ class KtorDownloadManager(
return Result.Success(out) return Result.Success(out)
} }
private fun rewriteRawGithubUrl(url: String): String {
val regex = Regex("^https?://raw\\.githubusercontent\\.com/([^/]+)/([^/]+)/([^/]+)/(.*)$", RegexOption.IGNORE_CASE)
val match = regex.matchEntire(url)
return if (match != null) {
val (org, repo, branch, path) = match.destructured
"https://cdn.jsdelivr.net/gh/$org/$repo@$branch/$path"
} else {
url
}
}
/** /**
* Wrapper around an exception that occurred from invoking Ktor * Wrapper around an exception that occurred from invoking Ktor
*/ */

View file

@ -22,7 +22,7 @@ class DownloadShiggyXposedStep : DownloadStep() {
override suspend fun execute(container: StepRunner) { override suspend fun execute(container: StepRunner) {
val latestRelease = shiggyGithubService.getLatestXposedRelease().getOrThrow() val latestRelease = shiggyGithubService.getLatestXposedRelease().getOrThrow()
container.log("Latest ShiggyXposed release is ${latestRelease.name}") container.log("Latest GoonXposed release is ${latestRelease.name}")
targetVersion = SemVer.parse(latestRelease.name) targetVersion = SemVer.parse(latestRelease.name)
targetUrl = latestRelease.assets.first { it.name == "app-release.apk" }.browserDownloadUrl targetUrl = latestRelease.assets.first { it.name == "app-release.apk" }.browserDownloadUrl

View file

@ -13,10 +13,11 @@ import org.lsposed.lspatch.share.LSPConfig
import org.lsposed.patch.LSPatch import org.lsposed.patch.LSPatch
import org.lsposed.patch.util.Logger import org.lsposed.patch.util.Logger
import java.io.File import java.io.File
import java.util.*
class InjectShiggyXposedStep : Step() { class InjectGoonXposedStep : Step() {
override val group: StepGroup = StepGroup.Install override val group: StepGroup = StepGroup.Install
override val localizedName: Int = R.string.patch_step_inject_shiggy override val localizedName: Int = R.string.patch_step_inject_goon
suspend fun patch( suspend fun patch(
container: StepRunner, container: StepRunner,
@ -82,7 +83,15 @@ class InjectShiggyXposedStep : Step() {
// FilenameUtils.getBaseName(apkFileName), // FilenameUtils.getBaseName(apkFileName),
// LSPConfig.instance.VERSION_CODE) // LSPConfig.instance.VERSION_CODE)
// ) // )
val patchedApkName = "${baseName}-${LSPConfig.instance.VERSION_CODE}-lspatched.apk" // Note: LSPatch uses Locale.getDefault() which can produce locale-specific numerals
// (e.g., Arabic numerals on Arabic locales). We must use Locale.US to ensure
// consistent filename matching regardless of device locale.
val patchedApkName = String.format(
Locale.US,
"%s-%d-lspatched.apk",
baseName,
LSPConfig.instance.VERSION_CODE
)
val patchedApk = File(tempDir, patchedApkName) val patchedApk = File(tempDir, patchedApkName)
if (patchedApk.exists()) { if (patchedApk.exists()) {

View file

@ -252,6 +252,8 @@ object ManifestPatcher {
extractNativeLibs ?: false extractNativeLibs ?: false
private var shouldAddMetadata = private var shouldAddMetadata =
addManagerMetadata ?: false addManagerMetadata ?: false
private var shouldAddCleartext = true
override fun attr( override fun attr(
ns: String?, ns: String?,
@ -269,6 +271,12 @@ object ManifestPatcher {
shouldAddExtractNativeLibs = false shouldAddExtractNativeLibs = false
if (name == DEBUGGABLE) if (name == DEBUGGABLE)
shouldAddDebuggable = false shouldAddDebuggable = false
if (name == "usesCleartextTraffic") {
shouldAddCleartext = false
super.attr(ns, name, 0x010104ec, TYPE_INT_BOOLEAN, 1)
return
}
super.attr( super.attr(
ns, ns,
name, name,
@ -425,7 +433,15 @@ object ManifestPatcher {
0 0
) )
} }
if (shouldAddCleartext) {
super.attr(
ANDROID_NAMESPACE,
"usesCleartextTraffic",
0x010104ec,
TYPE_INT_BOOLEAN,
1
)
}
super.end() super.end()
} }
} }

View file

@ -98,6 +98,14 @@ class SettingsScreen : Screen, Parcelable {
} }
SettingsSwitch(
label = stringResource(R.string.setting_amoled),
secondaryLabel = stringResource(R.string.setting_amoled_desc),
pref = preferences.amoled,
icon = { Icon(painterResource(R.drawable.ic_night), null) },
onPrefChange = { preferences.amoled = it },
)
// Material You theming on Android 12+ // Material You theming on Android 12+
if (Build.VERSION.SDK_INT >= 31) { if (Build.VERSION.SDK_INT >= 31) {
SettingsSwitch( SettingsSwitch(

View file

@ -20,6 +20,7 @@ import dev.goon.manager.R
fun ManagerTheme( fun ManagerTheme(
theme: Theme = Theme.System, theme: Theme = Theme.System,
dynamicColor: Boolean = true, dynamicColor: Boolean = true,
amoled: Boolean = false,
content: @Composable () -> Unit, content: @Composable () -> Unit,
) { ) {
val dynamicColor = dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S val dynamicColor = dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
@ -28,12 +29,63 @@ fun ManagerTheme(
Theme.Dark -> true Theme.Dark -> true
Theme.Light -> false Theme.Light -> false
} }
val colorScheme = when {
dynamicColor && darkTheme -> dynamicDarkColorScheme(LocalContext.current) val context = LocalContext.current
dynamicColor && !darkTheme -> dynamicLightColorScheme(LocalContext.current)
val baseScheme = when {
dynamicColor && darkTheme -> dynamicDarkColorScheme(context)
dynamicColor && !darkTheme -> dynamicLightColorScheme(context)
darkTheme -> darkColorScheme() darkTheme -> darkColorScheme()
else -> lightColorScheme() else -> lightColorScheme()
} }
val colorScheme = if (amoled && darkTheme) {
baseScheme.copy(
// Core surfaces: true black with white content
background = Color(0xFF000000),
onBackground = Color(0xFFFFFFFF),
surface = Color(0xFF000000),
onSurface = Color(0xFFFFFFFF),
// Surface variants / tints for containers and subtle surfaces
surfaceVariant = Color(0xFF000000),
onSurfaceVariant = Color(0xFFFFFFFF),
surfaceTint = Color(0xFF000000),
// Primary (controls). Set both primary and primaryContainer to white so
// Filled / FilledTonal controls and other components using either token
// will have a white container with black text/icons.
primary = Color(0xFFFFFFFF),
onPrimary = Color(0xFF000000),
primaryContainer = Color(0xFFFFFFFF),
onPrimaryContainer = Color(0xFF000000),
// Secondary / tertiary: match primary behavior for consistency across different control types
secondary = Color(0xFFFFFFFF),
onSecondary = Color(0xFF000000),
secondaryContainer = Color(0xFFFFFFFF),
onSecondaryContainer = Color(0xFF000000),
tertiary = Color(0xFFFFFFFF),
onTertiary = Color(0xFF000000),
tertiaryContainer = Color(0xFFFFFFFF),
onTertiaryContainer = Color(0xFF000000),
// Inverse surfaces for components that might use them
inverseSurface = Color(0xFF121212),
inverseOnSurface = Color(0xFFFFFFFF),
// Outline and subtle elements: semi-transparent white for edges/highlights
outline = Color(0x66FFFFFF),
// Preserve error semantics from base (keeps readable error colors)
error = baseScheme.error,
onError = baseScheme.onError,
errorContainer = baseScheme.errorContainer,
onErrorContainer = baseScheme.onErrorContainer,
)
} else baseScheme
val customColors = when (darkTheme) { val customColors = when (darkTheme) {
true -> DarkCustomColors true -> DarkCustomColors
false -> LightCustomColors false -> LightCustomColors

View file

@ -19,6 +19,10 @@ data class CustomColors(
val onWarning: Color, val onWarning: Color,
val warningContainer: Color, val warningContainer: Color,
val onWarningContainer: Color, val onWarningContainer: Color,
val instanceCardBackground: Color,
val instanceCardContent: Color,
val instanceCardButtonContainer: Color,
val instanceCardButtonContent: Color,
) )
private val YellowAlt1 = Color(0xFFE9C414) private val YellowAlt1 = Color(0xFFE9C414)
@ -32,6 +36,10 @@ val DarkCustomColors = CustomColors(
onWarning = DarkBrown, onWarning = DarkBrown,
warningContainer = DarkBronze, warningContainer = DarkBronze,
onWarningContainer = Shandy, onWarningContainer = Shandy,
instanceCardBackground = Color(0xFF0E0E0E),
instanceCardContent = Color(0xFFFFFFFF),
instanceCardButtonContainer = Color(0xFFF2F2F2),
instanceCardButtonContent = Color(0xFF000000),
) )
val LightCustomColors = CustomColors( val LightCustomColors = CustomColors(
@ -39,4 +47,8 @@ val LightCustomColors = CustomColors(
onWarning = Color.White, onWarning = Color.White,
warningContainer = Shandy, warningContainer = Shandy,
onWarningContainer = DarkerBrown, onWarningContainer = DarkerBrown,
instanceCardBackground = Color(0xFFFFFFFF),
instanceCardContent = Color(0xFF000000),
instanceCardButtonContainer = Color(0xFFFAFAFA),
instanceCardButtonContent = Color(0xFF000000),
) )

View file

@ -1,17 +1,15 @@
<vector <vector
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:width="108dp"
android:height="24dp" android:height="108dp"
android:viewportWidth="256" android:viewportWidth="256"
android:viewportHeight="256" android:viewportHeight="256"
> >
<!-- Solid circular background (Shiggy yellow) -->
<!-- Solid circular background (Discord blurple) --> <path android:fillColor="#fcc680" android:pathData="M256,128 A128,128 0 1,1 0,128 A128,128 0 1,1 256,128 Z" />
<path android:fillColor="#5865F2" android:pathData="M256,128 A128,128 0 1,1 0,128 A128,128 0 1,1 256,128 Z" /> <!-- White droplet -->
<!-- White Discord mark (borrowed path scaled by viewport) -->
<path <path
android:fillColor="#FFFFFFFF" android:fillColor="#FFFFFF"
android:pathData="M216.86,45.1C200.29,37.34 182.57,31.71 164.04,28.5C161.77,32.61 159.11,38.15 157.28,42.55C137.58,39.58 118.07,39.58 98.74,42.55C96.91,38.15 94.19,32.61 91.9,28.5C73.35,31.71 55.61,37.36 39.04,45.14C5.62,95.65 -3.44,144.9 1.09,193.46C23.26,210.01 44.74,220.07 65.86,226.65C71.08,219.47 75.73,211.84 79.74,203.8C72.1,200.9 64.79,197.32 57.89,193.17C59.72,191.81 61.51,190.39 63.24,188.93C105.37,208.63 151.13,208.63 192.75,188.93C194.51,190.39 196.3,191.81 198.11,193.17C191.18,197.34 183.85,200.92 176.22,203.82C180.23,211.84 184.86,219.49 190.1,226.67C211.24,220.09 232.74,210.03 254.91,193.46C260.23,137.17 245.83,88.37 216.86,45.1ZM85.47,163.59C72.83,163.59 62.46,151.79 62.46,137.41C62.46,123.04 72.61,111.21 85.47,111.21C98.34,111.21 108.71,123.02 108.49,137.41C108.51,151.79 98.34,163.59 85.47,163.59ZM170.53,163.59C157.88,163.59 147.51,151.79 147.51,137.41C147.51,123.04 157.66,111.21 170.53,111.21C183.39,111.21 193.76,123.02 193.54,137.41C193.54,151.79 183.39,163.59 170.53,163.59Z" android:pathData="M128,38.4 C64,89.6 51.2,166.4 76.8,204.8 Q102.4,230.4 128,217.6 Q153.6,230.4 179.2,204.8 C204.8,166.4 192,89.6 128,38.4 Z"
/> />
</vector> </vector>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

View file

@ -6,5 +6,5 @@
android:viewportHeight="108" android:viewportHeight="108"
> >
<!-- Flat background color for launcher adaptive icon --> <!-- Flat background color for launcher adaptive icon -->
<path android:pathData="M0,0H108V108H0Z" android:fillColor="#FFFFCB82" /> <path android:pathData="M0,0H108V108H0Z" android:fillColor="#070700" />
</vector> </vector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

View file

@ -5,15 +5,8 @@
android:viewportWidth="256" android:viewportWidth="256"
android:viewportHeight="256" android:viewportHeight="256"
> >
<path
<!-- Solid circular background (Shiggy yellow) --> android:fillColor="#000000"
<path android:fillColor="#fcc680" android:pathData="M256,128 A128,128 0 1,1 0,128 A128,128 0 1,1 256,128 Z" /> android:pathData="M128,38.4 C64,89.6 51.2,166.4 76.8,204.8 Q102.4,230.4 128,217.6 Q153.6,230.4 179.2,204.8 C204.8,166.4 192,89.6 128,38.4 Z"
/>
<!-- White Discord mark (scaled down and centered) -->
<group android:scaleX="0.7" android:scaleY="0.7" android:translateX="38.4" android:translateY="38.4">
<path
android:fillColor="#FFFFFFFF"
android:pathData="M216.86,45.1C200.29,37.34 182.57,31.71 164.04,28.5C161.77,32.61 159.11,38.15 157.28,42.55C137.58,39.58 118.07,39.58 98.74,42.55C96.91,38.15 94.19,32.61 91.9,28.5C73.35,31.71 55.61,37.36 39.04,45.14C5.62,95.65 -3.44,144.9 1.09,193.46C23.26,210.01 44.74,220.07 65.86,226.65C71.08,219.47 75.73,211.84 79.74,203.8C72.1,200.9 64.79,197.32 57.89,193.17C59.72,191.81 61.51,190.39 63.24,188.93C105.37,208.63 151.13,208.63 192.75,188.93C194.51,190.39 196.3,191.81 198.11,193.17C191.18,197.34 183.85,200.92 176.22,203.82C180.23,211.84 184.86,219.49 190.1,226.67C211.24,220.09 232.74,210.03 254.91,193.46C260.23,137.17 245.83,88.37 216.86,45.1ZM85.47,163.59C72.83,163.59 62.46,151.79 62.46,137.41C62.46,123.04 72.61,111.21 85.47,111.21C98.34,111.21 108.71,123.02 108.49,137.41C108.51,151.79 98.34,163.59 85.47,163.59ZM170.53,163.59C157.88,163.59 147.51,151.79 147.51,137.41C147.51,123.04 157.66,111.21 170.53,111.21C183.39,111.21 193.76,123.02 193.54,137.41C193.54,151.79 183.39,163.59 170.53,163.59Z"
/>
</group>
</vector> </vector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

View file

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Adaptive icon updated to use Shiggy flat background and provided foreground image -->
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<monochrome android:drawable="@drawable/ic_launcher_monochrome" />
</adaptive-icon>

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

View file

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<monochrome android:drawable="@drawable/ic_launcher_monochrome" />
</adaptive-icon>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

View file

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<color name="ic_launcher_background">#FFFFFFFF</color> <color name="ic_launcher_background">#FFFFFF</color>
</resources> </resources>

View file

@ -51,8 +51,12 @@
<string name="settings_header_info">Info</string> <string name="settings_header_info">Info</string>
<string name="setting_theme">Theme</string> <string name="setting_theme">Theme</string>
<string name="setting_theme_desc">The theme to apply to this app</string> <string name="setting_theme_desc">The theme to apply to this app</string>
<string name="setting_amoled">Amoled mode</string>
<string name="setting_amoled_desc">Force true-black backgrounds for AMOLED displays</string>
<string name="setting_dynamic_color">Dynamic color</string> <string name="setting_dynamic_color">Dynamic color</string>
<string name="setting_dynamic_color_desc">Enables Material You theming on Android 12+</string> <string
name="setting_dynamic_color_desc"
>Enables Material You theming on Android 12+; dynamic colors will also be applied to the Amoled theme when enabled</string>
<string name="setting_installer">Installer</string> <string name="setting_installer">Installer</string>
<string name="setting_installer_desc">The method to use for installing Goon</string> <string name="setting_installer_desc">The method to use for installing Goon</string>
<string name="setting_developer_options">Developer options</string> <string name="setting_developer_options">Developer options</string>
@ -72,6 +76,7 @@
<string name="theme_system">System</string> <string name="theme_system">System</string>
<string name="theme_dark">Dark</string> <string name="theme_dark">Dark</string>
<string name="theme_light">Light</string> <string name="theme_light">Light</string>
<string name="theme_amoled">Amoled</string>
<string name="navigation_back">Back</string> <string name="navigation_back">Back</string>
<string name="navigation_about">About</string> <string name="navigation_about">About</string>
@ -84,7 +89,7 @@
<string name="lead_role_kettu">Kettu - Creator</string> <string name="lead_role_kettu">Kettu - Creator</string>
<string name="lead_role_shiggycord">GoonCord - Creator</string> <string name="lead_role_shiggycord">GoonCord - Creator</string>
<string name="lead_role_bunny">Bunny - Creator</string> <string name="lead_role_bunny">Bunny - Creator</string>
<string name="role_creator_vendetta">Creator of Vendetta</string> <string name="role_creator_vendetta">Vendetta - Creator</string>
<string name="role_original_manager_creator">Original Manager Creator</string> <string name="role_original_manager_creator">Original Manager Creator</string>
<string name="network_load_fail">Failed to load</string> <string name="network_load_fail">Failed to load</string>
@ -280,10 +285,10 @@
<string name="permissions_shizuku_denied">Failed to obtain Shizuku permissions</string> <string name="permissions_shizuku_denied">Failed to obtain Shizuku permissions</string>
<string name="fun_fact_prefix">Fun Fact: %s</string> <string name="fun_fact_prefix">Fun Fact: %s</string>
<string name="fun_fact_1">ShiggyCord on first release was meant to be custom Kettu build!</string> <string name="fun_fact_1">GoonCord on second release was meant to be custom ShiggyCord build!</string>
<string name="fun_fact_2">The refreshed UI inside the settings was made from developer boredom</string> <string name="fun_fact_2">This client is not same as CumCord i made it as an Joke</string>
<string name="fun_fact_3">ShiggyCord as first vendetta like client used to show users the built in plugins and even add extra ones!</string> <string name="fun_fact_3">GoonCord as second vendetta like client used to show users the built in plugins and even add extra ones!</string>
<string name="fun_fact_4">You love boys, don\'t you?</string> <string name="fun_fact_4">You love Femboys, don\'t you?</string>
<string name="fun_fact_5">Aliucord is the best client with old discord UI</string> <string name="fun_fact_5">Aliucord is the best client with old discord UI</string>
<string name="fun_fact_6">We love you cocobo and pylix!</string> <string name="fun_fact_6">We love you cocobo and pylix!</string>
<string name="fun_fact_7">The Vendetta react native part was a total dogshit</string> <string name="fun_fact_7">The Vendetta react native part was a total dogshit</string>
@ -291,7 +296,6 @@
<string name="fun_fact_9">This client can be run on a android TV!</string> <string name="fun_fact_9">This client can be run on a android TV!</string>
<string name="fun_fact_10">The Main Developer one and half a year ago didn\'t even know how to code</string> <string name="fun_fact_10">The Main Developer one and half a year ago didn\'t even know how to code</string>
<string name="fun_fact_11">This client does not support iOS!</string> <string name="fun_fact_11">This client does not support iOS!</string>
<string name="fun_fact_12">Boom!</string> <string name="fun_fact_12">Boom :3!</string>
<string name="fun_fact_13">This client is not same as CumCord i made it as an Joke</string>
</resources> </resources>

View file

@ -2,7 +2,7 @@
<resources> <resources>
<style name="Theme.AliucordManager.SplashScreen" parent="Theme.SplashScreen"> <style name="Theme.AliucordManager.SplashScreen" parent="Theme.SplashScreen">
<item name="windowSplashScreenAnimatedIcon">@drawable/ic_launcher_foreground</item> <item name="windowSplashScreenAnimatedIcon">@drawable/ic_launcher</item>
<item name="postSplashScreenTheme">@style/Theme.AppCompat.NoActionBar</item> <item name="postSplashScreenTheme">@style/Theme.AppCompat.NoActionBar</item>
<item name="android:windowActionBar">false</item> <item name="android:windowActionBar">false</item>