1
1
@@ -1,21 +0,0 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 sail-tunnel
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -1 +0,0 @@
|
||||
include: package:flutter_lints/flutter.yaml
|
||||
@@ -1,13 +0,0 @@
|
||||
gradle-wrapper.jar
|
||||
/.gradle
|
||||
/captures/
|
||||
/gradlew
|
||||
/gradlew.bat
|
||||
/local.properties
|
||||
GeneratedPluginRegistrant.java
|
||||
|
||||
# Remember to never publicly share your keystore.
|
||||
# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
|
||||
key.properties
|
||||
**/*.keystore
|
||||
**/*.jks
|
||||
@@ -1,108 +0,0 @@
|
||||
def localProperties = new Properties()
|
||||
def localPropertiesFile = rootProject.file('local.properties')
|
||||
if (localPropertiesFile.exists()) {
|
||||
localPropertiesFile.withReader('UTF-8') { reader ->
|
||||
localProperties.load(reader)
|
||||
}
|
||||
}
|
||||
|
||||
def flutterRoot = localProperties.getProperty('flutter.sdk')
|
||||
if (flutterRoot == null) {
|
||||
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
|
||||
}
|
||||
|
||||
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
|
||||
if (flutterVersionCode == null) {
|
||||
flutterVersionCode = '1'
|
||||
}
|
||||
|
||||
def flutterVersionName = localProperties.getProperty('flutter.versionName')
|
||||
if (flutterVersionName == null) {
|
||||
flutterVersionName = '1.0'
|
||||
}
|
||||
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply plugin: 'kotlin-parcelize'
|
||||
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
|
||||
|
||||
android {
|
||||
compileSdk 34
|
||||
ndkVersion flutter.ndkVersion
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = '1.8'
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main.java.srcDirs += 'src/main/kotlin'
|
||||
main.jniLibs.srcDirs = ['libs', 'src/main/jniLibs']
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
||||
applicationId "com.vpntunnel.vpnzeus"
|
||||
// You can update the following values to match your application needs.
|
||||
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration.
|
||||
minSdkVersion 28
|
||||
//noinspection ExpiredTargetSdkVersion
|
||||
// targetSdkVersion 34
|
||||
compileSdk 34
|
||||
versionCode flutterVersionCode.toInteger()
|
||||
versionName flutterVersionName
|
||||
// ndk {
|
||||
// abiFilters 'armeabi', 'armeabi-v7a', 'arm64-v8a', 'x86', "x86_64"
|
||||
// }
|
||||
// dexOptions {
|
||||
// incremental true
|
||||
// javaMaxHeapSize "4g"
|
||||
// preDexLibraries true
|
||||
// dexInProcess = true
|
||||
// }
|
||||
ndk {
|
||||
if (!project.hasProperty('target-platform')) {
|
||||
abiFilters 'arm64-v8a', 'armeabi-v7a', 'x86_64'
|
||||
} else {
|
||||
def platforms = project.property('target-platform').split(',')
|
||||
def platformMap = [
|
||||
'android-arm' : 'armeabi-v7a',
|
||||
'android-arm64': 'arm64-v8a',
|
||||
'android-x86' : 'x86',
|
||||
'android-x64' : 'x86_64',
|
||||
]
|
||||
abiFilters = platforms.stream().map({ e ->
|
||||
platformMap.containsKey(e) ? platformMap[e] : e
|
||||
}).toArray()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
// TODO: Add your own signing config for the release build.
|
||||
// Signing with the debug keys for now, so `flutter run --release` works.
|
||||
signingConfig signingConfigs.debug
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
flutter {
|
||||
source '../..'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||
implementation "com.jakewharton.timber:timber:5.0.1"
|
||||
implementation 'androidx.work:work-runtime-ktx:2.7.1'
|
||||
implementation 'androidx.preference:preference-ktx:1.2.0'
|
||||
implementation "dnsjava:dnsjava:3.5.1"
|
||||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.6.4"
|
||||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4"
|
||||
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1"
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
{
|
||||
"version": 3,
|
||||
"artifactType": {
|
||||
"type": "APK",
|
||||
"kind": "Directory"
|
||||
},
|
||||
"applicationId": "com.sail_tunnel.sail",
|
||||
"variantName": "profile",
|
||||
"elements": [
|
||||
{
|
||||
"type": "SINGLE",
|
||||
"filters": [],
|
||||
"attributes": [],
|
||||
"versionCode": 3,
|
||||
"versionName": "1.0.2",
|
||||
"outputFile": "app-profile.apk"
|
||||
}
|
||||
],
|
||||
"elementType": "File"
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.sail_tunnel.sail">
|
||||
<!-- The INTERNET permission is required for development. Specifically,
|
||||
the Flutter tool needs it to communicate with the running application
|
||||
to allow setting breakpoints, to provide hot reload, etc.
|
||||
-->
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
|
||||
</manifest>
|
||||
@@ -1,87 +0,0 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.sail_tunnel.sail">
|
||||
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
|
||||
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
|
||||
<uses-permission android:name="android.permission.READ_PHONE_NUMBERS" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK"></uses-permission>
|
||||
|
||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
|
||||
<uses-permission android:name="android.permission.SYSTEM_OVERLAY_WINDOW"/>
|
||||
|
||||
|
||||
<uses-feature
|
||||
android:name="android.software.leanback"
|
||||
android:required="false" />
|
||||
<uses-feature
|
||||
android:name="android.hardware.touchscreen"
|
||||
android:required="false" />
|
||||
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission
|
||||
android:name="android.permission.QUERY_ALL_PACKAGES"
|
||||
/>
|
||||
|
||||
<application
|
||||
android:label="UUVPN"
|
||||
android:name="${applicationName}"
|
||||
android:icon="@mipmap/app_icon"
|
||||
android:largeHeap="true"
|
||||
android:supportsRtl="true"
|
||||
android:allowBackup="true"
|
||||
android:hardwareAccelerated="false">
|
||||
<!-- android:icon="@mipmap/ic_launcher"-->
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:exported="true"
|
||||
android:launchMode="singleTop"
|
||||
android:theme="@style/LaunchTheme"
|
||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
|
||||
android:hardwareAccelerated="false"
|
||||
android:windowSoftInputMode="adjustResize"
|
||||
>
|
||||
<!-- Specifies an Android theme to apply to this Activity as soon as
|
||||
the Android process has started. This theme is visible to the user
|
||||
while the Flutter UI initializes. After that, this theme continues
|
||||
to determine the Window background behind the Flutter UI. -->
|
||||
<meta-data
|
||||
android:name="io.flutter.embedding.android.NormalTheme"
|
||||
android:resource="@style/NormalTheme"
|
||||
/>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<service
|
||||
android:name=".TunnelService"
|
||||
android:enabled="true"
|
||||
|
||||
android:permission="android.permission.BIND_VPN_SERVICE"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="android.net.VpnService"/>
|
||||
</intent-filter>
|
||||
</service>
|
||||
|
||||
<!-- Don't delete the meta-data below.
|
||||
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
|
||||
<meta-data
|
||||
android:name="flutterEmbedding"
|
||||
android:value="2"/>
|
||||
</application>
|
||||
</manifest>
|
||||
@@ -1,54 +0,0 @@
|
||||
package com.sail_tunnel.sail
|
||||
|
||||
import android.app.*
|
||||
import android.content.*
|
||||
import android.net.ConnectivityManager
|
||||
import android.util.Log
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import androidx.core.content.getSystemService
|
||||
import kotlinx.coroutines.DEBUG_PROPERTY_NAME
|
||||
import kotlinx.coroutines.DEBUG_PROPERTY_VALUE_ON
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import kotlin.reflect.KClass
|
||||
import androidx.work.Configuration
|
||||
import com.sail_tunnel.sail.utils.DeviceStorageApp
|
||||
|
||||
object Core : Configuration.Provider {
|
||||
lateinit var app: MainActivity
|
||||
@VisibleForTesting set
|
||||
lateinit var configureIntent: (Context) -> PendingIntent
|
||||
val activity by lazy { app.getSystemService<ActivityManager>()!! }
|
||||
val connectivity by lazy { app.getSystemService<ConnectivityManager>()!! }
|
||||
|
||||
val deviceStorage by lazy { DeviceStorageApp(app) }
|
||||
|
||||
fun init(app: MainActivity, configureClass: KClass<out Any>) {
|
||||
this.app = app
|
||||
this.configureIntent = {
|
||||
PendingIntent.getActivity(it, 0, Intent(it, configureClass.java)
|
||||
.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT), PendingIntent.FLAG_IMMUTABLE)
|
||||
}
|
||||
|
||||
// overhead of debug mode is minimal: https://github.com/Kotlin/kotlinx.coroutines/blob/f528898/docs/debugging.md#debug-mode
|
||||
System.setProperty(DEBUG_PROPERTY_NAME, DEBUG_PROPERTY_VALUE_ON)
|
||||
|
||||
Timber.plant(object : Timber.DebugTree() {
|
||||
override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {
|
||||
if (t == null) {
|
||||
if (priority != Log.DEBUG || BuildConfig.DEBUG) Log.println(priority, tag, message)
|
||||
} else {
|
||||
if (priority >= Log.WARN || priority == Log.DEBUG) Log.println(priority, tag, message)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun getWorkManagerConfiguration() = Configuration.Builder().apply {
|
||||
setDefaultProcessName(app.packageName + ":bg")
|
||||
setMinimumLoggingLevel(if (BuildConfig.DEBUG) Log.VERBOSE else Log.INFO)
|
||||
setExecutor { GlobalScope.launch { it.run() } }
|
||||
setTaskExecutor { GlobalScope.launch { it.run() } }
|
||||
}.build()
|
||||
}
|
||||
@@ -1,160 +0,0 @@
|
||||
package com.sail_tunnel.sail
|
||||
|
||||
import android.content.Context
|
||||
import android.content.ContextWrapper
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.net.ConnectivityManager
|
||||
import android.net.NetworkCapabilities
|
||||
import android.net.VpnService
|
||||
import android.os.BatteryManager
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import com.sail_tunnel.sail.services.VpnState
|
||||
import io.flutter.embedding.android.FlutterActivity
|
||||
import io.flutter.embedding.android.FlutterView
|
||||
import io.flutter.embedding.engine.FlutterEngine
|
||||
import io.flutter.embedding.engine.plugins.util.GeneratedPluginRegister
|
||||
import io.flutter.plugin.common.MethodChannel
|
||||
|
||||
import io.flutter.plugins.GeneratedPluginRegistrant
|
||||
import java.io.File
|
||||
|
||||
class MainActivity: FlutterActivity() {
|
||||
private val channel = "com.vpntunnel.vpnzeus/vpn_manager"
|
||||
|
||||
private fun getServiceIntent(): Intent {
|
||||
return Intent(this, TunnelService::class.java)
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
Core.init(this, MainActivity::class)
|
||||
|
||||
GeneratedPluginRegistrant.registerWith(FlutterEngine(this))
|
||||
GeneratedPluginRegister.registerGeneratedPlugins(FlutterEngine(this));
|
||||
|
||||
// MethodChannel(FlutterView(this), channel).setMethodCallHandler { call, result ->
|
||||
// if (call.method == "getBatteryLevel") {
|
||||
// val batteryLevel : Int = getBatteryLevel()
|
||||
//
|
||||
// if (batteryLevel != -1) {
|
||||
// result.success(batteryLevel)
|
||||
// } else {
|
||||
// result.error("UNAVAILABLE", "Battery level not available.", null)
|
||||
// }
|
||||
// } else {
|
||||
// Log.e("user_debug", "getBatteryLevel is not method of called")
|
||||
// result.notImplemented()
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
private fun getBatteryLevel(): Int {
|
||||
val batteryLevel: Int
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
|
||||
val batteryManager = getSystemService(Context.BATTERY_SERVICE) as BatteryManager
|
||||
batteryLevel = batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY)
|
||||
} else {
|
||||
val intent = ContextWrapper(applicationContext).registerReceiver(null, IntentFilter(Intent.ACTION_BATTERY_CHANGED))
|
||||
batteryLevel = intent!!.getIntExtra(BatteryManager.EXTRA_LEVEL, -1) * 100 / intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1)
|
||||
}
|
||||
return batteryLevel
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
|
||||
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
|
||||
}
|
||||
|
||||
private fun getVPNConnectionStatus(): Boolean? {
|
||||
val context = this@MainActivity
|
||||
val connectivityManager =
|
||||
context.getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager
|
||||
val networks = connectivityManager.allNetworks
|
||||
//val TAG = "getVPNConnectionStatus"
|
||||
//Log.i(TAG, "Network count: " + networks.size);
|
||||
var hasvpn = false
|
||||
for (i in 0 until networks.size) {
|
||||
// connectivityManager.getNetworkCapabilities()
|
||||
val caps: NetworkCapabilities? = connectivityManager.getNetworkCapabilities(networks.get(i))
|
||||
|
||||
hasvpn = caps?.hasTransport(NetworkCapabilities.TRANSPORT_VPN) == true
|
||||
|
||||
// Log.i(TAG, "Network " + i + ": " + networks.get(i).toString())
|
||||
// Log.i(TAG, "VPN transport is: " + caps?.hasTransport(NetworkCapabilities.TRANSPORT_VPN))
|
||||
// Log.i(TAG, "NOT_VPN capability is: " + caps?.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN) )
|
||||
}
|
||||
return hasvpn
|
||||
|
||||
|
||||
|
||||
// val activeNetwork = connectivityManager.activeNetwork
|
||||
// val networkCapabilities = connectivityManager.getNetworkCapabilities(activeNetwork)
|
||||
//
|
||||
// return networkCapabilities?.hasTransport(NetworkCapabilities.TRANSPORT_VPN)
|
||||
}
|
||||
|
||||
override fun configureFlutterEngine( flutterEngine: FlutterEngine) {
|
||||
super.configureFlutterEngine(flutterEngine)
|
||||
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, channel).setMethodCallHandler {
|
||||
call, result ->
|
||||
// This method is invoked on the main thread.
|
||||
if (call.method == "getStatus") {
|
||||
result.success(getVPNConnectionStatus())
|
||||
} else if (call.method == "toggle") {
|
||||
val intent = VpnService.prepare(this)
|
||||
if (intent != null) {
|
||||
startActivityForResult(intent, 0)
|
||||
result.success(false)
|
||||
} else {
|
||||
startService(getServiceIntent())
|
||||
result.success(true)
|
||||
}
|
||||
} else if (call.method == "getTunnelLog") {
|
||||
// val context = Core.deviceStorage
|
||||
// val configRoot = context.noBackupFilesDir
|
||||
// val config = File(configRoot, VpnState.LEAF_LOG_FILE).readText()
|
||||
// result.success(config)
|
||||
} else if (call.method == "getTunnelConfiguration") {
|
||||
val context = Core.deviceStorage
|
||||
val configRoot = context.noBackupFilesDir
|
||||
val config = File(configRoot, VpnState.CONFIG_FILE).readText()
|
||||
val TAGs = "getVPNConnectionStatus"
|
||||
Log.i(TAGs, config);
|
||||
result.success(config)
|
||||
} else if (call.method == "setTunnelConfiguration") {
|
||||
try {
|
||||
val context = Core.deviceStorage
|
||||
val configRoot = context.noBackupFilesDir
|
||||
val TAGs = "setTunnelConfiguration"
|
||||
Log.i(TAGs, call.arguments.toString());
|
||||
File(configRoot, VpnState.CONFIG_FILE).writeText(call.arguments.toString())
|
||||
}catch (e: Exception ){
|
||||
println("setTunnelConfiguration FILE NullPointerException")
|
||||
}
|
||||
|
||||
|
||||
} else if (call.method == "update") {
|
||||
//
|
||||
} else {
|
||||
result.notImplemented()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onActivityResult(request: Int, result: Int, data: Intent?) {
|
||||
if (result == RESULT_OK) {
|
||||
startService(getServiceIntent())
|
||||
} else {
|
||||
super.onActivityResult(request, result, data)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,251 +0,0 @@
|
||||
package com.sail_tunnel.sail
|
||||
|
||||
import android.app.Notification
|
||||
import android.app.NotificationChannel
|
||||
import android.app.NotificationManager
|
||||
import android.app.PendingIntent
|
||||
import android.app.Service
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.graphics.BitmapFactory
|
||||
import android.media.projection.MediaProjection
|
||||
import android.media.projection.MediaProjectionManager
|
||||
import android.net.*
|
||||
import android.os.Build
|
||||
import android.os.ParcelFileDescriptor
|
||||
import androidx.core.app.NotificationCompat
|
||||
import com.sail_tunnel.sail.net.DefaultNetworkListener
|
||||
import com.sail_tunnel.sail.net.DnsResolverCompat
|
||||
import com.sail_tunnel.sail.services.LocalDnsWorker
|
||||
import com.sail_tunnel.sail.services.TunnelInstance
|
||||
import com.sail_tunnel.sail.services.VpnState
|
||||
import com.sail_tunnel.sail.utils.readableMessage
|
||||
import kotlinx.coroutines.*
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
|
||||
class TunnelService : VpnService() {
|
||||
companion object {
|
||||
private const val CORE_NAME = "leaf"
|
||||
private const val VPN_MTU = 1500
|
||||
private const val PRIVATE_VLAN4_CLIENT = "198.18.20.20"
|
||||
private const val PRIVATE_VLAN4_ROUTER = "1.1.1.1"
|
||||
}
|
||||
|
||||
inner class NullConnectionException : NullPointerException() {
|
||||
override fun getLocalizedMessage() =
|
||||
"Failed to start VPN service. You might need to reboot your device."
|
||||
}
|
||||
|
||||
private val data = VpnState.Data()
|
||||
|
||||
private fun startRunner() {
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 26) startForegroundService(Intent(this, javaClass))
|
||||
else startService(Intent(this, javaClass))
|
||||
}
|
||||
|
||||
private var pfd: ParcelFileDescriptor? = null
|
||||
private var active = false
|
||||
private var metered = false
|
||||
|
||||
|
||||
var notification: Notification? = null
|
||||
private val mResultData: Intent? = null
|
||||
private val mMediaProjection: MediaProjection? = null
|
||||
private val mMediaProjectionManager: MediaProjectionManager? = null
|
||||
|
||||
|
||||
@Volatile
|
||||
private var underlyingNetwork: Network? = null
|
||||
set(value) {
|
||||
field = value
|
||||
if (active) setUnderlyingNetworks(underlyingNetworks)
|
||||
}
|
||||
private val underlyingNetworks
|
||||
get() =
|
||||
// clearing underlyingNetworks makes Android 9 consider the network to be metered
|
||||
if (Build.VERSION.SDK_INT == 28 && metered) null else underlyingNetwork?.let {
|
||||
arrayOf(
|
||||
it
|
||||
)
|
||||
}
|
||||
|
||||
override fun onRevoke() = stopRunner()
|
||||
|
||||
private fun killProcesses(scope: CoroutineScope) {
|
||||
data.proxy?.run {
|
||||
shutdown(scope)
|
||||
data.proxy = null
|
||||
}
|
||||
data.localDns?.shutdown(scope)
|
||||
data.localDns = null
|
||||
|
||||
active = false
|
||||
scope.launch { DefaultNetworkListener.stop(this) }
|
||||
pfd?.close()
|
||||
pfd = null
|
||||
}
|
||||
|
||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||
val data = data
|
||||
if (data.state != VpnState.State.Stopped) return Service.START_NOT_STICKY
|
||||
|
||||
try {
|
||||
data.proxy = TunnelInstance()
|
||||
} catch (e: IllegalArgumentException) {
|
||||
stopRunner(false, e.message)
|
||||
return Service.START_NOT_STICKY
|
||||
}
|
||||
createNotificationChannel()
|
||||
data.changeState(VpnState.State.Connecting)
|
||||
data.connectingJob = GlobalScope.launch(Dispatchers.Main) {
|
||||
try {
|
||||
preInit()
|
||||
|
||||
startVpn()
|
||||
|
||||
data.changeState(VpnState.State.Connected)
|
||||
} catch (_: CancellationException) {
|
||||
// if the job was cancelled, it is canceller's responsibility to call stopRunner
|
||||
} catch (exc: Throwable) {
|
||||
stopRunner(false, exc.readableMessage)
|
||||
} finally {
|
||||
data.connectingJob = null
|
||||
}
|
||||
}
|
||||
|
||||
return START_NOT_STICKY
|
||||
}
|
||||
|
||||
|
||||
private fun createNotificationChannel() {
|
||||
val CHANNEL_ID: String = "notification_id"
|
||||
val builder = NotificationCompat.Builder(this.applicationContext,CHANNEL_ID) //获取一个Notification构造器
|
||||
val nfIntent = Intent(this, MainActivity::class.java) //点击后跳转的界面,可以设置跳转数据
|
||||
val pendingIntent: PendingIntent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
PendingIntent.getActivity(this, 0, nfIntent, PendingIntent.FLAG_IMMUTABLE)
|
||||
} else {
|
||||
PendingIntent.getActivity(this, 0, nfIntent, PendingIntent.FLAG_ONE_SHOT)
|
||||
}
|
||||
|
||||
val intentClick = Intent(
|
||||
this,MainActivity::class.java
|
||||
// BroadcastReceiver::class.java
|
||||
)
|
||||
|
||||
|
||||
intentClick.action = "notification_clicked"
|
||||
// intentClick.putExtra(BroadcastReceiver.TYPE, type)
|
||||
val pendingIntentClick =
|
||||
PendingIntent.getBroadcast(this, 0, intentClick, PendingIntent.FLAG_ONE_SHOT)
|
||||
|
||||
|
||||
//.setContentIntent(pendingIntent) // 设置PendingIntent
|
||||
builder.setContentIntent(pendingIntentClick).setLargeIcon(
|
||||
BitmapFactory.decodeResource(
|
||||
this.resources,
|
||||
R.mipmap.app_icon_round
|
||||
)
|
||||
) // 设置下拉列表中的图标(大图标)
|
||||
.setContentTitle("UUVPN") // 设置下拉列表里的标题
|
||||
.setSmallIcon( R.mipmap.app_icon_round) // 设置状态栏内的小图标
|
||||
.setContentText("正在运行...") // 设置上下文内容
|
||||
.setWhen(System.currentTimeMillis()) // 设置该通知发生的时间
|
||||
|
||||
/*以下是对Android 8.0的适配*/
|
||||
//普通notification适配
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
builder.setChannelId("notification_id")
|
||||
}
|
||||
|
||||
|
||||
//前台服务notification适配
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
|
||||
val channel = NotificationChannel(
|
||||
"notification_id",
|
||||
"notification_name",
|
||||
NotificationManager.IMPORTANCE_LOW
|
||||
)
|
||||
|
||||
|
||||
// Register the channel with the system
|
||||
val notificationManager: NotificationManager =
|
||||
getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||
notificationManager.createNotificationChannel(channel)
|
||||
|
||||
}
|
||||
|
||||
notification = builder.build() // 获取构建好的Notification
|
||||
// notification.defaulte = Notification.DEFAULT_SOUND //设置为默认的声音
|
||||
try {
|
||||
startForeground(110, notification)
|
||||
} catch (w: Exception) {
|
||||
w.printStackTrace()
|
||||
}
|
||||
}
|
||||
private suspend fun preInit() = DefaultNetworkListener.start(this) { underlyingNetwork = it }
|
||||
private suspend fun rawResolver(query: ByteArray) =
|
||||
// no need to listen for network here as this is only used for forwarding local DNS queries.
|
||||
// retries should be attempted by client.
|
||||
DnsResolverCompat.resolveRaw(underlyingNetwork ?: throw IOException("no network"), query)
|
||||
|
||||
private suspend fun startVpn() {
|
||||
val builder = Builder()
|
||||
.setConfigureIntent(Core.configureIntent(this))
|
||||
.setSession(CORE_NAME)
|
||||
.setMtu(VPN_MTU)
|
||||
.addAddress(PRIVATE_VLAN4_CLIENT, 24)
|
||||
.addDnsServer(PRIVATE_VLAN4_ROUTER)
|
||||
.addRoute("0.0.0.0", 0)
|
||||
|
||||
active = true // possible race condition here?
|
||||
builder.setUnderlyingNetworks(underlyingNetworks)
|
||||
if (Build.VERSION.SDK_INT >= 29) builder.setMetered(metered)
|
||||
|
||||
this.pfd = builder.establish() ?: throw NullConnectionException()
|
||||
|
||||
val context = Core.deviceStorage
|
||||
val configRoot = context.noBackupFilesDir
|
||||
|
||||
data.localDns = LocalDnsWorker(this::rawResolver).apply { start() }
|
||||
|
||||
val configFile = File(configRoot, VpnState.CONFIG_FILE)
|
||||
val configContent = configFile
|
||||
.readText()
|
||||
.replace("{{leafLogFile}}", File(configRoot, VpnState.LEAF_LOG_FILE).absolutePath)
|
||||
.replace("{{tunFd}}", this.pfd?.fd?.toLong().toString())
|
||||
|
||||
configFile.writeText(configContent)
|
||||
|
||||
data.proxy!!.start(
|
||||
this,
|
||||
File(Core.deviceStorage.noBackupFilesDir, "stat_main"),
|
||||
configFile,
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
private fun stopRunner(restart: Boolean = false, msg: String? = null) {
|
||||
if (data.state == VpnState.State.Stopping) return
|
||||
// channge the state
|
||||
data.changeState(VpnState.State.Stopping)
|
||||
GlobalScope.launch(Dispatchers.Main.immediate) {
|
||||
data.connectingJob?.cancelAndJoin() // ensure stop connecting first
|
||||
// we use a coroutineScope here to allow clean-up in parallel
|
||||
coroutineScope {
|
||||
killProcesses(GlobalScope)
|
||||
}
|
||||
|
||||
// change the state
|
||||
data.changeState(VpnState.State.Stopped, msg)
|
||||
|
||||
// stop the service if nothing has bound to it
|
||||
if (restart) startRunner() else {
|
||||
stopSelf()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
package com.sail_tunnel.sail.net
|
||||
|
||||
import android.net.LocalSocket
|
||||
import kotlinx.coroutines.*
|
||||
import timber.log.Timber
|
||||
import java.io.File
|
||||
|
||||
abstract class ConcurrentLocalSocketListener(name: String, socketFile: File) : LocalSocketListener(name, socketFile),
|
||||
CoroutineScope {
|
||||
override val coroutineContext = Dispatchers.IO + SupervisorJob() + CoroutineExceptionHandler { _, t -> Timber.w(t) }
|
||||
|
||||
override fun accept(socket: LocalSocket) {
|
||||
launch { super.accept(socket) }
|
||||
}
|
||||
|
||||
override fun shutdown(scope: CoroutineScope) {
|
||||
running = false
|
||||
cancel()
|
||||
super.shutdown(scope)
|
||||
coroutineContext[Job]!!.also { job -> scope.launch { job.join() } }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,126 +0,0 @@
|
||||
package com.sail_tunnel.sail.net
|
||||
|
||||
import android.annotation.TargetApi
|
||||
import android.net.ConnectivityManager
|
||||
import android.net.Network
|
||||
import android.net.NetworkCapabilities
|
||||
import android.net.NetworkRequest
|
||||
import android.os.Build
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import androidx.annotation.RequiresApi
|
||||
import com.sail_tunnel.sail.Core
|
||||
import kotlinx.coroutines.CompletableDeferred
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.channels.actor
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import java.net.UnknownHostException
|
||||
|
||||
object DefaultNetworkListener {
|
||||
private sealed class NetworkMessage {
|
||||
class Start(val key: Any, val listener: (Network?) -> Unit) : NetworkMessage()
|
||||
class Get : NetworkMessage() {
|
||||
val response = CompletableDeferred<Network>()
|
||||
}
|
||||
class Stop(val key: Any) : NetworkMessage()
|
||||
|
||||
class Put(val network: Network) : NetworkMessage()
|
||||
class Update(val network: Network) : NetworkMessage()
|
||||
class Lost(val network: Network) : NetworkMessage()
|
||||
}
|
||||
|
||||
private val networkActor = GlobalScope.actor<NetworkMessage>(Dispatchers.Unconfined) {
|
||||
val listeners = mutableMapOf<Any, (Network?) -> Unit>()
|
||||
var network: Network? = null
|
||||
val pendingRequests = arrayListOf<NetworkMessage.Get>()
|
||||
for (message in channel) when (message) {
|
||||
is NetworkMessage.Start -> {
|
||||
if (listeners.isEmpty()) register()
|
||||
listeners[message.key] = message.listener
|
||||
if (network != null) message.listener(network)
|
||||
}
|
||||
is NetworkMessage.Get -> {
|
||||
check(listeners.isNotEmpty()) { "Getting network without any listeners is not supported" }
|
||||
if (network == null) pendingRequests += message else message.response.complete(network)
|
||||
}
|
||||
is NetworkMessage.Stop -> if (listeners.isNotEmpty() && // was not empty
|
||||
listeners.remove(message.key) != null && listeners.isEmpty()) {
|
||||
network = null
|
||||
unregister()
|
||||
}
|
||||
|
||||
is NetworkMessage.Put -> {
|
||||
network = message.network
|
||||
pendingRequests.forEach { it.response.complete(message.network) }
|
||||
pendingRequests.clear()
|
||||
listeners.values.forEach { it(network) }
|
||||
}
|
||||
is NetworkMessage.Update -> if (network == message.network) listeners.values.forEach { it(network) }
|
||||
is NetworkMessage.Lost -> if (network == message.network) {
|
||||
network = null
|
||||
listeners.values.forEach { it(null) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun start(key: Any, listener: (Network?) -> Unit) = networkActor.send(NetworkMessage.Start(key, listener))
|
||||
suspend fun get() = if (fallback) {
|
||||
Core.connectivity.activeNetwork ?: throw UnknownHostException() // failed to listen, return current if available
|
||||
} else NetworkMessage.Get().run {
|
||||
networkActor.send(this)
|
||||
response.await()
|
||||
}
|
||||
suspend fun stop(key: Any) = networkActor.send(NetworkMessage.Stop(key))
|
||||
|
||||
// NB: this runs in ConnectivityThread, and this behavior cannot be changed until API 26
|
||||
private object Callback : ConnectivityManager.NetworkCallback() {
|
||||
override fun onAvailable(network: Network) = runBlocking { networkActor.send(NetworkMessage.Put(network)) }
|
||||
override fun onCapabilitiesChanged(network: Network, networkCapabilities: NetworkCapabilities) {
|
||||
// it's a good idea to refresh capabilities
|
||||
runBlocking { networkActor.send(NetworkMessage.Update(network)) }
|
||||
}
|
||||
override fun onLost(network: Network) = runBlocking { networkActor.send(NetworkMessage.Lost(network)) }
|
||||
}
|
||||
|
||||
private var fallback = false
|
||||
private val request = NetworkRequest.Builder().apply {
|
||||
addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
|
||||
addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
|
||||
}.build()
|
||||
private val mainHandler = Handler(Looper.getMainLooper())
|
||||
|
||||
/**
|
||||
* Unfortunately registerDefaultNetworkCallback is going to return VPN interface since Android P DP1:
|
||||
* https://android.googlesource.com/platform/frameworks/base/+/dda156ab0c5d66ad82bdcf76cda07cbc0a9c8a2e
|
||||
*
|
||||
* This makes doing a requestNetwork with REQUEST necessary so that we don't get ALL possible networks that
|
||||
* satisfies default network capabilities but only THE default network. Unfortunately, we need to have
|
||||
* android.permission.CHANGE_NETWORK_STATE to be able to call requestNetwork.
|
||||
*
|
||||
* Source: https://android.googlesource.com/platform/frameworks/base/+/2df4c7d/services/core/java/com/android/server/ConnectivityService.java#887
|
||||
*/
|
||||
private fun register() {
|
||||
when (Build.VERSION.SDK_INT) {
|
||||
in 31..Int.MAX_VALUE -> @TargetApi(31) {
|
||||
Core.connectivity.registerBestMatchingNetworkCallback(request, Callback, mainHandler)
|
||||
}
|
||||
in 28 until 31 -> @TargetApi(28) { // we want REQUEST here instead of LISTEN
|
||||
Core.connectivity.requestNetwork(request, Callback, mainHandler)
|
||||
}
|
||||
in 26 until 28 -> @TargetApi(26) {
|
||||
Core.connectivity.registerDefaultNetworkCallback(Callback, mainHandler)
|
||||
}
|
||||
in 24 until 26 -> {
|
||||
Core.connectivity.registerDefaultNetworkCallback(Callback)
|
||||
}
|
||||
else -> try {
|
||||
fallback = false
|
||||
Core.connectivity.requestNetwork(request, Callback)
|
||||
} catch (e: RuntimeException) {
|
||||
fallback = true // known bug on API 23: https://stackoverflow.com/a/33509180/2245107
|
||||
}
|
||||
}
|
||||
}
|
||||
private fun unregister() = Core.connectivity.unregisterNetworkCallback(Callback)
|
||||
}
|
||||
@@ -1,167 +0,0 @@
|
||||
package com.sail_tunnel.sail.net
|
||||
|
||||
import android.annotation.TargetApi
|
||||
import android.net.DnsResolver
|
||||
import android.net.Network
|
||||
import android.os.Build
|
||||
import android.os.CancellationSignal
|
||||
import androidx.annotation.RequiresApi
|
||||
import com.sail_tunnel.sail.Core
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.asCoroutineDispatcher
|
||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.xbill.DNS.*
|
||||
import java.io.IOException
|
||||
import java.net.Inet4Address
|
||||
import java.net.Inet6Address
|
||||
import java.net.InetAddress
|
||||
import java.util.concurrent.Executor
|
||||
import java.util.concurrent.Executors
|
||||
import kotlin.coroutines.resume
|
||||
import kotlin.coroutines.resumeWithException
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
sealed class DnsResolverCompat {
|
||||
companion object : DnsResolverCompat() {
|
||||
private val instance by lazy {
|
||||
when (Build.VERSION.SDK_INT) {
|
||||
in 29..Int.MAX_VALUE -> DnsResolverCompat29
|
||||
in 23 until 29 -> DnsResolverCompat23
|
||||
else -> error("Unsupported API level")
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun resolve(network: Network, host: String) = instance.resolve(network, host)
|
||||
override suspend fun resolveOnActiveNetwork(host: String) = instance.resolveOnActiveNetwork(host)
|
||||
override suspend fun resolveRaw(network: Network, query: ByteArray) = instance.resolveRaw(network, query)
|
||||
override suspend fun resolveRawOnActiveNetwork(query: ByteArray) = instance.resolveRawOnActiveNetwork(query)
|
||||
|
||||
// additional platform-independent DNS helpers
|
||||
|
||||
/**
|
||||
* TTL returned from localResolver is set to 120. Android API does not provide TTL,
|
||||
* so we suppose Android apps should not care about TTL either.
|
||||
*/
|
||||
private const val TTL = 120L
|
||||
|
||||
fun prepareDnsResponse(request: Message) = Message(request.header.id).apply {
|
||||
header.setFlag(Flags.QR.toInt()) // this is a response
|
||||
header.setFlag(Flags.RA.toInt()) // recursion available
|
||||
if (request.header.getFlag(Flags.RD.toInt())) header.setFlag(Flags.RD.toInt())
|
||||
request.question?.also { addRecord(it, Section.QUESTION) }
|
||||
}
|
||||
}
|
||||
|
||||
abstract suspend fun resolve(network: Network, host: String): Array<InetAddress>
|
||||
abstract suspend fun resolveOnActiveNetwork(host: String): Array<InetAddress>
|
||||
abstract suspend fun resolveRaw(network: Network, query: ByteArray): ByteArray
|
||||
abstract suspend fun resolveRawOnActiveNetwork(query: ByteArray): ByteArray
|
||||
|
||||
private object DnsResolverCompat23 : DnsResolverCompat() {
|
||||
/**
|
||||
* This dispatcher is used for noncancellable possibly-forever-blocking operations in network IO.
|
||||
*
|
||||
* See also: https://issuetracker.google.com/issues/133874590
|
||||
*/
|
||||
private val unboundedIO by lazy {
|
||||
if (Core.activity.isLowRamDevice) Dispatchers.IO
|
||||
else Executors.newCachedThreadPool().asCoroutineDispatcher()
|
||||
}
|
||||
|
||||
override suspend fun resolve(network: Network, host: String) =
|
||||
withContext(unboundedIO) { network.getAllByName(host) }
|
||||
override suspend fun resolveOnActiveNetwork(host: String) =
|
||||
withContext(unboundedIO) { InetAddress.getAllByName(host) }
|
||||
|
||||
private suspend fun resolveRaw(query: ByteArray, networkSpecified: Boolean = true,
|
||||
hostResolver: suspend (String) -> Array<InetAddress>): ByteArray {
|
||||
val request = try {
|
||||
Message(query)
|
||||
} catch (e: IOException) {
|
||||
throw UnsupportedOperationException(e) // unrecognized packet
|
||||
}
|
||||
when (val opcode = request.header.opcode) {
|
||||
Opcode.QUERY -> { }
|
||||
else -> throw UnsupportedOperationException("Unsupported opcode $opcode")
|
||||
}
|
||||
val question = request.question
|
||||
val isIpv6 = when (val type = question?.type) {
|
||||
Type.A -> false
|
||||
Type.AAAA -> true
|
||||
Type.PTR -> {
|
||||
/* Android does not provide a PTR lookup API for Network prior to Android 10 */
|
||||
if (networkSpecified) throw IOException(UnsupportedOperationException("Network unspecified"))
|
||||
val ip = try {
|
||||
ReverseMap.fromName(question.name)
|
||||
} catch (e: IOException) {
|
||||
throw UnsupportedOperationException(e) // unrecognized PTR name
|
||||
}
|
||||
val hostname = withContext(unboundedIO) { ip.hostName }.let { hostname ->
|
||||
if (hostname == ip.hostAddress) null else Name.fromString("$hostname.")
|
||||
}
|
||||
return prepareDnsResponse(request).apply {
|
||||
hostname?.let { addRecord(PTRRecord(question.name, DClass.IN, TTL, it), Section.ANSWER) }
|
||||
}.toWire()
|
||||
}
|
||||
else -> throw UnsupportedOperationException("Unsupported query type $type")
|
||||
}
|
||||
val host = question.name.canonicalize().toString(true)
|
||||
return prepareDnsResponse(request).apply {
|
||||
for (address in hostResolver(host).asIterable().run {
|
||||
if (isIpv6) filterIsInstance<Inet6Address>() else filterIsInstance<Inet4Address>()
|
||||
}) addRecord(when (address) {
|
||||
is Inet4Address -> ARecord(question.name, DClass.IN, TTL, address)
|
||||
is Inet6Address -> AAAARecord(question.name, DClass.IN, TTL, address)
|
||||
else -> error("Unsupported address $address")
|
||||
}, Section.ANSWER)
|
||||
}.toWire()
|
||||
}
|
||||
override suspend fun resolveRaw(network: Network, query: ByteArray) =
|
||||
resolveRaw(query) { resolve(network, it) }
|
||||
override suspend fun resolveRawOnActiveNetwork(query: ByteArray) =
|
||||
resolveRaw(query, false, this::resolveOnActiveNetwork)
|
||||
}
|
||||
|
||||
@TargetApi(29)
|
||||
private object DnsResolverCompat29 : DnsResolverCompat(), Executor {
|
||||
/**
|
||||
* This executor will run on its caller directly. On Q beta 3 thru 4, this results in calling in main thread.
|
||||
*/
|
||||
override fun execute(command: Runnable) = command.run()
|
||||
|
||||
private val activeNetwork get() = Core.connectivity.activeNetwork ?: throw IOException("no network")
|
||||
|
||||
override suspend fun resolve(network: Network, host: String): Array<InetAddress> {
|
||||
return suspendCancellableCoroutine { cont ->
|
||||
val signal = CancellationSignal()
|
||||
cont.invokeOnCancellation { signal.cancel() }
|
||||
// retry should be handled by client instead
|
||||
DnsResolver.getInstance().query(network, host, DnsResolver.FLAG_NO_RETRY, this,
|
||||
signal, object : DnsResolver.Callback<Collection<InetAddress>> {
|
||||
override fun onAnswer(answer: Collection<InetAddress>, rcode: Int) =
|
||||
cont.resume(answer.toTypedArray())
|
||||
override fun onError(error: DnsResolver.DnsException) = cont.resumeWithException(
|
||||
IOException(error)
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
override suspend fun resolveOnActiveNetwork(host: String) = resolve(activeNetwork, host)
|
||||
|
||||
override suspend fun resolveRaw(network: Network, query: ByteArray): ByteArray {
|
||||
return suspendCancellableCoroutine { cont ->
|
||||
val signal = CancellationSignal()
|
||||
cont.invokeOnCancellation { signal.cancel() }
|
||||
DnsResolver.getInstance().rawQuery(network, query, DnsResolver.FLAG_NO_RETRY, this,
|
||||
signal, object : DnsResolver.Callback<ByteArray> {
|
||||
override fun onAnswer(answer: ByteArray, rcode: Int) = cont.resume(answer)
|
||||
override fun onError(error: DnsResolver.DnsException) = cont.resumeWithException(
|
||||
IOException(error)
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
override suspend fun resolveRawOnActiveNetwork(query: ByteArray) = resolveRaw(activeNetwork, query)
|
||||
}
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
package com.sail_tunnel.sail.net
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.net.LocalServerSocket
|
||||
import android.net.LocalSocket
|
||||
import android.net.LocalSocketAddress
|
||||
import android.system.ErrnoException
|
||||
import android.system.Os
|
||||
import android.system.OsConstants
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.channels.onFailure
|
||||
import kotlinx.coroutines.channels.trySendBlocking
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
|
||||
abstract class LocalSocketListener(name: String, socketFile: File) : Thread(name) {
|
||||
private val localSocket = LocalSocket().apply {
|
||||
socketFile.delete() // It's a must-have to close and reuse previous local socket.
|
||||
bind(LocalSocketAddress(socketFile.absolutePath, LocalSocketAddress.Namespace.FILESYSTEM))
|
||||
}
|
||||
private val serverSocket = LocalServerSocket(localSocket.fileDescriptor)
|
||||
private val closeChannel = Channel<Unit>(1)
|
||||
@Volatile
|
||||
protected var running = true
|
||||
|
||||
/**
|
||||
* Inherited class do not need to close input/output streams as they will be closed automatically.
|
||||
*/
|
||||
protected open fun accept(socket: LocalSocket) = socket.use { acceptInternal(socket) }
|
||||
protected abstract fun acceptInternal(socket: LocalSocket)
|
||||
final override fun run() {
|
||||
localSocket.use {
|
||||
while (running) {
|
||||
try {
|
||||
accept(serverSocket.accept())
|
||||
} catch (e: IOException) {
|
||||
if (running) Timber.w(e)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
closeChannel.trySendBlocking(Unit).onFailure { throw it!! }
|
||||
}
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
open fun shutdown(scope: CoroutineScope) {
|
||||
running = false
|
||||
localSocket.fileDescriptor?.apply {
|
||||
// see also: https://issuetracker.google.com/issues/36945762#comment15
|
||||
if (valid()) try {
|
||||
Os.shutdown(this, OsConstants.SHUT_RDWR)
|
||||
} catch (e: ErrnoException) {
|
||||
// suppress fd inactive or already closed
|
||||
if (e.errno != OsConstants.EBADF && e.errno != OsConstants.ENOTCONN) throw e.rethrowAsSocketException()
|
||||
}
|
||||
}
|
||||
scope.launch { closeChannel.receive() }
|
||||
}
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
package com.sail_tunnel.sail.services
|
||||
|
||||
import android.net.LocalSocket
|
||||
import android.os.Build
|
||||
import androidx.annotation.RequiresApi
|
||||
import com.sail_tunnel.sail.Core
|
||||
import com.sail_tunnel.sail.net.ConcurrentLocalSocketListener
|
||||
import com.sail_tunnel.sail.net.DnsResolverCompat
|
||||
import com.sail_tunnel.sail.utils.readableMessage
|
||||
import kotlinx.coroutines.CancellationException
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.TimeoutCancellationException
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import java.io.DataInputStream
|
||||
import java.io.DataOutputStream
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import org.xbill.DNS.Message
|
||||
import org.xbill.DNS.Rcode
|
||||
|
||||
class LocalDnsWorker(private val resolver: suspend (ByteArray) -> ByteArray) : ConcurrentLocalSocketListener(
|
||||
"LocalDnsThread", File(Core.deviceStorage.noBackupFilesDir, "local_dns_path")
|
||||
), CoroutineScope {
|
||||
override fun acceptInternal(socket: LocalSocket) = error("big no no")
|
||||
override fun accept(socket: LocalSocket) {
|
||||
launch {
|
||||
socket.use {
|
||||
val input = DataInputStream(socket.inputStream)
|
||||
val query = try {
|
||||
ByteArray(input.readUnsignedShort()).also { input.read(it) }
|
||||
} catch (e: IOException) { // connection early close possibly due to resolving timeout
|
||||
return@use Timber.d(e)
|
||||
}
|
||||
try {
|
||||
resolver(query)
|
||||
} catch (e: Exception) {
|
||||
when (e) {
|
||||
is TimeoutCancellationException -> Timber.w("Resolving timed out")
|
||||
is CancellationException -> { } // ignore
|
||||
is IOException -> Timber.d(e)
|
||||
is UnsupportedOperationException -> Timber.w(e.message)
|
||||
else -> Timber.w(e)
|
||||
}
|
||||
try {
|
||||
DnsResolverCompat.prepareDnsResponse(Message(query)).apply {
|
||||
header.rcode = Rcode.SERVFAIL
|
||||
}.toWire()
|
||||
} catch (_: IOException) {
|
||||
byteArrayOf() // return empty if cannot parse packet
|
||||
}
|
||||
}.let { response ->
|
||||
try {
|
||||
val output = DataOutputStream(socket.outputStream)
|
||||
output.writeShort(response.size)
|
||||
output.write(response)
|
||||
} catch (e: IOException) {
|
||||
Timber.d(e.readableMessage)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
package com.sail_tunnel.sail.services
|
||||
|
||||
import android.net.LocalSocket
|
||||
import android.os.SystemClock
|
||||
import com.sail_tunnel.sail.net.LocalSocketListener
|
||||
import com.sail_tunnel.sail.utils.TrafficStats
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.nio.ByteBuffer
|
||||
import java.nio.ByteOrder
|
||||
|
||||
class TrafficMonitor(statFile: File) {
|
||||
val thread = object : LocalSocketListener("TrafficMonitor-" + statFile.name, statFile) {
|
||||
private val buffer = ByteArray(16)
|
||||
private val stat = ByteBuffer.wrap(buffer).order(ByteOrder.LITTLE_ENDIAN)
|
||||
override fun acceptInternal(socket: LocalSocket) {
|
||||
when (val read = socket.inputStream.read(buffer)) {
|
||||
-1 -> return
|
||||
16 -> { }
|
||||
else -> throw IOException("Unexpected traffic stat length $read")
|
||||
}
|
||||
val tx = stat.getLong(0)
|
||||
val rx = stat.getLong(8)
|
||||
if (current.txTotal != tx) {
|
||||
current.txTotal = tx
|
||||
dirty = true
|
||||
}
|
||||
if (current.rxTotal != rx) {
|
||||
current.rxTotal = rx
|
||||
dirty = true
|
||||
}
|
||||
}
|
||||
}.apply { start() }
|
||||
|
||||
val current = TrafficStats()
|
||||
var out = TrafficStats()
|
||||
private var timestampLast = 0L
|
||||
private var dirty = false
|
||||
private var persisted: TrafficStats? = null
|
||||
|
||||
fun requestUpdate(): Pair<TrafficStats, Boolean> {
|
||||
val now = SystemClock.elapsedRealtime()
|
||||
val delta = now - timestampLast
|
||||
timestampLast = now
|
||||
var updated = false
|
||||
if (delta != 0L) {
|
||||
if (dirty) {
|
||||
out = current.copy().apply {
|
||||
txRate = (txTotal - out.txTotal) * 1024 / delta
|
||||
rxRate = (rxTotal - out.rxTotal) * 1024 / delta
|
||||
}
|
||||
dirty = false
|
||||
updated = true
|
||||
} else {
|
||||
if (out.txRate != 0L) {
|
||||
out.txRate = 0
|
||||
updated = true
|
||||
}
|
||||
if (out.rxRate != 0L) {
|
||||
out.rxRate = 0
|
||||
updated = true
|
||||
}
|
||||
}
|
||||
}
|
||||
return Pair(out, updated)
|
||||
}
|
||||
|
||||
fun persistStats() {
|
||||
val current = current
|
||||
check(persisted == null || persisted == current) { "Data loss occurred" }
|
||||
persisted = current
|
||||
|
||||
// try {
|
||||
// // profile may have host, etc. modified and thus a re-fetch is necessary (possible race condition)
|
||||
// val profile = ProfileManager.getProfile(id) ?: return
|
||||
// profile.tx += current.txTotal
|
||||
// profile.rx += current.rxTotal
|
||||
// ProfileManager.updateProfile(profile)
|
||||
// } catch (e: IOException) {
|
||||
// if (!DataStore.directBootAware) throw e // we should only reach here because we're in direct boot
|
||||
// val profile = DirectBoot.getDeviceProfile()!!.toList().single { it.id == id }
|
||||
// profile.tx += current.txTotal
|
||||
// profile.rx += current.rxTotal
|
||||
// profile.dirty = true
|
||||
// DirectBoot.update(profile)
|
||||
// DirectBoot.listenForUnlock()
|
||||
// }
|
||||
}
|
||||
}
|
||||
@@ -1,106 +0,0 @@
|
||||
package com.sail_tunnel.sail.services
|
||||
|
||||
import android.net.LocalServerSocket
|
||||
import android.net.LocalSocket
|
||||
import android.net.LocalSocketAddress
|
||||
import android.system.Os
|
||||
import com.sail_tunnel.sail.Core
|
||||
import com.sail_tunnel.sail.TunnelService
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import timber.log.Timber
|
||||
import java.io.File
|
||||
import java.nio.ByteBuffer
|
||||
import kotlin.concurrent.thread
|
||||
|
||||
class TunnelInstance() {
|
||||
private var configFile: File? = null
|
||||
var trafficMonitor: TrafficMonitor? = null
|
||||
|
||||
private val rtId: Int = 666
|
||||
|
||||
init {
|
||||
System.loadLibrary("leaf")
|
||||
}
|
||||
|
||||
private external fun leafRun(rtId: Int, configPath: String)
|
||||
private external fun leafReload(rtId: Int)
|
||||
private external fun leafShutdown(rtId: Int)
|
||||
private external fun leafTestConfig(configPath: String)
|
||||
|
||||
/**
|
||||
* Sensitive shadowsocks configuration file requires extra protection. It may be stored in encrypted storage or
|
||||
* device storage, depending on which is currently available.
|
||||
*/
|
||||
fun start(
|
||||
service: TunnelService,
|
||||
stat: File,
|
||||
configFile: File,
|
||||
) {
|
||||
// setup traffic monitor path
|
||||
trafficMonitor = TrafficMonitor(stat)
|
||||
|
||||
Timber.i("start process")
|
||||
|
||||
val context = Core.deviceStorage
|
||||
val configRoot = context.noBackupFilesDir //noBackupFilesDir
|
||||
val protectPath =
|
||||
File.createTempFile("socket_protect", ".sock", configRoot).absolutePath
|
||||
|
||||
Os.setenv("SOCKET_PROTECT_PATH", protectPath, true)
|
||||
|
||||
println("protectPath: $protectPath")
|
||||
|
||||
thread (start = true) {
|
||||
val localSocket = LocalSocket()
|
||||
localSocket.bind(
|
||||
LocalSocketAddress(
|
||||
protectPath,
|
||||
LocalSocketAddress.Namespace.FILESYSTEM
|
||||
)
|
||||
)
|
||||
val socket = LocalServerSocket(localSocket.fileDescriptor)
|
||||
val buffer = ByteBuffer.allocate(4)
|
||||
|
||||
while (true) {
|
||||
val stream = socket.accept()
|
||||
buffer.clear()
|
||||
val n = stream.inputStream.read(buffer.array())
|
||||
|
||||
System.out.write(n)
|
||||
|
||||
if (n == 4) {
|
||||
val fd = buffer.int
|
||||
if (!service.protect(fd)) {
|
||||
println("protect failed")
|
||||
}
|
||||
buffer.clear()
|
||||
buffer.putInt(0)
|
||||
} else {
|
||||
buffer.clear()
|
||||
buffer.putInt(1)
|
||||
}
|
||||
stream.outputStream.write(buffer.array())
|
||||
}
|
||||
}
|
||||
|
||||
// start tunnel program
|
||||
thread(start = true) {
|
||||
leafRun(rtId, configFile.absolutePath)
|
||||
}
|
||||
}
|
||||
|
||||
fun shutdown(scope: CoroutineScope) {
|
||||
trafficMonitor?.apply {
|
||||
thread.shutdown(scope)
|
||||
persistStats() // Make sure update total traffic when stopping the runner
|
||||
}
|
||||
trafficMonitor = null
|
||||
configFile?.delete() // remove old config possibly in device storage
|
||||
configFile = null
|
||||
|
||||
// stop tunnel program
|
||||
thread(start = true, isDaemon = true) {
|
||||
leafShutdown(rtId)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
package com.sail_tunnel.sail.services
|
||||
|
||||
import kotlinx.coroutines.Job
|
||||
|
||||
object VpnState {
|
||||
enum class State {
|
||||
/**
|
||||
* Idle state is only used by UI and will never be returned by BaseService.
|
||||
*/
|
||||
Idle,
|
||||
Connecting,
|
||||
Connected,
|
||||
Stopping,
|
||||
Stopped,
|
||||
}
|
||||
|
||||
const val CONFIG_FILE = "leaf.conf"
|
||||
const val LEAF_LOG_FILE = "leaf.log"
|
||||
|
||||
class Data internal constructor() {
|
||||
var state = State.Stopped
|
||||
var proxy: TunnelInstance? = null
|
||||
var localDns: LocalDnsWorker? = null
|
||||
|
||||
var connectingJob: Job? = null
|
||||
|
||||
fun changeState(s: State, msg: String? = null) {
|
||||
if (state == s && msg == null) return
|
||||
state = s
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
package com.sail_tunnel.sail.utils
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Application
|
||||
import android.content.Context
|
||||
|
||||
@SuppressLint("Registered")
|
||||
class DeviceStorageApp(context: Context) : Application() {
|
||||
init {
|
||||
attachBaseContext(context.createDeviceProtectedStorageContext())
|
||||
}
|
||||
|
||||
/**
|
||||
* Thou shalt not get the REAL underlying application context which would no longer be operating under device
|
||||
* protected storage.
|
||||
*/
|
||||
override fun getApplicationContext() = this
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
package com.sail_tunnel.sail.utils
|
||||
|
||||
import android.os.Parcelable
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
@Parcelize
|
||||
data class TrafficStats(
|
||||
// Bytes per second
|
||||
var txRate: Long = 0L,
|
||||
var rxRate: Long = 0L,
|
||||
|
||||
// Bytes for the current session
|
||||
var txTotal: Long = 0L,
|
||||
var rxTotal: Long = 0L
|
||||
) : Parcelable {
|
||||
operator fun plus(other: TrafficStats) = TrafficStats(
|
||||
txRate + other.txRate, rxRate + other.rxRate,
|
||||
txTotal + other.txTotal, rxTotal + other.rxTotal
|
||||
)
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
package com.sail_tunnel.sail.utils
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.os.Build
|
||||
import kotlinx.coroutines.*
|
||||
import java.io.FileDescriptor
|
||||
import java.net.HttpURLConnection
|
||||
import kotlin.coroutines.resume
|
||||
import kotlin.coroutines.resumeWithException
|
||||
|
||||
val Throwable.readableMessage: String get() = localizedMessage ?: javaClass.name
|
||||
|
||||
/**
|
||||
* https://android.googlesource.com/platform/prebuilts/runtime/+/94fec32/appcompat/hiddenapi-light-greylist.txt#9466
|
||||
*/
|
||||
@SuppressLint("DiscouragedPrivateApi")
|
||||
private val getInt = FileDescriptor::class.java.getDeclaredMethod("getInt$")
|
||||
val FileDescriptor.int get() = getInt.invoke(this) as Int
|
||||
|
||||
suspend fun <T> HttpURLConnection.useCancellable(block: suspend HttpURLConnection.() -> T): T {
|
||||
return suspendCancellableCoroutine { cont ->
|
||||
cont.invokeOnCancellation {
|
||||
if (Build.VERSION.SDK_INT >= 26) disconnect() else GlobalScope.launch(Dispatchers.IO) { disconnect() }
|
||||
}
|
||||
GlobalScope.launch(Dispatchers.IO) {
|
||||
try {
|
||||
cont.resume(block())
|
||||
} catch (e: Throwable) {
|
||||
cont.resumeWithException(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Modify this file to customize your launch splash screen -->
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="?android:colorBackground" />
|
||||
|
||||
<!-- You can insert your own image assets here -->
|
||||
<!-- <item>
|
||||
<bitmap
|
||||
android:gravity="center"
|
||||
android:src="@mipmap/launch_image" />
|
||||
</item> -->
|
||||
</layer-list>
|
||||
@@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Modify this file to customize your launch splash screen -->
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@android:color/white" />
|
||||
|
||||
<!-- You can insert your own image assets here -->
|
||||
<!-- <item>
|
||||
<bitmap
|
||||
android:gravity="center"
|
||||
android:src="@mipmap/launch_image" />
|
||||
</item> -->
|
||||
</layer-list>
|
||||
|
Before Width: | Height: | Size: 6.5 KiB |
|
Before Width: | Height: | Size: 6.5 KiB |
|
Before Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 9.3 KiB |
|
Before Width: | Height: | Size: 9.3 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 24 KiB |
@@ -1,18 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->
|
||||
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
|
||||
<!-- Show a splash screen on the activity. Automatically removed when
|
||||
the Flutter engine draws its first frame -->
|
||||
<item name="android:windowBackground">@drawable/launch_background</item>
|
||||
</style>
|
||||
<!-- Theme applied to the Android Window as soon as the process has started.
|
||||
This theme determines the color of the Android Window while your
|
||||
Flutter UI initializes, as well as behind your Flutter UI while its
|
||||
running.
|
||||
|
||||
This Theme is only used starting with V2 of Flutter's Android embedding. -->
|
||||
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
|
||||
<item name="android:windowBackground">?android:colorBackground</item>
|
||||
</style>
|
||||
</resources>
|
||||
@@ -1,18 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
|
||||
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
|
||||
<!-- Show a splash screen on the activity. Automatically removed when
|
||||
the Flutter engine draws its first frame -->
|
||||
<item name="android:windowBackground">@drawable/launch_background</item>
|
||||
</style>
|
||||
<!-- Theme applied to the Android Window as soon as the process has started.
|
||||
This theme determines the color of the Android Window while your
|
||||
Flutter UI initializes, as well as behind your Flutter UI while its
|
||||
running.
|
||||
|
||||
This Theme is only used starting with V2 of Flutter's Android embedding. -->
|
||||
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
|
||||
<item name="android:windowBackground">?android:colorBackground</item>
|
||||
</style>
|
||||
</resources>
|
||||
@@ -1,10 +0,0 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.sail_tunnel.sail">
|
||||
<!-- The INTERNET permission is required for development. Specifically,
|
||||
the Flutter tool needs it to communicate with the running application
|
||||
to allow setting breakpoints, to provide hot reload, etc.
|
||||
-->
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
|
||||
</manifest>
|
||||
@@ -1,31 +0,0 @@
|
||||
buildscript {
|
||||
ext.kotlin_version = '1.6.10'
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:7.1.3'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
|
||||
rootProject.buildDir = '../build'
|
||||
subprojects {
|
||||
project.buildDir = "${rootProject.buildDir}/${project.name}"
|
||||
}
|
||||
subprojects {
|
||||
project.evaluationDependsOn(':app')
|
||||
}
|
||||
|
||||
tasks.register("clean", Delete) {
|
||||
delete rootProject.buildDir
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
org.gradle.jvmargs=-Xmx1536M
|
||||
android.useAndroidX=true
|
||||
android.enableJetifier=true
|
||||
android.suppressUnsupportedCompileSdk=33
|
||||
@@ -1,5 +0,0 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip
|
||||
@@ -1,11 +0,0 @@
|
||||
include ':app'
|
||||
|
||||
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
|
||||
def properties = new Properties()
|
||||
|
||||
assert localPropertiesFile.exists()
|
||||
localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
|
||||
|
||||
def flutterSdkPath = properties.getProperty("flutter.sdk")
|
||||
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
|
||||
apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
|
||||
@@ -1,10 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg viewBox="0 0 36 17.2" xmlns="http://www.w3.org/2000/svg">
|
||||
<linearGradient id="a" gradientUnits="userSpaceOnUse" x1="-15.5" x2="59.992" y1="10" y2="75.024" gradientTransform="matrix(1.056419, 0, 0, 1, -59.971069, -0.317375)">
|
||||
<stop offset="0" stop-color="#62c"/>
|
||||
<stop offset="1" stop-color="#301060"/>
|
||||
</linearGradient>
|
||||
<g fill="url(#a)" transform="matrix(1, 0, 0, 1, -1.853645, -1.351658)">
|
||||
<path d="M 27.827 3.42 C 27.585 3.297 27.307 3.264 27.043 3.327 C 26.77 3.396 26.527 3.551 26.349 3.771 L 24.595 5.858 L 21.485 2.156 C 21.231 1.853 20.885 1.683 20.526 1.683 C 20.166 1.683 19.821 1.853 19.567 2.156 L 16.457 5.858 L 14.703 3.771 C 14.526 3.552 14.282 3.397 14.009 3.329 C 13.745 3.266 13.468 3.299 13.225 3.421 C 12.977 3.543 12.765 3.75 12.616 4.015 C 12.465 4.289 12.387 4.598 12.388 4.912 L 12.388 13.459 C 12.388 14.529 12.746 15.555 13.382 16.312 C 14.018 17.069 14.88 17.494 15.779 17.496 L 25.273 17.496 C 26.173 17.494 27.034 17.069 27.67 16.312 C 28.306 15.555 28.663 14.529 28.664 13.459 L 28.664 4.912 C 28.664 4.592 28.585 4.281 28.436 4.015 C 28.298 3.759 28.086 3.552 27.827 3.42 L 27.827 3.42 Z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.2 KiB |
@@ -1,3 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="22" fill="none" viewBox="0 0 20 22">
|
||||
<path fill="#AE77FF" d="M16.64 9.39a2.112 2.112 0 00-1.925 1.25h-.97L12.69 7.478a.859.859 0 00-1.64.035l-1.454 5.086L7.721 1.593a.86.86 0 00-1.68-.067L3.704 10.64H1.25v1.718h3.125a.86.86 0 00.834-.65l1.498-5.99 1.82 10.688a.86.86 0 00.8.718h.048a.86.86 0 00.826-.625l1.737-5.845.372 1.118a.859.859 0 00.815.586h1.59a2.11 2.11 0 101.926-2.968z"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 451 B |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 1.7 KiB |
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 900 600"><path fill="#EE1C25" d="M0 0h900v600H0z"/><g id="a"><path d="M449.964 299.913c-105.263-44.486-58.602-181.581 42.07-174.69-20.366 10.467-23.318 29.997-11.687 48.09 13.024 20.256-1.2 52.848-18.806 60.767-28.935 13.025-34.728 47.75-11.577 65.833z" fill="#fff"/><path d="M444.272 200.92l-5.92 9.294-2.144-10.815-10.679-2.759 9.625-5.39-.671-10.999 8.085 7.49 10.256-4.043-4.61 10.01 7.001 8.505zm6.288 97.839c-12.731-6.534-22.996-20.155-27.468-36.431-5.115-18.67-2.173-38.743 8.083-55.038l-2.208-1.394c-10.64 16.929-13.693 37.743-8.386 57.12 4.728 17.221 15.214 31.097 28.787 38.064z" fill="#EE1C25"/></g><use xlink:href="#a" transform="rotate(72 450 300)"/><use xlink:href="#a" transform="rotate(144 450 300)"/><use xlink:href="#a" transform="rotate(216 450 300)"/><use xlink:href="#a" transform="rotate(288 450 300)"/></svg>
|
||||
|
Before Width: | Height: | Size: 927 B |
@@ -1 +0,0 @@
|
||||
<svg viewBox="0 0 900 600" xmlns="http://www.w3.org/2000/svg"><path d="m0 0h900v600h-900z" fill="#fff"/><circle cx="450" cy="300" fill="#bc002d" r="180"/></svg>
|
||||
|
Before Width: | Height: | Size: 160 B |
@@ -1 +0,0 @@
|
||||
<svg viewBox="0 0 900 600" xmlns="http://www.w3.org/2000/svg"><g fill-rule="evenodd"><path d="m0 0h900v600h-900z" fill="#fe0000"/><path d="m0 0h450v300h-450z" fill="#000095"/></g><g fill="#fff"><path d="m225 37.5-56.25 209.928 153.678-153.678-209.928 56.25 209.928 56.25-153.678-153.678 56.25 209.928 56.25-209.928-153.678 153.678 209.928-56.25-209.928-56.25 153.678 153.678z"/><circle cx="225" cy="150" r="60" stroke="#000095" stroke-width="7.5"/></g></svg>
|
||||
|
Before Width: | Height: | Size: 458 B |
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 7410 3900"><path fill="#b22234" d="M0 0h7410v3900H0z"/><path d="M0 450h7410m0 600H0m0 600h7410m0 600H0m0 600h7410m0 600H0" stroke="#fff" stroke-width="300"/><path fill="#3c3b6e" d="M0 0h2964v2100H0z"/><g fill="#fff"><g id="d"><g id="c"><g id="e"><g id="b"><path id="a" d="M247 90l70.534 217.082-184.66-134.164h228.253L176.466 307.082z"/><use xlink:href="#a" y="420"/><use xlink:href="#a" y="840"/><use xlink:href="#a" y="1260"/></g><use xlink:href="#a" y="1680"/></g><use xlink:href="#b" x="247" y="210"/></g><use xlink:href="#c" x="494"/></g><use xlink:href="#d" x="988"/><use xlink:href="#c" x="1976"/><use xlink:href="#e" x="2470"/></g></svg>
|
||||
|
Before Width: | Height: | Size: 741 B |
@@ -1 +0,0 @@
|
||||
<svg fill="none" height="20" viewBox="0 0 20 20" width="20" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><clipPath id="a"><path d="m0 0h20v20h-20z"/></clipPath><g clip-path="url(#a)" fill="#ae77ff"><path d="m10 5a.833.833 0 0 0 -.833.833v4.167c0 .221.088.433.244.59l2.5 2.5a.833.833 0 0 0 1.178-1.18l-2.256-2.255v-3.822a.833.833 0 0 0 -.833-.833z"/><path d="m19.844 8.443a10 10 0 0 0 -16.862-5.597v-2.013a.833.833 0 0 0 -1.667 0v3.334a1.667 1.667 0 0 0 1.667 1.666h3.333a.833.833 0 1 0 0-1.666h-2.292a8.325 8.325 0 1 1 -2.363 6.565.818.818 0 0 0 -.826-.732.839.839 0 0 0 -.834.917 10 10 0 1 0 19.84-2.474z"/></g></svg>
|
||||
|
Before Width: | Height: | Size: 651 B |
@@ -1,4 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" fill="none" viewBox="0 0 22 22">
|
||||
<path fill="#B5AEBE" d="M21.484 9.6l-7.79-8.422a3.667 3.667 0 00-5.385 0L.533 9.597A1.833 1.833 0 000 10.889v8.347a2.75 2.75 0 002.75 2.75h3.667v-5.5a4.57 4.57 0 012.409-4.01l.139-.075a4.55 4.55 0 01.528-.223c.124-.045.25-.084.379-.117.129-.034.285-.065.431-.092.081-.013.156-.04.239-.049a4.53 4.53 0 01.417-.017c.014 0 .027-.005.041-.005h.017c.283.002.566.031.845.086.03.006.062.009.091.015.262.057.517.137.765.239.035.013.07.026.104.042.237.102.465.225.68.366l.102.068c.21.146.407.309.59.487l.085.086c.179.184.343.382.49.592l.062.092c.144.219.27.45.375.69l.034.092c.104.253.186.515.243.784 0 .02.007.04.01.061.06.292.09.59.09.888v5.5h3.667a2.75 2.75 0 002.75-2.75v-8.36c0-.477-.185-.934-.516-1.277z"/>
|
||||
<path fill="#B5AEBE" d="M11 13.736a2.75 2.75 0 00-2.75 2.75v5.5h5.5v-5.5a2.75 2.75 0 00-2.75-2.75z"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 913 B |
@@ -1,3 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="17" height="15" fill="none" viewBox="0 0 17 15">
|
||||
<path fill="#AE77FF" d="M3.727 15H.309V.781h3.418V15zm1.982 0V.781h4.58c1.257 0 2.386.287 3.39.86a5.934 5.934 0 012.343 2.412c.566 1.035.853 2.197.86 3.486v.654c0 1.302-.277 2.471-.83 3.506a6.03 6.03 0 01-2.325 2.422c-.996.58-2.11.872-3.34.879H5.71zM9.137 3.428v8.935h1.191c.984 0 1.739-.348 2.266-1.045.527-.703.791-1.744.791-3.125v-.615c0-1.374-.264-2.409-.79-3.105-.528-.697-1.296-1.045-2.306-1.045H9.138z"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 517 B |
@@ -1 +0,0 @@
|
||||
<svg fill="none" height="56" viewBox="0 0 56 56" width="56" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="-4.2" x2="36.4" y1="-22.4" y2="99.4"><stop offset="0" stop-color="#62c"/><stop offset="1" stop-color="#0b0415"/></linearGradient><path clip-rule="evenodd" d="m50.423 5.823a3.865 3.865 0 0 1 2.698.329c.852.433 1.58 1.166 2.093 2.107a6.67 6.67 0 0 1 .786 3.177v30.268c-.004 3.79-1.234 7.424-3.421 10.104s-5.153 4.188-8.246 4.192h-32.666c-3.093-.005-6.059-1.512-8.246-4.192s-3.417-6.314-3.421-10.104v-30.268c0-1.131.274-2.236.787-3.177.513-.939 1.241-1.673 2.093-2.105a3.876 3.876 0 0 1 2.696-.326c.905.22 1.736.765 2.389 1.565l6.035 7.394 10.7-13.113c.877-1.072 2.064-1.674 3.3-1.674 1.237 0 2.424.602 3.3 1.674l10.7 13.113 6.034-7.394c.652-.802 1.483-1.349 2.39-1.57zm-22.42 15.18c5.95.07 10.86 4.515 11.684 10.285.072.538.107 1.111.107 1.685 0 .573-.035 1.183-.107 1.756-.789 5.268-5.018 9.426-10.358 10.071h-10.967v-18.637h3.44v15.232h7.276c3.548-.537 6.38-3.225 7.097-6.666a7.363 7.363 0 0 0 .215-1.756c0-.574-.072-1.147-.18-1.685a8.589 8.589 0 0 0 -3.225-5.125c-1.326-1.003-2.975-1.613-4.767-1.72h-9.856v-3.44h9.64z" fill="url(#a)" fill-rule="evenodd"/></svg>
|
||||
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.7 KiB |
@@ -1,11 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg viewBox="0 0 16.3 15.8" xmlns="http://www.w3.org/2000/svg">
|
||||
<linearGradient id="a" gradientUnits="userSpaceOnUse" x1="-15.5" x2="59.992" y1="10" y2="75.024" gradientTransform="matrix(1.056419, 0, 0, 1, -60.033002, -0.422793)">
|
||||
<stop offset="0" stop-color="#62c"/>
|
||||
<stop offset="1" stop-color="#301060"/>
|
||||
</linearGradient>
|
||||
<g fill="url(#a)" transform="matrix(1, 0, 0, 1, -12.325989, -1.578)">
|
||||
<path d="M 27.765 3.315 C 27.523 3.192 20.823 1.578 20.464 1.578 C 20.104 1.578 13.406 3.194 13.163 3.316 C 12.915 3.438 12.703 3.645 12.554 3.91 C 12.403 4.184 12.325 4.493 12.326 4.807 L 12.326 13.354 C 12.326 14.424 12.684 15.45 13.32 16.207 C 13.956 16.964 14.818 17.389 15.717 17.391 L 25.211 17.391 C 26.111 17.389 26.972 16.964 27.608 16.207 C 28.244 15.45 28.601 14.424 28.602 13.354 L 28.602 4.807 C 28.602 4.487 28.523 4.176 28.374 3.91 C 28.236 3.654 28.024 3.447 27.765 3.315 Z"/>
|
||||
</g>
|
||||
<path d="M 12.276 0.128 L 12.956 0.128 L 12.956 7.651 L 12.218 7.651 L 8.427 1.317 L 8.427 7.651 L 7.712 7.651 L 7.712 0.128 L 8.509 0.128 L 12.276 6.368 Z" transform="matrix(1.86918, 0, 0, 0.767696, -11.240033, 5.053573)" style="fill: rgb(27, 27, 27); paint-order: fill; white-space: pre;"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 179 KiB |
@@ -1 +0,0 @@
|
||||
<svg fill="none" height="48" viewBox="0 0 46 48" width="46" xmlns="http://www.w3.org/2000/svg"><g fill="#ae77ff"><path d="m13.01 7.857c-.613-1.062-1.979-1.435-2.974-.719a22.2 22.2 0 1 0 25.928 0c-.995-.716-2.361-.343-2.974.719s-.239 2.409.738 3.15a17.76 17.76 0 1 1 -21.456 0c.977-.741 1.351-2.088.738-3.15z"/><rect height="14.8" rx="2.22" width="4.44" x="20.78"/></g></svg>
|
||||
|
Before Width: | Height: | Size: 374 B |
@@ -1,3 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="22" height="24" fill="none" viewBox="0 0 22 24">
|
||||
<path fill="#B5AEBE" stroke="#B5AEBE" stroke-width="2" d="M1 13.75c0-1.514 1.165-2.771 2.671-2.918l.586.697c3.51 4.178 9.976 4.178 13.486 0l.586-.697C19.835 10.978 21 12.236 21 13.75v3.16c0 3.355-2.746 6.09-6.15 6.09h-7.7C3.746 23 1 20.265 1 16.91v-3.16zm14.5-8.295c0 2.452-2.007 4.454-4.5 4.454S6.5 7.907 6.5 5.455C6.5 3.002 8.507 1 11 1s4.5 2.002 4.5 4.455z"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 468 B |
@@ -1,4 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="21" height="21" fill="none" viewBox="0 0 21 21">
|
||||
<path fill="#AE77FF" d="M18.406 10.58v-1.1l1.38-1.207a1.438 1.438 0 00.273-1.833l-1.696-2.875a1.438 1.438 0 00-1.243-.718 1.438 1.438 0 00-.46.071l-1.747.59c-.301-.2-.616-.38-.941-.54l-.367-1.81A1.437 1.437 0 0012.167 0H8.805a1.437 1.437 0 00-1.438 1.157L7 2.97a8.252 8.252 0 00-.949.539l-1.71-.618a1.438 1.438 0 00-.46-.043 1.438 1.438 0 00-1.244.718L.94 6.44a1.438 1.438 0 00.294 1.804l1.359 1.244v1.1l-1.359 1.207a1.437 1.437 0 00-.294 1.833l1.696 2.875a1.438 1.438 0 001.243.718c.157.002.312-.023.46-.071l1.747-.59c.301.2.616.38.941.54l.367 1.81a1.438 1.438 0 001.438 1.158h3.392a1.438 1.438 0 001.438-1.157l.366-1.812c.328-.158.645-.338.949-.539l1.74.59c.148.048.303.073.46.072a1.437 1.437 0 001.243-.72l1.638-2.874a1.437 1.437 0 00-.294-1.804l-1.359-1.244zm-1.286 5.204l-2.466-.834a6.369 6.369 0 01-1.947 1.129l-.51 2.58H8.803l-.51-2.551a6.73 6.73 0 01-1.941-1.129l-2.473.805-1.696-2.875 1.955-1.725a6.397 6.397 0 010-2.25L2.184 7.16 3.88 4.284l2.466.834a6.368 6.368 0 011.947-1.129l.51-2.58h3.393l.51 2.552a6.727 6.727 0 011.941 1.128l2.473-.805 1.696 2.875-1.955 1.725a6.397 6.397 0 010 2.25l1.955 1.775-1.696 2.875z"/>
|
||||
<path fill="#AE77FF" d="M10.5 14.347a4.312 4.312 0 114.313-4.313 4.268 4.268 0 01-4.313 4.313zm0-7.188a2.81 2.81 0 00-2.875 2.875 2.81 2.81 0 002.875 2.875 2.808 2.808 0 002.875-2.875A2.809 2.809 0 0010.5 7.159z"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.4 KiB |
@@ -1,14 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg viewBox="0 0 82 18" xmlns="http://www.w3.org/2000/svg">
|
||||
<g transform="matrix(0.012366, 0, 0, -0.010371, -37.907673, 26.353985)" id="g10" style="">
|
||||
<g transform="scale(0.1)" id="g12">
|
||||
<g transform="matrix(1.4411, 0, 0, 1.4411, 32303.105469, 1475.181641)" id="g2248">
|
||||
<path id="path2250" style="fill-opacity: 1; fill-rule: nonzero; stroke: none;" d="m 13914.7,14060.9 v -3973.1 c 0,-568.29 -21.3,-974.93 -63.7,-1219.88 -42.4,-244.95 -168.2,-451.6 -377.2,-619.73 -209,-168.28 -519.3,-252.31 -930.8,-252.31 -405,0 -724.3,88.96 -957.8,267.02 -233.6,177.99 -381.4,413.99 -443.4,707.93 -1.8,9.44 -3.6,19.64 -5.4,30.19 -32.3,194.78 -48.4,584.68 -48.4,1170.08 v 1354.4 l 91.6,255 552.6,1539.1 264.4,736.5 132.2,368.2 c 22.2,61.3 43.7,122.9 66.8,183.8 23.4,60.9 47.6,121.5 66.5,184 l 111,375.8 c 36.3,125.6 73.3,250.8 109,376.6 72.2,251.2 143.2,502.8 211.2,755.5 -108.4,-238.2 -213.6,-477.6 -317.7,-717.3 -52.4,-119.7 -103.6,-239.9 -155.4,-359.9 l -153.5,-360.6 c -25.1,-60.2 -45,-122.3 -65.8,-184.2 -20.8,-61.8 -43.5,-122.9 -65.3,-184.3 l -132.2,-368.2 -264.5,-736.5 -359.3,-1000.9 -91.6,-255 -606.7,-1689.7 L 9768.62,8458.65 9423.54,7497.72 9177.2,6811.58 8894.71,6024.89 8784.1,5648.93 c -36.43,-125.46 -73.28,-250.78 -109.16,-376.44 -36.22,-125.6 -71.95,-251.34 -107.55,-377.08 l -52.74,-188.95 -26.3,-94.44 -25.88,-94.65 40.31,89.44 39.77,89.66 79.45,179.3 c 52.6,119.7 104.99,239.4 156.89,359.31 52.26,119.84 103.53,239.96 155.3,359.93 l 153.77,360.49 323.85,901.88 204.98,570.95 252.66,703.56 c 74.73,-178.89 180.45,-352.44 317.05,-520.57 72.2,-88.83 153.6,-171.82 244.1,-248.98 167.5,-142.74 366.1,-265.49 596.2,-368.33 354.3,-158.35 874.4,-237.59 1560.3,-237.59 568.2,0 1028.8,72.72 1381.5,218.02 352.7,145.31 634.4,340.51 845.1,585.46 210.7,244.95 355.2,545.34 433.6,901.39 78.4,355.98 117.6,965.09 117.6,1827.31 v 3772.3 h -1450.2"/>
|
||||
</g>
|
||||
<g transform="scale(1.4411)" id="g2252">
|
||||
<path id="path2254" style="fill-opacity: 1; fill-rule: nonzero; stroke: none;" d="M 31195.072 9019.019 L 32037.612 11365.629 L 32077.242 11475.929 L 32168.832 11730.929 L 33095.322 14311.229 L 33359.722 15047.729 L 33361.522 15052.529 L 33492.022 15415.929 C 33514.122 15477.229 33535.522 15538.829 33558.822 15599.729 C 33582.122 15660.629 33606.322 15721.229 33625.222 15783.729 L 33736.222 16159.529 C 33772.422 16285.129 33809.422 16410.329 33845.222 16536.129 C 33917.322 16787.329 33988.422 17038.929 34056.322 17291.629 C 33948.122 17053.429 33842.822 16814.029 33738.722 16574.329 C 33686.322 16454.629 33635.122 16334.429 33583.322 16214.429 L 33429.822 15853.829 C 33404.722 15793.629 33384.822 15731.529 33364.022 15669.629 C 33343.222 15607.829 33320.622 15546.729 33298.622 15485.329 L 33166.522 15117.129 L 33143.322 15052.529 L 32168.832 15052.529 L 32077.242 15052.529 L 32077.242 12083.629 L 31844.362 11435.029 L 30967.392 8992.719 C 30912.712 8989.319 30855.952 8987.509 30797.042 8987.509 C 30392.072 8987.509 30072.802 9076.469 29839.302 9254.529 C 29605.732 9432.519 29457.932 9668.519 29395.892 9962.459 C 29359.962 10145.309 29342.062 10545.409 29342.062 11162.729 L 29342.062 15052.529 L 27891.932 15052.529 L 27891.932 11221.529 C 27891.932 10418.009 27939.242 9810.559 28033.982 9399.069 C 28099.292 9121.369 28234.852 8856.019 28440.622 8602.949 C 28646.382 8349.809 28926.402 8144.059 29280.822 7985.639 C 29578.112 7852.759 29992.102 7775.659 30522.742 7754.219 L 30257.802 7016.519 L 30147.192 6640.559 C 30110.762 6515.099 30073.912 6389.779 30038.042 6264.119 C 30001.812 6138.519 29966.082 6012.779 29930.482 5887.039 L 29877.812 5698.089 L 29851.442 5603.649 L 29825.632 5508.999 L 29865.882 5598.439 L 29905.642 5688.099 L 29985.162 5867.399 C 30037.692 5987.099 30090.152 6106.799 30142.062 6226.709 C 30194.312 6346.549 30245.592 6466.669 30297.282 6586.639 L 30451.052 6947.129 L 30738.892 7748.739 L 30979.952 8419.959 L 31195.072 9019.019"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<path d="M 38.475 12.15 L 41.667 3.315 L 44.898 3.315 L 39.995 15.063 L 36.966 15.063 L 32.081 3.314 L 35.302 3.314 L 38.474 12.15 L 38.475 12.15 Z M 48.738 10.923 L 48.738 15.063 L 45.837 15.063 L 45.837 3.314 L 51.332 3.314 C 52.389 3.314 53.317 3.476 54.118 3.799 C 54.923 4.121 55.542 4.581 55.974 5.179 C 56.406 5.77 56.622 6.446 56.622 7.203 C 56.622 8.355 56.148 9.264 55.201 9.931 C 54.26 10.592 52.953 10.923 51.282 10.923 L 48.738 10.923 Z M 48.738 8.963 L 51.332 8.963 C 52.099 8.963 52.683 8.812 53.082 8.511 C 53.488 8.21 53.692 7.78 53.692 7.22 C 53.692 6.644 53.488 6.179 53.082 5.824 C 52.677 5.469 52.115 5.286 51.399 5.275 L 48.738 5.275 L 48.738 8.963 Z M 69.682 15.063 L 66.779 15.063 L 61.13 7.333 L 61.13 15.063 L 58.23 15.063 L 58.23 3.314 L 61.13 3.314 L 66.789 11.06 L 66.789 3.315 L 69.682 3.315 L 69.682 15.063 Z" fill="#000" style=""/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 4.7 KiB |
@@ -1 +0,0 @@
|
||||
*.a filter=lfs diff=lfs merge=lfs -text
|
||||
@@ -1,33 +0,0 @@
|
||||
*.mode1v3
|
||||
*.mode2v3
|
||||
*.moved-aside
|
||||
*.pbxuser
|
||||
*.perspectivev3
|
||||
**/*sync/
|
||||
.sconsign.dblite
|
||||
.tags*
|
||||
**/.vagrant/
|
||||
**/DerivedData/
|
||||
Icon?
|
||||
**/Pods/
|
||||
**/.symlinks/
|
||||
profile
|
||||
xcuserdata
|
||||
**/.generated/
|
||||
**/build/
|
||||
Flutter/App.framework
|
||||
Flutter/Flutter.framework
|
||||
Flutter/Flutter.podspec
|
||||
Flutter/Generated.xcconfig
|
||||
Flutter/app.flx
|
||||
Flutter/app.zip
|
||||
Flutter/flutter_assets/
|
||||
Flutter/flutter_export_environment.sh
|
||||
ServiceDefinitions.json
|
||||
Runner/GeneratedPluginRegistrant.*
|
||||
|
||||
# Exceptions to above rules.
|
||||
!default.mode1v3
|
||||
!default.mode2v3
|
||||
!default.pbxuser
|
||||
!default.perspectivev3
|
||||
@@ -1,26 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>App</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>io.flutter.flutter.app</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>App</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.0</string>
|
||||
<key>MinimumOSVersion</key>
|
||||
<string>12.0</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1,2 +0,0 @@
|
||||
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
|
||||
#include "Generated.xcconfig"
|
||||
@@ -1,2 +0,0 @@
|
||||
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
|
||||
#include "Generated.xcconfig"
|
||||
@@ -1,35 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>PacketTunnel</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>$(MARKETING_VERSION)</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
<key>NSCameraUsageDescription</key>
|
||||
<string>用于客服消息上传图片</string>
|
||||
<key>NSExtension</key>
|
||||
<dict>
|
||||
<key>NSExtensionPointIdentifier</key>
|
||||
<string>com.apple.networkextension.packet-tunnel</string>
|
||||
<key>NSExtensionPrincipalClass</key>
|
||||
<string>$(PRODUCT_MODULE_NAME).PacketTunnelProvider</string>
|
||||
</dict>
|
||||
<key>NSPhotoLibraryAddUsageDescription</key>
|
||||
<string>用于客服消息上传图片</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1,14 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.developer.networking.networkextension</key>
|
||||
<array>
|
||||
<string>packet-tunnel-provider</string>
|
||||
</array>
|
||||
<key>com.apple.security.application-groups</key>
|
||||
<array>
|
||||
<string>group.com.vpntunnel.vpnzeus</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1,49 +0,0 @@
|
||||
# Uncomment this line to define a global platform for your project
|
||||
|
||||
|
||||
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
|
||||
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
|
||||
|
||||
platform :ios, '14.0'
|
||||
|
||||
project 'Runner', {
|
||||
'Debug' => :debug,
|
||||
'Profile' => :release,
|
||||
'Release' => :release,
|
||||
}
|
||||
|
||||
def flutter_root
|
||||
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
|
||||
unless File.exist?(generated_xcode_build_settings_path)
|
||||
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
|
||||
end
|
||||
|
||||
File.foreach(generated_xcode_build_settings_path) do |line|
|
||||
matches = line.match(/FLUTTER_ROOT\=(.*)/)
|
||||
return matches[1].strip if matches
|
||||
end
|
||||
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
|
||||
end
|
||||
|
||||
|
||||
# 添加打印语句
|
||||
puts "Flutter Root Path: #{flutter_root}"
|
||||
|
||||
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
|
||||
|
||||
|
||||
|
||||
flutter_ios_podfile_setup
|
||||
|
||||
target 'Runner' do
|
||||
use_frameworks!
|
||||
use_modular_headers!
|
||||
puts "flutter_install_all_ios_pods : #{File.dirname(File.realpath(__FILE__))}"
|
||||
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
|
||||
end
|
||||
|
||||
post_install do |installer|
|
||||
installer.pods_project.targets.each do |target|
|
||||
flutter_additional_ios_build_settings(target)
|
||||
end
|
||||
end
|
||||
@@ -1,950 +0,0 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 54;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
1273FB492B1EBCA4005B78AF /* leaf.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1273FB472B1EBC5E005B78AF /* leaf.xcframework */; };
|
||||
1273FB4A2B1EBCA4005B78AF /* leaf.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 1273FB472B1EBC5E005B78AF /* leaf.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
|
||||
2FD21F1125A363E300F556E0 /* PacketTunnelProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FD21F1025A363E300F556E0 /* PacketTunnelProvider.swift */; };
|
||||
2FD21F1625A363E300F556E0 /* PacketTunnel.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 2FD21F0D25A363E300F556E0 /* PacketTunnel.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
||||
2FD21F2425A364B700F556E0 /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2FD21EF825A363AA00F556E0 /* NetworkExtension.framework */; };
|
||||
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
|
||||
3E06F985293FACBB00E04D92 /* PacketTunnelProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FD21F1025A363E300F556E0 /* PacketTunnelProvider.swift */; };
|
||||
3E06F989293FAFC600E04D92 /* LeafAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E06F988293FAFC600E04D92 /* LeafAdapter.swift */; };
|
||||
3E06F98A293FAFC600E04D92 /* LeafAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E06F988293FAFC600E04D92 /* LeafAdapter.swift */; };
|
||||
3E06F98C293FB8F600E04D92 /* TunnelConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E06F98B293FB8F600E04D92 /* TunnelConfiguration.swift */; };
|
||||
3E06F98D293FB8F600E04D92 /* TunnelConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E06F98B293FB8F600E04D92 /* TunnelConfiguration.swift */; };
|
||||
3EA6B274293F185700B2BABC /* FileManager+Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EA6B273293F185700B2BABC /* FileManager+Helpers.swift */; };
|
||||
3EA6B276293F1AC500B2BABC /* template.conf in Resources */ = {isa = PBXBuildFile; fileRef = 3EA6B275293F1AC500B2BABC /* template.conf */; };
|
||||
3EA6B278293F1D1600B2BABC /* URL+Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EA6B277293F1D1600B2BABC /* URL+Helpers.swift */; };
|
||||
3EA6B27A293F1FAD00B2BABC /* Logger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EA6B279293F1FAD00B2BABC /* Logger.swift */; };
|
||||
3EA6B27C293F68B500B2BABC /* VPNManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F50954A25A36FD0001A32D5 /* VPNManager.swift */; };
|
||||
3EA6B27E293F69A400B2BABC /* VPNManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F50954A25A36FD0001A32D5 /* VPNManager.swift */; };
|
||||
3EA6B27F293F6AB500B2BABC /* FileManager+Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EA6B273293F185700B2BABC /* FileManager+Helpers.swift */; };
|
||||
3EA6B280293F6AB900B2BABC /* URL+Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EA6B277293F1D1600B2BABC /* URL+Helpers.swift */; };
|
||||
3EA6B281293F6AF800B2BABC /* template.conf in Resources */ = {isa = PBXBuildFile; fileRef = 3EA6B275293F1AC500B2BABC /* template.conf */; };
|
||||
3EA6B282293F6BA500B2BABC /* Logger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EA6B279293F1FAD00B2BABC /* Logger.swift */; };
|
||||
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
|
||||
7A31DD8228420C0B00E82EE1 /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2FD21EF825A363AA00F556E0 /* NetworkExtension.framework */; };
|
||||
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
|
||||
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
|
||||
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
|
||||
C09CB0942C50BC8D0028C461 /* leaf.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1273FB472B1EBC5E005B78AF /* leaf.xcframework */; };
|
||||
DBC6F25A26C78B1D91884CE1 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4A9C0075B77637136AF52D8B /* Pods_Runner.framework */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
2FD21F1425A363E300F556E0 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 97C146E61CF9000F007C117D /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 2FD21F0C25A363E300F556E0;
|
||||
remoteInfo = PacketTunnel;
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
1273FB4B2B1EBCA4005B78AF /* Embed Frameworks */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = "";
|
||||
dstSubfolderSpec = 10;
|
||||
files = (
|
||||
1273FB4A2B1EBCA4005B78AF /* leaf.xcframework in Embed Frameworks */,
|
||||
);
|
||||
name = "Embed Frameworks";
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
2FD21F0625A363AA00F556E0 /* Embed App Extensions */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = "";
|
||||
dstSubfolderSpec = 13;
|
||||
files = (
|
||||
2FD21F1625A363E300F556E0 /* PacketTunnel.appex in Embed App Extensions */,
|
||||
);
|
||||
name = "Embed App Extensions";
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
9705A1C41CF9048500538489 /* Embed Frameworks */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = "";
|
||||
dstSubfolderSpec = 10;
|
||||
files = (
|
||||
);
|
||||
name = "Embed Frameworks";
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
1273FB472B1EBC5E005B78AF /* leaf.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = leaf.xcframework; sourceTree = "<group>"; };
|
||||
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
|
||||
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
|
||||
2F50954A25A36FD0001A32D5 /* VPNManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPNManager.swift; sourceTree = "<group>"; };
|
||||
2FD21EF825A363AA00F556E0 /* NetworkExtension.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = NetworkExtension.framework; path = System/Library/Frameworks/NetworkExtension.framework; sourceTree = SDKROOT; };
|
||||
2FD21F0D25A363E300F556E0 /* PacketTunnel.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = PacketTunnel.appex; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
2FD21F1025A363E300F556E0 /* PacketTunnelProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PacketTunnelProvider.swift; sourceTree = "<group>"; };
|
||||
2FD21F1225A363E300F556E0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
2FD21F1325A363E300F556E0 /* PacketTunnel.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = PacketTunnel.entitlements; sourceTree = "<group>"; };
|
||||
2FD21F2325A364B600F556E0 /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = "<group>"; };
|
||||
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
|
||||
3E06F988293FAFC600E04D92 /* LeafAdapter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LeafAdapter.swift; sourceTree = "<group>"; };
|
||||
3E06F98B293FB8F600E04D92 /* TunnelConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelConfiguration.swift; sourceTree = "<group>"; };
|
||||
3EA6B273293F185700B2BABC /* FileManager+Helpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FileManager+Helpers.swift"; sourceTree = "<group>"; };
|
||||
3EA6B275293F1AC500B2BABC /* template.conf */ = {isa = PBXFileReference; lastKnownFileType = text; path = template.conf; sourceTree = "<group>"; };
|
||||
3EA6B277293F1D1600B2BABC /* URL+Helpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "URL+Helpers.swift"; sourceTree = "<group>"; };
|
||||
3EA6B279293F1FAD00B2BABC /* Logger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Logger.swift; sourceTree = "<group>"; };
|
||||
4A9C0075B77637136AF52D8B /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
|
||||
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
|
||||
7F9A79C99E6BB92BFA8F918D /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
8B949A6E3580C410A6129430 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
|
||||
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
|
||||
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
|
||||
9788364E2A66C2C5DE332140 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
|
||||
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
|
||||
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
2FD21F0A25A363E300F556E0 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
7A31DD8228420C0B00E82EE1 /* NetworkExtension.framework in Frameworks */,
|
||||
1273FB492B1EBCA4005B78AF /* leaf.xcframework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
97C146EB1CF9000F007C117D /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
2FD21F2425A364B700F556E0 /* NetworkExtension.framework in Frameworks */,
|
||||
DBC6F25A26C78B1D91884CE1 /* Pods_Runner.framework in Frameworks */,
|
||||
C09CB0942C50BC8D0028C461 /* leaf.xcframework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
2FD21F0F25A363E300F556E0 /* PacketTunnel */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
2FD21F1225A363E300F556E0 /* Info.plist */,
|
||||
2FD21F1325A363E300F556E0 /* PacketTunnel.entitlements */,
|
||||
);
|
||||
path = PacketTunnel;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
3EA6B272293F183000B2BABC /* Helpers */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
3EA6B273293F185700B2BABC /* FileManager+Helpers.swift */,
|
||||
3EA6B277293F1D1600B2BABC /* URL+Helpers.swift */,
|
||||
);
|
||||
path = Helpers;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
3EA6B27D293F699400B2BABC /* Shared */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
3E06F988293FAFC600E04D92 /* LeafAdapter.swift */,
|
||||
2FD21F1025A363E300F556E0 /* PacketTunnelProvider.swift */,
|
||||
3EA6B272293F183000B2BABC /* Helpers */,
|
||||
2F50954A25A36FD0001A32D5 /* VPNManager.swift */,
|
||||
3EA6B279293F1FAD00B2BABC /* Logger.swift */,
|
||||
3EA6B275293F1AC500B2BABC /* template.conf */,
|
||||
3E06F98B293FB8F600E04D92 /* TunnelConfiguration.swift */,
|
||||
);
|
||||
path = Shared;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
460845DE28877D00F1FA7B32 /* Pods */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
7F9A79C99E6BB92BFA8F918D /* Pods-Runner.debug.xcconfig */,
|
||||
8B949A6E3580C410A6129430 /* Pods-Runner.release.xcconfig */,
|
||||
9788364E2A66C2C5DE332140 /* Pods-Runner.profile.xcconfig */,
|
||||
);
|
||||
path = Pods;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9740EEB11CF90186004384FC /* Flutter */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
|
||||
9740EEB21CF90195004384FC /* Debug.xcconfig */,
|
||||
7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
|
||||
9740EEB31CF90195004384FC /* Generated.xcconfig */,
|
||||
);
|
||||
name = Flutter;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
97C146E51CF9000F007C117D = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
3EA6B27D293F699400B2BABC /* Shared */,
|
||||
9740EEB11CF90186004384FC /* Flutter */,
|
||||
97C146F01CF9000F007C117D /* Runner */,
|
||||
2FD21F0F25A363E300F556E0 /* PacketTunnel */,
|
||||
97C146EF1CF9000F007C117D /* Products */,
|
||||
460845DE28877D00F1FA7B32 /* Pods */,
|
||||
F6BCB37E43B89DAB5A76B9D0 /* Frameworks */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
97C146EF1CF9000F007C117D /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
97C146EE1CF9000F007C117D /* Runner.app */,
|
||||
2FD21F0D25A363E300F556E0 /* PacketTunnel.appex */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
97C146F01CF9000F007C117D /* Runner */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
2FD21F2325A364B600F556E0 /* Runner.entitlements */,
|
||||
97C146FA1CF9000F007C117D /* Main.storyboard */,
|
||||
97C146FD1CF9000F007C117D /* Assets.xcassets */,
|
||||
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
|
||||
97C147021CF9000F007C117D /* Info.plist */,
|
||||
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
|
||||
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
|
||||
74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
|
||||
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
|
||||
);
|
||||
path = Runner;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
F6BCB37E43B89DAB5A76B9D0 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1273FB472B1EBC5E005B78AF /* leaf.xcframework */,
|
||||
2FD21EF825A363AA00F556E0 /* NetworkExtension.framework */,
|
||||
4A9C0075B77637136AF52D8B /* Pods_Runner.framework */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
2FD21F0C25A363E300F556E0 /* PacketTunnel */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 2FD21F1725A363E300F556E0 /* Build configuration list for PBXNativeTarget "PacketTunnel" */;
|
||||
buildPhases = (
|
||||
2FD21F0925A363E300F556E0 /* Sources */,
|
||||
2FD21F0A25A363E300F556E0 /* Frameworks */,
|
||||
2FD21F0B25A363E300F556E0 /* Resources */,
|
||||
1273FB4B2B1EBCA4005B78AF /* Embed Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = PacketTunnel;
|
||||
productName = PacketTunnel;
|
||||
productReference = 2FD21F0D25A363E300F556E0 /* PacketTunnel.appex */;
|
||||
productType = "com.apple.product-type.app-extension";
|
||||
};
|
||||
97C146ED1CF9000F007C117D /* Runner */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
|
||||
buildPhases = (
|
||||
4A4528B4E4B302F57B5EDB65 /* [CP] Check Pods Manifest.lock */,
|
||||
9705A1C41CF9048500538489 /* Embed Frameworks */,
|
||||
9740EEB61CF901F6004384FC /* Run Script */,
|
||||
97C146EA1CF9000F007C117D /* Sources */,
|
||||
97C146EB1CF9000F007C117D /* Frameworks */,
|
||||
97C146EC1CF9000F007C117D /* Resources */,
|
||||
2FD21F0625A363AA00F556E0 /* Embed App Extensions */,
|
||||
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
|
||||
30B17F94E53B12A0859D0A8C /* [CP] Embed Pods Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
2FD21F1525A363E300F556E0 /* PBXTargetDependency */,
|
||||
);
|
||||
name = Runner;
|
||||
productName = Runner;
|
||||
productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
97C146E61CF9000F007C117D /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastSwiftUpdateCheck = 1230;
|
||||
LastUpgradeCheck = 1510;
|
||||
ORGANIZATIONNAME = "";
|
||||
TargetAttributes = {
|
||||
2FD21F0C25A363E300F556E0 = {
|
||||
CreatedOnToolsVersion = 12.3;
|
||||
};
|
||||
97C146ED1CF9000F007C117D = {
|
||||
CreatedOnToolsVersion = 7.3.1;
|
||||
LastSwiftMigration = 1100;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
|
||||
compatibilityVersion = "Xcode 9.3";
|
||||
developmentRegion = en;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
Base,
|
||||
);
|
||||
mainGroup = 97C146E51CF9000F007C117D;
|
||||
packageReferences = (
|
||||
C09CB0932C50B5DF0028C461 /* XCRemoteSwiftPackageReference "SwiftLoader" */,
|
||||
);
|
||||
productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
97C146ED1CF9000F007C117D /* Runner */,
|
||||
2FD21F0C25A363E300F556E0 /* PacketTunnel */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXResourcesBuildPhase section */
|
||||
2FD21F0B25A363E300F556E0 /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
3EA6B276293F1AC500B2BABC /* template.conf in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
97C146EC1CF9000F007C117D /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
3EA6B281293F6AF800B2BABC /* template.conf in Resources */,
|
||||
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
|
||||
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
|
||||
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
|
||||
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXShellScriptBuildPhase section */
|
||||
30B17F94E53B12A0859D0A8C /* [CP] Embed Pods Frameworks */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
|
||||
);
|
||||
name = "[CP] Embed Pods Frameworks";
|
||||
outputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
alwaysOutOfDate = 1;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${TARGET_BUILD_DIR}/${INFOPLIST_PATH}",
|
||||
);
|
||||
name = "Thin Binary";
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin\n";
|
||||
};
|
||||
4A4528B4E4B302F57B5EDB65 /* [CP] Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||
"${PODS_ROOT}/Manifest.lock",
|
||||
);
|
||||
name = "[CP] Check Pods Manifest.lock";
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
9740EEB61CF901F6004384FC /* Run Script */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
alwaysOutOfDate = 1;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "Run Script";
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\necho \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\"\necho build\necho \">>>>>>>>>\"\n/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build\n";
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
2FD21F0925A363E300F556E0 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
2FD21F1125A363E300F556E0 /* PacketTunnelProvider.swift in Sources */,
|
||||
3EA6B278293F1D1600B2BABC /* URL+Helpers.swift in Sources */,
|
||||
3EA6B27E293F69A400B2BABC /* VPNManager.swift in Sources */,
|
||||
3E06F98A293FAFC600E04D92 /* LeafAdapter.swift in Sources */,
|
||||
3EA6B274293F185700B2BABC /* FileManager+Helpers.swift in Sources */,
|
||||
3E06F98D293FB8F600E04D92 /* TunnelConfiguration.swift in Sources */,
|
||||
3EA6B27A293F1FAD00B2BABC /* Logger.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
97C146EA1CF9000F007C117D /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
|
||||
3EA6B282293F6BA500B2BABC /* Logger.swift in Sources */,
|
||||
3EA6B280293F6AB900B2BABC /* URL+Helpers.swift in Sources */,
|
||||
3EA6B27F293F6AB500B2BABC /* FileManager+Helpers.swift in Sources */,
|
||||
3EA6B27C293F68B500B2BABC /* VPNManager.swift in Sources */,
|
||||
3E06F989293FAFC600E04D92 /* LeafAdapter.swift in Sources */,
|
||||
3E06F985293FACBB00E04D92 /* PacketTunnelProvider.swift in Sources */,
|
||||
3E06F98C293FB8F600E04D92 /* TunnelConfiguration.swift in Sources */,
|
||||
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
2FD21F1525A363E300F556E0 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 2FD21F0C25A363E300F556E0 /* PacketTunnel */;
|
||||
targetProxy = 2FD21F1425A363E300F556E0 /* PBXContainerItemProxy */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
97C146FA1CF9000F007C117D /* Main.storyboard */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
97C146FB1CF9000F007C117D /* Base */,
|
||||
);
|
||||
name = Main.storyboard;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
97C147001CF9000F007C117D /* Base */,
|
||||
);
|
||||
name = LaunchScreen.storyboard;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
249021D3217E4FDB00AE95B9 /* Profile */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_BITCODE = NO;
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
|
||||
MODULEMAP_FILE = "${PROJECT_DIR}/LeafFFI/module.modulemap";
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = iphoneos;
|
||||
SUPPORTED_PLATFORMS = iphoneos;
|
||||
SWIFT_INCLUDE_PATHS = "${PROJECT_DIR}/LeafFFI";
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Profile;
|
||||
};
|
||||
249021D4217E4FDB00AE95B9 /* Profile */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_TEAM = U288ZP9B22;
|
||||
ENABLE_BITCODE = NO;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/Flutter",
|
||||
);
|
||||
INFOPLIST_FILE = Runner/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = UUVPN;
|
||||
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/Flutter",
|
||||
);
|
||||
MODULEMAP_FILE = "${PROJECT_DIR}/LeafFFI/module.modulemap";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.vpntunnel.vpnzeus;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES;
|
||||
SWIFT_INCLUDE_PATHS = "";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = 1;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
};
|
||||
name = Profile;
|
||||
};
|
||||
2FD21F1825A363E300F556E0 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
|
||||
buildSettings = {
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
||||
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CODE_SIGN_ENTITLEMENTS = PacketTunnel/PacketTunnel.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 200;
|
||||
DEVELOPMENT_TEAM = 26XWXKSR3B;
|
||||
ENABLE_BITCODE = NO;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "i386 arm64";
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/Flutter",
|
||||
);
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
INFOPLIST_FILE = PacketTunnel/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
LIBRARY_SEARCH_PATHS = "$(inherited)";
|
||||
MARKETING_VERSION = 2.0.0;
|
||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.vpntunnel.vpnzeus.PacketTunnel;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
||||
SWIFT_INCLUDE_PATHS = "";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
2FD21F1925A363E300F556E0 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
|
||||
buildSettings = {
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
||||
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CODE_SIGN_ENTITLEMENTS = PacketTunnel/PacketTunnel.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 200;
|
||||
DEVELOPMENT_TEAM = 26XWXKSR3B;
|
||||
ENABLE_BITCODE = NO;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "i386 arm64";
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/Flutter",
|
||||
);
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
INFOPLIST_FILE = PacketTunnel/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
LIBRARY_SEARCH_PATHS = "$(inherited)";
|
||||
MARKETING_VERSION = 2.0.0;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.vpntunnel.vpnzeus.PacketTunnel;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_INCLUDE_PATHS = "";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
2FD21F1A25A363E300F556E0 /* Profile */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
|
||||
buildSettings = {
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
||||
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||
CODE_SIGN_ENTITLEMENTS = PacketTunnel/PacketTunnel.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 200;
|
||||
DEVELOPMENT_TEAM = 26XWXKSR3B;
|
||||
ENABLE_BITCODE = NO;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "i386 arm64";
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/Flutter",
|
||||
);
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
INFOPLIST_FILE = PacketTunnel/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
LIBRARY_SEARCH_PATHS = "$(inherited)";
|
||||
MARKETING_VERSION = 2.0.0;
|
||||
MTL_FAST_MATH = YES;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.vpntunnel.vpnzeus.PacketTunnel;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_INCLUDE_PATHS = "";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Profile;
|
||||
};
|
||||
97C147031CF9000F007C117D /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
ENABLE_BITCODE = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
|
||||
MODULEMAP_FILE = "${PROJECT_DIR}/LeafFFI/module.modulemap";
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_INCLUDE_PATHS = "${PROJECT_DIR}/LeafFFI";
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
97C147041CF9000F007C117D /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_BITCODE = NO;
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
|
||||
MODULEMAP_FILE = "${PROJECT_DIR}/LeafFFI/module.modulemap";
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = iphoneos;
|
||||
SUPPORTED_PLATFORMS = iphoneos;
|
||||
SWIFT_COMPILATION_MODE = wholemodule;
|
||||
SWIFT_INCLUDE_PATHS = "${PROJECT_DIR}/LeafFFI";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
97C147061CF9000F007C117D /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_TEAM = U288ZP9B22;
|
||||
ENABLE_BITCODE = NO;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/Flutter",
|
||||
);
|
||||
INFOPLIST_FILE = Runner/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = UUVPN;
|
||||
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/Flutter",
|
||||
);
|
||||
MODULEMAP_FILE = "${PROJECT_DIR}/LeafFFI/module.modulemap";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.vpntunnel.vpnzeus;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES;
|
||||
SWIFT_INCLUDE_PATHS = "";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = 1;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
97C147071CF9000F007C117D /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_TEAM = U288ZP9B22;
|
||||
ENABLE_BITCODE = NO;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/Flutter",
|
||||
);
|
||||
INFOPLIST_FILE = Runner/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = UUVPN;
|
||||
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"$(PROJECT_DIR)/Flutter",
|
||||
);
|
||||
MODULEMAP_FILE = "${PROJECT_DIR}/LeafFFI/module.modulemap";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.vpntunnel.vpnzeus;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||
SUPPORTS_MACCATALYST = NO;
|
||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = YES;
|
||||
SWIFT_INCLUDE_PATHS = "";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = 1;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
2FD21F1725A363E300F556E0 /* Build configuration list for PBXNativeTarget "PacketTunnel" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
2FD21F1825A363E300F556E0 /* Debug */,
|
||||
2FD21F1925A363E300F556E0 /* Release */,
|
||||
2FD21F1A25A363E300F556E0 /* Profile */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
97C147031CF9000F007C117D /* Debug */,
|
||||
97C147041CF9000F007C117D /* Release */,
|
||||
249021D3217E4FDB00AE95B9 /* Profile */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
97C147061CF9000F007C117D /* Debug */,
|
||||
97C147071CF9000F007C117D /* Release */,
|
||||
249021D4217E4FDB00AE95B9 /* Profile */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
|
||||
/* Begin XCRemoteSwiftPackageReference section */
|
||||
C09CB0932C50B5DF0028C461 /* XCRemoteSwiftPackageReference "SwiftLoader" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/leoru/SwiftLoader";
|
||||
requirement = {
|
||||
kind = upToNextMajorVersion;
|
||||
minimumVersion = 1.0.0;
|
||||
};
|
||||
};
|
||||
/* End XCRemoteSwiftPackageReference section */
|
||||
};
|
||||
rootObject = 97C146E61CF9000F007C117D /* Project object */;
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
@@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDEDidComputeMac32BitWarning</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>PreviewsEnabled</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1,14 +0,0 @@
|
||||
{
|
||||
"pins" : [
|
||||
{
|
||||
"identity" : "swiftloader",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/leoru/SwiftLoader",
|
||||
"state" : {
|
||||
"revision" : "3d03ac07764075bfab4c9ce9d5ba4556d6af350e",
|
||||
"version" : "1.1.0"
|
||||
}
|
||||
}
|
||||
],
|
||||
"version" : 2
|
||||
}
|
||||
@@ -1,87 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1510"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
|
||||
BuildableName = "Runner.app"
|
||||
BlueprintName = "Runner"
|
||||
ReferencedContainer = "container:Runner.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
|
||||
BuildableName = "Runner.app"
|
||||
BlueprintName = "Runner"
|
||||
ReferencedContainer = "container:Runner.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<Testables>
|
||||
</Testables>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
|
||||
BuildableName = "Runner.app"
|
||||
BlueprintName = "Runner"
|
||||
ReferencedContainer = "container:Runner.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Profile"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
|
||||
BuildableName = "Runner.app"
|
||||
BlueprintName = "Runner"
|
||||
ReferencedContainer = "container:Runner.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
@@ -1,10 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:Runner.xcodeproj">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:Pods/Pods.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
@@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDEDidComputeMac32BitWarning</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>PreviewsEnabled</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1,14 +0,0 @@
|
||||
{
|
||||
"pins" : [
|
||||
{
|
||||
"identity" : "swiftloader",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/leoru/SwiftLoader",
|
||||
"state" : {
|
||||
"revision" : "3d03ac07764075bfab4c9ce9d5ba4556d6af350e",
|
||||
"version" : "1.1.0"
|
||||
}
|
||||
}
|
||||
],
|
||||
"version" : 2
|
||||
}
|
||||
@@ -1,134 +0,0 @@
|
||||
import UIKit
|
||||
import Flutter
|
||||
import NetworkExtension
|
||||
import os
|
||||
|
||||
@UIApplicationMain
|
||||
@objc class AppDelegate: FlutterAppDelegate {
|
||||
override func application(
|
||||
_ application: UIApplication,
|
||||
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
|
||||
) -> Bool {
|
||||
GeneratedPluginRegistrant.register(with: self)
|
||||
|
||||
let controller : FlutterViewController = window?.rootViewController as! FlutterViewController;
|
||||
let vpnManagerChannel = FlutterMethodChannel.init(name: "com.vpntunnel.vpnzeus/vpn_manager",
|
||||
binaryMessenger: controller.binaryMessenger);
|
||||
let manager = VPNManager.shared()
|
||||
|
||||
vpnManagerChannel.setMethodCallHandler({
|
||||
(call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in
|
||||
|
||||
switch call.method {
|
||||
case "toggle":
|
||||
manager.loadVPNPreference() { error in
|
||||
guard error == nil else {
|
||||
fatalError("load VPN preference failed: \(error.debugDescription)")
|
||||
}
|
||||
|
||||
manager.enableVPNManager() { error in
|
||||
guard error == nil else {
|
||||
fatalError("enable VPN failed: \(error.debugDescription)")
|
||||
}
|
||||
manager.toggleVPNConnection() { error in
|
||||
guard error == nil else {
|
||||
fatalError("toggle VPN connection failed: \(error.debugDescription)")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result(true)
|
||||
break
|
||||
case "getStatus":
|
||||
let status = manager.getStatus()
|
||||
|
||||
switch status {
|
||||
case NEVPNStatus.disconnected:
|
||||
result(0)
|
||||
case NEVPNStatus.connecting:
|
||||
result(1)
|
||||
case NEVPNStatus.reasserting:
|
||||
result(4)
|
||||
case NEVPNStatus.disconnecting:
|
||||
result(5)
|
||||
case NEVPNStatus.connected:
|
||||
result(2)
|
||||
default:
|
||||
result(3)
|
||||
}
|
||||
|
||||
break
|
||||
case "getConnectedDate":
|
||||
let connectedDate = manager.getConnectedDate()
|
||||
|
||||
result(connectedDate?.timeIntervalSince1970)
|
||||
break
|
||||
case "getTunnelLog":
|
||||
let fm = FileManager.default
|
||||
|
||||
guard let conf = fm.leafLogFile?.contents else {
|
||||
fatalError("get leaf log file contents fail")
|
||||
}
|
||||
|
||||
result(conf)
|
||||
break
|
||||
case "getTunnelConfiguration":
|
||||
LeafAdapater.shared().getRuntimeConfiguration { conf in
|
||||
guard conf != nil else {
|
||||
fatalError("get runtime VPN configuratioin failed")
|
||||
}
|
||||
|
||||
result(conf)
|
||||
}
|
||||
break
|
||||
case "setTunnelConfiguration":
|
||||
guard let conf = call.arguments as? String else {
|
||||
fatalError("call arguments is empty")
|
||||
}
|
||||
LeafAdapater.shared().setRuntimeConfiguration(conf: conf) { error in
|
||||
guard error == nil else {
|
||||
fatalError("set runtime configuration failed: \(error.debugDescription)")
|
||||
}
|
||||
}
|
||||
case "update":
|
||||
guard let conf = call.arguments as? String else {
|
||||
fatalError("call arguments is empty")
|
||||
}
|
||||
|
||||
LeafAdapater.shared().update(conf: conf) { error in
|
||||
guard error == nil else {
|
||||
fatalError("update tunnel failed: \(error.debugDescription)")
|
||||
}
|
||||
}
|
||||
default:
|
||||
result(FlutterMethodNotImplemented)
|
||||
return
|
||||
}
|
||||
})
|
||||
|
||||
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
|
||||
}
|
||||
|
||||
override func applicationWillResignActive(_ application: UIApplication) {
|
||||
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
|
||||
// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
|
||||
}
|
||||
|
||||
override func applicationDidEnterBackground(_ application: UIApplication) {
|
||||
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
|
||||
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
|
||||
}
|
||||
|
||||
override func applicationWillEnterForeground(_ application: UIApplication) {
|
||||
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
|
||||
}
|
||||
|
||||
override func applicationDidBecomeActive(_ application: UIApplication) {
|
||||
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
|
||||
}
|
||||
|
||||
override func applicationWillTerminate(_ application: UIApplication) {
|
||||
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
|
||||
}
|
||||
}
|
||||
@@ -1,119 +0,0 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"scale" : "2x",
|
||||
"platform" : "ios",
|
||||
"filename" : "icon-20@2x.png",
|
||||
"size" : "20x20",
|
||||
"idiom" : "universal"
|
||||
},
|
||||
{
|
||||
"filename" : "icon-20@3x.png",
|
||||
"platform" : "ios",
|
||||
"idiom" : "universal",
|
||||
"size" : "20x20",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"size" : "29x29",
|
||||
"platform" : "ios",
|
||||
"scale" : "2x",
|
||||
"filename" : "icon-29@2x.png"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"scale" : "3x",
|
||||
"filename" : "icon-29@3x.png",
|
||||
"idiom" : "universal",
|
||||
"platform" : "ios"
|
||||
},
|
||||
{
|
||||
"platform" : "ios",
|
||||
"idiom" : "universal",
|
||||
"filename" : "icon-38@2x.png",
|
||||
"size" : "38x38",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"size" : "38x38",
|
||||
"platform" : "ios",
|
||||
"filename" : "icon-38@3x.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"scale" : "2x",
|
||||
"filename" : "icon-40@2x.png",
|
||||
"platform" : "ios",
|
||||
"idiom" : "universal",
|
||||
"size" : "40x40"
|
||||
},
|
||||
{
|
||||
"filename" : "icon-40@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x",
|
||||
"size" : "40x40",
|
||||
"platform" : "ios"
|
||||
},
|
||||
{
|
||||
"size" : "60x60",
|
||||
"filename" : "icon-60@2x.png",
|
||||
"idiom" : "universal",
|
||||
"platform" : "ios",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "icon-60@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x",
|
||||
"platform" : "ios",
|
||||
"size" : "60x60"
|
||||
},
|
||||
{
|
||||
"platform" : "ios",
|
||||
"size" : "64x64",
|
||||
"scale" : "2x",
|
||||
"filename" : "icon-64@2x.png",
|
||||
"idiom" : "universal"
|
||||
},
|
||||
{
|
||||
"platform" : "ios",
|
||||
"size" : "64x64",
|
||||
"filename" : "icon-64@3x.png",
|
||||
"scale" : "3x",
|
||||
"idiom" : "universal"
|
||||
},
|
||||
{
|
||||
"size" : "68x68",
|
||||
"scale" : "2x",
|
||||
"idiom" : "universal",
|
||||
"filename" : "icon-68@2x.png",
|
||||
"platform" : "ios"
|
||||
},
|
||||
{
|
||||
"platform" : "ios",
|
||||
"filename" : "icon-76@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x",
|
||||
"size" : "76x76"
|
||||
},
|
||||
{
|
||||
"platform" : "ios",
|
||||
"scale" : "2x",
|
||||
"filename" : "icon-83_5@2x.png",
|
||||
"idiom" : "universal",
|
||||
"size" : "83.5x83.5"
|
||||
},
|
||||
{
|
||||
"filename" : "ios-marketing.png",
|
||||
"size" : "1024x1024",
|
||||
"idiom" : "universal",
|
||||
"platform" : "ios"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 3.9 KiB |
|
Before Width: | Height: | Size: 6.4 KiB |
|
Before Width: | Height: | Size: 5.5 KiB |
|
Before Width: | Height: | Size: 9.0 KiB |
|
Before Width: | Height: | Size: 5.7 KiB |
|
Before Width: | Height: | Size: 9.6 KiB |
|
Before Width: | Height: | Size: 9.6 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 17 KiB |