1
0

Merge pull request #36 from keta1/main

add windowBackground
optimize code structure
This commit is contained in:
chinosk 2024-06-29 09:28:22 -05:00 committed by GitHub
commit d84ba3d245
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
23 changed files with 290 additions and 1546 deletions

View File

@ -72,8 +72,10 @@ jobs:
keyStorePassword: ${{ secrets.ANDROID_KEYSTORE_PASSWORD }}
keyPassword: ${{ secrets.ANDROID_KEY_PASSWORD }}
buildToolsVersion: 33.0.0
continue-on-error: true
- uses: actions/upload-artifact@v4
with:
name: GakumasLocalify-Signed-apk
path: ${{steps.sign_app.outputs.signedFile}}
continue-on-error: true

View File

@ -36,6 +36,7 @@ android {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
buildConfigField "boolean", "ENABLE_LOG", "true"
signingConfig signingConfigs.debug
}
}
compileOptions {
@ -56,9 +57,6 @@ android {
version '3.22.1'
}
}
dataBinding {
enable true
}
packaging {
jniLibs {

View File

@ -2,17 +2,17 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:usesCleartextTraffic="true"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/Theme.GakumasLocalify"
android:usesCleartextTraffic="true"
tools:targetApi="31">
<meta-data
@ -43,14 +43,21 @@
</intent-filter>
</activity>
<activity
android:name=".TranslucentActivity"
android:exported="true"
android:theme="@style/Theme.GakumasLocalify.NoDisplay">
</activity>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
</application>

View File

@ -0,0 +1,104 @@
package io.github.chinosk.gakumas.localify
import android.app.Activity
import android.content.Intent
import androidx.core.content.FileProvider
import io.github.chinosk.gakumas.localify.GakumasHookMain.Companion.showToast
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 kotlinx.serialization.SerializationException
import java.io.File
interface IHasConfigItems {
var config: GakumasConfig
var programConfig: ProgramConfig
fun saveConfig() {} // do nothing
}
interface IConfigurableActivity<T : Activity> : IHasConfigItems
fun <T> T.getConfigContent(): String where T : Activity {
val configFile = File(filesDir, "gkms-config.json")
return if (configFile.exists()) {
configFile.readText()
} else {
showToast("检测到第一次启动,初始化配置文件...")
"{}"
}
}
fun <T> T.getProgramConfigContent(
excludes: List<String> = emptyList(),
origProgramConfig: ProgramConfig? = null
): String where T : Activity {
val configFile = File(filesDir, "localify-config.json")
if (excludes.isEmpty()) {
return if (configFile.exists()) {
configFile.readText()
} else {
"{}"
}
} else {
return if (origProgramConfig == null) {
if (configFile.exists()) {
val parsedConfig = json.decodeFromString<ProgramConfig>(configFile.readText())
json.encodeToString(ProgramConfigSerializer(excludes), parsedConfig)
} else {
"{}"
}
} else {
json.encodeToString(ProgramConfigSerializer(excludes), origProgramConfig)
}
}
}
fun <T> T.loadConfig() where T : Activity, T : IHasConfigItems {
val configStr = getConfigContent()
config = try {
json.decodeFromString<GakumasConfig>(configStr)
} catch (e: SerializationException) {
showToast("配置文件异常,已重置: $e")
GakumasConfig()
}
saveConfig()
val programConfigStr = getProgramConfigContent()
programConfig = try {
json.decodeFromString<ProgramConfig>(programConfigStr)
} catch (e: SerializationException) {
ProgramConfig()
}
}
fun <T> T.onClickStartGame() where T : Activity, T : IHasConfigItems {
val intent = Intent().apply {
setClassName(
"com.bandainamcoent.idolmaster_gakuen",
"com.google.firebase.MessagingUnityPlayerActivity"
)
putExtra("gkmsData", getConfigContent())
putExtra(
"localData",
getProgramConfigContent(listOf("transRemoteZipUrl", "p"), programConfig)
)
flags = Intent.FLAG_ACTIVITY_NEW_TASK
}
val updateFile = File(filesDir, "update_trans.zip")
if (updateFile.exists()) {
val dirUri = FileProvider.getUriForFile(
this,
"io.github.chinosk.gakumas.localify.fileprovider",
File(updateFile.absolutePath)
)
intent.setDataAndType(dirUri, "resource/file")
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
}
startActivity(intent)
}

View File

@ -3,7 +3,6 @@ package io.github.chinosk.gakumas.localify
import android.view.KeyEvent
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import io.github.chinosk.gakumas.localify.databinding.ActivityMainBinding
import io.github.chinosk.gakumas.localify.models.GakumasConfig
import io.github.chinosk.gakumas.localify.models.ProgramConfig
import io.github.chinosk.gakumas.localify.models.ProgramConfigViewModel
@ -14,7 +13,6 @@ import kotlinx.coroutines.flow.asStateFlow
interface ConfigListener {
fun onClickStartGame()
fun onEnabledChanged(value: Boolean)
fun onForceExportResourceChanged(value: Boolean)
fun onTextTestChanged(value: Boolean)
@ -82,57 +80,54 @@ class UserConfigViewModel(initValue: GakumasConfig) : ViewModel() {
}
interface ConfigUpdateListener: ConfigListener {
var binding: ActivityMainBinding
interface ConfigUpdateListener: ConfigListener, IHasConfigItems {
var factory: UserConfigViewModelFactory
var viewModel: UserConfigViewModel
var programConfig: ProgramConfig
var programConfigFactory: ProgramConfigViewModelFactory
var programConfigViewModel: ProgramConfigViewModel
fun pushKeyEvent(event: KeyEvent): Boolean
fun getConfigContent(): String
fun checkConfigAndUpdateView()
fun saveConfig()
fun checkConfigAndUpdateView() {} // do nothing
// fun saveConfig()
fun saveProgramConfig()
override fun onEnabledChanged(value: Boolean) {
binding.config!!.enabled = value
config.enabled = value
saveConfig()
pushKeyEvent(KeyEvent(1145, 29))
}
override fun onForceExportResourceChanged(value: Boolean) {
binding.config!!.forceExportResource = value
config.forceExportResource = value
saveConfig()
pushKeyEvent(KeyEvent(1145, 30))
}
override fun onReplaceFontChanged(value: Boolean) {
binding.config!!.replaceFont = value
config.replaceFont = value
saveConfig()
pushKeyEvent(KeyEvent(1145, 30))
}
override fun onTextTestChanged(value: Boolean) {
binding.config!!.textTest = value
config.textTest = value
saveConfig()
}
override fun onDumpTextChanged(value: Boolean) {
binding.config!!.dumpText = value
config.dumpText = value
saveConfig()
}
override fun onEnableFreeCameraChanged(value: Boolean) {
binding.config!!.enableFreeCamera = value
config.enableFreeCamera = value
saveConfig()
}
override fun onUnlockAllLiveChanged(value: Boolean) {
binding.config!!.unlockAllLive = value
config.unlockAllLive = value
saveConfig()
}
@ -145,7 +140,7 @@ interface ConfigUpdateListener: ConfigListener {
} else {
valueStr.toInt()
}
binding.config!!.targetFrameRate = value
config.targetFrameRate = value
saveConfig()
}
catch (e: Exception) {
@ -154,22 +149,22 @@ interface ConfigUpdateListener: ConfigListener {
}
override fun onLiveCustomeDressChanged(value: Boolean) {
binding.config!!.enableLiveCustomeDress = value
config.enableLiveCustomeDress = value
saveConfig()
}
override fun onLiveCustomeCostumeIdChanged(s: CharSequence, start: Int, before: Int, count: Int) {
binding.config!!.liveCustomeCostumeId = s.toString()
config.liveCustomeCostumeId = s.toString()
saveConfig()
}
override fun onUseCustomeGraphicSettingsChanged(value: Boolean) {
binding.config!!.useCustomeGraphicSettings = value
config.useCustomeGraphicSettings = value
saveConfig()
}
override fun onRenderScaleChanged(s: CharSequence, start: Int, before: Int, count: Int) {
binding.config!!.renderScale = try {
config.renderScale = try {
s.toString().toFloat()
}
catch (e: Exception) {
@ -179,7 +174,7 @@ interface ConfigUpdateListener: ConfigListener {
}
override fun onQualitySettingsLevelChanged(s: CharSequence, start: Int, before: Int, count: Int) {
binding.config!!.qualitySettingsLevel = try {
config.qualitySettingsLevel = try {
s.toString().toInt()
}
catch (e: Exception) {
@ -189,7 +184,7 @@ interface ConfigUpdateListener: ConfigListener {
}
override fun onVolumeIndexChanged(s: CharSequence, start: Int, before: Int, count: Int) {
binding.config!!.volumeIndex = try {
config.volumeIndex = try {
s.toString().toInt()
}
catch (e: Exception) {
@ -199,7 +194,7 @@ interface ConfigUpdateListener: ConfigListener {
}
override fun onMaxBufferPixelChanged(s: CharSequence, start: Int, before: Int, count: Int) {
binding.config!!.maxBufferPixel = try {
config.maxBufferPixel = try {
s.toString().toInt()
}
catch (e: Exception) {
@ -209,12 +204,12 @@ interface ConfigUpdateListener: ConfigListener {
}
override fun onLiveCustomeHeadIdChanged(s: CharSequence, start: Int, before: Int, count: Int) {
binding.config!!.liveCustomeHeadId = s.toString()
config.liveCustomeHeadId = s.toString()
saveConfig()
}
override fun onReflectionQualityLevelChanged(s: CharSequence, start: Int, before: Int, count: Int) {
binding.config!!.reflectionQualityLevel = try {
config.reflectionQualityLevel = try {
val value = s.toString().toInt()
if (value > 5) 5 else value
}
@ -225,7 +220,7 @@ interface ConfigUpdateListener: ConfigListener {
}
override fun onLodQualityLevelChanged(s: CharSequence, start: Int, before: Int, count: Int) {
binding.config!!.lodQualityLevel = try {
config.lodQualityLevel = try {
val value = s.toString().toInt()
if (value > 5) 5 else value
}
@ -238,44 +233,44 @@ interface ConfigUpdateListener: ConfigListener {
override fun onChangePresetQuality(level: Int) {
when (level) {
0 -> {
binding.config!!.renderScale = 0.5f
binding.config!!.qualitySettingsLevel = 1
binding.config!!.volumeIndex = 0
binding.config!!.maxBufferPixel = 1024
binding.config!!.lodQualityLevel = 1
binding.config!!.reflectionQualityLevel = 1
config.renderScale = 0.5f
config.qualitySettingsLevel = 1
config.volumeIndex = 0
config.maxBufferPixel = 1024
config.lodQualityLevel = 1
config.reflectionQualityLevel = 1
}
1 -> {
binding.config!!.renderScale = 0.59f
binding.config!!.qualitySettingsLevel = 1
binding.config!!.volumeIndex = 1
binding.config!!.maxBufferPixel = 1440
binding.config!!.lodQualityLevel = 2
binding.config!!.reflectionQualityLevel = 2
config.renderScale = 0.59f
config.qualitySettingsLevel = 1
config.volumeIndex = 1
config.maxBufferPixel = 1440
config.lodQualityLevel = 2
config.reflectionQualityLevel = 2
}
2 -> {
binding.config!!.renderScale = 0.67f
binding.config!!.qualitySettingsLevel = 2
binding.config!!.volumeIndex = 2
binding.config!!.maxBufferPixel = 2538
binding.config!!.lodQualityLevel = 3
binding.config!!.reflectionQualityLevel = 3
config.renderScale = 0.67f
config.qualitySettingsLevel = 2
config.volumeIndex = 2
config.maxBufferPixel = 2538
config.lodQualityLevel = 3
config.reflectionQualityLevel = 3
}
3 -> {
binding.config!!.renderScale = 0.77f
binding.config!!.qualitySettingsLevel = 3
binding.config!!.volumeIndex = 3
binding.config!!.maxBufferPixel = 3384
binding.config!!.lodQualityLevel = 4
binding.config!!.reflectionQualityLevel = 4
config.renderScale = 0.77f
config.qualitySettingsLevel = 3
config.volumeIndex = 3
config.maxBufferPixel = 3384
config.lodQualityLevel = 4
config.reflectionQualityLevel = 4
}
4 -> {
binding.config!!.renderScale = 1.0f
binding.config!!.qualitySettingsLevel = 5
binding.config!!.volumeIndex = 4
binding.config!!.maxBufferPixel = 8190
binding.config!!.lodQualityLevel = 5
binding.config!!.reflectionQualityLevel = 5
config.renderScale = 1.0f
config.qualitySettingsLevel = 5
config.volumeIndex = 4
config.maxBufferPixel = 8190
config.lodQualityLevel = 5
config.reflectionQualityLevel = 5
}
}
checkConfigAndUpdateView()
@ -283,38 +278,31 @@ interface ConfigUpdateListener: ConfigListener {
}
override fun onGameOrientationChanged(checkedId: Int) {
when (checkedId) {
R.id.radioButtonGameDefault -> binding.config!!.gameOrientation = 0
R.id.radioButtonGamePortrait -> binding.config!!.gameOrientation = 1
R.id.radioButtonGameLandscape -> binding.config!!.gameOrientation = 2
else -> {
if (listOf(0, 1, 2).contains(checkedId)) {
binding.config!!.gameOrientation = checkedId
}
}
if (checkedId in listOf(0, 1, 2)) {
config.gameOrientation = checkedId
}
saveConfig()
}
override fun onEnableBreastParamChanged(value: Boolean) {
binding.config!!.enableBreastParam = value
config.enableBreastParam = value
saveConfig()
checkConfigAndUpdateView()
}
override fun onBUseArmCorrectionChanged(value: Boolean) {
binding.config!!.bUseArmCorrection = value
config.bUseArmCorrection = value
saveConfig()
}
override fun onBUseScaleChanged(value: Boolean) {
binding.config!!.bUseScale = value
config.bUseScale = value
saveConfig()
checkConfigAndUpdateView()
}
override fun onBDampingChanged(s: CharSequence, start: Int, before: Int, count: Int) {
binding.config!!.bDamping = try {
config.bDamping = try {
s.toString().toFloat()
}
catch (e: Exception) {
@ -324,7 +312,7 @@ interface ConfigUpdateListener: ConfigListener {
}
override fun onBStiffnessChanged(s: CharSequence, start: Int, before: Int, count: Int){
binding.config!!.bStiffness = try {
config.bStiffness = try {
s.toString().toFloat()
}
catch (e: Exception) {
@ -334,7 +322,7 @@ interface ConfigUpdateListener: ConfigListener {
}
override fun onBSpringChanged(s: CharSequence, start: Int, before: Int, count: Int){
binding.config!!.bSpring = try {
config.bSpring = try {
s.toString().toFloat()
}
catch (e: Exception) {
@ -344,7 +332,7 @@ interface ConfigUpdateListener: ConfigListener {
}
override fun onBPendulumChanged(s: CharSequence, start: Int, before: Int, count: Int){
binding.config!!.bPendulum = try {
config.bPendulum = try {
s.toString().toFloat()
}
catch (e: Exception) {
@ -354,7 +342,7 @@ interface ConfigUpdateListener: ConfigListener {
}
override fun onBPendulumRangeChanged(s: CharSequence, start: Int, before: Int, count: Int){
binding.config!!.bPendulumRange = try {
config.bPendulumRange = try {
s.toString().toFloat()
}
catch (e: Exception) {
@ -364,7 +352,7 @@ interface ConfigUpdateListener: ConfigListener {
}
override fun onBAverageChanged(s: CharSequence, start: Int, before: Int, count: Int){
binding.config!!.bAverage = try {
config.bAverage = try {
s.toString().toFloat()
}
catch (e: Exception) {
@ -374,7 +362,7 @@ interface ConfigUpdateListener: ConfigListener {
}
override fun onBRootWeightChanged(s: CharSequence, start: Int, before: Int, count: Int){
binding.config!!.bRootWeight = try {
config.bRootWeight = try {
s.toString().toFloat()
}
catch (e: Exception) {
@ -384,13 +372,13 @@ interface ConfigUpdateListener: ConfigListener {
}
override fun onBUseLimitChanged(value: Boolean){
binding.config!!.bUseLimit = value
config.bUseLimit = value
saveConfig()
checkConfigAndUpdateView()
}
override fun onBLimitXxChanged(s: CharSequence, start: Int, before: Int, count: Int) {
binding.config!!.bLimitXx = try {
config.bLimitXx = try {
s.toString().toFloat()
}
catch (e: Exception) {
@ -400,7 +388,7 @@ interface ConfigUpdateListener: ConfigListener {
}
override fun onBLimitXyChanged(s: CharSequence, start: Int, before: Int, count: Int) {
binding.config!!.bLimitXy = try {
config.bLimitXy = try {
s.toString().toFloat()
}
catch (e: Exception) {
@ -410,7 +398,7 @@ interface ConfigUpdateListener: ConfigListener {
}
override fun onBLimitYxChanged(s: CharSequence, start: Int, before: Int, count: Int) {
binding.config!!.bLimitYx = try {
config.bLimitYx = try {
s.toString().toFloat()
}
catch (e: Exception) {
@ -420,7 +408,7 @@ interface ConfigUpdateListener: ConfigListener {
}
override fun onBLimitYyChanged(s: CharSequence, start: Int, before: Int, count: Int) {
binding.config!!.bLimitYy = try {
config.bLimitYy = try {
s.toString().toFloat()
}
catch (e: Exception) {
@ -430,7 +418,7 @@ interface ConfigUpdateListener: ConfigListener {
}
override fun onBLimitZxChanged(s: CharSequence, start: Int, before: Int, count: Int) {
binding.config!!.bLimitZx = try {
config.bLimitZx = try {
s.toString().toFloat()
}
catch (e: Exception) {
@ -440,7 +428,7 @@ interface ConfigUpdateListener: ConfigListener {
}
override fun onBLimitZyChanged(s: CharSequence, start: Int, before: Int, count: Int) {
binding.config!!.bLimitZy = try {
config.bLimitZy = try {
s.toString().toFloat()
}
catch (e: Exception) {
@ -451,7 +439,7 @@ interface ConfigUpdateListener: ConfigListener {
override fun onBScaleChanged(s: CharSequence, start: Int, before: Int, count: Int) {
binding.config!!.bScale = try {
config.bScale = try {
s.toString().toFloat()
}
catch (e: Exception) {
@ -481,27 +469,27 @@ interface ConfigUpdateListener: ConfigListener {
1f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f)
}
binding.config!!.bDamping = setData[0]
binding.config!!.bStiffness = setData[1]
binding.config!!.bSpring = setData[2]
binding.config!!.bPendulum = setData[3]
binding.config!!.bPendulumRange = setData[4]
binding.config!!.bAverage = setData[5]
binding.config!!.bRootWeight = setData[6]
binding.config!!.bUseLimit = if (setData[7] == 0f) {
config.bDamping = setData[0]
config.bStiffness = setData[1]
config.bSpring = setData[2]
config.bPendulum = setData[3]
config.bPendulumRange = setData[4]
config.bAverage = setData[5]
config.bRootWeight = setData[6]
config.bUseLimit = if (setData[7] == 0f) {
false
}
else {
binding.config!!.bLimitXx = setData[8]
binding.config!!.bLimitXy = setData[9]
binding.config!!.bLimitYx = setData[10]
binding.config!!.bLimitYy = setData[11]
binding.config!!.bLimitZx = setData[12]
binding.config!!.bLimitZy = setData[13]
config.bLimitXx = setData[8]
config.bLimitXy = setData[9]
config.bLimitYx = setData[10]
config.bLimitYy = setData[11]
config.bLimitZx = setData[12]
config.bLimitZy = setData[13]
true
}
binding.config!!.bUseArmCorrection = true
config.bUseArmCorrection = true
checkConfigAndUpdateView()
saveConfig()
@ -539,5 +527,4 @@ interface ConfigUpdateListener: ConfigListener {
localResourceVersionState?.let{ programConfigViewModel.localResourceVersionState.value = localResourceVersionState }
errorString?.let{ programConfigViewModel.errorStringState.value = errorString }
}
}
}

View File

@ -347,7 +347,7 @@ class GakumasHookMain : IXposedHookLoadPackage, IXposedHookZygoteInit {
fun requestConfig(activity: Context) {
try {
val intent = Intent().apply {
setClassName("io.github.chinosk.gakumas.localify", "io.github.chinosk.gakumas.localify.MainActivity")
setClassName("io.github.chinosk.gakumas.localify", "io.github.chinosk.gakumas.localify.TranslucentActivity")
putExtra("gkmsData", "requestConfig")
flags = FLAG_ACTIVITY_NEW_TASK
}

View File

@ -12,30 +12,25 @@ import androidx.activity.compose.setContent
import androidx.compose.runtime.Composable
import androidx.compose.runtime.State
import androidx.compose.runtime.collectAsState
import androidx.core.content.FileProvider
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.ViewModelProvider
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
class MainActivity : ComponentActivity(), ConfigUpdateListener {
override lateinit var binding: ActivityMainBinding
class MainActivity : ComponentActivity(), ConfigUpdateListener, IConfigurableActivity<MainActivity> {
override lateinit var config: GakumasConfig
override lateinit var programConfig: ProgramConfig
override lateinit var factory: UserConfigViewModelFactory
@ -44,64 +39,21 @@ class MainActivity : ComponentActivity(), ConfigUpdateListener {
override lateinit var programConfigFactory: ProgramConfigViewModelFactory
override lateinit var programConfigViewModel: ProgramConfigViewModel
override fun onClickStartGame() {
val intent = Intent().apply {
setClassName("com.bandainamcoent.idolmaster_gakuen", "com.google.firebase.MessagingUnityPlayerActivity")
putExtra("gkmsData", getConfigContent())
putExtra("localData", getProgramConfigContent(listOf("transRemoteZipUrl", "p")))
flags = Intent.FLAG_ACTIVITY_NEW_TASK
}
val updateFile = File(filesDir, "update_trans.zip")
if (updateFile.exists()) {
val dirUri = FileProvider.getUriForFile(this, "io.github.chinosk.gakumas.localify.fileprovider", File(updateFile.absolutePath))
intent.setDataAndType(dirUri, "resource/file")
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
}
startActivity(intent)
}
private fun showToast(message: String) {
Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
}
override fun getConfigContent(): String {
val configFile = File(filesDir, "gkms-config.json")
return if (configFile.exists()) {
configFile.readText()
}
else {
showToast("检测到第一次启动,初始化配置文件...")
"{}"
}
}
private fun getProgramConfigContent(excludes: List<String> = emptyList()): String {
if (excludes.isEmpty()) {
val configFile = File(filesDir, "localify-config.json")
return if (configFile.exists()) {
configFile.readText()
}
else {
"{}"
}
}
else {
return json.encodeToString(ProgramConfigSerializer(excludes), programConfig)
}
}
override fun saveConfig() {
try {
binding.config!!.pf = false
viewModel.configState.value = binding.config!!.copy( pf = true ) // 更新 UI
config.pf = false
viewModel.configState.value = config.copy( pf = true ) // 更新 UI
}
catch (e: RuntimeException) {
Log.d(TAG, e.toString())
}
val configFile = File(filesDir, "gkms-config.json")
configFile.writeText(json.encodeToString(binding.config!!))
configFile.writeText(json.encodeToString(config))
}
override fun saveProgramConfig() {
@ -140,31 +92,6 @@ class MainActivity : ComponentActivity(), ConfigUpdateListener {
startActivity(intent)
}
private fun loadConfig() {
val configStr = getConfigContent()
binding.config = try {
json.decodeFromString<GakumasConfig>(configStr)
}
catch (e: SerializationException) {
showToast("配置文件异常,已重置: $e")
GakumasConfig()
}
saveConfig()
val programConfigStr = getProgramConfigContent()
programConfig = try {
json.decodeFromString<ProgramConfig>(programConfigStr)
}
catch (e: SerializationException) {
ProgramConfig()
}
}
override fun checkConfigAndUpdateView() {
binding.config = binding.config
binding.notifyChange()
}
override fun pushKeyEvent(event: KeyEvent): Boolean {
return dispatchKeyEvent(event)
}
@ -173,13 +100,11 @@ class MainActivity : ComponentActivity(), ConfigUpdateListener {
override fun dispatchKeyEvent(event: KeyEvent): Boolean {
// Log.d(TAG, "${event.keyCode}, ${event.action}")
if (MainKeyEventDispatcher.checkDbgKey(event.keyCode, event.action)) {
val origDbg = binding.config?.dbgMode
if (origDbg != null) {
binding.config!!.dbgMode = !origDbg
checkConfigAndUpdateView()
saveConfig()
showToast("TestMode: ${!origDbg}")
}
val origDbg = config.dbgMode
config.dbgMode = !origDbg
checkConfigAndUpdateView()
saveConfig()
showToast("TestMode: ${!origDbg}")
}
return if (event.action == 1145) true else super.dispatchKeyEvent(event)
}
@ -187,19 +112,9 @@ class MainActivity : ComponentActivity(), ConfigUpdateListener {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main)
loadConfig()
binding.listener = this
val requestData = intent.getStringExtra("gkmsData")
if (requestData != null) {
if (requestData == "requestConfig") {
onClickStartGame()
finish()
}
}
factory = UserConfigViewModelFactory(binding.config!!)
factory = UserConfigViewModelFactory(config)
viewModel = ViewModelProvider(this, factory)[UserConfigViewModel::class.java]
programConfigFactory = ProgramConfigViewModelFactory(programConfig,
@ -210,18 +125,7 @@ class MainActivity : ComponentActivity(), ConfigUpdateListener {
setContent {
GakumasLocalifyTheme(dynamicColor = false, darkTheme = false) {
MainUI(context = this)
/*
val navController = rememberNavController()
NavHost(navController, startDestination = "splash") {
composable("splash") {
SplashScreen(navController)
}
composable("main") {
MainUI(context = this@MainActivity)
}
}*/
}
}
}
}
@ -292,150 +196,3 @@ fun getProgramDownloadErrorStringState(context: MainActivity?): State<String> {
configMSF.asStateFlow().collectAsState()
}
}
/*
class OldActivity : AppCompatActivity(), ConfigUpdateListener {
override lateinit var binding: ActivityMainBinding
private val TAG = "GakumasLocalify"
override lateinit var factory: UserConfigViewModelFactory // No usage
override lateinit var viewModel: UserConfigViewModel // No usage
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
binding = DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main)
loadConfig()
binding.listener = this
val requestData = intent.getStringExtra("gkmsData")
if (requestData != null) {
if (requestData == "requestConfig") {
onClickStartGame()
finish()
}
}
showVersion()
val scrollView: ScrollView = findViewById(R.id.scrollView)
scrollView.viewTreeObserver.addOnScrollChangedListener { onScrollChanged() }
onScrollChanged()
val coordinatorLayout = findViewById<View>(R.id.coordinatorLayout)
coordinatorLayout.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
override fun onGlobalLayout() {
onScrollChanged()
coordinatorLayout.viewTreeObserver.removeOnGlobalLayoutListener(this)
}
})
}
override fun onClickStartGame() {
val intent = Intent().apply {
setClassName("com.bandainamcoent.idolmaster_gakuen", "com.google.firebase.MessagingUnityPlayerActivity")
putExtra("gkmsData", getConfigContent())
flags = Intent.FLAG_ACTIVITY_NEW_TASK
}
startActivity(intent)
}
private fun onScrollChanged() {
val fab: FloatingActionButton = findViewById(R.id.fabStartGame)
val startGameButton: MaterialButton = findViewById(R.id.StartGameButton)
val scrollView: ScrollView = findViewById(R.id.scrollView)
val location = IntArray(2)
startGameButton.getLocationOnScreen(location)
val buttonTop = location[1]
val buttonBottom = buttonTop + startGameButton.height
val scrollViewLocation = IntArray(2)
scrollView.getLocationOnScreen(scrollViewLocation)
val scrollViewTop = scrollViewLocation[1]
val scrollViewBottom = scrollViewTop + scrollView.height
val isButtonVisible = buttonTop >= scrollViewTop && buttonBottom <= scrollViewBottom
if (isButtonVisible) {
fab.hide()
} else {
fab.show()
}
}
private fun showToast(message: String) {
Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
}
override fun getConfigContent(): String {
val configFile = File(filesDir, "gkms-config.json")
return if (configFile.exists()) {
configFile.readText()
}
else {
showToast("检测到第一次启动,初始化配置文件...")
"{}"
}
}
override fun saveConfig() {
val configFile = File(filesDir, "gkms-config.json")
configFile.writeText(Gson().toJson(binding.config!!))
}
@SuppressLint("SetTextI18n")
private fun showVersion() {
val titleLabel = findViewById<TextView>(R.id.textViewTitle)
val versionLabel = findViewById<TextView>(R.id.textViewResVersion)
var versionText = "unknown"
try {
val stream = assets.open("${FilesChecker.localizationFilesDir}/version.txt")
versionText = FilesChecker.convertToString(stream)
val packInfo = packageManager.getPackageInfo(packageName, 0)
val version = packInfo.versionName
val versionCode = packInfo.longVersionCode
titleLabel.text = "${titleLabel.text} $version ($versionCode)"
}
catch (_: Exception) {}
versionLabel.text = "Assets Version: $versionText"
}
private fun loadConfig() {
val configStr = getConfigContent()
binding.config = try {
Gson().fromJson(configStr, GakumasConfig::class.java)
}
catch (e: JsonSyntaxException) {
showToast("配置文件异常,已重置: $e")
Gson().fromJson("{}", GakumasConfig::class.java)
}
saveConfig()
}
override fun checkConfigAndUpdateView() {
binding.config = binding.config
binding.notifyChange()
}
override fun pushKeyEvent(event: KeyEvent): Boolean {
return dispatchKeyEvent(event)
}
override fun dispatchKeyEvent(event: KeyEvent): Boolean {
// Log.d(TAG, "${event.keyCode}, ${event.action}")
if (MainKeyEventDispatcher.checkDbgKey(event.keyCode, event.action)) {
val origDbg = binding.config?.dbgMode
if (origDbg != null) {
binding.config!!.dbgMode = !origDbg
checkConfigAndUpdateView()
saveConfig()
showToast("TestMode: ${!origDbg}")
}
}
return if (event.action == 1145) true else super.dispatchKeyEvent(event)
}
}
*/

View File

@ -0,0 +1,24 @@
package io.github.chinosk.gakumas.localify
import android.os.Bundle
import androidx.activity.ComponentActivity
import io.github.chinosk.gakumas.localify.models.GakumasConfig
import io.github.chinosk.gakumas.localify.models.ProgramConfig
class TranslucentActivity : ComponentActivity(), IConfigurableActivity<TranslucentActivity> {
override lateinit var config: GakumasConfig
override lateinit var programConfig: ProgramConfig
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
loadConfig()
val requestData = intent.getStringExtra("gkmsData")
if (requestData != null) {
if (requestData == "requestConfig") {
onClickStartGame()
finish()
}
}
}
}

View File

@ -1,7 +1,5 @@
package io.github.chinosk.gakumas.localify.mainUtils
import android.util.Log
import io.github.chinosk.gakumas.localify.TAG
import okhttp3.*
import java.io.IOException
import java.io.ByteArrayOutputStream

View File

@ -1,3 +1,5 @@
package io.github.chinosk.gakumas.localify.ui.components
import android.content.res.Configuration.UI_MODE_NIGHT_NO
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*

View File

@ -5,7 +5,6 @@ import androidx.compose.foundation.layout.Arrangement
import androidx.compose.ui.Alignment
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material3.Text
import androidx.compose.material3.Switch
import androidx.compose.material3.SwitchDefaults
import androidx.compose.runtime.Composable

View File

@ -2,7 +2,6 @@ package io.github.chinosk.gakumas.localify.ui.components
import android.content.res.Configuration.UI_MODE_NIGHT_NO
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column

View File

@ -24,6 +24,7 @@ import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import io.github.chinosk.gakumas.localify.MainActivity
import io.github.chinosk.gakumas.localify.models.GakumasConfig
import io.github.chinosk.gakumas.localify.onClickStartGame
import io.github.chinosk.gakumas.localify.ui.components.GakuTabRow
import io.github.chinosk.gakumas.localify.ui.pages.subPages.AboutPage
import io.github.chinosk.gakumas.localify.ui.pages.subPages.AdvanceSettingsPage

View File

@ -1,6 +1,6 @@
package io.github.chinosk.gakumas.localify.ui.pages.subPages
import GakuGroupBox
import io.github.chinosk.gakumas.localify.ui.components.GakuGroupBox
import android.content.res.Configuration.UI_MODE_NIGHT_NO
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column

View File

@ -1,6 +1,6 @@
package io.github.chinosk.gakumas.localify.ui.pages.subPages
import GakuGroupBox
import io.github.chinosk.gakumas.localify.ui.components.GakuGroupBox
import android.content.res.Configuration.UI_MODE_NIGHT_NO
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 650 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 MiB

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="@color/white" />
</shape>
</item>
<item>
<bitmap android:src="@drawable/splash"
android:gravity="center"
android:tileMode="disabled"/>
</item>
</layer-list>

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Theme.GakumasLocalify" parent="@style/Theme.MaterialComponents.Light.NoActionBar" />
<style name="Theme.GakumasLocalify" parent="@style/Theme.MaterialComponents.Light.NoActionBar" >
<item name="android:windowBackground">@drawable/splash_style</item>
</style>
</resources>
<style name="Theme.GakumasLocalify.NoDisplay" parent="@style/Theme.MaterialComponents.Light.NoActionBar" >
<item name="android:windowFrame">@null</item>
<!-- 设置是否可滑动 -->
<item name="android:windowIsFloating">true</item>
<!-- 设置是否透明 -->
<item name="android:windowIsTranslucent">true</item>
<!-- 无标题 -->
<item name="android:windowNoTitle">true</item>
<!-- 背景 -->
<item name="android:background">@null</item>
<!-- 窗口背景 -->
<item name="android:windowBackground">@android:color/transparent</item>
<!-- 是否变暗 -->
<item name="android:backgroundDimEnabled">false</item>
<!-- 点击空白部分activity不消失 -->
<item name="android:windowCloseOnTouchOutside">true</item>
<!-- 无标题 有的手机设置这行代码-->
<item name="windowNoTitle">true</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowAnimationStyle">@null</item>
<item name="android:windowDisablePreview">true</item>
<item name="android:windowNoDisplay">true</item>
</style>
</resources>