Merge pull request #1 from ZaneYork/master

Bug fix
This commit is contained in:
ELL 2020-06-23 12:38:12 +07:00 committed by GitHub
commit f55b33ccf1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 147 additions and 46 deletions

View File

@ -12,8 +12,8 @@ android {
applicationId "com.zane.smapiinstaller" applicationId "com.zane.smapiinstaller"
minSdkVersion 19 minSdkVersion 19
targetSdkVersion 28 targetSdkVersion 28
versionCode 46 versionCode 48
versionName "1.5.5" versionName "1.5.7"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
multiDexEnabled true multiDexEnabled true

View File

@ -1,5 +1,5 @@
{ {
"version": 21, "version": 23,
"contents": [ "contents": [
{ {
"type": "COMPAT", "type": "COMPAT",
@ -14,16 +14,16 @@
"name": "SMAPI for Galaxy Store", "name": "SMAPI for Galaxy Store",
"assetPath": "compat/samsung_138/", "assetPath": "compat/samsung_138/",
"description": "SMAPI compat package for game 1.4.4.138 - latest, SMAPI 3.6.1", "description": "SMAPI compat package for game 1.4.4.138 - latest, SMAPI 3.6.1",
"url": "http://zaneyork.cn/download/compat/smapi_samsung_138_16.zip", "url": "http://zaneyork.cn/download/compat/smapi_samsung_138_17.zip",
"hash": "20cf2ce515dcf05596d523387b244c9e14c235387db61545e7067835e5856626" "hash": "ac6cff4a1decb19fc01da7314e79483f2a77d34523665370d62f8bf69dcf09dc"
}, },
{ {
"type": "COMPAT", "type": "COMPAT",
"name": "SMAPI for Amazon Store", "name": "SMAPI for Amazon Store",
"assetPath": "compat/amazon_138/", "assetPath": "compat/amazon_138/",
"description": "SMAPI compat package for game 1.4.4.138 - latest, SMAPI 3.6.1", "description": "SMAPI compat package for game 1.4.4.138 - latest, SMAPI 3.6.1",
"url": "http://zaneyork.cn/download/compat/smapi_amazon_138_6.zip", "url": "http://zaneyork.cn/download/compat/smapi_amazon_138_7.zip",
"hash": "f487f8f14fcdd0ee31ca4e3b731e6e9114bc4b43a50c930f651a939e927eeb5d" "hash": "8a63e326ab122df5157a6c70c6cac8b8669ec81701f687746b80b7a860578dbb"
}, },
{ {
"type": "LOCALE", "type": "LOCALE",

View File

@ -1,5 +1,5 @@
{ {
"version": 21, "version": 23,
"contents": [ "contents": [
{ {
"type": "COMPAT", "type": "COMPAT",
@ -14,16 +14,16 @@
"name": "SMAPI for Galaxy Store", "name": "SMAPI for Galaxy Store",
"assetPath": "compat/samsung_138/", "assetPath": "compat/samsung_138/",
"description": "SMAPI compat package for game 1.4.4.138 - latest, SMAPI 3.6.1", "description": "SMAPI compat package for game 1.4.4.138 - latest, SMAPI 3.6.1",
"url": "http://zaneyork.cn/download/compat/smapi_samsung_138_16.zip", "url": "http://zaneyork.cn/download/compat/smapi_samsung_138_17.zip",
"hash": "20cf2ce515dcf05596d523387b244c9e14c235387db61545e7067835e5856626" "hash": "ac6cff4a1decb19fc01da7314e79483f2a77d34523665370d62f8bf69dcf09dc"
}, },
{ {
"type": "COMPAT", "type": "COMPAT",
"name": "SMAPI for Amazon Store", "name": "SMAPI for Amazon Store",
"assetPath": "compat/amazon_138/", "assetPath": "compat/amazon_138/",
"description": "SMAPI compat package for game 1.4.4.138 - latest, SMAPI 3.6.1", "description": "SMAPI compat package for game 1.4.4.138 - latest, SMAPI 3.6.1",
"url": "http://zaneyork.cn/download/compat/smapi_amazon_138_6.zip", "url": "http://zaneyork.cn/download/compat/smapi_amazon_138_7.zip",
"hash": "f487f8f14fcdd0ee31ca4e3b731e6e9114bc4b43a50c930f651a939e927eeb5d" "hash": "8a63e326ab122df5157a6c70c6cac8b8669ec81701f687746b80b7a860578dbb"
}, },
{ {
"type": "LOCALE", "type": "LOCALE",

View File

@ -1,5 +1,5 @@
{ {
"version": 21, "version": 23,
"contents": [ "contents": [
{ {
"type": "COMPAT", "type": "COMPAT",
@ -14,16 +14,16 @@
"name": "SMAPI untuk Galaxy Store", "name": "SMAPI untuk Galaxy Store",
"assetPath": "compat/samsung_138/", "assetPath": "compat/samsung_138/",
"description": "Paket kompatibilitas SMAPI untuk versi 1.4.4.138 - terbaru, SMAPI 3.6.1", "description": "Paket kompatibilitas SMAPI untuk versi 1.4.4.138 - terbaru, SMAPI 3.6.1",
"url": "http://zaneyork.cn/download/compat/smapi_samsung_138_16.zip", "url": "http://zaneyork.cn/download/compat/smapi_samsung_138_17.zip",
"hash": "20cf2ce515dcf05596d523387b244c9e14c235387db61545e7067835e5856626" "hash": "ac6cff4a1decb19fc01da7314e79483f2a77d34523665370d62f8bf69dcf09dc"
}, },
{ {
"type": "COMPAT", "type": "COMPAT",
"name": "SMAPI untuk Amazon Store", "name": "SMAPI untuk Amazon Store",
"assetPath": "compat/amazon_138/", "assetPath": "compat/amazon_138/",
"description": "Paket kompatibilitas SMAPI untuk versi 1.4.4.138 - terbaru, SMAPI 3.6.1", "description": "Paket kompatibilitas SMAPI untuk versi 1.4.4.138 - terbaru, SMAPI 3.6.1",
"url": "http://zaneyork.cn/download/compat/smapi_amazon_138_6.zip", "url": "http://zaneyork.cn/download/compat/smapi_amazon_138_7.zip",
"hash": "f487f8f14fcdd0ee31ca4e3b731e6e9114bc4b43a50c930f651a939e927eeb5d" "hash": "8a63e326ab122df5157a6c70c6cac8b8669ec81701f687746b80b7a860578dbb"
}, },
{ {
"type": "LOCAL", "type": "LOCAL",

View File

@ -1,5 +1,5 @@
{ {
"version": 21, "version": 23,
"contents": [ "contents": [
{ {
"type": "COMPAT", "type": "COMPAT",
@ -14,16 +14,16 @@
"name": "SMAPI三星商店兼容包", "name": "SMAPI三星商店兼容包",
"assetPath": "compat/samsung_138/", "assetPath": "compat/samsung_138/",
"description": "SMAPI三星商店兼容包 适用版本1.4.4.138至今, SMAPI 3.6.1", "description": "SMAPI三星商店兼容包 适用版本1.4.4.138至今, SMAPI 3.6.1",
"url": "http://zaneyork.cn/download/compat/smapi_samsung_138_16.zip", "url": "http://zaneyork.cn/download/compat/smapi_samsung_138_17.zip",
"hash": "20cf2ce515dcf05596d523387b244c9e14c235387db61545e7067835e5856626" "hash": "ac6cff4a1decb19fc01da7314e79483f2a77d34523665370d62f8bf69dcf09dc"
}, },
{ {
"type": "COMPAT", "type": "COMPAT",
"name": "SMAPI亚马逊商店兼容包", "name": "SMAPI亚马逊商店兼容包",
"assetPath": "compat/amazon_138/", "assetPath": "compat/amazon_138/",
"description": "SMAPI亚马逊商店兼容包 适用版本1.4.4.138至今, SMAPI 3.6.1", "description": "SMAPI亚马逊商店兼容包 适用版本1.4.4.138至今, SMAPI 3.6.1",
"url": "http://zaneyork.cn/download/compat/smapi_amazon_138_6.zip", "url": "http://zaneyork.cn/download/compat/smapi_amazon_138_7.zip",
"hash": "f487f8f14fcdd0ee31ca4e3b731e6e9114bc4b43a50c930f651a939e927eeb5d" "hash": "8a63e326ab122df5157a6c70c6cac8b8669ec81701f687746b80b7a860578dbb"
}, },
{ {
"type": "LOCALE", "type": "LOCALE",

View File

@ -26,6 +26,7 @@ import com.zane.smapiinstaller.constant.DialogAction;
import com.zane.smapiinstaller.dto.AppUpdateCheckResultDto; import com.zane.smapiinstaller.dto.AppUpdateCheckResultDto;
import com.zane.smapiinstaller.entity.AppConfig; import com.zane.smapiinstaller.entity.AppConfig;
import com.zane.smapiinstaller.entity.FrameworkConfig; import com.zane.smapiinstaller.entity.FrameworkConfig;
import com.zane.smapiinstaller.logic.ActivityResultHandler;
import com.zane.smapiinstaller.logic.CommonLogic; import com.zane.smapiinstaller.logic.CommonLogic;
import com.zane.smapiinstaller.logic.ConfigManager; import com.zane.smapiinstaller.logic.ConfigManager;
import com.zane.smapiinstaller.logic.GameLauncher; import com.zane.smapiinstaller.logic.GameLauncher;
@ -42,6 +43,7 @@ import java.io.File;
import java.util.Locale; import java.util.Locale;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import androidx.core.app.ActivityCompat; import androidx.core.app.ActivityCompat;
@ -97,6 +99,12 @@ public class MainActivity extends AppCompatActivity {
} }
} }
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
ActivityResultHandler.triggerListener(requestCode, resultCode, data);
}
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);

View File

@ -0,0 +1,24 @@
package com.zane.smapiinstaller.logic;
import android.content.Intent;
import java.util.concurrent.ConcurrentHashMap;
import java9.util.function.BiConsumer;
public class ActivityResultHandler {
public static int REQUEST_CODE_APP_INSTALL = 1001;
public static ConcurrentHashMap<Integer, BiConsumer<Integer, Intent>> listenerMap = new ConcurrentHashMap<>();
public static void registerListener(int requestCode, BiConsumer<Integer, Intent> listener) {
listenerMap.put(requestCode, listener);
}
public static void triggerListener(int requestCode, int resultCode, Intent data) {
BiConsumer<Integer, Intent> biConsumer = listenerMap.get(requestCode);
if(biConsumer != null) {
biConsumer.accept(resultCode, data);
}
}
}

View File

@ -8,6 +8,7 @@ import android.content.pm.PackageManager;
import android.net.Uri; import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.os.Environment; import android.os.Environment;
import android.provider.Settings;
import android.util.Log; import android.util.Log;
import com.android.apksig.ApkSigner; import com.android.apksig.ApkSigner;
@ -19,11 +20,14 @@ import com.google.common.collect.Iterables;
import com.google.common.hash.Hashing; import com.google.common.hash.Hashing;
import com.google.common.io.Files; import com.google.common.io.Files;
import com.zane.smapiinstaller.BuildConfig; import com.zane.smapiinstaller.BuildConfig;
import com.zane.smapiinstaller.MainActivity;
import com.zane.smapiinstaller.R; import com.zane.smapiinstaller.R;
import com.zane.smapiinstaller.constant.Constants; import com.zane.smapiinstaller.constant.Constants;
import com.zane.smapiinstaller.constant.DialogAction;
import com.zane.smapiinstaller.constant.ManifestPatchConstants; import com.zane.smapiinstaller.constant.ManifestPatchConstants;
import com.zane.smapiinstaller.entity.ApkFilesManifest; import com.zane.smapiinstaller.entity.ApkFilesManifest;
import com.zane.smapiinstaller.entity.ManifestEntry; import com.zane.smapiinstaller.entity.ManifestEntry;
import com.zane.smapiinstaller.utils.DialogUtils;
import com.zane.smapiinstaller.utils.FileUtils; import com.zane.smapiinstaller.utils.FileUtils;
import com.zane.smapiinstaller.utils.ZipUtils; import com.zane.smapiinstaller.utils.ZipUtils;
@ -131,8 +135,7 @@ public class ApkPatcher {
errorMessage.set(context.getString(R.string.error_directory_exists_with_same_filename, contentFolder.getAbsolutePath())); errorMessage.set(context.getString(R.string.error_directory_exists_with_same_filename, contentFolder.getAbsolutePath()));
return null; return null;
} }
} } else {
else {
extract(0); extract(0);
} }
ZipUtils.removeEntries(sourceDir, "assets/Content", distFile.getAbsolutePath(), (progress) -> emitProgress((int) (progress * 0.05))); ZipUtils.removeEntries(sourceDir, "assets/Content", distFile.getAbsolutePath(), (progress) -> emitProgress((int) (progress * 0.05)));
@ -209,11 +212,9 @@ public class ApkPatcher {
errorMessage.set(StringUtils.stripToEmpty(errorMessage.get()) + "\n" + errorMsg); errorMessage.set(StringUtils.stripToEmpty(errorMessage.get()) + "\n" + errorMsg);
return null; return null;
} }
} } else if (StringUtils.equals(crc, entry.getPatchedCrc())) {
else if(StringUtils.equals(crc, entry.getPatchedCrc())){
bytes = originBytes; bytes = originBytes;
} } else {
else {
String errorMsg = context.getString(R.string.error_patch_crc_incorrect, entry.getTargetPath(), crc); String errorMsg = context.getString(R.string.error_patch_crc_incorrect, entry.getTargetPath(), crc);
errorMessage.set(StringUtils.stripToEmpty(errorMessage.get()) + "\n" + errorMsg); errorMessage.set(StringUtils.stripToEmpty(errorMessage.get()) + "\n" + errorMsg);
return null; return null;
@ -402,6 +403,20 @@ public class ApkPatcher {
* @param apkPath 安装包路径 * @param apkPath 安装包路径
*/ */
public void install(String apkPath) { public void install(String apkPath) {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
boolean haveInstallPermission = context.getPackageManager().canRequestPackageInstalls();
if (!haveInstallPermission) {
DialogUtils.showConfirmDialog(MainActivity.instance, R.string.confirm, R.string.request_unknown_source_permission, ((dialog, dialogAction) -> {
if(dialogAction == DialogAction.POSITIVE) {
Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES);
ActivityResultHandler.registerListener(ActivityResultHandler.REQUEST_CODE_APP_INSTALL, (resultCode, data) -> this.install(apkPath));
MainActivity.instance.startActivityForResult(intent, ActivityResultHandler.REQUEST_CODE_APP_INSTALL);
}
}));
return;
}
}
Intent intent = new Intent(Intent.ACTION_VIEW); Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(fromFile(new File(apkPath)), "application/vnd.android.package-archive"); intent.setDataAndType(fromFile(new File(apkPath)), "application/vnd.android.package-archive");
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

View File

@ -7,6 +7,7 @@ import android.view.ViewGroup;
import android.widget.Button; import android.widget.Button;
import android.widget.TextView; import android.widget.TextView;
import com.zane.smapiinstaller.MobileNavigationDirections;
import com.zane.smapiinstaller.R; import com.zane.smapiinstaller.R;
import com.zane.smapiinstaller.constant.Constants; import com.zane.smapiinstaller.constant.Constants;
import com.zane.smapiinstaller.constant.DialogAction; import com.zane.smapiinstaller.constant.DialogAction;
@ -175,7 +176,7 @@ public class ModManifestAdapter extends RecyclerView.Adapter<ModManifestAdapter.
File file = new File(modPath, "config.json"); File file = new File(modPath, "config.json");
if(file.exists()) { if(file.exists()) {
NavController controller = Navigation.findNavController(itemView); NavController controller = Navigation.findNavController(itemView);
ConfigFragmentDirections.ActionNavConfigToConfigEditFragment action = ConfigFragmentDirections.actionNavConfigToConfigEditFragment(file.getAbsolutePath()); MobileNavigationDirections.ActionNavAnyToConfigEditFragment action = ConfigFragmentDirections.actionNavAnyToConfigEditFragment(file.getAbsolutePath());
controller.navigate(action); controller.navigate(action);
} }
} }

View File

@ -6,6 +6,7 @@ import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import com.zane.smapiinstaller.MobileNavigationDirections;
import com.zane.smapiinstaller.R; import com.zane.smapiinstaller.R;
import com.zane.smapiinstaller.constant.Constants; import com.zane.smapiinstaller.constant.Constants;
import com.zane.smapiinstaller.entity.HelpItemList; import com.zane.smapiinstaller.entity.HelpItemList;
@ -60,7 +61,7 @@ public class HelpFragment extends Fragment {
NavController controller = Navigation.findNavController(view); NavController controller = Navigation.findNavController(view);
File logFile = new File(Environment.getExternalStorageDirectory(), Constants.LOG_PATH); File logFile = new File(Environment.getExternalStorageDirectory(), Constants.LOG_PATH);
if(logFile.exists()) { if(logFile.exists()) {
HelpFragmentDirections.ActionNavHelpToConfigEditFragment action = HelpFragmentDirections.actionNavHelpToConfigEditFragment(logFile.getAbsolutePath()); MobileNavigationDirections.ActionNavAnyToConfigEditFragment action = HelpFragmentDirections.actionNavAnyToConfigEditFragment(logFile.getAbsolutePath());
action.setEditable(false); action.setEditable(false);
controller.navigate(action); controller.navigate(action);
} }

View File

@ -67,6 +67,13 @@ public class DialogUtils {
materialDialog.show(); materialDialog.show();
}); });
} }
public static void showAlertDialog(Activity context, int title, String message) {
CommonLogic.runOnUiThread(context, (activity) -> {
MaterialDialog materialDialog = new MaterialDialog(activity, MaterialDialog.getDEFAULT_BEHAVIOR()).title(title, null).message(null, message, null).positiveButton(R.string.ok, null, null);
DialogUtils.setCurrentDialog(materialDialog);
materialDialog.show();
});
}
/** /**
* 显示警告对话框 * 显示警告对话框
@ -83,6 +90,14 @@ public class DialogUtils {
}); });
} }
public static void showAlertDialog(Activity context, int title, int message) {
CommonLogic.runOnUiThread(context, (activity) -> {
MaterialDialog materialDialog = new MaterialDialog(activity, MaterialDialog.getDEFAULT_BEHAVIOR()).title(title, null).message(message, null, null).positiveButton(R.string.ok, null, null);
DialogUtils.setCurrentDialog(materialDialog);
materialDialog.show();
});
}
/** /**
* 显示确认对话框 * 显示确认对话框
* *
@ -104,6 +119,19 @@ public class DialogUtils {
materialDialog.show(); materialDialog.show();
}); });
} }
public static void showConfirmDialog(Activity context, int title, int message, BiConsumer<MaterialDialog, DialogAction> callback) {
CommonLogic.runOnUiThread(context, (activity) -> {
MaterialDialog materialDialog = new MaterialDialog(activity, MaterialDialog.getDEFAULT_BEHAVIOR()).title(title, null).message(message, null, null).positiveButton(R.string.confirm, null, dialog -> {
callback.accept(dialog, DialogAction.POSITIVE);
return null;
}).negativeButton(R.string.cancel, null, dialog -> {
callback.accept(dialog, DialogAction.NEGATIVE);
return null;
});
DialogUtils.setCurrentDialog(materialDialog);
materialDialog.show();
});
}
/** /**
* 显示确认对话框 * 显示确认对话框
@ -178,6 +206,20 @@ public class DialogUtils {
}); });
return reference; return reference;
} }
public static AtomicReference<ProgressDialog> showProgressDialog(Activity context, int title, String message) {
AtomicReference<ProgressDialog> reference = new AtomicReference<>();
CommonLogic.runOnUiThread(context, (activity) -> {
ProgressDialog dialog = new ProgressDialog(activity);
DialogUtils.setCurrentDialog(dialog);
dialog.setMessage(message);
dialog.setCancelable(false);
dialog.setMax(100);
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
dialog.show();
reference.set(dialog);
});
return reference;
}
/** /**
* 解散指定对话框 * 解散指定对话框
@ -221,6 +263,20 @@ public class DialogUtils {
} }
} }
public static void dismissDialog(Activity activity, ProgressDialog dialog) {
if (activity != null && !activity.isFinishing()) {
activity.runOnUiThread(() -> {
if (dialog != null) {
try {
dialog.dismiss();
} catch (Exception e) {
Crashes.trackError(e);
}
}
});
}
}
/** /**
* 解散当前对话框 * 解散当前对话框
*/ */

View File

@ -31,24 +31,12 @@
android:name="com.zane.smapiinstaller.ui.config.ConfigFragment" android:name="com.zane.smapiinstaller.ui.config.ConfigFragment"
android:label="@string/menu_config" android:label="@string/menu_config"
tools:layout="@layout/fragment_config"> tools:layout="@layout/fragment_config">
<action
android:id="@+id/action_nav_config_to_config_edit_fragment"
app:destination="@id/config_edit_fragment">
<argument android:name="configPath" app:argType="string"/>
<argument android:name="editable" android:defaultValue="true" app:argType="boolean"/>
</action>
</fragment> </fragment>
<fragment <fragment
android:id="@+id/nav_help" android:id="@+id/nav_help"
android:name="com.zane.smapiinstaller.ui.help.HelpFragment" android:name="com.zane.smapiinstaller.ui.help.HelpFragment"
android:label="@string/menu_help" android:label="@string/menu_help"
tools:layout="@layout/fragment_help"> tools:layout="@layout/fragment_help">
<action
android:id="@+id/action_nav_help_to_config_edit_fragment"
app:destination="@id/config_edit_fragment" >
<argument android:name="configPath" app:argType="string"/>
<argument android:name="editable" android:defaultValue="true" app:argType="boolean"/>
</action>
</fragment> </fragment>
<fragment <fragment
android:id="@+id/nav_download" android:id="@+id/nav_download"
@ -60,7 +48,6 @@
android:name="com.zane.smapiinstaller.ui.about.AboutFragment" android:name="com.zane.smapiinstaller.ui.about.AboutFragment"
android:label="@string/menu_about" android:label="@string/menu_about"
tools:layout="@layout/fragment_about" /> tools:layout="@layout/fragment_about" />
<fragment <fragment
android:id="@+id/nav_mod_update" android:id="@+id/nav_mod_update"
android:name="com.zane.smapiinstaller.ui.update.ModUpdateFragment" android:name="com.zane.smapiinstaller.ui.update.ModUpdateFragment"
@ -71,6 +58,12 @@
android:defaultValue="{}" android:defaultValue="{}"
app:argType="string" /> app:argType="string" />
</fragment> </fragment>
<action
android:id="@+id/action_nav_any_to_config_edit_fragment"
app:destination="@id/config_edit_fragment">
<argument android:name="configPath" app:argType="string"/>
<argument android:name="editable" android:defaultValue="true" app:argType="boolean"/>
</action>
<action <action
android:id="@+id/action_nav_any_to_mod_update_fragment" android:id="@+id/action_nav_any_to_mod_update_fragment"
app:destination="@id/nav_mod_update" > app:destination="@id/nav_mod_update" >

View File

@ -81,4 +81,5 @@
<string name="error_directory_exists_with_same_filename">%1$s不是一個文件夾, 請手動刪除該文件</string> <string name="error_directory_exists_with_same_filename">%1$s不是一個文件夾, 請手動刪除該文件</string>
<string name="error_patch_crc_incorrect">增量更新%1$s失敗: CRC (%2$s))</string> <string name="error_patch_crc_incorrect">增量更新%1$s失敗: CRC (%2$s))</string>
<string name="settings_rewrite_in_parallel">多線程重寫</string> <string name="settings_rewrite_in_parallel">多線程重寫</string>
<string name="request_unknown_source_permission">需要开启未知源权限以安装Mod框架是否前往设置开启</string>
</resources> </resources>

View File

@ -81,4 +81,5 @@
<string name="error_directory_exists_with_same_filename">%1$s不是一个文件夹, 请手动删除该文件</string> <string name="error_directory_exists_with_same_filename">%1$s不是一个文件夹, 请手动删除该文件</string>
<string name="error_patch_crc_incorrect">增量更新%1$s失败: CRC (%2$s))</string> <string name="error_patch_crc_incorrect">增量更新%1$s失败: CRC (%2$s))</string>
<string name="settings_rewrite_in_parallel">多线程重写</string> <string name="settings_rewrite_in_parallel">多线程重写</string>
<string name="request_unknown_source_permission">需要开启未知源权限以安装Mod框架是否前往设置开启</string>
</resources> </resources>

View File

@ -85,4 +85,5 @@
<string name="error_directory_exists_with_same_filename">%1$s is not a directory, please delete it manually.</string> <string name="error_directory_exists_with_same_filename">%1$s is not a directory, please delete it manually.</string>
<string name="error_patch_crc_incorrect">Patch %1$s failed: CRC (%2$s))</string> <string name="error_patch_crc_incorrect">Patch %1$s failed: CRC (%2$s))</string>
<string name="settings_rewrite_in_parallel">Rewrite in Parallel</string> <string name="settings_rewrite_in_parallel">Rewrite in Parallel</string>
<string name="request_unknown_source_permission">Needs to switch unknown source permission on to install mod framework, open settings?</string>
</resources> </resources>