From 36a64e4ad3dd9c60800106e7617fdc7d800b7adf Mon Sep 17 00:00:00 2001 From: ZaneYork Date: Fri, 20 Mar 2020 18:30:21 +0800 Subject: [PATCH] 1.Mod list search feature 2.Indonesia translate file 3.Code clean up --- .../com/zane/smapiinstaller/MainActivity.java | 24 +++++-- .../zane/smapiinstaller/MainApplication.java | 3 +- .../smapiinstaller/constant/Constants.java | 6 ++ .../constant/DownloadableContentTypes.java | 7 ++ .../constant/ManifestPatchConstants.java | 9 +++ .../entity/FrameworkConfig.java | 1 + .../entity/ModManifestEntry.java | 3 +- .../entity/YouDaoTranslationDto.java | 1 - .../zane/smapiinstaller/logic/ApkPatcher.java | 20 ++++-- .../smapiinstaller/logic/CommonLogic.java | 5 +- .../logic/ModAssetsManager.java | 28 +++++--- .../ui/about/AboutFragment.java | 12 ++-- .../ui/config/ConfigEditFragment.java | 1 + .../ui/config/ConfigFragment.java | 13 +++- .../ui/config/ConfigViewModel.java | 59 ++++++++++------ .../ui/config/ModManifestAdapter.java | 43 +++++++++--- .../download/DownloadableContentAdapter.java | 9 ++- .../smapiinstaller/ui/help/HelpFragment.java | 1 + .../ui/install/InstallFragment.java | 3 +- .../utils/GzipRequestInterceptor.java | 6 +- .../zane/smapiinstaller/utils/JSONUtil.java | 18 ++--- .../smapiinstaller/utils/TranslateUtil.java | 14 ++-- .../smapiinstaller/utils/VersionUtil.java | 11 +-- app/src/main/res/layout/fragment_config.xml | 48 ++++++++++++- app/src/main/res/layout/fragment_help.xml | 2 +- app/src/main/res/values-in/strings.xml | 68 +++++++++++++++++++ app/src/main/res/values-zh-rHK/arrays.xml | 1 + app/src/main/res/values-zh-rTW/arrays.xml | 1 + app/src/main/res/values-zh/arrays.xml | 1 + app/src/main/res/values/arrays.xml | 1 + 30 files changed, 325 insertions(+), 94 deletions(-) create mode 100644 app/src/main/java/com/zane/smapiinstaller/constant/DownloadableContentTypes.java create mode 100644 app/src/main/java/com/zane/smapiinstaller/constant/ManifestPatchConstants.java create mode 100644 app/src/main/res/values-in/strings.xml diff --git a/app/src/main/java/com/zane/smapiinstaller/MainActivity.java b/app/src/main/java/com/zane/smapiinstaller/MainActivity.java index 0711f98..11e789e 100644 --- a/app/src/main/java/com/zane/smapiinstaller/MainActivity.java +++ b/app/src/main/java/com/zane/smapiinstaller/MainActivity.java @@ -70,6 +70,7 @@ public class MainActivity extends AppCompatActivity { } } + @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { initView(); @@ -126,10 +127,11 @@ public class MainActivity extends AppCompatActivity { @Override public boolean onOptionsItemSelected(MenuItem item) { if(item.isCheckable()) { - if (item.isChecked()) + if (item.isChecked()) { item.setChecked(false); - else + } else { item.setChecked(true); + } } ConfigManager manager = new ConfigManager(); FrameworkConfig config = manager.getConfig(); @@ -190,6 +192,9 @@ public class MainActivity extends AppCompatActivity { case 8: restart = LanguagesManager.setAppLanguage(this, new Locale("pt", "")); break; + case 9: + restart = LanguagesManager.setAppLanguage(this, new Locale("in", "")); + break; default: return; } @@ -208,23 +213,28 @@ public class MainActivity extends AppCompatActivity { AppConfig activeTranslator = appConfigDao.queryBuilder().where(AppConfigDao.Properties.Name.eq(AppConfigKey.ACTIVE_TRANSLATOR)).build().unique(); switch (position) { case 0: - if(activeTranslator != null) + if(activeTranslator != null) { appConfigDao.delete(activeTranslator); + } break; case 1: - if(activeTranslator == null) + if(activeTranslator == null) { activeTranslator = new AppConfig(null, AppConfigKey.ACTIVE_TRANSLATOR, TranslateUtil.GOOGLE); - else + } else { activeTranslator.setValue(TranslateUtil.GOOGLE); + } appConfigDao.insertOrReplace(activeTranslator); break; case 2: - if(activeTranslator == null) + if(activeTranslator == null) { activeTranslator = new AppConfig(null, AppConfigKey.ACTIVE_TRANSLATOR, TranslateUtil.YOU_DAO); - else + } else { activeTranslator.setValue(TranslateUtil.YOU_DAO); + } appConfigDao.insertOrReplace(activeTranslator); break; + default: + break; } }).show()); return true; diff --git a/app/src/main/java/com/zane/smapiinstaller/MainApplication.java b/app/src/main/java/com/zane/smapiinstaller/MainApplication.java index edbc1b6..64edc37 100644 --- a/app/src/main/java/com/zane/smapiinstaller/MainApplication.java +++ b/app/src/main/java/com/zane/smapiinstaller/MainApplication.java @@ -22,7 +22,8 @@ public class MainApplication extends Application { public void onCreate() { super.onCreate(); OkHttpClient okHttpClient = new OkHttpClient.Builder() - .addInterceptor(new GzipRequestInterceptor())//开启Gzip压缩 + //开启Gzip压缩 + .addInterceptor(new GzipRequestInterceptor()) .build(); OkGo.getInstance().setOkHttpClient(okHttpClient).init(this); LanguagesManager.init(this); diff --git a/app/src/main/java/com/zane/smapiinstaller/constant/Constants.java b/app/src/main/java/com/zane/smapiinstaller/constant/Constants.java index 9bc1a43..f6375e0 100644 --- a/app/src/main/java/com/zane/smapiinstaller/constant/Constants.java +++ b/app/src/main/java/com/zane/smapiinstaller/constant/Constants.java @@ -34,6 +34,12 @@ public class Constants { */ public static final String APP_CENTER_SECRET = "cb44e94a-7b2f-431e-9ad9-48013ec8c208"; + public static final String RED_PACKET_CODE = "9188262"; + + public static final String HIDDEN_FILE_PREFIX = "."; + + public static final int URL_LENGTH_LIMIT = 4096; + /** * 有道翻译服务 */ diff --git a/app/src/main/java/com/zane/smapiinstaller/constant/DownloadableContentTypes.java b/app/src/main/java/com/zane/smapiinstaller/constant/DownloadableContentTypes.java new file mode 100644 index 0000000..ad970c5 --- /dev/null +++ b/app/src/main/java/com/zane/smapiinstaller/constant/DownloadableContentTypes.java @@ -0,0 +1,7 @@ +package com.zane.smapiinstaller.constant; + +public class DownloadableContentTypes { + public static final String LOCALE = "LOCALE"; + + public static final String COMPAT = "COMPAT"; +} diff --git a/app/src/main/java/com/zane/smapiinstaller/constant/ManifestPatchConstants.java b/app/src/main/java/com/zane/smapiinstaller/constant/ManifestPatchConstants.java new file mode 100644 index 0000000..e57f0b7 --- /dev/null +++ b/app/src/main/java/com/zane/smapiinstaller/constant/ManifestPatchConstants.java @@ -0,0 +1,9 @@ +package com.zane.smapiinstaller.constant; + +public class ManifestPatchConstants { + public static final String APP_NAME = "Stardew Valley"; + + public static final String PATTERN_MAIN_ACTIVITY = ".MainActivity"; + + public static final String PATTERN_VERSION_CODE = "versionCode"; +} diff --git a/app/src/main/java/com/zane/smapiinstaller/entity/FrameworkConfig.java b/app/src/main/java/com/zane/smapiinstaller/entity/FrameworkConfig.java index 27e70ef..8e08326 100644 --- a/app/src/main/java/com/zane/smapiinstaller/entity/FrameworkConfig.java +++ b/app/src/main/java/com/zane/smapiinstaller/entity/FrameworkConfig.java @@ -9,6 +9,7 @@ import lombok.Data; /** * SMAPI的配置 */ +@SuppressWarnings("AlibabaLowerCamelCaseVariableNaming") @Data @JsonAutoDetect(fieldVisibility=JsonAutoDetect.Visibility.ANY, getterVisibility= JsonAutoDetect.Visibility.NONE) public class FrameworkConfig { diff --git a/app/src/main/java/com/zane/smapiinstaller/entity/ModManifestEntry.java b/app/src/main/java/com/zane/smapiinstaller/entity/ModManifestEntry.java index accfa89..1c3cf21 100644 --- a/app/src/main/java/com/zane/smapiinstaller/entity/ModManifestEntry.java +++ b/app/src/main/java/com/zane/smapiinstaller/entity/ModManifestEntry.java @@ -7,6 +7,7 @@ import lombok.Data; /** * Mod信息 */ +@SuppressWarnings("ALL") @Data public class ModManifestEntry { /** @@ -47,7 +48,7 @@ public class ModManifestEntry { */ private Boolean IsRequired; - /* + /** * 翻译后的Description */ private transient String translatedDescription; diff --git a/app/src/main/java/com/zane/smapiinstaller/entity/YouDaoTranslationDto.java b/app/src/main/java/com/zane/smapiinstaller/entity/YouDaoTranslationDto.java index 06206a9..df1cabd 100644 --- a/app/src/main/java/com/zane/smapiinstaller/entity/YouDaoTranslationDto.java +++ b/app/src/main/java/com/zane/smapiinstaller/entity/YouDaoTranslationDto.java @@ -6,7 +6,6 @@ import lombok.Data; @Data public class YouDaoTranslationDto { - //{"type":"ZH_CN2EN","errorCode":0,"elapsedTime":2,"translateResult":[[{"src":"云计算","tgt":"Cloud computing"}],[{"src":"前往合肥","tgt":"Travel to hefei"}]]} private String type; private int errorCode; private int elapsedTime; diff --git a/app/src/main/java/com/zane/smapiinstaller/logic/ApkPatcher.java b/app/src/main/java/com/zane/smapiinstaller/logic/ApkPatcher.java index f0e3715..6ab6e17 100644 --- a/app/src/main/java/com/zane/smapiinstaller/logic/ApkPatcher.java +++ b/app/src/main/java/com/zane/smapiinstaller/logic/ApkPatcher.java @@ -17,6 +17,7 @@ import com.google.common.io.Files; import com.zane.smapiinstaller.BuildConfig; import com.zane.smapiinstaller.R; import com.zane.smapiinstaller.constant.Constants; +import com.zane.smapiinstaller.constant.ManifestPatchConstants; import com.zane.smapiinstaller.entity.ApkFilesManifest; import com.zane.smapiinstaller.entity.ManifestEntry; import com.zane.smapiinstaller.utils.FileUtils; @@ -101,11 +102,13 @@ public class ApkPatcher { * @return 是否成功打包 */ public boolean patch(String apkPath) { - if (apkPath == null) + if (apkPath == null) { return false; + } File file = new File(apkPath); - if (!file.exists()) + if (!file.exists()) { return false; + } try { List zipEntrySourceList = new ArrayList<>(); byte[] manifest = ZipUtil.unpackEntry(file, "AndroidManifest.xml"); @@ -158,7 +161,7 @@ public class ApkPatcher { } break; case "label": - if (strObj.contains("Stardew Valley")) { + if (strObj.contains(ManifestPatchConstants.APP_NAME)) { attr.obj = context.getString(R.string.smapi_game_name); } break; @@ -167,14 +170,16 @@ public class ApkPatcher { attr.obj = strObj.replace(packageName.get(), Constants.TARGET_PACKAGE_NAME); } case "name": - if (strObj.contains(".MainActivity")) { + if (strObj.contains(ManifestPatchConstants.PATTERN_MAIN_ACTIVITY)) { attr.obj = strObj.replaceFirst("\\w+\\.MainActivity", "md5723872fa9a204f7f942686e9ed9d0b7d.SMainActivity"); } break; + default: + break; } } else if(attr.type == NodeVisitor.TYPE_FIRST_INT) { - if(StringUtils.equals(attr.name, "versionCode")){ + if(StringUtils.equals(attr.name, ManifestPatchConstants.PATTERN_VERSION_CODE)){ long versionCode = (int) attr.obj; Iterables.removeIf(manifests, manifest -> { if (versionCode < manifest.getMinBuildCode()) { @@ -252,10 +257,11 @@ public class ApkPatcher { */ private Uri fromFile(File file) { //Android versions greater than Nougat use FileProvider, others use the URI.fromFile. - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { return FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".provider", file); - else + } else { return Uri.fromFile(file); + } } /** diff --git a/app/src/main/java/com/zane/smapiinstaller/logic/CommonLogic.java b/app/src/main/java/com/zane/smapiinstaller/logic/CommonLogic.java index a18f6a4..d645ee2 100644 --- a/app/src/main/java/com/zane/smapiinstaller/logic/CommonLogic.java +++ b/app/src/main/java/com/zane/smapiinstaller/logic/CommonLogic.java @@ -137,8 +137,9 @@ public class CommonLogic { */ public static boolean unpackSmapiFiles(Context context, String apkPath, boolean checkMode) { List manifestEntries = FileUtils.getAssetJson(context, "smapi_files_manifest.json", new TypeReference>() { }); - if (manifestEntries == null) + if (manifestEntries == null) { return false; + } File basePath = new File(Environment.getExternalStorageDirectory() + "/StardewValley/"); if (!basePath.exists()) { if (!basePath.mkdir()) { @@ -176,6 +177,8 @@ public class CommonLogic { ZipUtil.unpackEntry(new File(apkPath), entry.getAssetPath(), targetFile); } break; + default: + break; } } return true; diff --git a/app/src/main/java/com/zane/smapiinstaller/logic/ModAssetsManager.java b/app/src/main/java/com/zane/smapiinstaller/logic/ModAssetsManager.java index fc81289..9aad713 100644 --- a/app/src/main/java/com/zane/smapiinstaller/logic/ModAssetsManager.java +++ b/app/src/main/java/com/zane/smapiinstaller/logic/ModAssetsManager.java @@ -135,8 +135,9 @@ public class ModAssetsManager { public boolean installDefaultMods() { Activity context = CommonLogic.getActivityFromView(root); List modManifestEntries = FileUtils.getAssetJson(context, "mods_manifest.json", new TypeReference>() { }); - if (modManifestEntries == null) + if (modManifestEntries == null) { return false; + } File modFolder = new File(Environment.getExternalStorageDirectory(), Constants.MOD_PATH); ImmutableListMultimap installedModMap = Multimaps.index(findAllInstalledMods(), ModManifestEntry::getUniqueID); for (ModManifestEntry mod : modManifestEntries) { @@ -175,15 +176,17 @@ public class ModAssetsManager { public void checkModEnvironment(Consumer returnCallback) { ImmutableListMultimap installedModMap = Multimaps.index(findAllInstalledMods(true), ModManifestEntry::getUniqueID); checkDuplicateMod(installedModMap, (isConfirm) -> { - if (isConfirm) + if (isConfirm) { checkUnsatisfiedDependencies(installedModMap, (isConfirm2) -> { - if (isConfirm2) + if (isConfirm2) { checkContentpacks(installedModMap, returnCallback); - else + } else { returnCallback.accept(false); + } }); - else + } else { returnCallback.accept(false); + } }); } @@ -213,8 +216,9 @@ public class ModAssetsManager { } })); } - else + else { returnCallback.accept(true); + } } /** @@ -239,8 +243,9 @@ public class ModAssetsManager { } } } - if (entries.size() != 1) + if (entries.size() != 1) { return true; + } String version = entries.get(0).getVersion(); if (StringUtils.isBlank(version)) { return true; @@ -271,8 +276,9 @@ public class ModAssetsManager { } })); } - else + else { returnCallback.accept(true); + } } /** @@ -297,8 +303,9 @@ public class ModAssetsManager { } } } - if (entries.size() != 1) + if (entries.size() != 1) { return root.getContext().getString(R.string.error_depends_on_mod, mod.getUniqueID(), dependency.getUniqueID()); + } String version = entries.get(0).getVersion(); if (!StringUtils.isBlank(version)) { if (StringUtils.isBlank(dependency.getMinimumVersion())) { @@ -324,7 +331,8 @@ public class ModAssetsManager { } })); } - else + else { returnCallback.accept(true); + } } } diff --git a/app/src/main/java/com/zane/smapiinstaller/ui/about/AboutFragment.java b/app/src/main/java/com/zane/smapiinstaller/ui/about/AboutFragment.java index e88b095..428d14b 100644 --- a/app/src/main/java/com/zane/smapiinstaller/ui/about/AboutFragment.java +++ b/app/src/main/java/com/zane/smapiinstaller/ui/about/AboutFragment.java @@ -1,7 +1,6 @@ package com.zane.smapiinstaller.ui.about; import android.content.ActivityNotFoundException; -import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; @@ -21,11 +20,10 @@ import android.widget.Toast; import com.afollestad.materialdialogs.MaterialDialog; import com.zane.smapiinstaller.R; +import com.zane.smapiinstaller.constant.Constants; import com.zane.smapiinstaller.logic.CommonLogic; import com.zane.smapiinstaller.utils.DialogUtils; -import java.time.Duration; - public class AboutFragment extends Fragment { @Override @@ -41,7 +39,7 @@ public class AboutFragment extends Fragment { @OnClick(R.id.button_gplay) void gplay() { try { - this.OpenPlayStore("market://details?id=" + this.getActivity().getPackageName()); + this.openPlayStore("market://details?id=" + this.getActivity().getPackageName()); } catch (ActivityNotFoundException ex) { @@ -49,7 +47,7 @@ public class AboutFragment extends Fragment { } } - private void OpenPlayStore(String url) + private void openPlayStore(String url) { Intent intent = new Intent("android.intent.action.VIEW"); intent.setData(Uri.parse(url)); @@ -90,7 +88,7 @@ public class AboutFragment extends Fragment { case 3: hasInstalledAlipayClient = AlipayDonate.hasInstalledAlipayClient(context); if (hasInstalledAlipayClient) { - if (CommonLogic.copyToClipboard(context, "9188262")) { + if (CommonLogic.copyToClipboard(context, Constants.RED_PACKET_CODE)) { PackageManager packageManager = context.getPackageManager(); Intent intent = packageManager.getLaunchIntentForPackage("com.eg.android.AlipayGphone"); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); @@ -99,6 +97,8 @@ public class AboutFragment extends Fragment { } } break; + default: + break; } }).show()); } diff --git a/app/src/main/java/com/zane/smapiinstaller/ui/config/ConfigEditFragment.java b/app/src/main/java/com/zane/smapiinstaller/ui/config/ConfigEditFragment.java index fa12289..dd3e943 100644 --- a/app/src/main/java/com/zane/smapiinstaller/ui/config/ConfigEditFragment.java +++ b/app/src/main/java/com/zane/smapiinstaller/ui/config/ConfigEditFragment.java @@ -33,6 +33,7 @@ public class ConfigEditFragment extends Fragment { @BindView(R.id.button_config_cancel) Button buttonConfigCancel; + @Override public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View root = inflater.inflate(R.layout.fragment_config_edit, container, false); diff --git a/app/src/main/java/com/zane/smapiinstaller/ui/config/ConfigFragment.java b/app/src/main/java/com/zane/smapiinstaller/ui/config/ConfigFragment.java index 245d2f5..8aace73 100644 --- a/app/src/main/java/com/zane/smapiinstaller/ui/config/ConfigFragment.java +++ b/app/src/main/java/com/zane/smapiinstaller/ui/config/ConfigFragment.java @@ -12,22 +12,25 @@ import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import butterknife.BindView; import butterknife.ButterKnife; +import butterknife.OnClick; +import butterknife.OnTextChanged; import com.zane.smapiinstaller.R; public class ConfigFragment extends Fragment { - @BindView(R.id.view_mod_list) RecyclerView recyclerView; + private ConfigViewModel configViewModel; + @Override public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View root = inflater.inflate(R.layout.fragment_config, container, false); ButterKnife.bind(this, root); recyclerView.setLayoutManager(new LinearLayoutManager(this.getContext())); - ConfigViewModel configViewModel = new ConfigViewModel(root); - ModManifestAdapter modManifestAdapter = new ModManifestAdapter(configViewModel); + configViewModel = new ConfigViewModel(root); + ModManifestAdapter modManifestAdapter = new ModManifestAdapter(configViewModel, configViewModel.getModList()); recyclerView.setAdapter(modManifestAdapter); configViewModel.registerListChangeListener((list) -> { modManifestAdapter.setList(list); @@ -36,4 +39,8 @@ public class ConfigFragment extends Fragment { recyclerView.addItemDecoration(new DividerItemDecoration(recyclerView.getContext(), DividerItemDecoration.VERTICAL)); return root; } + + @OnTextChanged(R.id.button_search) void onSearchMod(CharSequence text){ + configViewModel.filter(text); + } } diff --git a/app/src/main/java/com/zane/smapiinstaller/ui/config/ConfigViewModel.java b/app/src/main/java/com/zane/smapiinstaller/ui/config/ConfigViewModel.java index efa07e2..1fd1e6b 100644 --- a/app/src/main/java/com/zane/smapiinstaller/ui/config/ConfigViewModel.java +++ b/app/src/main/java/com/zane/smapiinstaller/ui/config/ConfigViewModel.java @@ -21,6 +21,7 @@ import com.zane.smapiinstaller.logic.CommonLogic; import com.zane.smapiinstaller.logic.ModAssetsManager; import com.zane.smapiinstaller.utils.TranslateUtil; +import org.apache.commons.lang3.StringUtils; import org.greenrobot.greendao.query.Query; import java.util.ArrayList; @@ -34,10 +35,24 @@ class ConfigViewModel extends ViewModel { @NonNull private List modList; + private List filteredModList; + private List>> onChangedListener = new ArrayList<>(); ConfigViewModel(View root) { this.modList = ModAssetsManager.findAllInstalledMods(); + translateLogic(root); + Collections.sort(this.modList, (a, b) -> { + if (a.getContentPackFor() != null && b.getContentPackFor() == null) { + return 1; + } else if (b.getContentPackFor() != null) { + return -1; + } + return a.getName().compareTo(b.getName()); + }); + } + + private void translateLogic(View root) { MainApplication app = CommonLogic.getApplicationFromView(root); if (null != app) { DaoSession daoSession = app.getDaoSession(); @@ -79,14 +94,6 @@ class ConfigViewModel extends ViewModel { } } } - Collections.sort(this.modList, (a, b) -> { - if (a.getContentPackFor() != null && b.getContentPackFor() == null) { - return 1; - } else if (b.getContentPackFor() != null) { - return -1; - } - return a.getName().compareTo(b.getName()); - }); } @NonNull @@ -94,24 +101,12 @@ class ConfigViewModel extends ViewModel { return modList; } - public Integer findFirst(Predicate predicate) { - for (int i = 0; i < modList.size(); i++) { - if (predicate.apply(modList.get(i))) { - return i; - } - } - return null; - } - - public List removeAll(Predicate predicate) { - List deletedId = new ArrayList<>(); + public void removeAll(Predicate predicate) { for (int i = modList.size() - 1; i >= 0; i--) { if (predicate.apply(modList.get(i))) { modList.remove(i); - deletedId.add(i); } } - return deletedId; } /** @@ -122,4 +117,26 @@ class ConfigViewModel extends ViewModel { public void registerListChangeListener(Predicate> onChanged) { this.onChangedListener.add(onChanged); } + + public void filter(CharSequence text) { + if(StringUtils.isBlank(text)) { + filteredModList = modList; + } + else { + filteredModList = Lists.newArrayList(Iterables.filter(modList, mod -> { + if(StringUtils.containsIgnoreCase(mod.getName(), text)) { + return true; + } + if(StringUtils.isNoneBlank(mod.getTranslatedDescription())){ + return StringUtils.containsIgnoreCase(mod.getTranslatedDescription(), text); + } + else { + return StringUtils.containsIgnoreCase(mod.getDescription(), text); + } + })); + } + for (Predicate> listener : onChangedListener) { + listener.apply(filteredModList); + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/zane/smapiinstaller/ui/config/ModManifestAdapter.java b/app/src/main/java/com/zane/smapiinstaller/ui/config/ModManifestAdapter.java index a8be77b..c9d3e89 100644 --- a/app/src/main/java/com/zane/smapiinstaller/ui/config/ModManifestAdapter.java +++ b/app/src/main/java/com/zane/smapiinstaller/ui/config/ModManifestAdapter.java @@ -8,7 +8,9 @@ import android.widget.Button; import android.widget.TextView; import com.afollestad.materialdialogs.DialogAction; +import com.google.common.base.Predicate; import com.zane.smapiinstaller.R; +import com.zane.smapiinstaller.constant.Constants; import com.zane.smapiinstaller.entity.ModManifestEntry; import com.zane.smapiinstaller.utils.DialogUtils; import com.zane.smapiinstaller.utils.FileUtils; @@ -17,6 +19,7 @@ import org.apache.commons.lang3.StringUtils; import java.io.File; import java.io.IOException; +import java.util.ArrayList; import java.util.List; import androidx.annotation.NonNull; @@ -29,9 +32,11 @@ import butterknife.OnClick; public class ModManifestAdapter extends RecyclerView.Adapter { private ConfigViewModel model; + private List modList; - public ModManifestAdapter(ConfigViewModel model){ + public ModManifestAdapter(ConfigViewModel model, List modList){ this.model=model; + this.modList = modList; } @NonNull @@ -43,7 +48,7 @@ public class ModManifestAdapter extends RecyclerView.Adapter list) { + this.modList = list; notifyDataSetChanged(); } @@ -84,7 +90,7 @@ public class ModManifestAdapter extends RecyclerView.Adapter removeAll(Predicate predicate) { + List deletedId = new ArrayList<>(); + for (int i = modList.size() - 1; i >= 0; i--) { + if (predicate.apply(modList.get(i))) { + modList.remove(i); + deletedId.add(i); + } + } + return deletedId; + } + @OnClick(R.id.button_remove_mod) void removeMod() { DialogUtils.showConfirmDialog(itemView, R.string.confirm, R.string.confirm_delete_content, (dialog, which)->{ if (which == DialogAction.POSITIVE) { @@ -99,7 +116,8 @@ public class ModManifestAdapter extends RecyclerView.Adapter removed = model.removeAll(entry -> StringUtils.equals(entry.getAssetPath(), modPath)); + model.removeAll(entry -> StringUtils.equals(entry.getAssetPath(), modPath)); + List removed = removeAll(entry -> StringUtils.equals(entry.getAssetPath(), modPath)); for (int idx : removed) { notifyItemRemoved(idx); } @@ -113,7 +131,7 @@ public class ModManifestAdapter extends RecyclerView.Adapter predicate) { + for (int i = 0; i < modList.size(); i++) { + if (predicate.apply(modList.get(i))) { + return i; + } + } + return null; + } + private void moveMod(File file, File newFile) { try { FileUtils.moveDirectory(file, newFile); - Integer idx = model.findFirst(mod -> StringUtils.equalsIgnoreCase(mod.getAssetPath(), modPath)); + Integer idx = findFirst(mod -> StringUtils.equalsIgnoreCase(mod.getAssetPath(), modPath)); if (idx != null) { - model.getModList().get(idx).setAssetPath(newFile.getAbsolutePath()); + modList.get(idx).setAssetPath(newFile.getAbsolutePath()); notifyItemChanged(idx); } } catch (IOException e) { diff --git a/app/src/main/java/com/zane/smapiinstaller/ui/download/DownloadableContentAdapter.java b/app/src/main/java/com/zane/smapiinstaller/ui/download/DownloadableContentAdapter.java index f2a3556..5f292e0 100644 --- a/app/src/main/java/com/zane/smapiinstaller/ui/download/DownloadableContentAdapter.java +++ b/app/src/main/java/com/zane/smapiinstaller/ui/download/DownloadableContentAdapter.java @@ -19,6 +19,8 @@ import com.lzy.okgo.callback.FileCallback; import com.lzy.okgo.model.Progress; import com.lzy.okgo.model.Response; import com.zane.smapiinstaller.R; +import com.zane.smapiinstaller.constant.Constants; +import com.zane.smapiinstaller.constant.DownloadableContentTypes; import com.zane.smapiinstaller.entity.DownloadableContent; import com.zane.smapiinstaller.entity.ModManifestEntry; import com.zane.smapiinstaller.logic.ModAssetsManager; @@ -126,7 +128,7 @@ public class DownloadableContentAdapter extends RecyclerView.Adapter StringUtils.equals(mod.getUniqueID(), "ZaneYork.CustomLocalization") || StringUtils.equals(mod.getUniqueID(), "SMAPI.CustomLocalization")); if (modManifestEntry == null) { DialogUtils.showAlertDialog(itemView, R.string.error, String.format(context.getString(R.string.error_depends_on_mod), context.getString(R.string.locale_pack), "ZaneYork.CustomLocalization")); @@ -142,8 +144,9 @@ public class DownloadableContentAdapter extends RecyclerView.Adapter dialogRef = DialogUtils.showProgressDialog(itemView, R.string.progress, ""); @@ -184,7 +187,7 @@ public class DownloadableContentAdapter extends RecyclerView.Adapter { if (which == DialogAction.POSITIVE) { diff --git a/app/src/main/java/com/zane/smapiinstaller/utils/GzipRequestInterceptor.java b/app/src/main/java/com/zane/smapiinstaller/utils/GzipRequestInterceptor.java index 48dcb81..ce34cf0 100644 --- a/app/src/main/java/com/zane/smapiinstaller/utils/GzipRequestInterceptor.java +++ b/app/src/main/java/com/zane/smapiinstaller/utils/GzipRequestInterceptor.java @@ -1,5 +1,7 @@ package com.zane.smapiinstaller.utils; +import com.lzy.okgo.model.HttpHeaders; + import java.io.IOException; import okhttp3.Interceptor; @@ -15,12 +17,12 @@ public class GzipRequestInterceptor implements Interceptor { @Override public Response intercept(Chain chain) throws IOException { Request originalRequest = chain.request(); - if (originalRequest.body() == null || originalRequest.header("Content-Encoding") != null) { + if (originalRequest.body() == null || originalRequest.header(HttpHeaders.HEAD_KEY_CONTENT_ENCODING) != null) { return chain.proceed(originalRequest); } Request compressedRequest = originalRequest.newBuilder() - .header("Content-Encoding", "gzip") + .header(HttpHeaders.HEAD_KEY_CONTENT_ENCODING, "gzip") .method(originalRequest.method(), gzip(originalRequest.body())) .build(); return chain.proceed(compressedRequest); diff --git a/app/src/main/java/com/zane/smapiinstaller/utils/JSONUtil.java b/app/src/main/java/com/zane/smapiinstaller/utils/JSONUtil.java index 8b75af9..862260e 100644 --- a/app/src/main/java/com/zane/smapiinstaller/utils/JSONUtil.java +++ b/app/src/main/java/com/zane/smapiinstaller/utils/JSONUtil.java @@ -12,16 +12,16 @@ import com.fasterxml.jackson.databind.ObjectMapper; * JSON工具类 */ public class JSONUtil { - private static final ObjectMapper mapper = new ObjectMapper(); + private static final ObjectMapper MAPPER = new ObjectMapper(); static { // 允许未定义的属性 - mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false); + MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false); // 允许尾部额外的逗号 - mapper.configure(JsonReadFeature.ALLOW_TRAILING_COMMA.mappedFeature(), true); + MAPPER.configure(JsonReadFeature.ALLOW_TRAILING_COMMA.mappedFeature(), true); // 允许数组设置空值 - mapper.configure(JsonReadFeature.ALLOW_MISSING_VALUES.mappedFeature(), true); + MAPPER.configure(JsonReadFeature.ALLOW_MISSING_VALUES.mappedFeature(), true); // 允许Java注释 - mapper.configure(JsonReadFeature.ALLOW_JAVA_COMMENTS.mappedFeature(), true); + MAPPER.configure(JsonReadFeature.ALLOW_JAVA_COMMENTS.mappedFeature(), true); } /** @@ -31,7 +31,7 @@ public class JSONUtil { * @throws Exception 异常 */ public static String toJson(Object object) throws Exception { - return mapper.writeValueAsString(object); + return MAPPER.writeValueAsString(object); } /** @@ -40,7 +40,7 @@ public class JSONUtil { * @throws JsonProcessingException 异常 */ public static void checkJson(String jsonString) throws JsonProcessingException { - mapper.readValue(jsonString, Object.class); + MAPPER.readValue(jsonString, Object.class); } /** @@ -52,7 +52,7 @@ public class JSONUtil { */ public static T fromJson(String jsonString, Class cls) { try { - return mapper.readValue(jsonString, cls); + return MAPPER.readValue(jsonString, cls); } catch (JsonProcessingException e) { Log.e("JSON", "Deserialize error", e); } @@ -68,7 +68,7 @@ public class JSONUtil { */ public static T fromJson(String jsonString, TypeReference type) { try { - return mapper.readValue(jsonString, type); + return MAPPER.readValue(jsonString, type); } catch (JsonProcessingException e) { Log.e("JSON", "Deserialize error", e); } diff --git a/app/src/main/java/com/zane/smapiinstaller/utils/TranslateUtil.java b/app/src/main/java/com/zane/smapiinstaller/utils/TranslateUtil.java index 98b0ada..a7bc78d 100644 --- a/app/src/main/java/com/zane/smapiinstaller/utils/TranslateUtil.java +++ b/app/src/main/java/com/zane/smapiinstaller/utils/TranslateUtil.java @@ -19,6 +19,7 @@ import org.apache.commons.lang3.StringUtils; import java.util.ArrayList; import java.util.List; +import java.util.Locale; public class TranslateUtil { @@ -26,23 +27,25 @@ public class TranslateUtil { public static final String YOU_DAO = "YouDao"; public static void translateText(List textList, String translator, String locale, Predicate> resultCallback) { - if(textList == null || textList.size() == 0) + if(textList == null || textList.size() == 0) { return; + } textList = Lists.newArrayList(Iterables.filter(textList, item -> StringUtils.isNoneBlank(item) && !item.contains("\n"))); if(textList.size() == 0) { return; } String queryText = Joiner.on("%0A").join(textList); - if(queryText.length() > 4096) { - if(textList.size() == 1) + if(queryText.length() > Constants.URL_LENGTH_LIMIT) { + if(textList.size() == 1) { return; + } List subListA = textList.subList(0, textList.size() / 2); translateText(subListA, translator, locale, resultCallback); List subListB = textList.subList(textList.size() / 2, textList.size()); translateText(subListB, translator, locale, resultCallback); } if(StringUtils.equalsIgnoreCase(translator, YOU_DAO)) { - if (!StringUtils.equalsAnyIgnoreCase(locale, "zh")) { + if (!StringUtils.equalsAnyIgnoreCase(locale, Locale.CHINA.getLanguage())) { return; } OkGo.get(String.format(Constants.TRANSLATE_SERVICE_URL_YOUDAO, queryText)).execute(new StringCallback() { @@ -60,8 +63,9 @@ public class TranslateUtil { result.setTranslator(translator); result.setCreateTime(System.currentTimeMillis()); for (YouDaoTranslationDto.Entry entry : list) { - if (entry == null) + if (entry == null) { continue; + } result.setOrigin(result.getOrigin() + entry.getSrc()); result.setTranslation(result.getTranslation() + entry.getTgt()); } diff --git a/app/src/main/java/com/zane/smapiinstaller/utils/VersionUtil.java b/app/src/main/java/com/zane/smapiinstaller/utils/VersionUtil.java index 963ff27..091ccbb 100644 --- a/app/src/main/java/com/zane/smapiinstaller/utils/VersionUtil.java +++ b/app/src/main/java/com/zane/smapiinstaller/utils/VersionUtil.java @@ -37,12 +37,14 @@ public class VersionUtil { } catch (Exception ignored2) { } } - if(StringUtils.equals(listA.get(i), listB.get(i))) + if(StringUtils.equals(listA.get(i), listB.get(i))) { continue; - if(intA != null && intB == null) + } + if(intA != null && intB == null) { return 1; - else if(intA == null) + } else if(intA == null) { return -1; + } return listA.get(i).compareTo(listB.get(i)); } return Integer.compare(listA.size(), listB.size()); @@ -83,8 +85,9 @@ public class VersionUtil { return 1; } int compare = compareVersionSection(versionSectionsA.get(i), versionSectionsB.get(i)); - if(compare != 0) + if(compare != 0) { return compare; + } } if(versionSectionsA.size() < versionSectionsB.size()) { if(isZero(versionSectionsB.subList(versionSectionsA.size(), versionSectionsB.size()))) { diff --git a/app/src/main/res/layout/fragment_config.xml b/app/src/main/res/layout/fragment_config.xml index a5d3336..269509a 100644 --- a/app/src/main/res/layout/fragment_config.xml +++ b/app/src/main/res/layout/fragment_config.xml @@ -6,10 +6,52 @@ android:layout_height="match_parent" tools:context=".ui.config.ConfigFragment"> + + - + android:layout_width="0dp" + android:layout_height="0dp" + app:layout_constraintStart_toEndOf="@id/guideline_v1" + app:layout_constraintEnd_toStartOf="@id/guideline_v2" + app:layout_constraintTop_toBottomOf="@id/button_search" + app:layout_constraintBottom_toTopOf="@id/guideline_h2"/> + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_help.xml b/app/src/main/res/layout/fragment_help.xml index f174ca0..c49533f 100644 --- a/app/src/main/res/layout/fragment_help.xml +++ b/app/src/main/res/layout/fragment_help.xml @@ -32,7 +32,7 @@ + + Terminación + La versión de su sistema es demasiado antigua, lo que puede hacer que 0Harmony no sea válido. Se recomienda actualizar a Android 6 y superior + Instalador SMAPI + Compatibilidad + Donar + Detalles de la tienda de Google + Instalar + Registro + Nexus + QQ group①: 860453392 + QQ group②: 1078428449 + Sitio web oficial + Cancelar + Confirmar + ¿Estás seguro de que deseas eliminar este contenido? + ¿Seguro que quieresdeshabilitar este contenido? + Continuar + Descarga e instalación completadas + Descargando:%1$dKB /%2$dKB + Se han encontrado varias copias de este mod. Elimina los mods duplicados de:%s + Mal + %1$s depende de la interfaz de%2$s, instálelo primero + %1$s depende de la versión%2$s%3$s, actualícela primero + No se pudieron crear los siguientes archivos:%s + No se puede descargar el recurso de destino + No se puede reparar el entorno SMAPI + Incapaz de encontrar el cuerpo del juego, ¿instalaste Stardew Valley? + Por favor ingrese una ruta válida + La versión del juego no es compatible, actualice laversión o descargue el paquete compatible + SMAPI no está instalado, primero haga clic en el botón instalar + Extrayendo paquete de instalación + No se puede modificar el paquete de instalación, póngase en contacto con el desarrollador para obtener ayuda + No se puede procesar el archivo AndroidManifest.xml + No se puede firmar el paquete de instalación, póngase en contacto con el desarrollador para obtener ayuda + No se puede descomprimir el entorno SMAPI + Pista + Entrar + Por favor, introduzca la ruta de Mods + Progreso de la instalación + Instalando + Paquete de idiomas + Acerca de + Config + Editar + Descargar + Ayuda + Instalar + ZaneYork@qq.com + Instalador SMAPI + OK + Instalar el parche SMAPI + Progreso + Guardar + Buscar actualizaciones + Modo desarrollador + Idioma + Establecer la posición de Mods + Servicios Traducción + Registro detallado + Firmando paquete deinstalación + SMAPI Stardew Valley + Versión SMAPI: 3.3.2.3 + Nota: Requiere la versión del juego 1.4.5.138 o superior + El cuerpo del juego debe instalarse durante la actualización o instalación + Desempacando + \ No newline at end of file diff --git a/app/src/main/res/values-zh-rHK/arrays.xml b/app/src/main/res/values-zh-rHK/arrays.xml index d27f0bb..d00d790 100644 --- a/app/src/main/res/values-zh-rHK/arrays.xml +++ b/app/src/main/res/values-zh-rHK/arrays.xml @@ -16,6 +16,7 @@ Español Français Português + Bahasa Indonesia 關閉 diff --git a/app/src/main/res/values-zh-rTW/arrays.xml b/app/src/main/res/values-zh-rTW/arrays.xml index d27f0bb..d00d790 100644 --- a/app/src/main/res/values-zh-rTW/arrays.xml +++ b/app/src/main/res/values-zh-rTW/arrays.xml @@ -16,6 +16,7 @@ Español Français Português + Bahasa Indonesia 關閉 diff --git a/app/src/main/res/values-zh/arrays.xml b/app/src/main/res/values-zh/arrays.xml index e86cabf..39a1f79 100644 --- a/app/src/main/res/values-zh/arrays.xml +++ b/app/src/main/res/values-zh/arrays.xml @@ -16,6 +16,7 @@ Español Français Português + Bahasa Indonesia 关闭 diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index 002b4d0..b3761a4 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -16,6 +16,7 @@ Español Français Português + Bahasa Indonesia OFF