proxy activity
This commit is contained in:
16 files changed
+420
-136
No files matched your search
@@ -44,7 +44,7 @@
|
||||
android:exported="false"
|
||||
android:screenOrientation="portrait"/>
|
||||
<activity android:name=".ProxyActivity"
|
||||
android:label="@string/clash_profiles"
|
||||
android:label="@string/clash_proxy_manage"
|
||||
android:exported="false"
|
||||
android:screenOrientation="portrait"/>
|
||||
</application>
|
||||
|
||||
@@ -1,28 +1,70 @@
|
||||
package com.github.kr328.clash
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.github.kr328.clash.adapter.ProxyGroupAdapter
|
||||
import com.github.kr328.clash.core.model.Proxy
|
||||
import com.github.kr328.clash.core.model.ProxyPacket
|
||||
import com.github.kr328.clash.model.ListProxyGroup
|
||||
import kotlinx.android.synthetic.main.activity_proxies.*
|
||||
|
||||
class ProxyActivity : BaseActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_proxies)
|
||||
|
||||
val content = RecyclerView(this)
|
||||
setSupportActionBar(activity_proxies_toolbar)
|
||||
|
||||
setContentView(content)
|
||||
|
||||
content.layoutManager = LinearLayoutManager(this)
|
||||
content.adapter = ProxyGroupAdapter(this)
|
||||
activity_proxies_list.also {
|
||||
it.layoutManager = LinearLayoutManager(this)
|
||||
it.adapter = ProxyGroupAdapter(this)
|
||||
it.visibility = View.GONE
|
||||
}
|
||||
|
||||
runClash { clash ->
|
||||
val proxies = clash.queryAllProxies().proxies
|
||||
val adapterProxies = proxies
|
||||
.mapValues {
|
||||
ListProxyGroup.ListProxy(it.value.name,
|
||||
it.value.type.toString(),
|
||||
it.value.delay)
|
||||
}
|
||||
|
||||
val listData = proxies
|
||||
.asSequence()
|
||||
.filter {
|
||||
when (it.value.type) {
|
||||
ProxyPacket.Type.URL_TEST -> true
|
||||
ProxyPacket.Type.FALLBACK -> true
|
||||
ProxyPacket.Type.LOAD_BALANCE -> true
|
||||
ProxyPacket.Type.SELECT -> true
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
.sortedWith(compareBy(
|
||||
{
|
||||
it.value.type != ProxyPacket.Type.SELECT
|
||||
}, {
|
||||
it.value.name
|
||||
}))
|
||||
.map {
|
||||
ListProxyGroup(
|
||||
it.value.name,
|
||||
it.value.type.toString(),
|
||||
it.value.all.mapNotNull { hash ->
|
||||
adapterProxies[hash]
|
||||
},
|
||||
adapterProxies[it.value.now]
|
||||
)
|
||||
}
|
||||
.toList()
|
||||
|
||||
runOnUiThread {
|
||||
(content.adapter!! as ProxyGroupAdapter).data = proxies.toList()
|
||||
.sortedWith(compareBy({ it.second.type == Proxy.TYPE_SELECT }, { it.first }))
|
||||
(activity_proxies_list.adapter!! as ProxyGroupAdapter).apply {
|
||||
data = listData
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
activity_proxies_list.visibility = View.VISIBLE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
package com.github.kr328.clash.adapter
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.github.kr328.clash.R
|
||||
import com.github.kr328.clash.model.ListProxyGroup
|
||||
import com.google.android.material.card.MaterialCardView
|
||||
|
||||
class ProxyAdapter(private val context: Context): RecyclerView.Adapter<ProxyAdapter.Holder>() {
|
||||
var proxies: List<ListProxyGroup.ListProxy> = emptyList()
|
||||
var now: ListProxyGroup.ListProxy? = null
|
||||
|
||||
class Holder(view: View) : RecyclerView.ViewHolder(view) {
|
||||
val name: TextView = view.findViewById(R.id.adapter_proxy_name)
|
||||
val type: TextView = view.findViewById(R.id.adapter_proxy_type)
|
||||
val delay: TextView = view.findViewById(R.id.adapter_proxy_delay)
|
||||
val card: MaterialCardView = view.findViewById(R.id.adapter_proxy_card)
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder {
|
||||
return Holder(LayoutInflater.from(context).inflate(R.layout.adapter_proxy, parent, false))
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return proxies.size
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: Holder, position: Int) {
|
||||
val current = proxies[position]
|
||||
|
||||
if ( current === now ) {
|
||||
holder.card.setCardBackgroundColor(context.getColor(R.color.colorAccent))
|
||||
holder.name.setTextColor(Color.WHITE)
|
||||
holder.type.setTextColor(Color.WHITE - 0x22222222)
|
||||
holder.delay.setTextColor(Color.WHITE - 0x11111111)
|
||||
}
|
||||
else{
|
||||
holder.card.setCardBackgroundColor(Color.WHITE)
|
||||
holder.name.setTextColor(Color.BLACK)
|
||||
holder.type.setTextColor(Color.LTGRAY)
|
||||
holder.delay.setTextColor(Color.DKGRAY)
|
||||
}
|
||||
|
||||
holder.name.text = current.name
|
||||
holder.type.text = current.type
|
||||
holder.delay.text = if ( current.delay > 0 ) current.delay.toString() else ""
|
||||
}
|
||||
}
|
||||
@@ -5,21 +5,28 @@ import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.github.kr328.clash.R
|
||||
import com.github.kr328.clash.core.model.Proxy
|
||||
import com.github.kr328.clash.model.ListProxyGroup
|
||||
|
||||
class ProxyGroupAdapter(private val context: Context) : RecyclerView.Adapter<ProxyGroupAdapter.Holder>() {
|
||||
var data: List<Pair<String, Proxy>> = emptyList()
|
||||
var data: List<ListProxyGroup> = emptyList()
|
||||
|
||||
class Holder(view: View) : RecyclerView.ViewHolder(view) {
|
||||
val name = view.findViewById<TextView>(R.id.adapter_proxy_group_name)
|
||||
val list = view.findViewById<RecyclerView>(R.id.adapter_proxy_group_list)
|
||||
val name: TextView = view.findViewById(R.id.adapter_proxy_group_name)
|
||||
val list: RecyclerView = view.findViewById(R.id.adapter_proxy_group_list)
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder {
|
||||
return Holder(LayoutInflater.from(context)
|
||||
.inflate(R.layout.adapter_proxy_group, parent, false))
|
||||
.inflate(R.layout.adapter_proxy_group, parent, false)).apply {
|
||||
list.layoutManager = object: GridLayoutManager(context, 2) {
|
||||
override fun canScrollHorizontally(): Boolean = false
|
||||
override fun canScrollVertically(): Boolean = false
|
||||
}
|
||||
list.adapter = ProxyAdapter(context)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
@@ -29,6 +36,11 @@ class ProxyGroupAdapter(private val context: Context) : RecyclerView.Adapter<Pro
|
||||
override fun onBindViewHolder(holder: Holder, position: Int) {
|
||||
val current = data[position]
|
||||
|
||||
holder.name.text = current.first
|
||||
holder.name.text = current.name
|
||||
|
||||
(holder.list.adapter as ProxyAdapter).apply {
|
||||
proxies = current.proxies
|
||||
now = current.now
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.github.kr328.clash.model
|
||||
|
||||
data class ListProxyGroup(val name: String, val type: String, val proxies: List<ListProxy>, var now: ListProxy?) {
|
||||
data class ListProxy(val name: String, val type: String, val delay: Long)
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M16.59,8.59L12,13.17 7.41,8.59 6,10l6,6 6,-6z"/>
|
||||
</vector>
|
||||
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:animateLayoutChanges="true">
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/activity_proxies_toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="60dp" />
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/activity_proxies_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
</LinearLayout>
|
||||
@@ -1,29 +1,50 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
android:layout_height="wrap_content"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/adapter_proxy_card"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
android:layout_height="wrap_content"
|
||||
app:cardUseCompatPadding="true"
|
||||
app:cardElevation="2dp"
|
||||
app:cardCornerRadius="5dp">
|
||||
<RelativeLayout
|
||||
android:padding="18dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
android:padding="15dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/adapter_proxy_name"
|
||||
android:textColor="@android:color/black"
|
||||
android:text="@string/app_name"
|
||||
android:maxLines="1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/adapter_proxy_type"
|
||||
android:layout_below="@id/adapter_proxy_name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/app_name"/>
|
||||
android:textSize="12sp"
|
||||
android:text="@string/app_name"
|
||||
android:maxLines="1"/>
|
||||
|
||||
<TextView
|
||||
android:layout_alignParentEnd="true"
|
||||
android:gravity="end"
|
||||
android:textSize="12sp"
|
||||
android:id="@+id/adapter_proxy_delay"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_toEndOf="@id/adapter_proxy_name"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:minWidth="30dp"/>
|
||||
|
||||
</RelativeLayout>
|
||||
</androidx.cardview.widget.CardView>
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
</FrameLayout>
|
||||
@@ -1,18 +1,27 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:animateLayoutChanges="true">
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:animateLayoutChanges="true"
|
||||
android:paddingStart="12dp"
|
||||
android:paddingEnd="12dp"
|
||||
android:paddingTop="12dp">
|
||||
|
||||
<TextView
|
||||
android:padding="5dp"
|
||||
android:layout_marginStart="2dp"
|
||||
android:textColor="@color/colorAccent"
|
||||
android:text="@string/app_name"
|
||||
android:id="@+id/adapter_proxy_group_name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<View
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_width="16dp"
|
||||
android:layout_height="16dp"
|
||||
android:background="@drawable/ic_expand"/>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/adapter_proxy_group_list"
|
||||
android:layout_below="@id/adapter_proxy_group_name"
|
||||
|
||||
@@ -41,4 +41,6 @@
|
||||
<string name="clash_import_file_empty_name">Empty Name</string>
|
||||
<string name="clash_import_file_empty_path">Empty Path</string>
|
||||
<string name="clash_import_file_invalid">Invalid Config: %s</string>
|
||||
|
||||
<string name="clash_proxy_group_title">%s - %s</string>
|
||||
</resources>
|
||||
@@ -8,8 +8,7 @@ import com.github.kr328.clash.core.event.LogEvent
|
||||
import com.github.kr328.clash.core.event.ProcessEvent
|
||||
import com.github.kr328.clash.core.event.ProxyChangedEvent
|
||||
import com.github.kr328.clash.core.event.TrafficEvent
|
||||
import com.github.kr328.clash.core.model.Proxy
|
||||
import com.github.kr328.clash.core.model.ProxyPacket
|
||||
import com.github.kr328.clash.core.model.RawProxyPacket
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.json.JsonConfiguration
|
||||
import org.json.JSONObject
|
||||
@@ -57,14 +56,14 @@ class Clash(
|
||||
}
|
||||
}
|
||||
|
||||
fun queryProxies(): ProxyPacket {
|
||||
fun queryProxies(): RawProxyPacket {
|
||||
return runControl(COMMAND_QUERY_PROXIES) { _, input, _ ->
|
||||
val data = input.readString()
|
||||
|
||||
Log.d(TAG, data)
|
||||
|
||||
Json(JsonConfiguration.Stable.copy(strictMode = false))
|
||||
.parse(ProxyPacket.serializer(), data)
|
||||
.parse(RawProxyPacket.serializer(), data)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
package com.github.kr328.clash.core.model
|
||||
|
||||
import android.os.Parcel
|
||||
import android.os.Parcelable
|
||||
import com.github.kr328.clash.core.serialization.Parcels
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class Proxy(val type: String,
|
||||
val all: List<String> = emptyList(),
|
||||
val now: String = "",
|
||||
val history: List<History> = emptyList()) {
|
||||
@Serializable
|
||||
data class History(val delay: Long)
|
||||
|
||||
companion object {
|
||||
const val TYPE_SELECT = "Selector"
|
||||
const val TYPE_URL_TEST = "URLTest"
|
||||
const val TYPE_DIRECT = "Direct"
|
||||
const val TYPE_FALLBACK = "Fallback"
|
||||
const val TYPE_REJECT = "Reject"
|
||||
const val TYPE_SHADOWSOCKS = "Shadowsocks"
|
||||
const val TYPE_SNELL = "Snell"
|
||||
const val TYPE_SOCKS5 = "Socks5"
|
||||
const val TYPE_HTTP = "Http"
|
||||
const val TYPE_VMESS = "Vmess"
|
||||
const val TYPE_LOAD_BALANCE = "LoadBalance"
|
||||
const val TYPE_UNKNOWN = "Unknown"
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,99 @@ import com.github.kr328.clash.core.serialization.Parcels
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class ProxyPacket(val proxies: Map<String, Proxy>) : Parcelable {
|
||||
data class ProxyPacket(val proxies: Map<Int, Proxy>): Parcelable {
|
||||
@Serializable
|
||||
data class Proxy(val name: String, val type: Type, val now: Int, val all: Set<Int>, val delay: Long)
|
||||
|
||||
enum class Type {
|
||||
SELECT,
|
||||
URL_TEST,
|
||||
FALLBACK,
|
||||
DIRECT,
|
||||
REJECT,
|
||||
SHADOWSOCKS,
|
||||
SNELL,
|
||||
SOCKS5,
|
||||
HTTP,
|
||||
VMESS,
|
||||
LOAD_BALANCE,
|
||||
UNKNOWN;
|
||||
|
||||
override fun toString(): String {
|
||||
return when ( this ) {
|
||||
SELECT -> "Select"
|
||||
URL_TEST -> "UrlTest"
|
||||
FALLBACK -> "Fallback"
|
||||
DIRECT -> "Direct"
|
||||
REJECT -> "Reject"
|
||||
SHADOWSOCKS -> "Shadowsocks"
|
||||
SNELL -> "Snell"
|
||||
SOCKS5 -> "Socks5"
|
||||
HTTP -> "HTTP"
|
||||
VMESS -> "Vmess"
|
||||
LOAD_BALANCE -> "LoadBalance"
|
||||
UNKNOWN -> "Unknown"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TYPE_SELECT = "Selector"
|
||||
private const val TYPE_URL_TEST = "URLTest"
|
||||
private const val TYPE_FALLBACK = "Fallback"
|
||||
private const val TYPE_DIRECT = "Direct"
|
||||
private const val TYPE_REJECT = "Reject"
|
||||
private const val TYPE_SHADOWSOCKS = "Shadowsocks"
|
||||
private const val TYPE_SNELL = "Snell"
|
||||
private const val TYPE_SOCKS5 = "Socks5"
|
||||
private const val TYPE_HTTP = "Http"
|
||||
private const val TYPE_VMESS = "Vmess"
|
||||
private const val TYPE_LOAD_BALANCE = "LoadBalance"
|
||||
private const val TYPE_UNKNOWN = "Unknown"
|
||||
|
||||
fun fromRawProxy(rawProxy: RawProxyPacket): ProxyPacket {
|
||||
val hashed = rawProxy.proxies
|
||||
.map { it.key to (it.key.hashCode() to it.value) }.toMap()
|
||||
|
||||
val proxies = hashed.map { entry ->
|
||||
val type = when ( entry.value.second.type ) {
|
||||
TYPE_SELECT -> Type.SELECT
|
||||
TYPE_URL_TEST -> Type.URL_TEST
|
||||
TYPE_FALLBACK -> Type.FALLBACK
|
||||
TYPE_DIRECT -> Type.DIRECT
|
||||
TYPE_REJECT -> Type.REJECT
|
||||
TYPE_SHADOWSOCKS -> Type.SHADOWSOCKS
|
||||
TYPE_SNELL -> Type.SNELL
|
||||
TYPE_SOCKS5 -> Type.SOCKS5
|
||||
TYPE_HTTP -> Type.HTTP
|
||||
TYPE_VMESS -> Type.VMESS
|
||||
TYPE_LOAD_BALANCE -> Type.LOAD_BALANCE
|
||||
TYPE_UNKNOWN -> Type.UNKNOWN
|
||||
else -> Type.UNKNOWN
|
||||
}
|
||||
|
||||
val now = hashed[entry.value.second.now]?.first ?: 0
|
||||
val all = entry.value.second.all.mapNotNull { hashed[it]?.first }.toSet()
|
||||
val delay = entry.value.second.history.firstOrNull()?.delay ?: 0
|
||||
|
||||
entry.value.first to Proxy(entry.key, type, now, all, delay)
|
||||
}
|
||||
|
||||
return ProxyPacket(proxies.toMap())
|
||||
}
|
||||
|
||||
@JvmField
|
||||
val CREATOR = object: Parcelable.Creator<ProxyPacket> {
|
||||
override fun createFromParcel(parcel: Parcel): ProxyPacket {
|
||||
return Parcels.load(serializer(), parcel)
|
||||
}
|
||||
|
||||
override fun newArray(size: Int): Array<ProxyPacket?> {
|
||||
return arrayOfNulls(size)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun writeToParcel(parcel: Parcel, flags: Int) {
|
||||
Parcels.dump(serializer(), this, parcel)
|
||||
}
|
||||
@@ -14,15 +106,4 @@ data class ProxyPacket(val proxies: Map<String, Proxy>) : Parcelable {
|
||||
override fun describeContents(): Int {
|
||||
return 0
|
||||
}
|
||||
|
||||
companion object CREATOR : Parcelable.Creator<ProxyPacket> {
|
||||
override fun createFromParcel(parcel: Parcel): ProxyPacket {
|
||||
return Parcels.load(serializer(), parcel)
|
||||
}
|
||||
|
||||
override fun newArray(size: Int): Array<ProxyPacket?> {
|
||||
return arrayOfNulls(size)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.github.kr328.clash.core.model
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class RawProxyPacket(val proxies: Map<String, RawProxy>) {
|
||||
@Serializable
|
||||
data class RawProxy(val type: String,
|
||||
val all: List<String> = emptyList(),
|
||||
val now: String = "",
|
||||
val history: List<History> = emptyList()) {
|
||||
@Serializable
|
||||
data class History(val delay: Long)
|
||||
}
|
||||
}
|
||||
@@ -18,14 +18,85 @@ object Parcels : AbstractSerialFormat(EmptyModule) {
|
||||
}
|
||||
|
||||
private class ParcelsEncoder(private val parcel: Parcel) :
|
||||
ElementValueEncoder() {
|
||||
override fun encodeValue(value: Any) {
|
||||
parcel.writeValue(value)
|
||||
Encoder, CompositeEncoder {
|
||||
override val context: SerialModule
|
||||
get() = EmptyModule
|
||||
|
||||
override fun beginCollection(
|
||||
desc: SerialDescriptor,
|
||||
collectionSize: Int,
|
||||
vararg typeParams: KSerializer<*>
|
||||
): CompositeEncoder {
|
||||
encodeInt(collectionSize)
|
||||
return super.beginCollection(desc, collectionSize, *typeParams)
|
||||
}
|
||||
|
||||
override fun encodeNull() {
|
||||
parcel.writeValue(null)
|
||||
}
|
||||
override fun encodeBooleanElement(desc: SerialDescriptor, index: Int, value: Boolean) =
|
||||
encodeBoolean(value)
|
||||
override fun encodeByteElement(desc: SerialDescriptor, index: Int, value: Byte) =
|
||||
encodeByte(value)
|
||||
override fun encodeCharElement(desc: SerialDescriptor, index: Int, value: Char) =
|
||||
encodeChar(value)
|
||||
override fun encodeDoubleElement(desc: SerialDescriptor, index: Int, value: Double) =
|
||||
encodeDouble(value)
|
||||
override fun encodeFloatElement(desc: SerialDescriptor, index: Int, value: Float) =
|
||||
encodeFloat(value)
|
||||
override fun encodeIntElement(desc: SerialDescriptor, index: Int, value: Int) =
|
||||
encodeInt(value)
|
||||
override fun encodeLongElement(desc: SerialDescriptor, index: Int, value: Long) =
|
||||
encodeLong(value)
|
||||
override fun encodeShortElement(desc: SerialDescriptor, index: Int, value: Short) =
|
||||
encodeShort(value)
|
||||
override fun encodeStringElement(desc: SerialDescriptor, index: Int, value: String) =
|
||||
encodeString(value)
|
||||
override fun encodeUnitElement(desc: SerialDescriptor, index: Int) =
|
||||
encodeUnit()
|
||||
|
||||
override fun encodeNonSerializableElement(desc: SerialDescriptor, index: Int, value: Any) =
|
||||
throw IllegalArgumentException("Unsupported")
|
||||
override fun <T : Any> encodeNullableSerializableElement(
|
||||
desc: SerialDescriptor,
|
||||
index: Int,
|
||||
serializer: SerializationStrategy<T>,
|
||||
value: T?
|
||||
) = encodeNullableSerializableValue(serializer, value)
|
||||
override fun <T> encodeSerializableElement(
|
||||
desc: SerialDescriptor,
|
||||
index: Int,
|
||||
serializer: SerializationStrategy<T>,
|
||||
value: T
|
||||
) = encodeSerializableValue(serializer, value)
|
||||
|
||||
override fun beginStructure(
|
||||
desc: SerialDescriptor,
|
||||
vararg typeParams: KSerializer<*>
|
||||
): CompositeEncoder = this
|
||||
|
||||
override fun encodeBoolean(value: Boolean) =
|
||||
parcel.writeByte(if ( value ) 1 else 0)
|
||||
override fun encodeByte(value: Byte) =
|
||||
parcel.writeByte(value)
|
||||
override fun encodeChar(value: Char) =
|
||||
parcel.writeInt(value.toInt())
|
||||
override fun encodeDouble(value: Double) =
|
||||
parcel.writeDouble(value)
|
||||
override fun encodeEnum(enumDescription: SerialDescriptor, ordinal: Int) =
|
||||
parcel.writeInt(ordinal)
|
||||
override fun encodeFloat(value: Float) =
|
||||
parcel.writeFloat(value)
|
||||
override fun encodeInt(value: Int) =
|
||||
parcel.writeInt(value)
|
||||
override fun encodeLong(value: Long) =
|
||||
parcel.writeLong(value)
|
||||
override fun encodeNotNullMark() =
|
||||
encodeBoolean(true)
|
||||
override fun encodeNull() =
|
||||
encodeBoolean(false)
|
||||
override fun encodeShort(value: Short) =
|
||||
parcel.writeInt(value.toInt())
|
||||
override fun encodeString(value: String) =
|
||||
parcel.writeString(value)
|
||||
override fun encodeUnit() {}
|
||||
}
|
||||
|
||||
class ParcelsDecoder(private val parcel: Parcel) : Decoder, CompositeDecoder {
|
||||
@@ -36,6 +107,8 @@ object Parcels : AbstractSerialFormat(EmptyModule) {
|
||||
|
||||
override fun decodeElementIndex(desc: SerialDescriptor) =
|
||||
CompositeDecoder.READ_ALL
|
||||
override fun decodeCollectionSize(desc: SerialDescriptor) =
|
||||
decodeInt()
|
||||
|
||||
override fun decodeBooleanElement(desc: SerialDescriptor, index: Int) =
|
||||
decodeBoolean()
|
||||
@@ -88,57 +161,31 @@ object Parcels : AbstractSerialFormat(EmptyModule) {
|
||||
vararg typeParams: KSerializer<*>
|
||||
): CompositeDecoder = this
|
||||
|
||||
override fun decodeBoolean(): Boolean {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun decodeByte(): Byte {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun decodeChar(): Char {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun decodeDouble(): Double {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun decodeEnum(enumDescription: SerialDescriptor): Int {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun decodeFloat(): Float {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun decodeInt(): Int {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun decodeLong(): Long {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun decodeNotNullMark(): Boolean {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun decodeNull(): Nothing? {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun decodeShort(): Short {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun decodeString(): String {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override fun decodeUnit() {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
override fun decodeBoolean() =
|
||||
parcel.readByte() != 0.toByte()
|
||||
override fun decodeByte() =
|
||||
parcel.readByte()
|
||||
override fun decodeChar() =
|
||||
parcel.readInt().toChar()
|
||||
override fun decodeDouble() =
|
||||
parcel.readDouble()
|
||||
override fun decodeEnum(enumDescription: SerialDescriptor) =
|
||||
parcel.readInt()
|
||||
override fun decodeFloat() =
|
||||
parcel.readFloat()
|
||||
override fun decodeInt() =
|
||||
parcel.readInt()
|
||||
override fun decodeLong() =
|
||||
parcel.readLong()
|
||||
override fun decodeNotNullMark() =
|
||||
decodeBoolean()
|
||||
override fun decodeNull() =
|
||||
null
|
||||
override fun decodeShort() =
|
||||
parcel.readInt().toShort()
|
||||
override fun decodeString() =
|
||||
parcel.readString() ?: throw NullPointerException("String null")
|
||||
override fun decodeUnit() {}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,9 +12,9 @@ import android.os.ParcelFileDescriptor
|
||||
import com.github.kr328.clash.core.Clash
|
||||
import com.github.kr328.clash.core.event.*
|
||||
import com.github.kr328.clash.core.model.ProxyPacket
|
||||
import com.github.kr328.clash.core.model.RawProxyPacket
|
||||
import com.github.kr328.clash.core.utils.Log
|
||||
import com.github.kr328.clash.service.data.ClashDatabase
|
||||
import java.io.EOFException
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.util.concurrent.Executors
|
||||
@@ -40,14 +40,11 @@ class ClashService : Service(), IClashEventObserver, ClashEventService.Master,
|
||||
|
||||
override fun queryAllProxies(): ProxyPacket {
|
||||
return try {
|
||||
ProxyPacket(clash.queryProxies().proxies.mapValues {
|
||||
it.value.copy(history = it.value.history.take(1))
|
||||
})
|
||||
ProxyPacket.fromRawProxy(clash.queryProxies())
|
||||
} catch (e: Exception) {
|
||||
this@ClashService.eventService.preformErrorEvent(
|
||||
ErrorEvent(ErrorEvent.Type.QUERY_PROXY_FAILURE, e.toString())
|
||||
)
|
||||
|
||||
ProxyPacket(emptyMap())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user