package com.jihe.punchnet.helper import android.app.Activity import android.content.Context import android.content.SharedPreferences import com.jihe.punchnet.data.RouteItem import com.jihe.punchnet.sdlan.network.maskDigitToInt const val PreferenceRepositoryName = "pref" sealed class PreferenceName(val name: String) { object PreferenceToken: PreferenceName("token") } private fun getEncryptedSharedPrefs(context: Context): SharedPreferences { val masterKey = androidx.security.crypto.MasterKey.Builder(context) .setKeyScheme(androidx.security.crypto.MasterKey.KeyScheme.AES256_GCM) .build() return androidx.security.crypto.EncryptedSharedPreferences.create( context, PreferenceRepositoryName, masterKey, androidx.security.crypto.EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV, androidx.security.crypto.EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM ) } private fun getPlainSharedPrefs(context: Context): SharedPreferences { return context.getSharedPreferences(PreferenceRepositoryName, Activity.MODE_PRIVATE) } private fun migratePlainPreference(context: Context, name: PreferenceName, encryptedPrefs: SharedPreferences) { if (encryptedPrefs.contains(name.name)) return val plainPrefs = getPlainSharedPrefs(context) if (!plainPrefs.contains(name.name)) return when (val value = plainPrefs.all[name.name]) { is String -> encryptedPrefs.edit().putString(name.name, value).apply() is Int -> encryptedPrefs.edit().putInt(name.name, value).apply() } plainPrefs.edit().remove(name.name).apply() } fun getPreferenceString(context: Context, name: PreferenceName): String? { try { val preference = getEncryptedSharedPrefs(context) migratePlainPreference(context, name, preference) return preference.getString(name.name, "") } catch (e: Exception) { return null } } fun getPreferenceInt(context: Context, name: PreferenceName): Int? { try { val preference = getEncryptedSharedPrefs(context) migratePlainPreference(context, name, preference) return preference.getInt(name.name, 0) } catch (e: Exception) { return null } } fun setPreferenceString(context: Context, name: PreferenceName, value: String) { try { val preference = getEncryptedSharedPrefs(context) preference.edit().putString(name.name, value).apply() } catch (e: Exception) { return } } fun setPreferenceInt(context: Context, name: PreferenceName, value: Int) { try { val preference = getEncryptedSharedPrefs(context) preference.edit().putInt(name.name, value).apply() } catch (e: Exception) { return } } sealed class Screen(val route: String) { object ScreenRoutes: Screen("routes") object ScreenMain: Screen("main") } fun IntToIPString(ip: Int): String { val one = ((ip ushr 24) and 0x000000ff) val two = ((ip ushr 16) and 0x000000ff) val three = ((ip ushr 8) and 0x000000ff) val four = ((ip) and 0x000000ff) return "${one}.${two}.${three}.${four}" } fun IPStringToInt(ipStr: String): Int? { val digits = ipStr.split('.').filter{ val single = try { it.toInt() } catch(e: Exception) { return@filter false } single in 0..255 } if (digits.size != 4) { return null } val result: Int try { result = (digits[0].toInt() shl 24) + (digits[1].toInt() shl 16) + (digits[2].toInt() shl 8) + (digits[3].toInt()) } catch(e: Exception) { return null } return result } fun parseCIDRAndGW(cidr: String, gw: String): RouteItem? { val cidrSplit = cidr.split('/') var ip = 0 var digit = 0 if (cidrSplit.size == 1) { digit = 32 } else if (cidrSplit.size == 2) { try { val k = cidrSplit[1].toInt() if (k in 1..32) { digit = k } else { return null } } catch (e: Exception) { return null } } else { return null } val ipvalue = IPStringToInt(cidrSplit[0]) val gateway = IPStringToInt(gw) if (ipvalue == null) { return null } if (gateway == null) { return null } val mask = maskDigitToInt(digit)!! return RouteItem( net_ip = ipvalue, gateway = gateway, mask_ip = mask, ) }