Compat with latest 1.4.5.151 version

This commit is contained in:
ZaneYork 2021-01-28 15:55:18 +08:00
parent 68ee8ec4b0
commit 5456cf397b
95 changed files with 437 additions and 232 deletions

View File

@ -4,5 +4,6 @@
<annotationProcessing>
<profile default="true" name="Default" enabled="true" />
</annotationProcessing>
<bytecodeTargetLevel target="1.8" />
</component>
</project>

View File

@ -14,6 +14,7 @@
</set>
</option>
<option name="resolveModulePerSourceSet" value="false" />
<option name="useQualifiedModuleNames" value="true" />
</GradleProjectSettings>
</option>
</component>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">

View File

@ -12,8 +12,8 @@ android {
applicationId "com.zane.smapiinstaller"
minSdkVersion 19
targetSdkVersion 30
versionCode 60
versionName "1.7.0"
versionCode 63
versionName "3.7.6.1"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
multiDexEnabled true
@ -65,7 +65,7 @@ dependencies {
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'com.google.android.material:material:1.2.1'
implementation 'androidx.constraintlayout:constraintlayout:2.0.2'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation "androidx.navigation:navigation-fragment:2.3.1"
implementation "androidx.navigation:navigation-ui:2.3.1"
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
@ -82,7 +82,7 @@ dependencies {
// https://mvnrepository.com/artifact/org.zeroturnaround/zt-zip
implementation group: 'org.zeroturnaround', name: 'zt-zip', version: '1.14'
// https://mvnrepository.com/artifact/org.apache.commons/commons-lang3
implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.10'
implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.11'
// https://mvnrepository.com/artifact/commons-io/commons-io
implementation group: 'commons-io', name: 'commons-io', version: '2.7'
implementation 'com.lzy.net:okgo:3.0.4'
@ -90,6 +90,8 @@ dependencies {
implementation group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.11.0'
implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.11.0'
implementation group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version: '2.11.0'
// https://mvnrepository.com/artifact/org.lz4/lz4-java
compile group: 'org.lz4', name: 'lz4-java', version: '1.7.1'
implementation 'com.github.didikee:AndroidDonate:0.1.0'
implementation 'com.hjq:language:3.0'
@ -106,7 +108,7 @@ dependencies {
implementation "com.microsoft.appcenter:appcenter-analytics:${appCenterSdkVersion}"
implementation "com.microsoft.appcenter:appcenter-crashes:${appCenterSdkVersion}"
compileOnly 'org.projectlombok:lombok:1.18.12'
annotationProcessor 'org.projectlombok:lombok:1.18.12'
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.10'
compileOnly 'org.projectlombok:lombok:1.18.16'
annotationProcessor 'org.projectlombok:lombok:1.18.16'
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.0'
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,5 +1,5 @@
{
"minBuildCode": 138,
"minBuildCode": 148,
"maxBuildCode": null,
"basePath": "",
"targetPackageName": [
@ -45,47 +45,78 @@
"external": false
},
{
"targetPath": "assemblies/Newtonsoft.Json.dll",
"assetPath": "apk/Newtonsoft.Json.dll",
"targetPath": "assemblies/",
"assetPath": "apk/*.dll",
"compression": 0,
"external": false
},
{
"targetPath": "assemblies/SMAPI.Toolkit.CoreInterfaces.dll",
"assetPath": "apk/SMAPI.Toolkit.CoreInterfaces.dll",
"targetPath": "lib/arm64-v8a/",
"assetPath": "apk/lib/arm64-v8a/*.so",
"compression": 8,
"external": false
},
{
"targetPath": "lib/armeabi-v7a/",
"assetPath": "apk/lib/armeabi-v7a/*.so",
"compression": 8,
"external": false
},
{
"targetPath": "lib/x86/",
"assetPath": "apk/lib/x86/*.so",
"compression": 8,
"external": false
},
{
"targetPath": "lib/x86_64/",
"assetPath": "apk/lib/x86_64/*.so",
"compression": 8,
"external": false
},
{
"targetPath": "assemblies/0Harmony.dll",
"assetPath": "smapi/0Harmony.dll",
"compression": 0,
"external": false
},
{
"targetPath": "assemblies/SMAPI.Toolkit.dll",
"assetPath": "apk/SMAPI.Toolkit.dll",
"targetPath": "assemblies/Mono.Cecil.dll",
"assetPath": "smapi/Mono.Cecil.dll",
"compression": 0,
"external": false
},
{
"targetPath": "assemblies/StardewModdingAPI.dll",
"assetPath": "apk/StardewModdingAPI.dll",
"targetPath": "assemblies/MonoMod.RuntimeDetour.dll",
"assetPath": "smapi/MonoMod.RuntimeDetour.dll",
"compression": 0,
"external": false
},
{
"targetPath": "assemblies/System.Data.dll",
"assetPath": "apk/System.Data.dll",
"targetPath": "assemblies/MonoMod.Utils.dll",
"assetPath": "smapi/MonoMod.Utils.dll",
"compression": 0,
"external": false
},
{
"targetPath": "assemblies/System.Numerics.dll",
"assetPath": "apk/System.Numerics.dll",
"targetPath": "assemblies/System.Xml.Linq.dll",
"assetPath": "smapi/System.Xml.Linq.dll",
"compression": 0,
"external": false
},
{
"targetPath": "assemblies/MonoGame.Framework.dll",
"assetPath": "apk/MonoGame.Framework.dll",
"targetPath": "assemblies/TMXTile.dll",
"assetPath": "smapi/TMXTile.dll",
"compression": 0,
"external": false,
"advanced": true
"external": false
},
{
"targetPath": "assemblies/",
"assetPath": "assemblies/*.dll",
"origin": 1,
"isXALZ": true,
"compression": 0,
"external": false
}
]
}

View File

@ -1,6 +1,14 @@
{
"version": 31,
"version": 32,
"contents": [
{
"type": "COMPAT",
"name": "SMAPI for 1.4.5.145",
"assetPath": "compat/145/",
"description": "SMAPI compat package for game 1.4.4.138 - 1.4.5.147, SMAPI 3.7.5",
"url": "http://zaneyork.cn/dl/compat/smapi_145_210128.zip",
"hash": "3424287f98e9cfdd2a653e2e06b1b88f2f3080f7e56a976a8de9cc36afdede8a"
},
{
"type": "COMPAT",
"name": "SMAPI for 1.4.5.137",
@ -13,17 +21,17 @@
"type": "COMPAT",
"name": "SMAPI for Galaxy Store",
"assetPath": "compat/samsung_138/",
"description": "SMAPI compat package for game 1.4.4.138 - latest, SMAPI 3.7.5",
"url": "http://zaneyork.cn/dl/compat/smapi_samsung_138_201019.zip",
"hash": "648c4b387c5b61642614aa6677909a755a9b84fd96d717703fc83f5f73f515c0"
"description": "SMAPI compat package for game 1.4.4.138 - 1.4.5.147, SMAPI 3.7.5",
"url": "http://zaneyork.cn/dl/compat/smapi_samsung_145_210128.zip",
"hash": "256d1a4f6ccfcae916f22575f04d8f677e91ae85b24993f010552cffb401e6a0"
},
{
"type": "COMPAT",
"name": "SMAPI for Amazon Store",
"assetPath": "compat/amazon_138/",
"description": "SMAPI compat package for game 1.4.4.138 - latest, SMAPI 3.7.5",
"url": "http://zaneyork.cn/dl/compat/smapi_amazon_138_201019.zip",
"hash": "1c826b1419491cae063fd046131873f30640b841f2e8e6498d3f23ad82988d87"
"description": "SMAPI compat package for game 1.4.4.138 - 1.4.5.147, SMAPI 3.7.5",
"url": "http://zaneyork.cn/dl/compat/smapi_amazon_145_210128.zip",
"hash": "3e461ae9dcb6269340bfc923b720dd9f0f9c724acb66807b68571779e575c4e3"
},
{
"type": "LOCALE",

View File

@ -1,6 +1,14 @@
{
"version": 31,
"version": 32,
"contents": [
{
"type": "COMPAT",
"name": "SMAPI for 1.4.5.145",
"assetPath": "compat/145/",
"description": "SMAPI compat package for game 1.4.4.138 - 1.4.5.147, SMAPI 3.7.5",
"url": "http://zaneyork.cn/dl/compat/smapi_145_210128.zip",
"hash": "3424287f98e9cfdd2a653e2e06b1b88f2f3080f7e56a976a8de9cc36afdede8a"
},
{
"type": "COMPAT",
"name": "SMAPI for 1.4.5.137",
@ -13,17 +21,17 @@
"type": "COMPAT",
"name": "SMAPI for Galaxy Store",
"assetPath": "compat/samsung_138/",
"description": "SMAPI compat package for game 1.4.4.138 - latest, SMAPI 3.7.5",
"url": "http://zaneyork.cn/dl/compat/smapi_samsung_138_201019.zip",
"hash": "648c4b387c5b61642614aa6677909a755a9b84fd96d717703fc83f5f73f515c0"
"description": "SMAPI compat package for game 1.4.4.138 - 1.4.5.147, SMAPI 3.7.5",
"url": "http://zaneyork.cn/dl/compat/smapi_samsung_145_210128.zip",
"hash": "256d1a4f6ccfcae916f22575f04d8f677e91ae85b24993f010552cffb401e6a0"
},
{
"type": "COMPAT",
"name": "SMAPI for Amazon Store",
"assetPath": "compat/amazon_138/",
"description": "SMAPI compat package for game 1.4.4.138 - latest, SMAPI 3.7.5",
"url": "http://zaneyork.cn/dl/compat/smapi_amazon_138_201019.zip",
"hash": "1c826b1419491cae063fd046131873f30640b841f2e8e6498d3f23ad82988d87"
"description": "SMAPI compat package for game 1.4.4.138 - 1.4.5.147, SMAPI 3.7.5",
"url": "http://zaneyork.cn/dl/compat/smapi_amazon_145_210128.zip",
"hash": "3e461ae9dcb6269340bfc923b720dd9f0f9c724acb66807b68571779e575c4e3"
},
{
"type": "LOCALE",

View File

@ -1,6 +1,14 @@
{
"version": 31,
"version": 32,
"contents": [
{
"type": "COMPAT",
"name": "SMAPI for 1.4.5.145",
"assetPath": "compat/145/",
"description": "SMAPI compat package for game 1.4.4.138 - 1.4.5.147, SMAPI 3.7.5",
"url": "http://zaneyork.cn/dl/compat/smapi_145_210128.zip",
"hash": "3424287f98e9cfdd2a653e2e06b1b88f2f3080f7e56a976a8de9cc36afdede8a"
},
{
"type": "COMPAT",
"name": "SMAPI untuk 1.4.5.137",
@ -13,17 +21,17 @@
"type": "COMPAT",
"name": "SMAPI untuk Galaxy Store",
"assetPath": "compat/samsung_138/",
"description": "Paket kompatibilitas SMAPI untuk versi 1.4.4.138 - terbaru, SMAPI 3.7.5",
"url": "http://zaneyork.cn/dl/compat/smapi_samsung_138_201019.zip",
"hash": "648c4b387c5b61642614aa6677909a755a9b84fd96d717703fc83f5f73f515c0"
"description": "Paket kompatibilitas SMAPI untuk versi 1.4.4.138 - 1.4.5.147, SMAPI 3.7.5",
"url": "http://zaneyork.cn/dl/compat/smapi_samsung_145_210128.zip",
"hash": "256d1a4f6ccfcae916f22575f04d8f677e91ae85b24993f010552cffb401e6a0"
},
{
"type": "COMPAT",
"name": "SMAPI untuk Amazon Store",
"assetPath": "compat/amazon_138/",
"description": "Paket kompatibilitas SMAPI untuk versi 1.4.4.138 - terbaru, SMAPI 3.7.5",
"url": "http://zaneyork.cn/dl/compat/smapi_amazon_138_201019.zip",
"hash": "1c826b1419491cae063fd046131873f30640b841f2e8e6498d3f23ad82988d87"
"description": "Paket kompatibilitas SMAPI untuk versi 1.4.4.138 - 1.4.5.147, SMAPI 3.7.5",
"url": "http://zaneyork.cn/dl/compat/smapi_amazon_145_210128.zip",
"hash": "3e461ae9dcb6269340bfc923b720dd9f0f9c724acb66807b68571779e575c4e3"
},
{
"type": "LOCAL",

View File

@ -1,6 +1,14 @@
{
"version": 31,
"version": 32,
"contents": [
{
"type": "COMPAT",
"name": "SMAPI for 1.4.5.145",
"assetPath": "compat/145/",
"description": "SMAPI compat package for game 1.4.4.138 - 1.4.5.147, SMAPI 3.7.5",
"url": "http://zaneyork.cn/dl/compat/smapi_145_210128.zip",
"hash": "3424287f98e9cfdd2a653e2e06b1b88f2f3080f7e56a976a8de9cc36afdede8a"
},
{
"type": "COMPAT",
"name": "SMAPI สำหรับ 1.4.5.137",
@ -13,17 +21,17 @@
"type": "COMPAT",
"name": "SMAPI สำหรับ Galaxy Store",
"assetPath": "compat/samsung_138/",
"description": "แพคเกจแอพลิเคชั่น SMAPI สำหรับเกม Stardew Valley เวอร์ชั่น 1.4.4.138 - ล่าสุด, SMAPI 3.7.5",
"url": "http://zaneyork.cn/dl/compat/smapi_samsung_138_201019.zip",
"hash": "648c4b387c5b61642614aa6677909a755a9b84fd96d717703fc83f5f73f515c0"
"description": "แพคเกจแอพลิเคชั่น SMAPI สำหรับเกม Stardew Valley เวอร์ชั่น 1.4.4.138 - 1.4.5.147, SMAPI 3.7.5",
"url": "http://zaneyork.cn/dl/compat/smapi_samsung_145_210128.zip",
"hash": "256d1a4f6ccfcae916f22575f04d8f677e91ae85b24993f010552cffb401e6a0"
},
{
"type": "COMPAT",
"name": "SMAPI สำหรับ Amazon Store",
"assetPath": "compat/amazon_138/",
"description": "แพคเกจแอพลิเคชั่น SMAPI สำหรับเกม Stardew Valley เวอร์ชั่น 1.4.4.138 - ล่าสุด, SMAPI 3.7.5",
"url": "http://zaneyork.cn/dl/compat/smapi_amazon_138_201019.zip",
"hash": "1c826b1419491cae063fd046131873f30640b841f2e8e6498d3f23ad82988d87"
"description": "แพคเกจแอพลิเคชั่น SMAPI สำหรับเกม Stardew Valley เวอร์ชั่น 1.4.4.138 - 1.4.5.147, SMAPI 3.7.5",
"url": "http://zaneyork.cn/dl/compat/smapi_amazon_145_210128.zip",
"hash": "3e461ae9dcb6269340bfc923b720dd9f0f9c724acb66807b68571779e575c4e3"
},
{
"type": "LOCALE",

View File

@ -1,6 +1,14 @@
{
"version": 31,
"version": 32,
"contents": [
{
"type": "COMPAT",
"name": "SMAPI兼容包 1.4.5.145",
"assetPath": "compat/145/",
"description": "SMAPI兼容包, 适用版本1.4.4.138 - 1.4.5.147, SMAPI 3.7.5",
"url": "http://zaneyork.cn/dl/compat/smapi_145_210128.zip",
"hash": "3424287f98e9cfdd2a653e2e06b1b88f2f3080f7e56a976a8de9cc36afdede8a"
},
{
"type": "COMPAT",
"name": "SMAPI兼容包 1.4.5.137",
@ -13,17 +21,17 @@
"type": "COMPAT",
"name": "SMAPI三星商店兼容包",
"assetPath": "compat/samsung_138/",
"description": "SMAPI三星商店兼容包 适用版本1.4.4.138至今, SMAPI 3.7.5",
"url": "http://zaneyork.cn/dl/compat/smapi_samsung_138_201019.zip",
"hash": "648c4b387c5b61642614aa6677909a755a9b84fd96d717703fc83f5f73f515c0"
"description": "SMAPI三星商店兼容包 适用版本1.4.4.138 - 1.4.5.147, SMAPI 3.7.5",
"url": "http://zaneyork.cn/dl/compat/smapi_samsung_145_210128.zip",
"hash": "256d1a4f6ccfcae916f22575f04d8f677e91ae85b24993f010552cffb401e6a0"
},
{
"type": "COMPAT",
"name": "SMAPI亚马逊商店兼容包",
"assetPath": "compat/amazon_138/",
"description": "SMAPI亚马逊商店兼容包 适用版本1.4.4.138至今, SMAPI 3.7.5",
"url": "http://zaneyork.cn/dl/compat/smapi_amazon_138_201019.zip",
"hash": "1c826b1419491cae063fd046131873f30640b841f2e8e6498d3f23ad82988d87"
"description": "SMAPI亚马逊商店兼容包 适用版本1.4.4.138 - 1.4.5.147, SMAPI 3.7.5",
"url": "http://zaneyork.cn/dl/compat/smapi_amazon_145_210128.zip",
"hash": "3e461ae9dcb6269340bfc923b720dd9f0f9c724acb66807b68571779e575c4e3"
},
{
"type": "LOCALE",

View File

@ -1,43 +1,33 @@
[
{
"targetPath": "smapi-internal/0Harmony.dll",
"assetPath": "smapi/0Harmony.dll",
"targetPath": "smapi-internal/",
"assetPath": "smapi/*.json",
"origin": 0
},
{
"targetPath": "smapi-internal/config.json",
"assetPath": "smapi/config.json",
"targetPath": "smapi-internal/i18n/",
"assetPath": "smapi/i18n/*.json",
"origin": 0
},
{
"targetPath": "smapi-internal/metadata.json",
"assetPath": "smapi/metadata.json",
"targetPath": "smapi-internal/",
"assetPath": "smapi/*.dll",
"origin": 0
},
{
"targetPath": "smapi-internal/Mono.Cecil.dll",
"assetPath": "smapi/Mono.Cecil.dll",
"targetPath": "smapi-internal/Mono.Android.dll",
"assetPath": "apk/Mono.Android.dll",
"origin": 0
},
{
"targetPath": "smapi-internal/MonoGame.Framework.dll",
"assetPath": "assemblies/MonoGame.Framework.dll",
"origin": 1
},
{
"targetPath": "smapi-internal/MonoMod.RuntimeDetour.dll",
"assetPath": "smapi/MonoMod.RuntimeDetour.dll",
"origin": 0
},
{
"targetPath": "smapi-internal/MonoMod.Utils.dll",
"assetPath": "smapi/MonoMod.Utils.dll",
"assetPath": "apk/MonoGame.Framework.dll",
"origin": 0
},
{
"targetPath": "smapi-internal/mscorlib.dll",
"assetPath": "assemblies/mscorlib.dll",
"origin": 1
"assetPath": "apk/mscorlib.dll",
"origin": 0
},
{
"targetPath": "smapi-internal/Newtonsoft.Json.dll",
@ -62,17 +52,19 @@
{
"targetPath": "smapi-internal/StardewValley.dll",
"assetPath": "assemblies/StardewValley.dll",
"isXALZ": true,
"origin": 1
},
{
"targetPath": "smapi-internal/StardewValley.GameData.dll",
"assetPath": "assemblies/StardewValley.GameData.dll",
"isXALZ": true,
"origin": 1
},
{
"targetPath": "smapi-internal/System.Core.dll",
"assetPath": "assemblies/System.Core.dll",
"origin": 1
"assetPath": "apk/System.Core.dll",
"origin": 0
},
{
"targetPath": "smapi-internal/System.Data.dll",
@ -81,13 +73,13 @@
},
{
"targetPath": "smapi-internal/System.dll",
"assetPath": "assemblies/System.dll",
"origin": 1
"assetPath": "apk/System.dll",
"origin": 0
},
{
"targetPath": "smapi-internal/System.Net.Http.dll",
"assetPath": "assemblies/System.Net.Http.dll",
"origin": 1
"assetPath": "apk/System.Net.Http.dll",
"origin": 0
},
{
"targetPath": "smapi-internal/System.Numerics.dll",
@ -96,97 +88,22 @@
},
{
"targetPath": "smapi-internal/System.Runtime.Serialization.dll",
"assetPath": "assemblies/System.Runtime.Serialization.dll",
"origin": 1
},
{
"targetPath": "smapi-internal/System.ServiceModel.Internals.dll",
"assetPath": "assemblies/System.ServiceModel.Internals.dll",
"origin": 1
},
{
"targetPath": "smapi-internal/System.Xml.dll",
"assetPath": "assemblies/System.Xml.dll",
"origin": 1
},
{
"targetPath": "smapi-internal/Mono.Android.dll",
"assetPath": "assemblies/Mono.Android.dll",
"origin": 1
},
{
"targetPath": "smapi-internal/System.Xml.Linq.dll",
"assetPath": "smapi/System.Xml.Linq.dll",
"assetPath": "apk/System.Runtime.Serialization.dll",
"origin": 0
},
{
"targetPath": "smapi-internal/TMXTile.dll",
"assetPath": "smapi/TMXTile.dll",
"targetPath": "smapi-internal/System.ServiceModel.Internals.dll",
"assetPath": "apk/System.ServiceModel.Internals.dll",
"origin": 0
},
{
"targetPath": "smapi-internal/System.Xml.dll",
"assetPath": "apk/System.Xml.dll",
"origin": 0
},
{
"targetPath": "smapi-internal/xTile.dll",
"assetPath": "assemblies/xTile.dll",
"origin": 1
},
{
"targetPath": "smapi-internal/BmFont.dll",
"assetPath": "assemblies/BmFont.dll",
"origin": 1
},
{
"targetPath": "smapi-internal/i18n/de.json",
"assetPath": "smapi/i18n/de.json",
"origin": 0
},
{
"targetPath": "smapi-internal/i18n/default.json",
"assetPath": "smapi/i18n/default.json",
"origin": 0
},
{
"targetPath": "smapi-internal/i18n/es.json",
"assetPath": "smapi/i18n/es.json",
"origin": 0
},
{
"targetPath": "smapi-internal/i18n/fr.json",
"assetPath": "smapi/i18n/fr.json",
"origin": 0
},
{
"targetPath": "smapi-internal/i18n/hu.json",
"assetPath": "smapi/i18n/hu.json",
"origin": 0
},
{
"targetPath": "smapi-internal/i18n/it.json",
"assetPath": "smapi/i18n/it.json",
"origin": 0
},
{
"targetPath": "smapi-internal/i18n/ja.json",
"assetPath": "smapi/i18n/ja.json",
"origin": 0
},
{
"targetPath": "smapi-internal/i18n/pt.json",
"assetPath": "smapi/i18n/pt.json",
"origin": 0
},
{
"targetPath": "smapi-internal/i18n/ru.json",
"assetPath": "smapi/i18n/ru.json",
"origin": 0
},
{
"targetPath": "smapi-internal/i18n/tr.json",
"assetPath": "smapi/i18n/tr.json",
"origin": 0
},
{
"targetPath": "smapi-internal/i18n/zh.json",
"assetPath": "smapi/i18n/zh.json",
"assetPath": "apk/xTile.dll",
"origin": 0
}
]

View File

@ -67,7 +67,7 @@ public class Constants {
/**
* SMAPI版本
*/
public static final String SMAPI_VERSION = "3.7.5";
public static final String SMAPI_VERSION = "3.7.6";
/**
* 应用名称

View File

@ -1,5 +1,7 @@
package com.zane.smapiinstaller.entity;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/**
@ -43,4 +45,9 @@ public class ManifestEntry {
* 是否为高级模式补丁
*/
private boolean advanced;
/**
* 是否为XALZ压缩格式
*/
@JsonProperty("isXALZ")
private boolean isXALZ;
}

View File

@ -14,7 +14,7 @@ import com.android.apksig.ApkSigner;
import com.android.apksig.ApkVerifier;
import com.fasterxml.jackson.core.type.TypeReference;
import com.google.common.base.Stopwatch;
import com.google.common.collect.Iterables;
import com.google.common.io.ByteStreams;
import com.google.common.io.Files;
import com.zane.smapiinstaller.BuildConfig;
import com.zane.smapiinstaller.MainActivity;
@ -22,18 +22,16 @@ import com.zane.smapiinstaller.R;
import com.zane.smapiinstaller.constant.Constants;
import com.zane.smapiinstaller.constant.DialogAction;
import com.zane.smapiinstaller.constant.ManifestPatchConstants;
import com.zane.smapiinstaller.dto.Tuple2;
import com.zane.smapiinstaller.entity.ApkFilesManifest;
import com.zane.smapiinstaller.entity.ManifestEntry;
import com.zane.smapiinstaller.utils.DialogUtils;
import com.zane.smapiinstaller.utils.FileUtils;
import com.zane.smapiinstaller.utils.StringUtils;
import com.zane.smapiinstaller.utils.ZipUtils;
import net.fornwall.apksigner.KeyStoreFileManager;
import org.apache.commons.lang3.NotImplementedException;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.Nullable;
import org.zeroturnaround.zip.ZipUtil;
import java.io.File;
@ -53,8 +51,10 @@ import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.zip.Deflater;
import androidx.annotation.Nullable;
import androidx.core.content.FileProvider;
import pxb.android.axml.NodeVisitor;
@ -71,6 +71,10 @@ public class ApkPatcher {
private final AtomicReference<String> errorMessage = new AtomicReference<>();
private final AtomicReference<String> gamePackageName = new AtomicReference<>();
private final AtomicLong gameVersionCode = new AtomicLong();
private final AtomicInteger switchAction = new AtomicInteger();
private final List<Consumer<Integer>> progressListener = new ArrayList<>();
@ -103,6 +107,13 @@ public class ApkPatcher {
try {
PackageInfo packageInfo = packageManager.getPackageInfo(packageName, 0);
String sourceDir = packageInfo.applicationInfo.publicSourceDir;
gamePackageName.set(packageName);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
gameVersionCode.set(packageInfo.getLongVersionCode());
}
else {
gameVersionCode.set(packageInfo.versionCode);
}
File apkFile = new File(sourceDir);
String stadewValleyBasePath = FileUtils.getStadewValleyBasePath();
@ -190,8 +201,8 @@ public class ApkPatcher {
List<ManifestEntry> manifestEntries = apkFilesManifest.getManifestEntries();
errorMessage.set(null);
List<ZipUtils.ZipEntrySource> entries = manifestEntries.stream()
.map(entry -> processfileentry(file, apkFilesManifest, entry, isAdvanced))
.filter(Objects::nonNull).collect(Collectors.toList());
.map(entry -> processFileEntry(file, apkFilesManifest, entry, isAdvanced))
.filter(Objects::nonNull).flatMap(Stream::of).distinct().collect(Collectors.toList());
if (errorMessage.get() != null) {
return false;
}
@ -218,20 +229,58 @@ public class ApkPatcher {
}
@Nullable
private ZipUtils.ZipEntrySource processfileentry(File file, ApkFilesManifest apkFilesManifest, ManifestEntry entry, boolean isAdvanced) {
private ZipUtils.ZipEntrySource[] processFileEntry(File apkFile, ApkFilesManifest apkFilesManifest, ManifestEntry entry, boolean isAdvanced) {
if (entry.isAdvanced() && !isAdvanced) {
return null;
}
if (entry.getTargetPath().endsWith("/") && entry.getAssetPath().contains("*")) {
String path = StringUtils.substringBeforeLast(entry.getAssetPath(), "/");
String pattern = StringUtils.substringAfterLast(entry.getAssetPath(), "/");
try {
if (entry.getOrigin() == 1) {
ArrayList<ZipUtils.ZipEntrySource> list = new ArrayList<>();
ZipUtil.iterate(apkFile, (in, zipEntry) -> {
String entryPath = StringUtils.substringBeforeLast(zipEntry.getName(), "/");
String filename = StringUtils.substringAfterLast(zipEntry.getName(), "/");
if (entryPath.equals(path) && StringUtils.wildCardMatch(filename, pattern)) {
byte[] bytes = ByteStreams.toByteArray(in);
if (entry.isXALZ()) {
bytes = ZipUtils.decompressXALZ(bytes);
}
list.add(new ZipUtils.ZipEntrySource(entry.getTargetPath() + filename, bytes, entry.getCompression()));
}
});
return list.toArray(new ZipUtils.ZipEntrySource[0]);
} else {
return Stream.of(context.getAssets().list(path))
.filter(filename -> StringUtils.wildCardMatch(filename, pattern))
.map(filename -> {
byte[] bytes = FileUtils.getAssetBytes(context, path + "/" + filename);
return new ZipUtils.ZipEntrySource(entry.getTargetPath() + filename, bytes, entry.getCompression());
})
.toArray(ZipUtils.ZipEntrySource[]::new);
}
} catch (IOException ignored) {
}
return null;
}
byte[] bytes;
if (entry.isExternal()) {
bytes = FileUtils.getAssetBytes(context, apkFilesManifest.getBasePath() + entry.getAssetPath());
if (entry.getOrigin() == 1) {
bytes = ZipUtil.unpackEntry(apkFile, entry.getAssetPath());
if (entry.isXALZ()) {
bytes = ZipUtils.decompressXALZ(bytes);
}
} else {
bytes = FileUtils.getAssetBytes(context, entry.getAssetPath());
if (entry.isExternal()) {
bytes = FileUtils.getAssetBytes(context, apkFilesManifest.getBasePath() + entry.getAssetPath());
} else {
bytes = FileUtils.getAssetBytes(context, entry.getAssetPath());
}
if (StringUtils.isNoneBlank(entry.getPatchCrc())) {
throw new NotImplementedException("bs patch mode is not supported anymore.");
}
}
if (StringUtils.isNoneBlank(entry.getPatchCrc())) {
throw new NotImplementedException("bs patch mode is not supported anymore.");
}
return new ZipUtils.ZipEntrySource(entry.getTargetPath(), bytes, entry.getCompression());
return new ZipUtils.ZipEntrySource[]{new ZipUtils.ZipEntrySource(entry.getTargetPath(), bytes, entry.getCompression())};
}
/**
@ -281,7 +330,12 @@ public class ApkPatcher {
}
case "name":
if (strObj.contains(ManifestPatchConstants.PATTERN_MAIN_ACTIVITY)) {
attr.obj = strObj.replaceFirst("\\w+\\.MainActivity", "md5723872fa9a204f7f942686e9ed9d0b7d.SMainActivity");
if(versionCode.get() > 147) {
attr.obj = strObj.replaceFirst("\\w+\\.MainActivity", "crc648e5438a58262f792.SMainActivity");
}
else {
attr.obj = strObj.replaceFirst("\\w+\\.MainActivity", "md5723872fa9a204f7f942686e9ed9d0b7d.SMainActivity");
}
}
break;
default:
@ -311,23 +365,7 @@ public class ApkPatcher {
if (StringUtils.endsWith(versionName.get(), ManifestPatchConstants.PATTERN_VERSION_AMAZON)) {
packageName.set(ManifestPatchConstants.APP_PACKAGE_NAME + ManifestPatchConstants.PATTERN_VERSION_AMAZON);
}
Iterables.removeIf(manifests, manifest -> {
if (manifest == null) {
return true;
}
if (versionCode.get() < manifest.getMinBuildCode()) {
return true;
}
if (manifest.getMaxBuildCode() != null) {
if (versionCode.get() > manifest.getMaxBuildCode()) {
return true;
}
}
if (manifest.getTargetPackageName() != null && packageName.get() != null && !manifest.getTargetPackageName().contains(packageName.get())) {
return true;
}
return false;
});
CommonLogic.filterManifest(manifests, packageName.get(), versionCode.get());
return modifyManifest;
} catch (Exception e) {
errorMessage.set(e.getLocalizedMessage());
@ -454,6 +492,14 @@ public class ApkPatcher {
return errorMessage;
}
public String getGamePackageName() {
return gamePackageName.get();
}
public long getGameVersionCode() {
return gameVersionCode.get();
}
public AtomicInteger getSwitchAction() {
return switchAction;
}

View File

@ -19,6 +19,7 @@ import android.widget.ImageView;
import com.afollestad.materialdialogs.MaterialDialog;
import com.fasterxml.jackson.core.type.TypeReference;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.io.ByteStreams;
import com.lmntrx.android.library.livin.missme.ProgressDialog;
@ -26,16 +27,21 @@ import com.microsoft.appcenter.crashes.Crashes;
import com.zane.smapiinstaller.MainApplication;
import com.zane.smapiinstaller.R;
import com.zane.smapiinstaller.constant.DialogAction;
import com.zane.smapiinstaller.dto.Tuple2;
import com.zane.smapiinstaller.entity.ApkFilesManifest;
import com.zane.smapiinstaller.entity.ManifestEntry;
import com.zane.smapiinstaller.utils.DialogUtils;
import com.zane.smapiinstaller.utils.FileUtils;
import com.zane.smapiinstaller.utils.StringUtils;
import com.zane.smapiinstaller.utils.ZipUtils;
import org.apache.commons.io.filefilter.WildcardFileFilter;
import org.zeroturnaround.zip.ZipUtil;
import java.io.File;
import java.io.FileFilter;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
@ -45,6 +51,7 @@ import java.util.concurrent.atomic.AtomicReference;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Stream;
import pxb.android.axml.AxmlReader;
import pxb.android.axml.AxmlVisitor;
@ -188,11 +195,26 @@ public class CommonLogic {
* @param context context
* @param apkPath 安装包路径
* @param checkMode 是否为校验模式
* @param packageName
* @param versionCode
* @return 操作是否成功
*/
public static boolean unpackSmapiFiles(Context context, String apkPath, boolean checkMode) {
List<ManifestEntry> manifestEntries = FileUtils.getAssetJson(context, "smapi_files_manifest.json", new TypeReference<List<ManifestEntry>>() {
});
public static boolean unpackSmapiFiles(Context context, String apkPath, boolean checkMode, String packageName, long versionCode) {
List<ApkFilesManifest> apkFilesManifests = CommonLogic.findAllApkFileManifest(context);
filterManifest(apkFilesManifests, packageName, versionCode);
List<ManifestEntry> manifestEntries = null;
ApkFilesManifest apkFilesManifest = null;
if(apkFilesManifests.size() > 0) {
apkFilesManifest = apkFilesManifests.get(0);
String basePath = apkFilesManifest.getBasePath();
if(StringUtils.isNoneBlank(basePath)) {
manifestEntries = FileUtils.getAssetJson(context, basePath + "smapi_files_manifest.json", new TypeReference<List<ManifestEntry>>() {});
}
}
if(manifestEntries == null) {
manifestEntries = FileUtils.getAssetJson(context, "smapi_files_manifest.json", new TypeReference<List<ManifestEntry>>() {
});
}
if (manifestEntries == null) {
return false;
}
@ -202,6 +224,16 @@ public class CommonLogic {
return false;
}
}
else {
if(!checkMode) {
File[] oldAssemblies = new File(basePath, "smapi-internal").listFiles((FileFilter) new WildcardFileFilter("*.dll"));
if(oldAssemblies != null) {
for (File file : oldAssemblies) {
FileUtils.deleteQuietly(file);
}
}
}
}
File noMedia = new File(basePath, ".nomedia");
if (!noMedia.exists()) {
try {
@ -213,24 +245,55 @@ public class CommonLogic {
File targetFile = new File(basePath, entry.getTargetPath());
switch (entry.getOrigin()) {
case 0:
if (!checkMode || !targetFile.exists()) {
try (InputStream inputStream = context.getAssets().open(entry.getAssetPath())) {
if (!targetFile.getParentFile().exists()) {
if (!targetFile.getParentFile().mkdirs()) {
return false;
}
if(entry.isExternal() && apkFilesManifest != null){
byte[] bytes = FileUtils.getAssetBytes(context, apkFilesManifest.getBasePath() + entry.getAssetPath());
try (FileOutputStream outputStream = new FileOutputStream(targetFile)) {
outputStream.write(bytes);
} catch (IOException ignored) {
}
}
else {
if (entry.getTargetPath().endsWith("/") && entry.getAssetPath().contains("*")) {
String path = StringUtils.substring(entry.getAssetPath(), 0, StringUtils.lastIndexOf(entry.getAssetPath(), "/"));
String pattern = StringUtils.substringAfterLast(entry.getAssetPath(), "/");
try {
Stream.of(context.getAssets().list(path))
.filter(filename -> StringUtils.wildCardMatch(filename, pattern))
.forEach(filename -> {
unpackFile(context, checkMode, path + "/" + filename, new File(basePath, entry.getTargetPath() + filename));
});
} catch (IOException ignored) {
}
try (FileOutputStream outputStream = new FileOutputStream(targetFile)) {
ByteStreams.copy(inputStream, outputStream);
}
} catch (IOException e) {
Log.e("COMMON", "Copy Error", e);
} else {
unpackFile(context, checkMode, entry.getAssetPath(), targetFile);
}
}
break;
case 1:
if (!checkMode || !targetFile.exists()) {
ZipUtil.unpackEntry(new File(apkPath), entry.getAssetPath(), targetFile);
if(entry.isXALZ()){
byte[] bytes = ZipUtil.unpackEntry(new File(apkPath), entry.getAssetPath());
if (entry.isXALZ()) {
bytes = ZipUtils.decompressXALZ(bytes);
}
FileOutputStream stream = null;
try {
stream = FileUtils.openOutputStream(targetFile);
stream.write(bytes);
} catch (IOException ignore) {
}
finally {
if(stream != null) {
try {
stream.close();
} catch (IOException ignored) {
}
}
}
}
else {
ZipUtil.unpackEntry(new File(apkPath), entry.getAssetPath(), targetFile);
}
}
break;
default:
@ -240,10 +303,47 @@ public class CommonLogic {
return true;
}
public static void filterManifest(List<ApkFilesManifest> manifests, String packageName, long versionCode){
Iterables.removeIf(manifests, manifest -> {
if (manifest == null) {
return true;
}
if (versionCode < manifest.getMinBuildCode()) {
return true;
}
if (manifest.getMaxBuildCode() != null) {
if (versionCode > manifest.getMaxBuildCode()) {
return true;
}
}
if (manifest.getTargetPackageName() != null && packageName != null && !manifest.getTargetPackageName().contains(packageName)) {
return true;
}
return false;
});
}
private static void unpackFile(Context context, boolean checkMode, String assertPath, File targetFile) {
if (!checkMode || !targetFile.exists()) {
try (InputStream inputStream = context.getAssets().open(assertPath)) {
if (!targetFile.getParentFile().exists()) {
if (!targetFile.getParentFile().mkdirs()) {
Log.e("COMMON", "Make dirs error");
return;
}
}
try (FileOutputStream outputStream = new FileOutputStream(targetFile)) {
ByteStreams.copy(inputStream, outputStream);
}
} catch (IOException e) {
Log.e("COMMON", "Copy Error", e);
}
}
}
/**
* 修改AndroidManifest.xml文件
*
* @param bytes AndroidManifest.xml文件字符数组
* @param bytes AndroidManifest.xml文件字符数组
* @param attrProcessLogic 处理逻辑
* @return 修改后的AndroidManifest.xml文件字符数组
* @throws IOException 异常

View File

@ -4,6 +4,7 @@ import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.view.View;
import com.microsoft.appcenter.crashes.Crashes;
@ -55,7 +56,14 @@ public class GameLauncher {
DialogUtils.showAlertDialog(root, R.string.error, R.string.error_smapi_not_installed);
return;
}
if(!CommonLogic.unpackSmapiFiles(context, packageInfo.applicationInfo.publicSourceDir, true)) {
long versionCode;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
versionCode = packageInfo.getLongVersionCode();
}
else {
versionCode = packageInfo.versionCode;
}
if(!CommonLogic.unpackSmapiFiles(context, packageInfo.applicationInfo.publicSourceDir, true, packageInfo.packageName, versionCode)) {
DialogUtils.showAlertDialog(root, R.string.error, R.string.error_failed_to_repair);
return;
}

View File

@ -124,7 +124,7 @@ public class InstallFragment extends Fragment {
return;
}
DialogUtils.setProgressDialogState(binding.getRoot(), dialog, R.string.unpacking_smapi_files, null);
if (!CommonLogic.unpackSmapiFiles(context, path, false)) {
if (!CommonLogic.unpackSmapiFiles(context, path, false, patcher.getGamePackageName(), patcher.getGameVersionCode())) {
DialogUtils.showAlertDialog(binding.getRoot(), R.string.error, StringUtils.firstNonBlank(patcher.getErrorMessage().get(), context.getString(R.string.failed_to_unpack_smapi_files)));
return;
}

View File

@ -0,0 +1,34 @@
package com.zane.smapiinstaller.utils;
/**
* @author Zane
*/
public class StringUtils extends org.apache.commons.lang3.StringUtils {
public static boolean wildCardMatch(String str, String pattern) {
int i = 0;
int j = 0;
int starIndex = -1;
int iIndex = -1;
while (i < str.length()) {
if (j < pattern.length() && (pattern.charAt(j) == '?' || pattern.charAt(j) == str.charAt(i))) {
++i;
++j;
} else if (j < pattern.length() && pattern.charAt(j) == '*') {
starIndex = j;
iIndex = i;
j++;
} else if (starIndex != -1) {
j = starIndex + 1;
i = iIndex + 1;
iIndex++;
} else {
return false;
}
}
while (j < pattern.length() && pattern.charAt(j) == '*') {
++j;
}
return j == pattern.length();
}
}

View File

@ -7,22 +7,39 @@ import com.google.common.collect.Sets;
import net.fornwall.apksigner.zipio.ZioEntry;
import net.fornwall.apksigner.zipio.ZipInput;
import net.fornwall.apksigner.zipio.ZipOutput;
import net.jpountz.lz4.LZ4Factory;
import net.jpountz.lz4.LZ4FastDecompressor;
import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashSet;
import java.util.List;
import java.util.function.Consumer;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* @author Zane
*/
public class ZipUtils {
public static byte[] decompressXALZ(byte[] bytes){
if("XALZ".equals(new String(ByteUtils.subArray(bytes, 0, 4), StandardCharsets.ISO_8859_1))) {
LZ4Factory factory = LZ4Factory.fastestInstance();
LZ4FastDecompressor lz4FastDecompressor = factory.fastDecompressor();
byte[] length = ByteUtils.subArray(bytes, 8, 12);
int len = (length[0] & 0xff) | ((length[1] & 0xff) << 8) | ((length[2] & 0xff) << 16) | ((length[3] & 0xff) << 24);
bytes = lz4FastDecompressor.decompress(bytes, 12, len);
}
return bytes;
}
public static void addOrReplaceEntries(String inputZipFilename, List<ZipEntrySource> entrySources, String outputZipFilename, Consumer<Integer> progressCallback) throws IOException {
File inFile = new File(inputZipFilename).getCanonicalFile();
File outFile = new File(outputZipFilename).getCanonicalFile();
@ -94,6 +111,7 @@ public class ZipUtils {
@Data
@AllArgsConstructor
@EqualsAndHashCode(of = "path")
public static class ZipEntrySource {
private String path;
private byte[] data;

View File

@ -61,7 +61,7 @@
<string name="settings_verbose_logging">Registro detallado</string>
<string name="signing_package">Firmando paquete deinstalación</string>
<string name="smapi_game_name">SMAPI Stardew Valley</string>
<string name="smapi_version">Versión SMAPI: 3.7.5</string>
<string name="smapi_version">Versión SMAPI: 3.7.6</string>
<string name="text_install_tip1">Nota: Requiere la versión del juego 1.4.5.138 o superior</string>
<string name="text_install_tip2">El cuerpo del juego debe instalarse durante la actualización o instalación</string>
<string name="unpacking_smapi_files">Desempacando</string>

View File

@ -61,7 +61,7 @@
<string name="settings_verbose_logging">Journalisation détaillée</string>
<string name="signing_package">Signature</string>
<string name="smapi_game_name">SMAPI Stardew Valley</string>
<string name="smapi_version">Version SMAPI: 3.7.5</string>
<string name="smapi_version">Version SMAPI: 3.7.6</string>
<string name="text_install_tip1">Remarques: La version du jeu 1.4.5.138 ou ultérieure est requise.</string>
<string name="text_install_tip2">Le jeu de base est requis lors de la mise à jour / installation.</string>
<string name="unpacking_smapi_files">Déballage</string>

View File

@ -61,7 +61,7 @@
<string name="settings_verbose_logging">Catatan Terperinci</string>
<string name="signing_package">Menandatangani</string>
<string name="smapi_game_name">SMAPI Stardew Valley</string>
<string name="smapi_version">Versi SMAPI: 3.7.5</string>
<string name="smapi_version">Versi SMAPI: 3.7.6</string>
<string name="text_install_tip1">Catatan: Dibutuhkan Stardew Valley versi 1.4.5.138 atau yang lebih baru.</string>
<string name="text_install_tip2">Permainan dasar diperlukan saat memperbarui/menginstal.</string>
<string name="unpacking_smapi_files">Membongkar</string>

View File

@ -61,7 +61,7 @@
<string name="settings_verbose_logging">자세한 로그</string>
<string name="signing_package">설치 패키지 서명</string>
<string name="smapi_game_name">SMAPI Stardew Valley</string>
<string name="smapi_version">SMAPI버전: 3.7.5</string>
<string name="smapi_version">SMAPI버전: 3.7.6</string>
<string name="text_install_tip1">참고 : 게임 버전 1.4.5.138 이상이 필요합니다</string>
<string name="text_install_tip2">업데이트 또는 설치 중에 게임 본체를 설치해야합니다</string>
<string name="unpacking_smapi_files">포장 풀기</string>

View File

@ -61,7 +61,7 @@
<string name="settings_verbose_logging">Log detalhado</string>
<string name="signing_package">Assinatura</string>
<string name="smapi_game_name">SMAPI Stardew Valley</string>
<string name="smapi_version">Versão SMAPI: 3.7.5</string>
<string name="smapi_version">Versão SMAPI: 3.7.6</string>
<string name="text_install_tip1">Notas: É necessária a versão do jogo 1.4.5.138 ou posterior.</string>
<string name="text_install_tip2">O jogo base é necessário ao atualizar / instalar.</string>
<string name="unpacking_smapi_files">Desembalar</string>

View File

@ -61,7 +61,7 @@
<string name="settings_verbose_logging">บันทึกอย่างละเอียด</string>
<string name="signing_package">กำลังลงทะเบียนแอป</string>
<string name="smapi_game_name">SMAPI Stardew Valley</string>
<string name="smapi_version">เวอร์ชั่น SMAPI: 3.7.5</string>
<string name="smapi_version">เวอร์ชั่น SMAPI: 3.7.6</string>
<string name="text_install_tip1">หมายเหตุ: ต้องการเกมเวอร์ชั่น 1.4.5.138 หรือใหม่กว่า</string>
<string name="text_install_tip2">ต้องการเกมหลักเมื่อทำการอัปเดต / ติดตั้ง</string>
<string name="unpacking_smapi_files">กำลังแกะกล่อง</string>

View File

@ -60,7 +60,7 @@
<string name="settings_verbose_logging">詳細日誌</string>
<string name="signing_package">正在簽名安裝包</string>
<string name="smapi_game_name">SMAPI 星露谷物語</string>
<string name="smapi_version">SMAPI版本: 3.7.5</string>
<string name="smapi_version">SMAPI版本: 3.7.6</string>
<string name="text_install_tip1">注意:需要 1.4.5.138 以上遊戲版本</string>
<string name="text_install_tip2">更新或安裝期間需要安裝遊戲</string>
<string name="unpacking_smapi_files">正在解包</string>

View File

@ -60,7 +60,7 @@
<string name="settings_verbose_logging">详细日志</string>
<string name="signing_package">正在签名安装包</string>
<string name="smapi_game_name">SMAPI星露谷物语</string>
<string name="smapi_version">SMAPI版本: 3.7.5</string>
<string name="smapi_version">SMAPI版本: 3.7.6</string>
<string name="text_install_tip1">注意需要不低于1.4.5.138版本的游戏本体</string>
<string name="text_install_tip2">更新或安装期间需要安装游戏本体</string>
<string name="unpacking_smapi_files">正在解包</string>

View File

@ -60,7 +60,7 @@
<string name="settings_verbose_logging">Verbose Logging</string>
<string name="signing_package">Signing</string>
<string name="smapi_game_name">SMAPI Stardew Valley</string>
<string name="smapi_version">SMAPI Version: 3.7.5</string>
<string name="smapi_version">SMAPI Version: 3.7.6</string>
<string name="text_install_tip1">Notes: Game version 1.4.5.138 or later is required.</string>
<string name="text_install_tip2">The base game is required when updating/installing.</string>
<string name="unpacking_smapi_files">Unpacking</string>