ha-frp-rn 1.0.16 → 1.0.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/build/.transforms/66c11c57a73a38f4bbb04b9b88dc5137/transformed/bundleLibRuntimeToDirRelease/bundleLibRuntimeToDirRelease_dex/io/github/acedroidx/frp/ShellService$Companion.dex +0 -0
- package/android/build/.transforms/66c11c57a73a38f4bbb04b9b88dc5137/transformed/bundleLibRuntimeToDirRelease/bundleLibRuntimeToDirRelease_dex/io/github/acedroidx/frp/ShellService.dex +0 -0
- package/android/build/.transforms/8976eb8239f11fc86931495268aa2e67/transformed/classes/classes_dex/classes.dex +0 -0
- package/android/build/intermediates/aar_main_jar/release/syncReleaseLibJars/classes.jar +0 -0
- package/android/build/intermediates/compile_library_classes_jar/release/bundleLibCompileToJarRelease/classes.jar +0 -0
- package/android/build/intermediates/full_jar/release/createFullJarRelease/full.jar +0 -0
- package/android/build/intermediates/incremental/release/mergeReleaseResources/compile-file-map.properties +1 -1
- package/android/build/intermediates/incremental/release/packageReleaseResources/compile-file-map.properties +1 -1
- package/android/build/intermediates/local_aar_for_lint/release/out.aar +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/release/bundleLibRuntimeToDirRelease/io/github/acedroidx/frp/ShellService$Companion.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/release/bundleLibRuntimeToDirRelease/io/github/acedroidx/frp/ShellService.class +0 -0
- package/android/build/intermediates/runtime_library_classes_jar/release/bundleLibRuntimeToJarRelease/classes.jar +0 -0
- package/android/build/kotlin/compileReleaseKotlin/cacheable/caches-jvm/inputs/source-to-output.tab +0 -0
- package/android/build/kotlin/compileReleaseKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.values.at +0 -0
- package/android/build/kotlin/compileReleaseKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab +0 -0
- package/android/build/kotlin/compileReleaseKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.values.at +0 -0
- package/android/build/kotlin/compileReleaseKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab +0 -0
- package/android/build/kotlin/compileReleaseKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.values.at +0 -0
- package/android/build/kotlin/compileReleaseKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab +0 -0
- package/android/build/kotlin/compileReleaseKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.values.at +0 -0
- package/android/build/kotlin/compileReleaseKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab +0 -0
- package/android/build/kotlin/compileReleaseKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values.at +0 -0
- package/android/build/kotlin/compileReleaseKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab +0 -0
- package/android/build/kotlin/compileReleaseKotlin/cacheable/caches-jvm/jvm/kotlin/source-to-classes.tab.values.at +0 -0
- package/android/build/kotlin/compileReleaseKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab +0 -0
- package/android/build/kotlin/compileReleaseKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab.values.at +0 -0
- package/android/build/kotlin/compileReleaseKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab +0 -0
- package/android/build/kotlin/compileReleaseKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab.values.at +0 -0
- package/android/build/kotlin/compileReleaseKotlin/cacheable/caches-jvm/lookups/counters.tab +1 -1
- package/android/build/kotlin/compileReleaseKotlin/cacheable/caches-jvm/lookups/file-to-id.tab +0 -0
- package/android/build/kotlin/compileReleaseKotlin/cacheable/caches-jvm/lookups/file-to-id.tab.values.at +0 -0
- package/android/build/kotlin/compileReleaseKotlin/cacheable/caches-jvm/lookups/id-to-file.tab +0 -0
- package/android/build/kotlin/compileReleaseKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream +0 -0
- package/android/build/kotlin/compileReleaseKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.keystream.len +0 -0
- package/android/build/kotlin/compileReleaseKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.len +0 -0
- package/android/build/kotlin/compileReleaseKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.values.at +0 -0
- package/android/build/kotlin/compileReleaseKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i +0 -0
- package/android/build/kotlin/compileReleaseKotlin/cacheable/caches-jvm/lookups/lookups.tab +0 -0
- package/android/build/kotlin/compileReleaseKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream +0 -0
- package/android/build/kotlin/compileReleaseKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream.len +0 -0
- package/android/build/kotlin/compileReleaseKotlin/cacheable/caches-jvm/lookups/lookups.tab.len +0 -0
- package/android/build/kotlin/compileReleaseKotlin/cacheable/caches-jvm/lookups/lookups.tab.values.at +0 -0
- package/android/build/kotlin/compileReleaseKotlin/cacheable/caches-jvm/lookups/lookups.tab_i +0 -0
- package/android/build/kotlin/compileReleaseKotlin/cacheable/last-build.bin +0 -0
- package/android/build/kotlin/compileReleaseKotlin/classpath-snapshot/shrunk-classpath-snapshot.bin +0 -0
- package/android/build/kotlin/compileReleaseKotlin/local-state/build-history.bin +0 -0
- package/android/build/outputs/aar/ha-frp-rn-release.aar +0 -0
- package/android/build/outputs/logs/manifest-merger-release-report.txt +9 -9
- package/android/build/tmp/compileReleaseJavaWithJavac/previous-compilation-data.bin +0 -0
- package/android/build/tmp/kotlin-classes/release/io/github/acedroidx/frp/ShellService$Companion.class +0 -0
- package/android/build/tmp/kotlin-classes/release/io/github/acedroidx/frp/ShellService.class +0 -0
- package/android/src/main/java/io/github/acedroidx/frp/ShellService.kt +253 -226
- package/package.json +1 -1
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
#Tue Dec 30 14:08:53 CST 2025
|
|
2
2
|
io.github.acedroidx.frp.ha-frp-rn-appcompat-1.7.0-10\:/drawable-xxxhdpi-v4/abc_text_select_handle_right_mtrl.png=D\:\\Project\\Page_Manager\\ha-mobile-rn\\node_modules\\ha-frp-rn\\android\\build\\intermediates\\merged_res\\release\\mergeReleaseResources\\drawable-xxxhdpi-v4\\abc_text_select_handle_right_mtrl.png
|
|
3
3
|
io.github.acedroidx.frp.ha-frp-rn-appcompat-1.7.0-10\:/layout/abc_action_mode_bar.xml=D\:\\Project\\Page_Manager\\ha-mobile-rn\\node_modules\\ha-frp-rn\\android\\build\\intermediates\\merged_res\\release\\mergeReleaseResources\\layout\\abc_action_mode_bar.xml
|
|
4
4
|
io.github.acedroidx.frp.ha-frp-rn-core-1.13.1-17\:/drawable-hdpi-v4/notification_bg_low_pressed.9.png=D\:\\Project\\Page_Manager\\ha-mobile-rn\\node_modules\\ha-frp-rn\\android\\build\\intermediates\\merged_res\\release\\mergeReleaseResources\\drawable-hdpi-v4\\notification_bg_low_pressed.9.png
|
|
@@ -1 +1 @@
|
|
|
1
|
-
#
|
|
1
|
+
#Tue Dec 30 14:08:45 CST 2025
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/android/build/kotlin/compileReleaseKotlin/cacheable/caches-jvm/inputs/source-to-output.tab
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/android/build/kotlin/compileReleaseKotlin/cacheable/caches-jvm/jvm/kotlin/subtypes.tab
CHANGED
|
Binary file
|
|
Binary file
|
package/android/build/kotlin/compileReleaseKotlin/cacheable/caches-jvm/jvm/kotlin/supertypes.tab
CHANGED
|
Binary file
|
|
Binary file
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
6
|
|
2
2
|
0
|
package/android/build/kotlin/compileReleaseKotlin/cacheable/caches-jvm/lookups/file-to-id.tab
CHANGED
|
Binary file
|
|
Binary file
|
package/android/build/kotlin/compileReleaseKotlin/cacheable/caches-jvm/lookups/id-to-file.tab
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/android/build/kotlin/compileReleaseKotlin/cacheable/caches-jvm/lookups/id-to-file.tab.len
CHANGED
|
Binary file
|
|
Binary file
|
package/android/build/kotlin/compileReleaseKotlin/cacheable/caches-jvm/lookups/id-to-file.tab_i
CHANGED
|
Binary file
|
|
Binary file
|
package/android/build/kotlin/compileReleaseKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream
CHANGED
|
Binary file
|
|
Binary file
|
package/android/build/kotlin/compileReleaseKotlin/cacheable/caches-jvm/lookups/lookups.tab.len
CHANGED
|
Binary file
|
package/android/build/kotlin/compileReleaseKotlin/cacheable/caches-jvm/lookups/lookups.tab.values.at
CHANGED
|
Binary file
|
package/android/build/kotlin/compileReleaseKotlin/cacheable/caches-jvm/lookups/lookups.tab_i
CHANGED
|
Binary file
|
|
Binary file
|
package/android/build/kotlin/compileReleaseKotlin/classpath-snapshot/shrunk-classpath-snapshot.bin
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
-- Merging decision tree log ---
|
|
2
2
|
manifest
|
|
3
|
-
ADDED from D:\Project\Page_Manager\ha-mobile-rn\node_modules\ha-frp-rn\android\build\intermediates\tmp\ProcessLibraryManifest\release\
|
|
4
|
-
INJECTED from D:\Project\Page_Manager\ha-mobile-rn\node_modules\ha-frp-rn\android\build\intermediates\tmp\ProcessLibraryManifest\release\
|
|
3
|
+
ADDED from D:\Project\Page_Manager\ha-mobile-rn\node_modules\ha-frp-rn\android\build\intermediates\tmp\ProcessLibraryManifest\release\tempAndroidManifest14099836558573805620.xml:2:13-83
|
|
4
|
+
INJECTED from D:\Project\Page_Manager\ha-mobile-rn\node_modules\ha-frp-rn\android\build\intermediates\tmp\ProcessLibraryManifest\release\tempAndroidManifest14099836558573805620.xml:2:13-83
|
|
5
5
|
package
|
|
6
|
-
INJECTED from D:\Project\Page_Manager\ha-mobile-rn\node_modules\ha-frp-rn\android\build\intermediates\tmp\ProcessLibraryManifest\release\
|
|
6
|
+
INJECTED from D:\Project\Page_Manager\ha-mobile-rn\node_modules\ha-frp-rn\android\build\intermediates\tmp\ProcessLibraryManifest\release\tempAndroidManifest14099836558573805620.xml
|
|
7
7
|
xmlns:android
|
|
8
|
-
ADDED from D:\Project\Page_Manager\ha-mobile-rn\node_modules\ha-frp-rn\android\build\intermediates\tmp\ProcessLibraryManifest\release\
|
|
8
|
+
ADDED from D:\Project\Page_Manager\ha-mobile-rn\node_modules\ha-frp-rn\android\build\intermediates\tmp\ProcessLibraryManifest\release\tempAndroidManifest14099836558573805620.xml:2:23-81
|
|
9
9
|
uses-sdk
|
|
10
|
-
INJECTED from D:\Project\Page_Manager\ha-mobile-rn\node_modules\ha-frp-rn\android\build\intermediates\tmp\ProcessLibraryManifest\release\
|
|
11
|
-
INJECTED from D:\Project\Page_Manager\ha-mobile-rn\node_modules\ha-frp-rn\android\build\intermediates\tmp\ProcessLibraryManifest\release\
|
|
12
|
-
INJECTED from D:\Project\Page_Manager\ha-mobile-rn\node_modules\ha-frp-rn\android\build\intermediates\tmp\ProcessLibraryManifest\release\
|
|
10
|
+
INJECTED from D:\Project\Page_Manager\ha-mobile-rn\node_modules\ha-frp-rn\android\build\intermediates\tmp\ProcessLibraryManifest\release\tempAndroidManifest14099836558573805620.xml reason: use-sdk injection requested
|
|
11
|
+
INJECTED from D:\Project\Page_Manager\ha-mobile-rn\node_modules\ha-frp-rn\android\build\intermediates\tmp\ProcessLibraryManifest\release\tempAndroidManifest14099836558573805620.xml
|
|
12
|
+
INJECTED from D:\Project\Page_Manager\ha-mobile-rn\node_modules\ha-frp-rn\android\build\intermediates\tmp\ProcessLibraryManifest\release\tempAndroidManifest14099836558573805620.xml
|
|
13
13
|
android:targetSdkVersion
|
|
14
|
-
INJECTED from D:\Project\Page_Manager\ha-mobile-rn\node_modules\ha-frp-rn\android\build\intermediates\tmp\ProcessLibraryManifest\release\
|
|
14
|
+
INJECTED from D:\Project\Page_Manager\ha-mobile-rn\node_modules\ha-frp-rn\android\build\intermediates\tmp\ProcessLibraryManifest\release\tempAndroidManifest14099836558573805620.xml
|
|
15
15
|
android:minSdkVersion
|
|
16
|
-
INJECTED from D:\Project\Page_Manager\ha-mobile-rn\node_modules\ha-frp-rn\android\build\intermediates\tmp\ProcessLibraryManifest\release\
|
|
16
|
+
INJECTED from D:\Project\Page_Manager\ha-mobile-rn\node_modules\ha-frp-rn\android\build\intermediates\tmp\ProcessLibraryManifest\release\tempAndroidManifest14099836558573805620.xml
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,226 +1,253 @@
|
|
|
1
|
-
package io.github.acedroidx.frp
|
|
2
|
-
|
|
3
|
-
import android.content.Context
|
|
4
|
-
import android.util.Log
|
|
5
|
-
import java.io.*
|
|
6
|
-
import java.util.concurrent.Executors
|
|
7
|
-
import java.util.concurrent.TimeUnit
|
|
8
|
-
|
|
9
|
-
class ShellService(private val context: Context) {
|
|
10
|
-
|
|
11
|
-
enum class Status {
|
|
12
|
-
STOPPED,
|
|
13
|
-
STARTING,
|
|
14
|
-
RUNNING,
|
|
15
|
-
STOPPING,
|
|
16
|
-
ERROR
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
private var process: Process? = null
|
|
20
|
-
private var status = Status.STOPPED
|
|
21
|
-
private var lastMessage = ""
|
|
22
|
-
private var executorService = Executors.newSingleThreadExecutor()
|
|
23
|
-
private var onStatusChangeListener: ((Status, String) -> Unit)? = null
|
|
24
|
-
private val TAG = "ShellService"
|
|
25
|
-
|
|
26
|
-
fun setOnStatusChangeListener(listener: (Status, String) -> Unit) {
|
|
27
|
-
this.onStatusChangeListener = listener
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* 使用配置路径启动FRP访问者模式
|
|
32
|
-
*
|
|
33
|
-
* @param configPath - 配置文件路径
|
|
34
|
-
*/
|
|
35
|
-
fun startVisitor(configPath: String) {
|
|
36
|
-
startFrp("frpc", configPath)
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* 使用配置路径启动FRP服务器模式
|
|
41
|
-
*
|
|
42
|
-
* @param configPath - 配置文件路径
|
|
43
|
-
*/
|
|
44
|
-
fun startServer(configPath: String) {
|
|
45
|
-
startFrp("frps", configPath)
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* 使用FrpConfig对象启动FRP
|
|
50
|
-
*
|
|
51
|
-
* @param frpConfig - FRP配置对象
|
|
52
|
-
*/
|
|
53
|
-
fun start(frpConfig: FrpConfig) {
|
|
54
|
-
val binaryName = when (frpConfig.type) {
|
|
55
|
-
FrpType.FRPC -> "frpc"
|
|
56
|
-
FrpType.FRPS -> "frps"
|
|
57
|
-
}
|
|
58
|
-
val configPath = frpConfig.getFile(context).absolutePath
|
|
59
|
-
startFrp(binaryName, configPath)
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
private fun startFrp(binaryName: String, configPath: String) {
|
|
63
|
-
if (status == Status.RUNNING) {
|
|
64
|
-
Log.w(TAG, "FRP is already running")
|
|
65
|
-
return
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
setStatus(Status.STARTING, "Starting $binaryName...")
|
|
69
|
-
|
|
70
|
-
executorService.submit {
|
|
71
|
-
try {
|
|
72
|
-
//
|
|
73
|
-
val
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
val
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
//
|
|
108
|
-
val
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
)
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
"
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
1
|
+
package io.github.acedroidx.frp
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.util.Log
|
|
5
|
+
import java.io.*
|
|
6
|
+
import java.util.concurrent.Executors
|
|
7
|
+
import java.util.concurrent.TimeUnit
|
|
8
|
+
|
|
9
|
+
class ShellService(private val context: Context) {
|
|
10
|
+
|
|
11
|
+
enum class Status {
|
|
12
|
+
STOPPED,
|
|
13
|
+
STARTING,
|
|
14
|
+
RUNNING,
|
|
15
|
+
STOPPING,
|
|
16
|
+
ERROR
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
private var process: Process? = null
|
|
20
|
+
private var status = Status.STOPPED
|
|
21
|
+
private var lastMessage = ""
|
|
22
|
+
private var executorService = Executors.newSingleThreadExecutor()
|
|
23
|
+
private var onStatusChangeListener: ((Status, String) -> Unit)? = null
|
|
24
|
+
private val TAG = "ShellService"
|
|
25
|
+
|
|
26
|
+
fun setOnStatusChangeListener(listener: (Status, String) -> Unit) {
|
|
27
|
+
this.onStatusChangeListener = listener
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* 使用配置路径启动FRP访问者模式
|
|
32
|
+
*
|
|
33
|
+
* @param configPath - 配置文件路径
|
|
34
|
+
*/
|
|
35
|
+
fun startVisitor(configPath: String) {
|
|
36
|
+
startFrp("frpc", configPath)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* 使用配置路径启动FRP服务器模式
|
|
41
|
+
*
|
|
42
|
+
* @param configPath - 配置文件路径
|
|
43
|
+
*/
|
|
44
|
+
fun startServer(configPath: String) {
|
|
45
|
+
startFrp("frps", configPath)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* 使用FrpConfig对象启动FRP
|
|
50
|
+
*
|
|
51
|
+
* @param frpConfig - FRP配置对象
|
|
52
|
+
*/
|
|
53
|
+
fun start(frpConfig: FrpConfig) {
|
|
54
|
+
val binaryName = when (frpConfig.type) {
|
|
55
|
+
FrpType.FRPC -> "frpc"
|
|
56
|
+
FrpType.FRPS -> "frps"
|
|
57
|
+
}
|
|
58
|
+
val configPath = frpConfig.getFile(context).absolutePath
|
|
59
|
+
startFrp(binaryName, configPath)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
private fun startFrp(binaryName: String, configPath: String) {
|
|
63
|
+
if (status == Status.RUNNING) {
|
|
64
|
+
Log.w(TAG, "FRP is already running")
|
|
65
|
+
return
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
setStatus(Status.STARTING, "Starting $binaryName...")
|
|
69
|
+
|
|
70
|
+
executorService.submit {
|
|
71
|
+
try {
|
|
72
|
+
// === 关键修复:区分 asset 和真实文件 ===
|
|
73
|
+
val rawConfigFile = File(configPath)
|
|
74
|
+
val isAssetPath = configPath.startsWith("assets/") || configPath.contains("asset")
|
|
75
|
+
|
|
76
|
+
val actualConfigFile: File = if (isAssetPath) {
|
|
77
|
+
// 复制 asset 到可写目录
|
|
78
|
+
val internalDir = context.filesDir // /data/data/.../files
|
|
79
|
+
val destFile = File(internalDir, "frpc-running.toml") // 可写位置
|
|
80
|
+
copyAssetToFile(context, configPath.substringAfterLast("/"), destFile)
|
|
81
|
+
destFile
|
|
82
|
+
} else {
|
|
83
|
+
// 已经是真实路径
|
|
84
|
+
if (!rawConfigFile.exists()) {
|
|
85
|
+
Log.e(TAG, "Config file does not exist: $configPath")
|
|
86
|
+
setStatus(Status.ERROR, "Config file not found: $configPath")
|
|
87
|
+
return@submit
|
|
88
|
+
}
|
|
89
|
+
rawConfigFile
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// 此时 actualConfigFile 一定是可访问的真实文件
|
|
93
|
+
val workingDir = actualConfigFile.parentFile!!
|
|
94
|
+
val binaryPath = getBinaryPath(binaryName)
|
|
95
|
+
|
|
96
|
+
// 构建命令
|
|
97
|
+
val command = arrayOf(
|
|
98
|
+
binaryPath.absolutePath,
|
|
99
|
+
"-c",
|
|
100
|
+
actualConfigFile.name // 只传文件名,工作目录已设
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
Log.i(TAG, "Executing: ${command.joinToString(" ")}")
|
|
104
|
+
Log.i(TAG, "Working directory: ${workingDir.absolutePath}")
|
|
105
|
+
Log.i(TAG, "Config file: ${actualConfigFile.absolutePath}")
|
|
106
|
+
|
|
107
|
+
// 执行
|
|
108
|
+
val pb = ProcessBuilder(*command)
|
|
109
|
+
.redirectErrorStream(true)
|
|
110
|
+
.directory(workingDir)
|
|
111
|
+
|
|
112
|
+
process = pb.start()
|
|
113
|
+
setStatus(Status.RUNNING, "$binaryName started successfully")
|
|
114
|
+
|
|
115
|
+
// 输出监听
|
|
116
|
+
BufferedReader(InputStreamReader(process?.inputStream)).use { reader ->
|
|
117
|
+
var line: String?
|
|
118
|
+
while (reader.readLine().also { line = it } != null) {
|
|
119
|
+
Log.d(TAG, "FRP output: $line")
|
|
120
|
+
lastMessage = line ?: ""
|
|
121
|
+
onStatusChangeListener?.invoke(status, lastMessage)
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
monitorProcess()
|
|
126
|
+
|
|
127
|
+
} catch (e: Exception) {
|
|
128
|
+
Log.e(TAG, "Error running FRP: ${e.message}", e)
|
|
129
|
+
setStatus(Status.ERROR, "Failed to start FRP: ${e.message}")
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* 将 assets 中的文件复制到目标文件
|
|
136
|
+
*/
|
|
137
|
+
private fun copyAssetToFile(context: Context, assetName: String, destFile: File) {
|
|
138
|
+
try {
|
|
139
|
+
context.assets.open(assetName).use { input ->
|
|
140
|
+
FileOutputStream(destFile).use { output ->
|
|
141
|
+
val buffer = ByteArray(1024)
|
|
142
|
+
var length: Int
|
|
143
|
+
while (input.read(buffer).also { length = it } > 0) {
|
|
144
|
+
output.write(buffer, 0, length)
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
Log.i(TAG, "Successfully copied asset $assetName to ${destFile.absolutePath}")
|
|
149
|
+
} catch (e: IOException) {
|
|
150
|
+
Log.e(TAG, "Failed to copy asset $assetName", e)
|
|
151
|
+
throw RuntimeException("Failed to copy asset: $assetName", e)
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* 获取 native 二进制路径
|
|
157
|
+
*/
|
|
158
|
+
private fun getBinaryPath(binaryName: String): File {
|
|
159
|
+
val packageManager = context.packageManager
|
|
160
|
+
val applicationInfo = packageManager.getApplicationInfo(
|
|
161
|
+
context.packageName,
|
|
162
|
+
android.content.pm.PackageManager.GET_SHARED_LIBRARY_FILES
|
|
163
|
+
)
|
|
164
|
+
val nativeLibraryDir = File(applicationInfo.nativeLibraryDir)
|
|
165
|
+
val libName = when (binaryName) {
|
|
166
|
+
"frpc" -> "libfrpc.so"
|
|
167
|
+
"frps" -> "libfrps.so"
|
|
168
|
+
else -> throw IllegalArgumentException("Unknown binary: $binaryName")
|
|
169
|
+
}
|
|
170
|
+
return File(nativeLibraryDir, libName)
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
private fun monitorProcess() {
|
|
175
|
+
executorService.submit {
|
|
176
|
+
try {
|
|
177
|
+
process?.waitFor()
|
|
178
|
+
val exitCode = process?.exitValue() ?: -1
|
|
179
|
+
setStatus(Status.STOPPED, "FRP stopped with exit code $exitCode")
|
|
180
|
+
} catch (e: Exception) {
|
|
181
|
+
Log.e(TAG, "Error monitoring FRP process: ${e.message}", e)
|
|
182
|
+
setStatus(Status.ERROR, "Error monitoring FRP: ${e.message}")
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
fun stop() {
|
|
188
|
+
if (status != Status.RUNNING && status != Status.STARTING) {
|
|
189
|
+
Log.w(TAG, "FRP is not running")
|
|
190
|
+
return
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
setStatus(Status.STOPPING, "Stopping FRP...")
|
|
194
|
+
|
|
195
|
+
try {
|
|
196
|
+
process?.destroy()
|
|
197
|
+
process?.waitFor(5, TimeUnit.SECONDS)
|
|
198
|
+
if (process?.isAlive == true) {
|
|
199
|
+
process?.destroyForcibly()
|
|
200
|
+
process?.waitFor(2, TimeUnit.SECONDS)
|
|
201
|
+
}
|
|
202
|
+
setStatus(Status.STOPPED, "FRP stopped")
|
|
203
|
+
} catch (e: Exception) {
|
|
204
|
+
Log.e(TAG, "Error stopping FRP: ${e.message}", e)
|
|
205
|
+
setStatus(Status.ERROR, "Failed to stop FRP: ${e.message}")
|
|
206
|
+
} finally {
|
|
207
|
+
process = null
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
private fun extractBinary(binaryName: String): String? {
|
|
212
|
+
// FRP二进制文件作为Native Library打包在APK的lib目录下
|
|
213
|
+
// 直接返回正确的二进制文件名(Android会自动加载)
|
|
214
|
+
Log.i(TAG, "Using native library for $binaryName")
|
|
215
|
+
return when (binaryName) {
|
|
216
|
+
"frpc" -> "libfrpc.so"
|
|
217
|
+
"frps" -> "libfrps.so"
|
|
218
|
+
else -> {
|
|
219
|
+
Log.e(TAG, "Unknown binary name: $binaryName")
|
|
220
|
+
null
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
private fun setStatus(newStatus: Status, message: String) {
|
|
226
|
+
status = newStatus
|
|
227
|
+
lastMessage = message
|
|
228
|
+
Log.i(TAG, "Status: $status, Message: $message")
|
|
229
|
+
onStatusChangeListener?.invoke(newStatus, message)
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
fun getStatus(): Status {
|
|
233
|
+
return status
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
fun getLastMessage(): String {
|
|
237
|
+
return lastMessage
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
companion object {
|
|
241
|
+
// Properties for external access
|
|
242
|
+
val Status.status: Status
|
|
243
|
+
get() = this
|
|
244
|
+
val Status.message: String
|
|
245
|
+
get() = when (this) {
|
|
246
|
+
Status.STOPPED -> "Stopped"
|
|
247
|
+
Status.STARTING -> "Starting"
|
|
248
|
+
Status.RUNNING -> "Running"
|
|
249
|
+
Status.STOPPING -> "Stopping"
|
|
250
|
+
Status.ERROR -> "Error"
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|