mirror of
https://github.com/yggdrasil-network/crispa-android.git
synced 2025-01-22 16:06:30 +00:00
1. cache peer list pre-loading
This commit is contained in:
parent
69e9999dfa
commit
172b7e0ece
@ -404,7 +404,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
super.onRestoreInstanceState(savedInstanceState)
|
super.onRestoreInstanceState(savedInstanceState)
|
||||||
val preferences =
|
val preferences =
|
||||||
PreferenceManager.getDefaultSharedPreferences(this.baseContext)
|
PreferenceManager.getDefaultSharedPreferences(this.baseContext)
|
||||||
findViewById<Switch>(R.id.staticIP).isChecked =
|
findViewById<SwitchCompat>(R.id.staticIP).isChecked =
|
||||||
preferences.getString(STATIC_IP, null) != null
|
preferences.getString(STATIC_IP, null) != null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ import androidx.appcompat.app.AppCompatActivity
|
|||||||
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
import com.google.gson.reflect.TypeToken
|
import com.google.gson.reflect.TypeToken
|
||||||
|
import com.hbb20.BuildConfig
|
||||||
import com.hbb20.CCPCountry
|
import com.hbb20.CCPCountry
|
||||||
import com.vincentbrison.openlibraries.android.dualcache.Builder
|
import com.vincentbrison.openlibraries.android.dualcache.Builder
|
||||||
import com.vincentbrison.openlibraries.android.dualcache.SizeOf
|
import com.vincentbrison.openlibraries.android.dualcache.SizeOf
|
||||||
@ -21,21 +22,18 @@ import com.vincentbrison.openlibraries.android.dualcache.JsonSerializer
|
|||||||
import io.github.chronosx88.yggdrasil.models.PeerInfo
|
import io.github.chronosx88.yggdrasil.models.PeerInfo
|
||||||
import io.github.chronosx88.yggdrasil.models.Status
|
import io.github.chronosx88.yggdrasil.models.Status
|
||||||
import io.github.chronosx88.yggdrasil.models.config.DropDownAdapter
|
import io.github.chronosx88.yggdrasil.models.config.DropDownAdapter
|
||||||
import io.github.chronosx88.yggdrasil.models.config.Peer
|
|
||||||
import io.github.chronosx88.yggdrasil.models.config.SelectPeerInfoListAdapter
|
import io.github.chronosx88.yggdrasil.models.config.SelectPeerInfoListAdapter
|
||||||
import io.github.chronosx88.yggdrasil.models.config.Utils.Companion.deserializeStringList2PeerInfoSet
|
import io.github.chronosx88.yggdrasil.models.config.Utils.Companion.deserializeStringList2PeerInfoSet
|
||||||
import io.github.chronosx88.yggdrasil.models.config.Utils.Companion.ping
|
import io.github.chronosx88.yggdrasil.models.config.Utils.Companion.ping
|
||||||
import io.github.chronosx88.yggdrasil.models.config.Utils.Companion.serializePeerInfoSet2StringList
|
import io.github.chronosx88.yggdrasil.models.config.Utils.Companion.serializePeerInfoSet2StringList
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.*
|
||||||
import kotlinx.coroutines.GlobalScope
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import kotlinx.coroutines.withContext
|
|
||||||
import java.io.ByteArrayOutputStream
|
import java.io.ByteArrayOutputStream
|
||||||
import java.io.FileNotFoundException
|
import java.io.FileNotFoundException
|
||||||
import java.lang.reflect.Type
|
import java.lang.reflect.Type
|
||||||
import java.net.InetAddress
|
import java.net.InetAddress
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
|
import java.net.UnknownHostException
|
||||||
import java.nio.charset.Charset
|
import java.nio.charset.Charset
|
||||||
|
|
||||||
|
|
||||||
@ -44,9 +42,9 @@ class PeerListActivity : AppCompatActivity() {
|
|||||||
companion object {
|
companion object {
|
||||||
const val PEER_LIST_URL = "https://publicpeers.neilalexander.dev/publicnodes.json"
|
const val PEER_LIST_URL = "https://publicpeers.neilalexander.dev/publicnodes.json"
|
||||||
const val CACHE_NAME = "PEER_LIST_CACHE"
|
const val CACHE_NAME = "PEER_LIST_CACHE"
|
||||||
const val ONLINE_PEERINFO_LIST = "ONLINE_PEERINFO_LIST"
|
const val ONLINE_PEERINFO_LIST = "online_peer_info_list"
|
||||||
const val OFFLINE_PEERINFO_LIST = "OFFLINE_PEERINFO_LIST"
|
const val OFFLINE_PEERINFO_LIST = "offline_peer_info_list"
|
||||||
const val TEST_APP_VERSION = BuildConfig.VERSION_CODE;
|
const val TEST_APP_VERSION = BuildConfig.VERSION_CODE
|
||||||
const val RAM_MAX_SIZE = 100000
|
const val RAM_MAX_SIZE = 100000
|
||||||
const val DISK_MAX_SIZE = 100000
|
const val DISK_MAX_SIZE = 100000
|
||||||
}
|
}
|
||||||
@ -61,6 +59,7 @@ class PeerListActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var peerListPing = true
|
||||||
var popup: PopupWindow? = null
|
var popup: PopupWindow? = null
|
||||||
var adapter: DropDownAdapter? = null
|
var adapter: DropDownAdapter? = null
|
||||||
|
|
||||||
@ -83,72 +82,19 @@ class PeerListActivity : AppCompatActivity() {
|
|||||||
JsonSerializer(ArrayList<PeerInfo>().javaClass), baseContext
|
JsonSerializer(ArrayList<PeerInfo>().javaClass), baseContext
|
||||||
).build();
|
).build();
|
||||||
|
|
||||||
GlobalScope.launch {
|
GlobalScope.launch() {
|
||||||
try {
|
try {
|
||||||
var cp = deserializeStringList2PeerInfoSet(
|
var cp = deserializeStringList2PeerInfoSet(
|
||||||
extras!!.getStringArrayList(MainActivity.PEER_LIST)!!
|
extras!!.getStringArrayList(MainActivity.PEER_LIST)!!
|
||||||
)
|
)
|
||||||
for(pi in cp){
|
for (pi in cp) {
|
||||||
var ping = ping(pi.address, pi.port)
|
var ping = ping(pi.address, pi.port)
|
||||||
pi.ping = ping
|
pi.ping = ping
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
var json = downloadJson(PEER_LIST_URL)
|
var peerInfoCache = peerInfoListCache.get(ONLINE_PEERINFO_LIST)
|
||||||
var countries = CCPCountry.getLibraryMasterCountriesEnglish()
|
if (peerInfoCache != null && peerInfoCache.isNotEmpty()) {
|
||||||
val mapType: Type = object :
|
for (peerInfo in peerInfoCache) {
|
||||||
TypeToken<Map<String?, Map<String, Status>>>() {}.type
|
|
||||||
val peersMap: Map<String, Map<String, Status>> = Gson().fromJson(json, mapType)
|
|
||||||
for ((country, peers) in peersMap.entries) {
|
|
||||||
for ((peer, status) in peers) {
|
|
||||||
if (status.up) {
|
|
||||||
for (ccp in countries) {
|
|
||||||
if (ccp.name.toLowerCase()
|
|
||||||
.contains(country.replace(".md", "").replace("-", " "))
|
|
||||||
) {
|
|
||||||
var url = URI(peer)
|
|
||||||
try {
|
|
||||||
var address = InetAddress.getByName(url.host)
|
|
||||||
var peerInfo =
|
|
||||||
PeerInfo(
|
|
||||||
url.scheme,
|
|
||||||
address,
|
|
||||||
url.port,
|
|
||||||
ccp.nameCode
|
|
||||||
)
|
|
||||||
var ping = ping(address, url.port)
|
|
||||||
peerInfo.ping = ping
|
|
||||||
if(cp.contains(peerInfo)){
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
withContext(Dispatchers.Main) {
|
|
||||||
adapter.addItem(peerInfo)
|
|
||||||
if(adapter.count % 5 == 0) {
|
|
||||||
adapter.sort()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e: Throwable){
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var allPeersList = adapter.getAllPeers()
|
|
||||||
var cachePeerInfoList = mutableListOf<PeerInfo>()
|
|
||||||
for(p in allPeersList){
|
|
||||||
if(p.ping<Int.MAX_VALUE){
|
|
||||||
cachePeerInfoList.add(p)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(cachePeerInfoList.size>0){
|
|
||||||
peerInfoListCache.put(ONLINE_PEERINFO_LIST, cachePeerInfoList.toList())
|
|
||||||
}
|
|
||||||
} catch (e: FileNotFoundException){
|
|
||||||
e.printStackTrace()
|
|
||||||
var onlinePeerInfoList = peerInfoListCache.get(ONLINE_PEERINFO_LIST)
|
|
||||||
if(onlinePeerInfoList!=null) {
|
|
||||||
for (peerInfo in onlinePeerInfoList) {
|
|
||||||
var ping = ping(peerInfo.address, peerInfo.port)
|
var ping = ping(peerInfo.address, peerInfo.port)
|
||||||
peerInfo.ping = ping
|
peerInfo.ping = ping
|
||||||
if (cp.contains(peerInfo)) {
|
if (cp.contains(peerInfo)) {
|
||||||
@ -162,12 +108,89 @@ class PeerListActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
var json = downloadJson(PEER_LIST_URL)
|
||||||
|
var countries = CCPCountry.getLibraryMasterCountriesEnglish()
|
||||||
|
val mapType: Type = object :
|
||||||
|
TypeToken<Map<String?, Map<String, Status>>>() {}.type
|
||||||
|
val peersMap: Map<String, Map<String, Status>> = Gson().fromJson(json, mapType)
|
||||||
|
var cachePeerInfoList = mutableListOf<PeerInfo>()
|
||||||
|
for ((country, peers) in peersMap.entries) {
|
||||||
|
for ((peer, status) in peers) {
|
||||||
|
if (status.up) {
|
||||||
|
for (ccp in countries) {
|
||||||
|
if (ccp.name.toLowerCase()
|
||||||
|
.contains(country.replace(".md", "").replace("-", " "))
|
||||||
|
) {
|
||||||
|
if(!peerListPing){
|
||||||
|
return@launch
|
||||||
|
}
|
||||||
|
var url = URI(peer)
|
||||||
|
try {
|
||||||
|
var address = InetAddress.getByName(url.host)
|
||||||
|
var peerInfo =
|
||||||
|
PeerInfo(
|
||||||
|
url.scheme,
|
||||||
|
address,
|
||||||
|
url.port,
|
||||||
|
ccp.nameCode
|
||||||
|
)
|
||||||
|
var ping = ping(address, url.port)
|
||||||
|
peerInfo.ping = ping
|
||||||
|
if (cp.contains(peerInfo)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if (peerInfo.ping < Int.MAX_VALUE) {
|
||||||
|
cachePeerInfoList.add(peerInfo)
|
||||||
|
}
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
adapter.addItem(peerInfo)
|
||||||
|
if (adapter.count % 5 == 0) {
|
||||||
|
adapter.sort()
|
||||||
|
if (cachePeerInfoList.size > 0) {
|
||||||
|
peerInfoListCache.put(
|
||||||
|
ONLINE_PEERINFO_LIST,
|
||||||
|
cachePeerInfoList.toList()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
when (e) {
|
||||||
|
is FileNotFoundException, is UnknownHostException -> {
|
||||||
|
var onlinePeerInfoList = peerInfoListCache.get(ONLINE_PEERINFO_LIST)
|
||||||
|
if (onlinePeerInfoList != null) {
|
||||||
|
for (peerInfo in onlinePeerInfoList) {
|
||||||
|
var ping = ping(peerInfo.address, peerInfo.port)
|
||||||
|
peerInfo.ping = ping
|
||||||
|
if (cp.contains(peerInfo)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
adapter.addItem(peerInfo)
|
||||||
|
if (adapter.count % 5 == 0) {
|
||||||
|
adapter.sort()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
else -> e.printStackTrace()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
var currentPeers = ArrayList(cp.sortedWith(compareBy { it.ping }))
|
var currentPeers = ArrayList(cp.sortedWith(compareBy { it.ping }))
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
adapter.addAll(0, currentPeers)
|
adapter.addAll(0, currentPeers)
|
||||||
}
|
}
|
||||||
} catch (e: Throwable){
|
} catch (e: Throwable) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -283,6 +306,8 @@ class PeerListActivity : AppCompatActivity() {
|
|||||||
val saveButton = item
|
val saveButton = item
|
||||||
.actionView.findViewById<Button>(R.id.saveButton)
|
.actionView.findViewById<Button>(R.id.saveButton)
|
||||||
saveButton.setOnClickListener {
|
saveButton.setOnClickListener {
|
||||||
|
saveButton.isClickable = false
|
||||||
|
cancelPeerListPing()
|
||||||
val result = Intent(this, MainActivity::class.java)
|
val result = Intent(this, MainActivity::class.java)
|
||||||
var adapter = findViewById<ListView>(R.id.peerList).adapter as SelectPeerInfoListAdapter
|
var adapter = findViewById<ListView>(R.id.peerList).adapter as SelectPeerInfoListAdapter
|
||||||
val selectedPeers = adapter.getSelectedPeers()
|
val selectedPeers = adapter.getSelectedPeers()
|
||||||
@ -292,6 +317,15 @@ class PeerListActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun cancelPeerListPing() {
|
||||||
|
peerListPing = false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStop() {
|
||||||
|
super.onStop()
|
||||||
|
cancelPeerListPing()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SizeOfPeerList: SizeOf<List<PeerInfo>> {
|
class SizeOfPeerList: SizeOf<List<PeerInfo>> {
|
||||||
@ -317,5 +351,4 @@ class SizeOfPeerList: SizeOf<List<PeerInfo>> {
|
|||||||
}
|
}
|
||||||
return size
|
return size
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,11 @@ import java.net.InetAddress
|
|||||||
|
|
||||||
|
|
||||||
class PeerInfo {
|
class PeerInfo {
|
||||||
|
|
||||||
|
constructor(){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
constructor(schema: String, address: InetAddress, port: Int, countryCode: String){
|
constructor(schema: String, address: InetAddress, port: Int, countryCode: String){
|
||||||
this.schema = schema
|
this.schema = schema
|
||||||
this.address = address
|
this.address = address
|
||||||
@ -34,9 +39,9 @@ class PeerInfo {
|
|||||||
this.isMeshPeer = isMeshPeer
|
this.isMeshPeer = isMeshPeer
|
||||||
}
|
}
|
||||||
|
|
||||||
var schema: String
|
lateinit var schema: String
|
||||||
var address: InetAddress
|
lateinit var address: InetAddress
|
||||||
var hostName: String
|
lateinit var hostName: String
|
||||||
var port = 0
|
var port = 0
|
||||||
var countryCode: String?=null
|
var countryCode: String?=null
|
||||||
var ping: Int = Int.MAX_VALUE
|
var ping: Int = Int.MAX_VALUE
|
||||||
|
@ -79,7 +79,9 @@ class SelectPeerInfoListAdapter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun addItem(peerInfo: PeerInfo){
|
fun addItem(peerInfo: PeerInfo){
|
||||||
allPeers.add(peerInfo)
|
if(!allPeers.contains(peerInfo)){
|
||||||
|
allPeers.add(peerInfo)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addItem(index: Int, peerInfo: PeerInfo){
|
fun addItem(index: Int, peerInfo: PeerInfo){
|
||||||
|
Loading…
x
Reference in New Issue
Block a user