mirror of
https://git.chinosk6.cn/chinosk/gkms-local.git
synced 2026-02-04 09:04:52 +00:00
@@ -1,8 +1,9 @@
|
||||
plugins {
|
||||
id 'com.android.application'
|
||||
id 'org.jetbrains.kotlin.android'
|
||||
alias(libs.plugins.androidApplication)
|
||||
alias(libs.plugins.kotlinAndroid)
|
||||
alias(libs.plugins.compose.compiler)
|
||||
alias(libs.plugins.serialization)
|
||||
}
|
||||
android.buildFeatures.buildConfig true
|
||||
|
||||
android {
|
||||
namespace 'io.github.chinosk.gakumas.localify'
|
||||
@@ -38,39 +39,39 @@ android {
|
||||
}
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
sourceCompatibility JavaVersion.VERSION_11
|
||||
targetCompatibility JavaVersion.VERSION_11
|
||||
}
|
||||
kotlinOptions {
|
||||
jvmTarget = '1.8'
|
||||
jvmTarget = '11'
|
||||
}
|
||||
buildFeatures {
|
||||
buildConfig true
|
||||
compose true
|
||||
prefab true
|
||||
}
|
||||
composeOptions {
|
||||
kotlinCompilerExtensionVersion '1.5.1'
|
||||
}
|
||||
packaging {
|
||||
resources {
|
||||
excludes += '/META-INF/{AL2.0,LGPL2.1}'
|
||||
}
|
||||
}
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
path file('src/main/cpp/CMakeLists.txt')
|
||||
version '3.22.1'
|
||||
}
|
||||
}
|
||||
packagingOptions {
|
||||
pickFirst '**/libxdl.so'
|
||||
pickFirst '**/libshadowhook.so'
|
||||
exclude 'gakumas-local/gakuen-adapted-translation-data/**'
|
||||
}
|
||||
dataBinding {
|
||||
enable true
|
||||
}
|
||||
|
||||
packaging {
|
||||
jniLibs {
|
||||
pickFirsts += "**/libxdl.so"
|
||||
pickFirsts += "**/libshadowhook.so"
|
||||
}
|
||||
resources {
|
||||
excludes += "**/META-INF/{AL2.0,LGPL2.1}"
|
||||
excludes += "kotlin/**"
|
||||
excludes += "**.bin"
|
||||
}
|
||||
}
|
||||
|
||||
applicationVariants.configureEach { variant ->
|
||||
variant.mergeAssetsProvider.configure { mergeAssetsTask ->
|
||||
mergeAssetsTask.doLast {
|
||||
@@ -83,42 +84,40 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(libs.androidx.core.ktx)
|
||||
implementation(libs.androidx.lifecycle.runtime.ktx)
|
||||
implementation(libs.androidx.material3)
|
||||
implementation(libs.material)
|
||||
|
||||
implementation 'androidx.core:core-ktx:1.13.1'
|
||||
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.8.2'
|
||||
implementation 'androidx.compose.material3:material3'
|
||||
implementation 'com.google.android.material:material:1.12.0'
|
||||
implementation(libs.androidx.activity.compose)
|
||||
implementation(libs.androidx.appcompat)
|
||||
implementation(libs.androidx.navigation.compose)
|
||||
|
||||
implementation "androidx.activity:activity-compose:1.9.0"
|
||||
implementation "androidx.appcompat:appcompat:1.7.0"
|
||||
implementation 'androidx.navigation:navigation-compose:2.7.7'
|
||||
|
||||
def composeBom = platform('androidx.compose:compose-bom:2024.06.00')
|
||||
def composeBom = platform(libs.androidx.compose.bom)
|
||||
implementation(composeBom)
|
||||
androidTestImplementation(composeBom)
|
||||
implementation "androidx.compose.runtime:runtime"
|
||||
implementation "androidx.compose.material:material"
|
||||
implementation "androidx.compose.foundation:foundation"
|
||||
implementation "androidx.compose.foundation:foundation-layout"
|
||||
implementation "androidx.compose.animation:animation"
|
||||
implementation "androidx.compose.ui:ui-tooling-preview"
|
||||
androidTestImplementation "androidx.compose.ui:ui-test-junit4"
|
||||
debugImplementation "androidx.compose.ui:ui-tooling"
|
||||
debugImplementation "androidx.compose.ui:ui-test-manifest"
|
||||
implementation "com.google.accompanist:accompanist-pager:0.30.0"
|
||||
implementation "com.google.accompanist:accompanist-pager-indicators:0.30.0"
|
||||
implementation "androidx.lifecycle:lifecycle-viewmodel-compose:2.8.2"
|
||||
implementation(libs.androidx.runtime)
|
||||
implementation(libs.androidx.material)
|
||||
implementation(libs.androidx.foundation)
|
||||
implementation(libs.androidx.foundation.layout)
|
||||
implementation(libs.androidx.animation)
|
||||
implementation(libs.androidx.ui.tooling.preview)
|
||||
androidTestImplementation(libs.androidx.ui.test.junit4)
|
||||
debugImplementation(libs.androidx.ui.tooling)
|
||||
debugImplementation(libs.androidx.ui.test.manifest)
|
||||
implementation(libs.accompanist.pager)
|
||||
implementation(libs.accompanist.pager.indicators)
|
||||
implementation(libs.androidx.lifecycle.viewmodel.compose)
|
||||
|
||||
implementation "io.coil-kt:coil-compose:2.6.0"
|
||||
implementation "io.coil-kt:coil-svg:2.6.0"
|
||||
implementation(libs.coil.compose)
|
||||
implementation(libs.coil.svg)
|
||||
|
||||
implementation(platform("com.squareup.okhttp3:okhttp-bom:4.12.0"))
|
||||
implementation "com.squareup.okhttp3:okhttp"
|
||||
implementation "com.squareup.okhttp3:logging-interceptor"
|
||||
implementation(platform(libs.okhttp.bom))
|
||||
implementation(libs.okhttp)
|
||||
implementation(libs.logging.interceptor)
|
||||
|
||||
implementation 'io.github.hexhacking:xdl:2.1.1'
|
||||
implementation 'com.bytedance.android:shadowhook:1.0.9'
|
||||
compileOnly 'de.robv.android.xposed:api:82'
|
||||
implementation "org.jetbrains.kotlin:kotlin-reflect:1.9.22"
|
||||
implementation 'com.google.code.gson:gson:2.11.0'
|
||||
implementation(libs.xdl)
|
||||
implementation(libs.shadowhook)
|
||||
compileOnly(libs.xposed.api)
|
||||
implementation(libs.kotlinx.serialization.json)
|
||||
}
|
||||
7
app/proguard-rules.pro
vendored
7
app/proguard-rules.pro
vendored
@@ -18,4 +18,9 @@
|
||||
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
||||
#-renamesourcefileattribute SourceFile
|
||||
|
||||
-keep class io.github.chinosk.gakumas.localify.GakumasHookMain {
|
||||
<init>();
|
||||
native <methods>;
|
||||
}
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:exported="true"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/Theme.GakumasLocalify">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
package io.github.chinosk.gakumas.localify
|
||||
|
||||
import android.view.KeyEvent
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import io.github.chinosk.gakumas.localify.databinding.ActivityMainBinding
|
||||
|
||||
@@ -16,7 +16,6 @@ import android.view.MotionEvent
|
||||
import android.widget.Toast
|
||||
import com.bytedance.shadowhook.ShadowHook
|
||||
import com.bytedance.shadowhook.ShadowHook.ConfigBuilder
|
||||
import com.google.gson.Gson
|
||||
import de.robv.android.xposed.IXposedHookLoadPackage
|
||||
import de.robv.android.xposed.IXposedHookZygoteInit
|
||||
import de.robv.android.xposed.XC_MethodHook
|
||||
@@ -33,11 +32,9 @@ import kotlinx.coroutines.launch
|
||||
import java.io.File
|
||||
import java.util.Locale
|
||||
import kotlin.system.measureTimeMillis
|
||||
import android.content.ContentResolver
|
||||
import io.github.chinosk.gakumas.localify.hookUtils.FileHotUpdater
|
||||
import io.github.chinosk.gakumas.localify.mainUtils.json
|
||||
import io.github.chinosk.gakumas.localify.models.ProgramConfig
|
||||
import java.io.BufferedReader
|
||||
import java.io.InputStreamReader
|
||||
|
||||
val TAG = "GakumasLocalify"
|
||||
|
||||
@@ -225,13 +222,17 @@ class GakumasHookMain : IXposedHookLoadPackage, IXposedHookZygoteInit {
|
||||
if (gkmsData != null) {
|
||||
gkmsDataInited = true
|
||||
val initConfig = try {
|
||||
Gson().fromJson(gkmsData, GakumasConfig::class.java)
|
||||
json.decodeFromString<GakumasConfig>(gkmsData)
|
||||
}
|
||||
catch (e: Exception) {
|
||||
null
|
||||
}
|
||||
val programConfig = try {
|
||||
Gson().fromJson(programData, ProgramConfig::class.java)
|
||||
if (programData == null) {
|
||||
ProgramConfig()
|
||||
} else {
|
||||
json.decodeFromString<ProgramConfig>(programData)
|
||||
}
|
||||
}
|
||||
catch (e: Exception) {
|
||||
null
|
||||
|
||||
@@ -15,23 +15,22 @@ import androidx.compose.runtime.collectAsState
|
||||
import androidx.core.content.FileProvider
|
||||
import androidx.databinding.DataBindingUtil
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import com.google.gson.ExclusionStrategy
|
||||
import com.google.gson.FieldAttributes
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.GsonBuilder
|
||||
import com.google.gson.JsonSyntaxException
|
||||
import io.github.chinosk.gakumas.localify.databinding.ActivityMainBinding
|
||||
import io.github.chinosk.gakumas.localify.hookUtils.FileHotUpdater
|
||||
import io.github.chinosk.gakumas.localify.hookUtils.FilesChecker
|
||||
import io.github.chinosk.gakumas.localify.hookUtils.MainKeyEventDispatcher
|
||||
import io.github.chinosk.gakumas.localify.mainUtils.json
|
||||
import io.github.chinosk.gakumas.localify.models.GakumasConfig
|
||||
import io.github.chinosk.gakumas.localify.models.ProgramConfig
|
||||
import io.github.chinosk.gakumas.localify.models.ProgramConfigSerializer
|
||||
import io.github.chinosk.gakumas.localify.models.ProgramConfigViewModel
|
||||
import io.github.chinosk.gakumas.localify.models.ProgramConfigViewModelFactory
|
||||
import io.github.chinosk.gakumas.localify.ui.pages.MainUI
|
||||
import io.github.chinosk.gakumas.localify.ui.theme.GakumasLocalifyTheme
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.serialization.SerializationException
|
||||
import kotlinx.serialization.encodeToString
|
||||
import java.io.File
|
||||
|
||||
|
||||
@@ -78,8 +77,8 @@ class MainActivity : ComponentActivity(), ConfigUpdateListener {
|
||||
}
|
||||
}
|
||||
|
||||
private fun getProgramConfigContent(excludes: List<String>? = null): String {
|
||||
if (excludes == null) {
|
||||
private fun getProgramConfigContent(excludes: List<String> = emptyList()): String {
|
||||
if (excludes.isEmpty()) {
|
||||
val configFile = File(filesDir, "localify-config.json")
|
||||
return if (configFile.exists()) {
|
||||
configFile.readText()
|
||||
@@ -89,18 +88,7 @@ class MainActivity : ComponentActivity(), ConfigUpdateListener {
|
||||
}
|
||||
}
|
||||
else {
|
||||
val gson = GsonBuilder()
|
||||
.setExclusionStrategies(object : ExclusionStrategy {
|
||||
override fun shouldSkipField(f: FieldAttributes): Boolean {
|
||||
return excludes.contains(f.name)
|
||||
}
|
||||
|
||||
override fun shouldSkipClass(clazz: Class<*>): Boolean {
|
||||
return false
|
||||
}
|
||||
})
|
||||
.create()
|
||||
return gson.toJson(programConfig)
|
||||
return json.encodeToString(ProgramConfigSerializer(excludes), programConfig)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,7 +101,7 @@ class MainActivity : ComponentActivity(), ConfigUpdateListener {
|
||||
Log.d(TAG, e.toString())
|
||||
}
|
||||
val configFile = File(filesDir, "gkms-config.json")
|
||||
configFile.writeText(Gson().toJson(binding.config!!))
|
||||
configFile.writeText(json.encodeToString(binding.config!!))
|
||||
}
|
||||
|
||||
override fun saveProgramConfig() {
|
||||
@@ -125,7 +113,7 @@ class MainActivity : ComponentActivity(), ConfigUpdateListener {
|
||||
Log.d(TAG, e.toString())
|
||||
}
|
||||
val configFile = File(filesDir, "localify-config.json")
|
||||
configFile.writeText(Gson().toJson(programConfig))
|
||||
configFile.writeText(json.encodeToString(programConfig))
|
||||
}
|
||||
|
||||
fun getVersion(): List<String> {
|
||||
@@ -155,20 +143,20 @@ class MainActivity : ComponentActivity(), ConfigUpdateListener {
|
||||
private fun loadConfig() {
|
||||
val configStr = getConfigContent()
|
||||
binding.config = try {
|
||||
Gson().fromJson(configStr, GakumasConfig::class.java)
|
||||
json.decodeFromString<GakumasConfig>(configStr)
|
||||
}
|
||||
catch (e: JsonSyntaxException) {
|
||||
catch (e: SerializationException) {
|
||||
showToast("配置文件异常,已重置: $e")
|
||||
Gson().fromJson("{}", GakumasConfig::class.java)
|
||||
GakumasConfig()
|
||||
}
|
||||
saveConfig()
|
||||
|
||||
val programConfigStr = getProgramConfigContent()
|
||||
programConfig = try {
|
||||
Gson().fromJson(programConfigStr, ProgramConfig::class.java)
|
||||
json.decodeFromString<ProgramConfig>(programConfigStr)
|
||||
}
|
||||
catch (e: JsonSyntaxException) {
|
||||
Gson().fromJson("{}", ProgramConfig::class.java)
|
||||
catch (e: SerializationException) {
|
||||
ProgramConfig()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
package io.github.chinosk.gakumas.localify.hookUtils
|
||||
|
||||
import android.util.Log
|
||||
import android.view.KeyEvent
|
||||
|
||||
object MainKeyEventDispatcher {
|
||||
private val targetDbgKeyList: IntArray = intArrayOf(19, 19, 20, 20, 21, 22, 21, 22, 30, 29)
|
||||
private var currentIndex = 0;
|
||||
private var currentIndex = 0
|
||||
|
||||
fun checkDbgKey(code: Int, action: Int): Boolean {
|
||||
if (action == KeyEvent.ACTION_UP) return false
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package io.github.chinosk.gakumas.localify.mainUtils
|
||||
|
||||
import kotlinx.serialization.json.Json
|
||||
|
||||
val json = Json {
|
||||
encodeDefaults = true
|
||||
}
|
||||
@@ -1,24 +1,31 @@
|
||||
package io.github.chinosk.gakumas.localify.models
|
||||
|
||||
data class AboutPageConfig (
|
||||
var plugin_repo: String = "https://github.com/chinosk6/gakuen-imas-localify",
|
||||
var main_contributors: List<MainContributors> = listOf(),
|
||||
var contrib_img: ContribImg = ContribImg(
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class AboutPageConfig(
|
||||
val plugin_repo: String = "https://github.com/chinosk6/gakuen-imas-localify",
|
||||
val main_contributors: List<MainContributors> = listOf(),
|
||||
val contrib_img: ContribImg = ContribImg(
|
||||
"https://contrib.rocks/image?repo=chinosk6/gakuen-imas-localify",
|
||||
"https://contrib.rocks/image?repo=chinosk6/GakumasTranslationData")
|
||||
"https://contrib.rocks/image?repo=chinosk6/GakumasTranslationData"
|
||||
)
|
||||
)
|
||||
|
||||
data class MainContributors (
|
||||
var name: String,
|
||||
var links: List<Links>
|
||||
@Serializable
|
||||
data class MainContributors(
|
||||
val name: String,
|
||||
val links: List<Links>
|
||||
)
|
||||
|
||||
data class ContribImg (
|
||||
var plugin: String,
|
||||
var translation: String
|
||||
@Serializable
|
||||
data class ContribImg(
|
||||
val plugin: String,
|
||||
val translation: String
|
||||
)
|
||||
|
||||
data class Links (
|
||||
var name: String,
|
||||
var link: String
|
||||
)
|
||||
@Serializable
|
||||
data class Links(
|
||||
val name: String,
|
||||
val link: String
|
||||
)
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package io.github.chinosk.gakumas.localify.models
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class GakumasConfig (
|
||||
var dbgMode: Boolean = false,
|
||||
var enabled: Boolean = true,
|
||||
|
||||
@@ -1,12 +1,41 @@
|
||||
package io.github.chinosk.gakumas.localify.models
|
||||
|
||||
import io.github.chinosk.gakumas.localify.mainUtils.json
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.descriptors.SerialDescriptor
|
||||
import kotlinx.serialization.encoding.Decoder
|
||||
import kotlinx.serialization.encoding.Encoder
|
||||
import kotlinx.serialization.encoding.encodeStructure
|
||||
import kotlinx.serialization.json.JsonElement
|
||||
import kotlinx.serialization.json.encodeToJsonElement
|
||||
import kotlinx.serialization.json.jsonObject
|
||||
|
||||
data class ProgramConfig (
|
||||
@Serializable
|
||||
data class ProgramConfig(
|
||||
var checkBuiltInAssets: Boolean = true,
|
||||
var transRemoteZipUrl: String = "",
|
||||
var useRemoteAssets: Boolean = false,
|
||||
var delRemoteAfterUpdate: Boolean = true,
|
||||
var cleanLocalAssets: Boolean = false,
|
||||
|
||||
var p: Boolean = false
|
||||
)
|
||||
|
||||
class ProgramConfigSerializer(
|
||||
private val excludes: List<String> = emptyList(),
|
||||
) : KSerializer<ProgramConfig> {
|
||||
override val descriptor: SerialDescriptor = ProgramConfig.serializer().descriptor
|
||||
override fun serialize(encoder: Encoder, value: ProgramConfig) {
|
||||
val jsonObject = json.encodeToJsonElement(value).jsonObject
|
||||
encoder.encodeStructure(descriptor) {
|
||||
jsonObject.keys.forEachIndexed { index, k ->
|
||||
if (k in excludes) return@forEachIndexed
|
||||
encodeSerializableElement(descriptor, index, JsonElement.serializer(), jsonObject[k]!!)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun deserialize(decoder: Decoder): ProgramConfig {
|
||||
return ProgramConfig.serializer().deserialize(decoder)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,10 +28,10 @@ import coil.compose.rememberAsyncImagePainter
|
||||
import coil.decode.SvgDecoder
|
||||
import coil.request.ImageRequest
|
||||
import coil.size.Size
|
||||
import com.google.gson.Gson
|
||||
import io.github.chinosk.gakumas.localify.MainActivity
|
||||
import io.github.chinosk.gakumas.localify.R
|
||||
import io.github.chinosk.gakumas.localify.hookUtils.FilesChecker.convertToString
|
||||
import io.github.chinosk.gakumas.localify.mainUtils.json
|
||||
import io.github.chinosk.gakumas.localify.models.AboutPageConfig
|
||||
import io.github.chinosk.gakumas.localify.models.GakumasConfig
|
||||
import io.github.chinosk.gakumas.localify.ui.components.GakuButton
|
||||
@@ -48,7 +48,7 @@ fun AboutPage(modifier: Modifier = Modifier,
|
||||
val dataJsonString = context?.getString(R.string.about_contributors_asset_file)?.let {
|
||||
convertToString(context.assets?.open(it))
|
||||
}
|
||||
Gson().fromJson(dataJsonString, AboutPageConfig::class.java)
|
||||
dataJsonString?.let { json.decodeFromString<AboutPageConfig>(it) }
|
||||
?: AboutPageConfig()
|
||||
}
|
||||
|
||||
@@ -137,7 +137,7 @@ fun AboutPage(modifier: Modifier = Modifier,
|
||||
url = contributorInfo.contrib_img.plugin,
|
||||
contentDescription = "plugin-contrib"
|
||||
)
|
||||
|
||||
|
||||
Spacer(modifier = Modifier.height(4.dp))
|
||||
Text(stringResource(R.string.translation_repository), fontSize = 16.sp)
|
||||
NetworkSvgImage(
|
||||
|
||||
Reference in New Issue
Block a user