From fb017c6659f202af568035ed73144d3345cc5c20 Mon Sep 17 00:00:00 2001 From: yuhan6665 <1588741+yuhan6665@users.noreply.github.com> Date: Fri, 26 Mar 2021 20:55:00 -0400 Subject: [PATCH] Add migration - Fix some compile warnings - Add migration method - Add vmessBean migration --- .../kotlin/com/v2ray/ang/AngApplication.kt | 2 - .../kotlin/com/v2ray/ang/extension/_Ext.kt | 2 +- .../com/v2ray/ang/ui/BaseDrawerActivity.kt | 199 ------------------ .../kotlin/com/v2ray/ang/ui/MainActivity.kt | 19 +- .../com/v2ray/ang/ui/MainRecyclerAdapter.kt | 4 +- .../com/v2ray/ang/ui/PerAppProxyActivity.kt | 4 +- .../v2ray/ang/ui/RoutingSettingsFragment.kt | 4 +- .../com/v2ray/ang/ui/ScannerActivity.kt | 4 +- .../kotlin/com/v2ray/ang/ui/TaskerActivity.kt | 8 +- .../com/v2ray/ang/util/AngConfigManager.kt | 156 +++++++++++--- .../com/v2ray/ang/util/AppManagerUtil.kt | 2 +- .../main/kotlin/com/v2ray/ang/util/Utils.kt | 2 +- .../com/v2ray/ang/util/V2rayConfigUtil.kt | 16 +- .../src/main/res/values-zh-rCN/strings.xml | 2 + .../src/main/res/values-zh-rTW/strings.xml | 2 + V2rayNG/app/src/main/res/values/strings.xml | 2 + 16 files changed, 173 insertions(+), 255 deletions(-) delete mode 100644 V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/BaseDrawerActivity.kt diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/AngApplication.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/AngApplication.kt index 420a6827..38787b78 100644 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/AngApplication.kt +++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/AngApplication.kt @@ -3,7 +3,6 @@ package com.v2ray.ang import android.support.multidex.MultiDexApplication import android.support.v7.preference.PreferenceManager import com.tencent.mmkv.MMKV -import com.v2ray.ang.util.AngConfigManager class AngApplication : MultiDexApplication() { companion object { @@ -25,7 +24,6 @@ class AngApplication : MultiDexApplication() { defaultSharedPreferences.edit().putInt(PREF_LAST_VERSION, BuildConfig.VERSION_CODE).apply() //Logger.init().logLevel(if (BuildConfig.DEBUG) LogLevel.FULL else LogLevel.NONE) - AngConfigManager.inject(this) MMKV.initialize(this) } } diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/extension/_Ext.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/extension/_Ext.kt index b0e74368..4d317e67 100644 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/extension/_Ext.kt +++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/extension/_Ext.kt @@ -27,7 +27,7 @@ inline fun Context.toast(message: CharSequence): Toast = ToastCompat show() } -fun JSONObject.putOpt(pair: Pair) = putOpt(pair.first, pair.second)!! +fun JSONObject.putOpt(pair: Pair) = putOpt(pair.first, pair.second) fun JSONObject.putOpt(pairs: Map) = pairs.forEach { putOpt(it.key to it.value) } const val threshold = 1000 diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/BaseDrawerActivity.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/BaseDrawerActivity.kt deleted file mode 100644 index 231575bb..00000000 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/BaseDrawerActivity.kt +++ /dev/null @@ -1,199 +0,0 @@ -package com.v2ray.ang.ui - -import android.app.ActivityOptions -import android.app.FragmentManager -import android.content.Intent -import android.content.res.Configuration -import android.os.Bundle -import android.support.design.widget.NavigationView -import android.support.v4.view.GravityCompat -import android.support.v4.widget.DrawerLayout -import android.support.v7.app.ActionBarDrawerToggle -import android.support.v7.widget.Toolbar -import android.util.Log -import android.view.MenuItem -import android.view.View -import com.v2ray.ang.R - -abstract class BaseDrawerActivity : BaseActivity() { - companion object { - - private val TAG = "BaseDrawerActivity" - } - - private var mToolbar: Toolbar? = null - - private var mDrawerToggle: ActionBarDrawerToggle? = null - - private var mDrawerLayout: DrawerLayout? = null - - private var mToolbarInitialized: Boolean = false - - private var mItemToOpenWhenDrawerCloses = -1 - - private val backStackChangedListener = FragmentManager.OnBackStackChangedListener { updateDrawerToggle() } - - private val drawerListener = object : DrawerLayout.DrawerListener { - override fun onDrawerSlide(drawerView: View, slideOffset: Float) { - mDrawerToggle!!.onDrawerSlide(drawerView, slideOffset) - } - - override fun onDrawerOpened(drawerView: View) { - mDrawerToggle!!.onDrawerOpened(drawerView) - //supportActionBar!!.setTitle(R.string.app_name) - } - - override fun onDrawerClosed(drawerView: View) { - mDrawerToggle!!.onDrawerClosed(drawerView) - - if (mItemToOpenWhenDrawerCloses >= 0) { - val extras = ActivityOptions.makeCustomAnimation( - this@BaseDrawerActivity, R.anim.fade_in, R.anim.fade_out).toBundle() - var activityClass: Class<*>? = null - when (mItemToOpenWhenDrawerCloses) { - R.id.sub_setting -> activityClass = SubSettingActivity::class.java - R.id.settings -> activityClass = SettingsActivity::class.java - R.id.logcat -> { - startActivity(Intent(this@BaseDrawerActivity, LogcatActivity::class.java)) - return - } - R.id.donate -> { -// startActivity() - return - } - } - if (activityClass != null) { - startActivity(Intent(this@BaseDrawerActivity, activityClass), extras) - finish() - } - } - } - - override fun onDrawerStateChanged(newState: Int) { - mDrawerToggle!!.onDrawerStateChanged(newState) - } - } - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - Log.d(TAG, "Activity onCreate") - } - - override fun onStart() { - super.onStart() - if (!mToolbarInitialized) { - throw IllegalStateException("You must run super.initializeToolbar at " + "the end of your onCreate method") - } - } - - public override fun onResume() { - super.onResume() - // Whenever the fragment back stack changes, we may need to update the - // action bar toggle: only top level screens show the hamburger-like icon, inner - // screens - either Activities or fragments - show the "Up" icon instead. - fragmentManager.addOnBackStackChangedListener(backStackChangedListener) - } - - public override fun onPause() { - super.onPause() - fragmentManager.removeOnBackStackChangedListener(backStackChangedListener) - } - - override fun onPostCreate(savedInstanceState: Bundle?) { - super.onPostCreate(savedInstanceState) - mDrawerToggle!!.syncState() - } - - override fun onConfigurationChanged(newConfig: Configuration) { - super.onConfigurationChanged(newConfig) - mDrawerToggle!!.onConfigurationChanged(newConfig) - } - - override fun onOptionsItemSelected(item: MenuItem): Boolean { - if (mDrawerToggle != null && mDrawerToggle!!.onOptionsItemSelected(item)) { - return true - } - // If not handled by drawerToggle, home needs to be handled by returning to previous - if (item.itemId == android.R.id.home) { - onBackPressed() - return true - } - return super.onOptionsItemSelected(item) - } - - override fun onBackPressed() { - // If the drawer is open, back will close it - if (mDrawerLayout != null && mDrawerLayout!!.isDrawerOpen(GravityCompat.START)) { - mDrawerLayout!!.closeDrawers() - return - } - // Otherwise, it may return to the previous fragment stack - val fragmentManager = fragmentManager - if (fragmentManager.backStackEntryCount > 0) { - fragmentManager.popBackStack() - } else { - // Lastly, it will rely on the system behavior for back - super.onBackPressed() - } - } - - private fun updateDrawerToggle() { - if (mDrawerToggle == null) { - return - } - val isRoot = fragmentManager.backStackEntryCount == 0 - mDrawerToggle!!.isDrawerIndicatorEnabled = isRoot - - supportActionBar!!.setDisplayShowHomeEnabled(!isRoot) - supportActionBar!!.setDisplayHomeAsUpEnabled(!isRoot) - supportActionBar!!.setHomeButtonEnabled(!isRoot) - - if (isRoot) { - mDrawerToggle!!.syncState() - } - } - - protected fun initializeToolbar() { - mToolbar = findViewById(R.id.toolbar) as Toolbar - if (mToolbar == null) { - throw IllegalStateException("Layout is required to include a Toolbar with id " + "'toolbar'") - } - - // mToolbar.inflateMenu(R.menu.main); - - mDrawerLayout = findViewById(R.id.drawer_layout) as DrawerLayout - if (mDrawerLayout != null) { - val navigationView = findViewById(R.id.nav_view) as NavigationView - ?: throw IllegalStateException("Layout requires a NavigationView " + "with id 'nav_view'") - - // Create an ActionBarDrawerToggle that will handle opening/closing of the drawer: - mDrawerToggle = ActionBarDrawerToggle(this, mDrawerLayout, - mToolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close) - - mDrawerLayout!!.addDrawerListener(drawerListener) - - populateDrawerItems(navigationView) - setSupportActionBar(mToolbar) - updateDrawerToggle() - } else { - setSupportActionBar(mToolbar) - } - - mToolbarInitialized = true - } - - private fun populateDrawerItems(navigationView: NavigationView) { - navigationView.setNavigationItemSelectedListener { menuItem -> - menuItem.isChecked = true - mItemToOpenWhenDrawerCloses = menuItem.itemId - mDrawerLayout!!.closeDrawers() - true - } - - if (SubSettingActivity::class.java.isAssignableFrom(javaClass)) { - navigationView.setCheckedItem(R.id.sub_setting) - } else if (SettingsActivity::class.java.isAssignableFrom(javaClass)) { - navigationView.setCheckedItem(R.id.settings) - } - } -} diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/MainActivity.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/MainActivity.kt index 5c269dab..eec16e03 100644 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/MainActivity.kt +++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/MainActivity.kt @@ -100,6 +100,7 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList version.text = "v${BuildConfig.VERSION_NAME} (${Libv2ray.checkVersionX()})" setupViewModelObserver() + migrateLegacy() } private fun setupViewModelObserver() { @@ -129,6 +130,22 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList mainViewModel.startListenBroadcast() } + private fun migrateLegacy() { + GlobalScope.launch(Dispatchers.IO) { + val result = AngConfigManager.migrateLegacyConfig(this@MainActivity) + if (result != null) { + launch(Dispatchers.Main) { + if (result) { + toast(getString(R.string.migration_success)) + mainViewModel.reloadServerList() + } else { + toast(getString(R.string.migration_fail)) + } + } + } + } + } + fun startV2Ray() { if (mainStorage?.decodeString(MmkvManager.KEY_SELECTED_SERVER).isNullOrEmpty()) { return @@ -229,7 +246,7 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList } R.id.export_all -> { - if (AngConfigManager.shareNonCustomConfigsToClipboard(mainViewModel.serverList) == 0) { + if (AngConfigManager.shareNonCustomConfigsToClipboard(this, mainViewModel.serverList) == 0) { toast(R.string.toast_success) } else { toast(R.string.toast_failure) diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/MainRecyclerAdapter.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/MainRecyclerAdapter.kt index 385e0842..26161149 100644 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/MainRecyclerAdapter.kt +++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/MainRecyclerAdapter.kt @@ -92,7 +92,7 @@ class MainRecyclerAdapter(val activity: MainActivity) : RecyclerView.Adapter { - if (AngConfigManager.share2Clipboard(guid) == 0) { + if (AngConfigManager.share2Clipboard(mActivity, guid) == 0) { mActivity.toast(R.string.toast_success) } else { mActivity.toast(R.string.toast_failure) @@ -156,7 +156,7 @@ class MainRecyclerAdapter(val activity: MainActivity) : RecyclerView.Adapter + switch_per_app_proxy.setOnCheckedChangeListener { _, isChecked -> defaultSharedPreferences.edit().putBoolean(AppConfig.PREF_PER_APP_PROXY, isChecked).apply() } switch_per_app_proxy.isChecked = defaultSharedPreferences.getBoolean(AppConfig.PREF_PER_APP_PROXY, false) - switch_bypass_apps.setOnCheckedChangeListener { buttonView, isChecked -> + switch_bypass_apps.setOnCheckedChangeListener { _, isChecked -> defaultSharedPreferences.edit().putBoolean(AppConfig.PREF_BYPASS_APPS, isChecked).apply() } switch_bypass_apps.isChecked = defaultSharedPreferences.getBoolean(AppConfig.PREF_BYPASS_APPS, false) diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/RoutingSettingsFragment.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/RoutingSettingsFragment.kt index a32c2223..993c2d32 100644 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/RoutingSettingsFragment.kt +++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/RoutingSettingsFragment.kt @@ -42,8 +42,8 @@ class RoutingSettingsFragment : Fragment() { return fragment } - override fun onActivityCreated(savedInstanceState: Bundle?) { - super.onActivityCreated(savedInstanceState) + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) val content = defaultSharedPreferences.getString(arguments!!.getString(routing_arg), "") et_routing_content.text = Utils.getEditable(content!!) diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/ScannerActivity.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/ScannerActivity.kt index 6f1dafd1..5e973cb8 100644 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/ScannerActivity.kt +++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/ScannerActivity.kt @@ -23,8 +23,8 @@ class ScannerActivity : BaseActivity(), ZXingScannerView.ResultHandler { private var mScannerView: ZXingScannerView? = null - public override fun onCreate(state: Bundle?) { - super.onCreate(state) + public override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) mScannerView = ZXingScannerView(this) // Programmatically initialize the scanner view mScannerView?.setAutoFocus(true) diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/TaskerActivity.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/TaskerActivity.kt index b27f047b..2b8c1673 100644 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/TaskerActivity.kt +++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/ui/TaskerActivity.kt @@ -79,12 +79,10 @@ class TaskerActivity : BaseActivity() { val intent = Intent() val remarks = lstData[position] - var blurb = "" - - if (switch_start_service.isChecked) { - blurb = "Start $remarks" + val blurb = if (switch_start_service.isChecked) { + "Start $remarks" } else { - blurb = "Stop $remarks" + "Stop $remarks" } intent.putExtra(AppConfig.TASKER_EXTRA_BUNDLE, extraBundle) diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/AngConfigManager.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/AngConfigManager.kt index 290425c7..5becce11 100644 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/AngConfigManager.kt +++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/AngConfigManager.kt @@ -1,11 +1,13 @@ package com.v2ray.ang.util +import android.content.Context +import android.content.SharedPreferences import android.graphics.Bitmap import android.support.v7.preference.PreferenceManager import android.text.TextUtils import com.google.gson.Gson import com.tencent.mmkv.MMKV -import com.v2ray.ang.AngApplication +import com.v2ray.ang.AppConfig import com.v2ray.ang.AppConfig.ANG_CONFIG import com.v2ray.ang.AppConfig.HTTPS_PROTOCOL import com.v2ray.ang.AppConfig.HTTP_PROTOCOL @@ -19,43 +21,139 @@ import java.net.URLDecoder import java.util.* object AngConfigManager { - private lateinit var app: AngApplication - private lateinit var angConfig: AngConfig private val mainStorage by lazy { MMKV.mmkvWithID(MmkvManager.ID_MAIN, MMKV.MULTI_PROCESS_MODE) } private val settingsStorage by lazy { MMKV.mmkvWithID(MmkvManager.ID_SETTING, MMKV.MULTI_PROCESS_MODE) } - - fun inject(app: AngApplication) { - this.app = app - loadConfig() - } + private val subStorage by lazy { MMKV.mmkvWithID(MmkvManager.ID_SUB, MMKV.MULTI_PROCESS_MODE) } /** - * loading config + * Legacy loading config */ - private fun loadConfig() { + fun migrateLegacyConfig(c: Context): Boolean? { try { - val defaultSharedPreferences = PreferenceManager.getDefaultSharedPreferences(app) + val defaultSharedPreferences = PreferenceManager.getDefaultSharedPreferences(c) val context = defaultSharedPreferences.getString(ANG_CONFIG, "") - if (!TextUtils.isEmpty(context)) { - angConfig = Gson().fromJson(context, AngConfig::class.java) - } else { - angConfig = AngConfig(0, vmess = arrayListOf(AngConfig.VmessBean()), subItem = arrayListOf(AngConfig.SubItemBean())) - angConfig.index = -1 - angConfig.vmess.clear() - angConfig.subItem.clear() + if (context.isNullOrBlank()) { + return null } - + val angConfig = Gson().fromJson(context, AngConfig::class.java) for (i in angConfig.vmess.indices) { upgradeServerVersion(angConfig.vmess[i]) } -// if (configs.subItem == null) { -// configs.subItem = arrayListOf(AngConfig.SubItemBean()) -// } + copyLegacySettings(defaultSharedPreferences) + migrateVmessBean(angConfig, defaultSharedPreferences) + migrateSubItemBean(angConfig) + defaultSharedPreferences.edit().remove(ANG_CONFIG).apply() + return true } catch (e: Exception) { e.printStackTrace() } + return false + } + + private fun copyLegacySettings(sharedPreferences: SharedPreferences) { + listOf(AppConfig.PREF_MODE, + AppConfig.PREF_REMOTE_DNS, + AppConfig.PREF_DOMESTIC_DNS, +// AppConfig.PREF_LOCAL_DNS_PORT, +// AppConfig.PREF_SOCKS_PORT, +// AppConfig.PREF_HTTP_PORT, +// AppConfig.PREF_LOGLEVEL, + AppConfig.PREF_ROUTING_DOMAIN_STRATEGY, + AppConfig.PREF_ROUTING_MODE, + AppConfig.PREF_V2RAY_ROUTING_AGENT, + AppConfig.PREF_V2RAY_ROUTING_BLOCKED, + AppConfig.PREF_V2RAY_ROUTING_DIRECT,).forEach { key -> + settingsStorage?.encode(key, sharedPreferences.getString(key, "")) + } + listOf(AppConfig.PREF_SPEED_ENABLED, + AppConfig.PREF_SNIFFING_ENABLED, + AppConfig.PREF_PROXY_SHARING, + AppConfig.PREF_LOCAL_DNS_ENABLED, +// AppConfig.PREF_ALLOW_INSECURE, +// AppConfig.PREF_PREFER_IPV6, + AppConfig.PREF_PER_APP_PROXY, + AppConfig.PREF_BYPASS_APPS,).forEach { key -> + settingsStorage?.encode(key, sharedPreferences.getBoolean(key, false)) + } + settingsStorage?.encode(AppConfig.PREF_PER_APP_PROXY_SET, sharedPreferences.getStringSet(AppConfig.PREF_PER_APP_PROXY_SET, setOf())) + } + + private fun migrateVmessBean(angConfig: AngConfig, sharedPreferences: SharedPreferences) { + angConfig.vmess.forEachIndexed { index, vmessBean -> + val type = EConfigType.fromInt(vmessBean.configType) ?: return@forEachIndexed + val config = ServerConfig.create(type) + config.remarks = vmessBean.remarks + config.subscriptionId = vmessBean.subid + if (type == EConfigType.CUSTOM) { + val jsonConfig = sharedPreferences.getString(ANG_CONFIG + vmessBean.guid, "") + val v2rayConfig = try { + Gson().fromJson(jsonConfig, V2rayConfig::class.java) + } catch (e: Exception) { + e.printStackTrace() + return@forEachIndexed + } + config.fullConfig = v2rayConfig + } else { + config.outboundBean?.settings?.vnext?.get(0)?.let { vnext -> + vnext.address = vmessBean.address + vnext.port = vmessBean.port + vnext.users[0].id = vmessBean.id + if (config.configType == EConfigType.VMESS) { + vnext.users[0].alterId = vmessBean.alterId + vnext.users[0].security = vmessBean.security + } else if (config.configType == EConfigType.VLESS) { + vnext.users[0].encryption = vmessBean.security +// vnext.users[0].flow = vmessBean.flow + } + } + config.outboundBean?.settings?.servers?.get(0)?.let { server -> + server.address = vmessBean.address + server.port = vmessBean.port + if (config.configType == EConfigType.SHADOWSOCKS) { + server.password = vmessBean.id + server.method = vmessBean.security + } else if (config.configType == EConfigType.SOCKS) { + if (TextUtils.isEmpty(vmessBean.security) && TextUtils.isEmpty(vmessBean.id)) { + server.users = null + } else { + val socksUsersBean = V2rayConfig.OutboundBean.OutSettingsBean.ServersBean.SocksUsersBean() + socksUsersBean.user = vmessBean.security + socksUsersBean.pass = vmessBean.id + server.users = listOf(socksUsersBean) + } + } else if (config.configType == EConfigType.TROJAN) { + server.password = vmessBean.id + } + } + config.outboundBean?.streamSettings?.let { streamSetting -> + val sni = streamSetting.populateTransportSettings(vmessBean.network, vmessBean.headerType, + vmessBean.requestHost, vmessBean.path, vmessBean.path, vmessBean.requestHost, vmessBean.path) +// val allowInsecure = if (vmessBean.allowInsecure.isBlank()) { +// settingsStorage?.decodeBool(AppConfig.PREF_ALLOW_INSECURE) ?: false +// } else { +// vmessBean.allowInsecure.toBoolean() +// } + streamSetting.populateTlsSettings(vmessBean.streamSecurity, false, + sni)//if (vmessBean.sni.isNotBlank()) vmessBean.sni else sni) + } + } + val key = MmkvManager.encodeServerConfig(vmessBean.guid, config) + if (index == angConfig.index) { + mainStorage?.encode(KEY_SELECTED_SERVER, key) + } + } + } + + private fun migrateSubItemBean(angConfig: AngConfig) { + angConfig.subItem.forEach { + val subItem = SubscriptionItem() + subItem.remarks = it.remarks + subItem.url = it.url + //subItem.enabled = it.enabled + subStorage?.encode(it.id, Gson().toJson(subItem)) + } } /** @@ -437,14 +535,14 @@ object AngConfigManager { /** * share2Clipboard */ - fun share2Clipboard(guid: String): Int { + fun share2Clipboard(context: Context, guid: String): Int { try { val conf = shareConfig(guid) if (TextUtils.isEmpty(conf)) { return -1 } - Utils.setClipboard(app.applicationContext, conf) + Utils.setClipboard(context, conf) } catch (e: Exception) { e.printStackTrace() @@ -456,7 +554,7 @@ object AngConfigManager { /** * share2Clipboard */ - fun shareNonCustomConfigsToClipboard(serverList: List): Int { + fun shareNonCustomConfigsToClipboard(context: Context, serverList: List): Int { try { val sb = StringBuilder() for (guid in serverList) { @@ -468,7 +566,7 @@ object AngConfigManager { sb.appendLine() } if (sb.count() > 0) { - Utils.setClipboard(app.applicationContext, sb.toString()) + Utils.setClipboard(context, sb.toString()) } } catch (e: Exception) { e.printStackTrace() @@ -497,12 +595,12 @@ object AngConfigManager { /** * shareFullContent2Clipboard */ - fun shareFullContent2Clipboard(guid: String?): Int { + fun shareFullContent2Clipboard(context: Context, guid: String?): Int { try { if (guid == null) return -1 - val result = V2rayConfigUtil.getV2rayConfig(app, guid) + val result = V2rayConfigUtil.getV2rayConfig(context, guid) if (result.status) { - Utils.setClipboard(app.applicationContext, result.content) + Utils.setClipboard(context, result.content) } else { return -1 } diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/AppManagerUtil.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/AppManagerUtil.kt index 91ef1796..b95b408b 100644 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/AppManagerUtil.kt +++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/AppManagerUtil.kt @@ -31,7 +31,7 @@ object AppManagerUtil { return apps } - fun rxLoadNetworkAppList(ctx: Context): Observable> = Observable.create { + fun rxLoadNetworkAppList(ctx: Context): Observable> = Observable.unsafeCreate { it.onNext(loadNetworkAppList(ctx)) } diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/Utils.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/Utils.kt index 66845af2..a619d7bf 100644 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/Utils.kt +++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/Utils.kt @@ -258,7 +258,7 @@ object Utils { */ fun isValidUrl(value: String?): Boolean { try { - if (Patterns.WEB_URL.matcher(value).matches() || URLUtil.isValidUrl(value)) { + if (value != null && Patterns.WEB_URL.matcher(value).matches() || URLUtil.isValidUrl(value)) { return true } } catch (e: WriterException) { diff --git a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/V2rayConfigUtil.kt b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/V2rayConfigUtil.kt index 62180964..7dc3aefb 100644 --- a/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/V2rayConfigUtil.kt +++ b/V2rayNG/app/src/main/kotlin/com/v2ray/ang/util/V2rayConfigUtil.kt @@ -60,16 +60,16 @@ object V2rayConfigUtil { //v2rayConfig.log.loglevel = settingsStorage?.decodeString(AppConfig.PREF_LOGLEVEL) ?: "warning" - inbounds(v2rayConfig, context) + inbounds(v2rayConfig) v2rayConfig.outbounds[0] = outbound - routing(v2rayConfig, context) + routing(v2rayConfig) if (settingsStorage?.decodeBool(AppConfig.PREF_LOCAL_DNS_ENABLED) == true) { - customLocalDns(v2rayConfig, context) + customLocalDns(v2rayConfig) } else { - customRemoteDns(v2rayConfig, context) + customRemoteDns(v2rayConfig) } if (settingsStorage?.decodeBool(AppConfig.PREF_SPEED_ENABLED) != true) { v2rayConfig.stats = null @@ -83,7 +83,7 @@ object V2rayConfigUtil { /** * */ - private fun inbounds(v2rayConfig: V2rayConfig, context: Context): Boolean { + private fun inbounds(v2rayConfig: V2rayConfig): Boolean { try { //val socksPort = Utils.parseInt(settingsStorage?.decodeString(AppConfig.PREF_SOCKS_PORT) ?: AppConfig.PORT_SOCKS) //val httpPort = Utils.parseInt(settingsStorage?.decodeString(AppConfig.PREF_HTTP_PORT) ?: AppConfig.PORT_HTTP) @@ -115,7 +115,7 @@ object V2rayConfigUtil { /** * routing */ - private fun routing(v2rayConfig: V2rayConfig, context: Context): Boolean { + private fun routing(v2rayConfig: V2rayConfig): Boolean { try { routingUserRule(settingsStorage?.decodeString(AppConfig.PREF_V2RAY_ROUTING_AGENT) ?: "", AppConfig.TAG_AGENT, v2rayConfig) routingUserRule(settingsStorage?.decodeString(AppConfig.PREF_V2RAY_ROUTING_DIRECT) ?: "", AppConfig.TAG_DIRECT, v2rayConfig) @@ -233,7 +233,7 @@ object V2rayConfigUtil { /** * Custom Dns */ - private fun customLocalDns(v2rayConfig: V2rayConfig, context: Context): Boolean { + private fun customLocalDns(v2rayConfig: V2rayConfig): Boolean { try { val hosts = mutableMapOf() val servers = ArrayList() @@ -342,7 +342,7 @@ object V2rayConfigUtil { /** * Custom Remote Dns */ - private fun customRemoteDns(v2rayConfig: V2rayConfig, context: Context): Boolean { + private fun customRemoteDns(v2rayConfig: V2rayConfig): Boolean { try { val servers = ArrayList() val hosts = mutableMapOf() diff --git a/V2rayNG/app/src/main/res/values-zh-rCN/strings.xml b/V2rayNG/app/src/main/res/values-zh-rCN/strings.xml index 44675d2d..9a91f38a 100644 --- a/V2rayNG/app/src/main/res/values-zh-rCN/strings.xml +++ b/V2rayNG/app/src/main/res/values-zh-rCN/strings.xml @@ -6,6 +6,8 @@ 初次使用此功能请先用APP添加配置 Open navigation drawer Close navigation drawer + 数据迁移成功! + 数据迁移失败啦! 停止 diff --git a/V2rayNG/app/src/main/res/values-zh-rTW/strings.xml b/V2rayNG/app/src/main/res/values-zh-rTW/strings.xml index db86bbc1..5303fdbb 100644 --- a/V2rayNG/app/src/main/res/values-zh-rTW/strings.xml +++ b/V2rayNG/app/src/main/res/values-zh-rTW/strings.xml @@ -6,6 +6,8 @@ 首次使用此功能,請使用此應用程式新增組態 Open navigation drawer Close navigation drawer + 數據遷移成功! + 數據遷移失敗啦! 停止 diff --git a/V2rayNG/app/src/main/res/values/strings.xml b/V2rayNG/app/src/main/res/values/strings.xml index 1d4944a4..b45ed29b 100644 --- a/V2rayNG/app/src/main/res/values/strings.xml +++ b/V2rayNG/app/src/main/res/values/strings.xml @@ -6,6 +6,8 @@ First use of this feature, please use the app to add server Open navigation drawer Close navigation drawer + Data migration success! + Data migration failed! Stop