[WIP] refactor services
This commit is contained in:
7 files changed
+136
-99
No files matched your search
@@ -1 +1,6 @@
|
||||
package bridge
|
||||
|
||||
type DoneCallback interface {
|
||||
Done()
|
||||
DoneWithError(error)
|
||||
}
|
||||
@@ -1,15 +1,64 @@
|
||||
package bridge
|
||||
|
||||
import "github.com/kr328/cfa/profile"
|
||||
import (
|
||||
"github.com/kr328/cfa/profile"
|
||||
"sync"
|
||||
)
|
||||
|
||||
func LoadProfileFile(path, baseDir string) error {
|
||||
return profile.LoadFromFile(path, baseDir)
|
||||
var mutex sync.Mutex
|
||||
|
||||
func LoadProfileFile(path, baseDir string, callback DoneCallback) {
|
||||
go func() {
|
||||
mutex.Lock()
|
||||
defer mutex.Unlock()
|
||||
|
||||
err := profile.LoadFromFile(path, baseDir)
|
||||
if err != nil {
|
||||
callback.DoneWithError(err)
|
||||
} else {
|
||||
callback.Done()
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func DownloadProfileAndCheck(url, output string) error {
|
||||
return profile.DownloadAndCheck(url, output)
|
||||
func DownloadProfileAndCheck(url, output, baseDir string, callback DoneCallback) {
|
||||
go func() {
|
||||
mutex.Lock()
|
||||
defer mutex.Unlock()
|
||||
|
||||
err := profile.DownloadAndCheck(url, output, baseDir)
|
||||
if err != nil {
|
||||
callback.DoneWithError(err)
|
||||
} else {
|
||||
callback.Done()
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func SaveProfileAndCheck(data []byte, output string) error {
|
||||
return profile.SaveAndCheck(data, output)
|
||||
func SaveProfileAndCheck(data []byte, output, baseDir string, callback DoneCallback) {
|
||||
go func() {
|
||||
mutex.Lock()
|
||||
defer mutex.Unlock()
|
||||
|
||||
err := profile.SaveAndCheck(data, output, baseDir)
|
||||
if err != nil {
|
||||
callback.DoneWithError(err)
|
||||
} else {
|
||||
callback.Done()
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func MoveProfileAndCheck(source, target, baseDir string, callback DoneCallback) {
|
||||
go func() {
|
||||
mutex.Lock()
|
||||
defer mutex.Unlock()
|
||||
|
||||
err := profile.MoveAndCheck(source, target, baseDir)
|
||||
if err != nil {
|
||||
callback.DoneWithError(err)
|
||||
} else {
|
||||
callback.Done()
|
||||
}
|
||||
}()
|
||||
}
|
||||
@@ -33,10 +33,6 @@ type ProxyCollection interface {
|
||||
Add(proxy *ProxyItem) bool
|
||||
}
|
||||
|
||||
type UrlTestCallback interface {
|
||||
Done()
|
||||
}
|
||||
|
||||
func (p *ProxyGroupItem) QueryAllProxies(collection ProxyCollection) {
|
||||
for _, v := range p.providers {
|
||||
for _, p := range v.Proxies() {
|
||||
@@ -51,7 +47,7 @@ func (p *ProxyGroupItem) QueryAllProxies(collection ProxyCollection) {
|
||||
}
|
||||
}
|
||||
|
||||
func StartUrlTest(group string, callback UrlTestCallback) {
|
||||
func StartUrlTest(group string, callback DoneCallback) {
|
||||
go func() {
|
||||
defer callback.Done()
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
"github.com/Dreamacro/clash/adapters/inbound"
|
||||
"github.com/Dreamacro/clash/component/socks5"
|
||||
@@ -43,7 +44,11 @@ var client = &http.Client{
|
||||
},
|
||||
}
|
||||
|
||||
func DownloadAndCheck(url, output string) error {
|
||||
func DownloadAndCheck(url, output, baseDir string) error {
|
||||
original := constant.Path.HomeDir()
|
||||
constant.SetHomeDir(baseDir)
|
||||
defer constant.SetHomeDir(original)
|
||||
|
||||
response, err := client.Get(url)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -63,7 +68,11 @@ func DownloadAndCheck(url, output string) error {
|
||||
return ioutil.WriteFile(output, data, defaultFileMode)
|
||||
}
|
||||
|
||||
func SaveAndCheck(data []byte, output string) error {
|
||||
func SaveAndCheck(data []byte, output, baseDir string) error {
|
||||
original := constant.Path.HomeDir()
|
||||
constant.SetHomeDir(baseDir)
|
||||
defer constant.SetHomeDir(original)
|
||||
|
||||
_, err := config.Parse(data)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -71,3 +80,27 @@ func SaveAndCheck(data []byte, output string) error {
|
||||
|
||||
return ioutil.WriteFile(output, data, defaultFileMode)
|
||||
}
|
||||
|
||||
func MoveAndCheck(source, target, baseDir string) error {
|
||||
original := constant.Path.HomeDir()
|
||||
constant.SetHomeDir(baseDir)
|
||||
defer constant.SetHomeDir(original)
|
||||
|
||||
buf, err := ioutil.ReadFile(source)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = config.Parse(buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := ioutil.WriteFile(target, buf, defaultFileMode); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
os.Remove(source)
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -10,6 +10,7 @@ import com.github.kr328.clash.core.event.TrafficEvent
|
||||
import com.github.kr328.clash.core.model.General
|
||||
import com.github.kr328.clash.core.model.Proxy
|
||||
import com.github.kr328.clash.core.model.ProxyGroup
|
||||
import com.github.kr328.clash.core.transact.DoneCallbackImpl
|
||||
import com.github.kr328.clash.core.transact.ProxyCollectionImpl
|
||||
import com.github.kr328.clash.core.transact.ProxyGroupCollectionImpl
|
||||
import java.io.InputStream
|
||||
@@ -20,13 +21,6 @@ class Clash(
|
||||
context: Context,
|
||||
private val listener: (ProcessEvent) -> Unit
|
||||
) {
|
||||
companion object {
|
||||
const val CLASH_DIR = "clash"
|
||||
|
||||
const val DEFAULT_URL_TEST_TIMEOUT = 5000
|
||||
const val DEFAULT_URL_TEST_URL = "https://www.gstatic.com/generate_204"
|
||||
}
|
||||
|
||||
class Poll(private val poll: EventPoll) {
|
||||
fun stop() {
|
||||
poll.stop()
|
||||
@@ -82,18 +76,30 @@ class Clash(
|
||||
Bridge.stopTunDevice()
|
||||
}
|
||||
|
||||
fun loadProfile(path: String, baseDir: String) {
|
||||
fun loadProfile(path: String, baseDir: String): CompletableFuture<Unit> {
|
||||
enforceStarted()
|
||||
|
||||
Bridge.loadProfileFile(path, baseDir)
|
||||
return DoneCallbackImpl().apply {
|
||||
Bridge.loadProfileFile(path, baseDir, this)
|
||||
}
|
||||
}
|
||||
|
||||
fun downloadProfile(url: String, output: String) {
|
||||
Bridge.downloadProfileAndCheck(url, output)
|
||||
fun downloadProfile(url: String, output: String, baseDir: String): CompletableFuture<Unit> {
|
||||
return DoneCallbackImpl().apply {
|
||||
Bridge.downloadProfileAndCheck(url, output, baseDir,this)
|
||||
}
|
||||
}
|
||||
|
||||
fun saveProfile(data: ByteArray, output: String) {
|
||||
Bridge.saveProfileAndCheck(data, output)
|
||||
fun saveProfile(data: ByteArray, output: String, baseDir: String): CompletableFuture<Unit> {
|
||||
return DoneCallbackImpl().apply {
|
||||
Bridge.saveProfileAndCheck(data, output, baseDir, this)
|
||||
}
|
||||
}
|
||||
|
||||
fun moveProfile(source: String, target: String, baseDir: String): CompletableFuture<Unit> {
|
||||
return DoneCallbackImpl().apply {
|
||||
Bridge.moveProfileAndCheck(source, target, baseDir, this)
|
||||
}
|
||||
}
|
||||
|
||||
fun queryProxyGroups(): List<ProxyGroup> {
|
||||
@@ -119,13 +125,9 @@ class Clash(
|
||||
}
|
||||
|
||||
fun startUrlTest(name: String): CompletableFuture<Unit> {
|
||||
val future = CompletableFuture<Unit>()
|
||||
|
||||
Bridge.startUrlTest(name) {
|
||||
future.complete(Unit)
|
||||
return DoneCallbackImpl().apply {
|
||||
Bridge.startUrlTest(name, this)
|
||||
}
|
||||
|
||||
return future
|
||||
}
|
||||
|
||||
fun queryGeneral(): General {
|
||||
|
||||
@@ -1,66 +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 com.github.kr328.clash.core.utils.Log
|
||||
import kotlinx.serialization.Serializable
|
||||
import java.lang.IllegalStateException
|
||||
|
||||
fun List<Proxy>.compress(): CompressedProxyList {
|
||||
val nameMap = this.toList().mapIndexed { index, proxy ->
|
||||
proxy.name to index
|
||||
}.toMap()
|
||||
|
||||
val elements = this.map {
|
||||
CompressedProxyList.Element(
|
||||
name = nameMap[it.name] ?: throw IllegalStateException("Unknown proxy ${it.name}"),
|
||||
type = it.type,
|
||||
now = nameMap[it.now] ?: -1,
|
||||
all = it.all.mapNotNull { name -> nameMap[name] },
|
||||
delay = it.delay
|
||||
)
|
||||
}
|
||||
|
||||
return CompressedProxyList(nameMap.entries.associate { (k, v) -> v to k }, elements)
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class CompressedProxyList(val proxyName: Map<Int, String>, val elements: List<Element>): Parcelable {
|
||||
@Serializable
|
||||
data class Element(val name: Int,
|
||||
val type: Proxy.Type,
|
||||
val now: Int,
|
||||
val all: List<Int>,
|
||||
val delay: Long)
|
||||
|
||||
fun uncompress(): List<Proxy> {
|
||||
return elements.map {
|
||||
Proxy(
|
||||
name = proxyName[it.name] ?: throw IllegalStateException("Unknown proxy $it"),
|
||||
type = it.type,
|
||||
now = proxyName[it.now] ?: "",
|
||||
all = it.all.mapNotNull { index -> proxyName[index] },
|
||||
delay = it.delay
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun writeToParcel(parcel: Parcel, flags: Int) {
|
||||
Parcels.dump(serializer(), this, parcel)
|
||||
}
|
||||
|
||||
override fun describeContents(): Int {
|
||||
return 0
|
||||
}
|
||||
|
||||
companion object CREATOR : Parcelable.Creator<CompressedProxyList> {
|
||||
override fun createFromParcel(parcel: Parcel): CompressedProxyList {
|
||||
return Parcels.load(serializer(), parcel)
|
||||
}
|
||||
|
||||
override fun newArray(size: Int): Array<CompressedProxyList?> {
|
||||
return arrayOfNulls(size)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.github.kr328.clash.core.transact
|
||||
|
||||
import bridge.DoneCallback
|
||||
import java.lang.Exception
|
||||
import java.util.concurrent.CompletableFuture
|
||||
|
||||
class DoneCallbackImpl : DoneCallback, CompletableFuture<Unit>() {
|
||||
override fun doneWithError(e: Exception?) {
|
||||
if ( e == null )
|
||||
complete(Unit)
|
||||
else
|
||||
completeExceptionally(e)
|
||||
}
|
||||
|
||||
override fun done() {
|
||||
complete(Unit)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user