Skip to content

Commit f10d59e

Browse files
committed
Separate each VpnCore protocol into files
1 parent 9a37771 commit f10d59e

File tree

5 files changed

+315
-311
lines changed

5 files changed

+315
-311
lines changed

lib/vpnclient_engine/core.dart

Lines changed: 0 additions & 310 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ import 'dart:async';
22
import 'dart:convert';
33
import 'package:http/http.dart' as http;
44
import 'package:dart_ping/dart_ping.dart';
5-
import 'package:vpnclient_engine_flutter/vpnclient_engine/core.dart';
6-
75
import 'package:flutter/foundation.dart';
86
import 'package:flutter_v2ray/flutter_v2ray.dart';
97
import 'package:rxdart/rxdart.dart';
@@ -96,17 +94,6 @@ class RoutingRule {
9694
RoutingRule({this.appName, this.domain, required this.action});
9795
}
9896

99-
class WireGuardCore implements VpnCore {
100-
@override
101-
Future<void> connect({
102-
required int subscriptionIndex,
103-
required int serverIndex,
104-
}) {
105-
// TODO: implement connect
106-
throw UnimplementedError();
107-
}
108-
}
109-
11097
abstract class VpnCore {
11198
Future<void> connect({
11299
required int subscriptionIndex,
@@ -122,300 +109,3 @@ abstract class VpnCore {
122109
void setAutoConnect({required bool enable});
123110
void setKillSwitch({required bool enable});
124111
}
125-
126-
class V2RayCore implements VpnCore {
127-
final FlutterV2ray _flutterV2ray = FlutterV2ray(
128-
onStatusChanged: (status) {
129-
// do something
130-
},
131-
);
132-
List<List<String>> _subscriptionServers = [];
133-
List<String> _subscriptions = [];
134-
135-
final _connectionStatusSubject = BehaviorSubject<ConnectionStatus>();
136-
Stream<ConnectionStatus> get onConnectionStatusChanged =>
137-
_connectionStatusSubject.stream;
138-
139-
final _errorSubject = BehaviorSubject<ErrorDetails>();
140-
Stream<ErrorDetails> get onError => _errorSubject.stream;
141-
142-
final _serverSwitchedSubject = BehaviorSubject<String>();
143-
Stream<String> get onServerSwitched => _serverSwitchedSubject.stream;
144-
145-
final _pingResultSubject = BehaviorSubject<PingResult>();
146-
Stream<PingResult> get onPingResult => _pingResultSubject.stream;
147-
148-
final _subscriptionLoadedSubject = BehaviorSubject<SubscriptionDetails>();
149-
Stream<SubscriptionDetails> get onSubscriptionLoaded =>
150-
_subscriptionLoadedSubject.stream;
151-
152-
final _dataUsageUpdatedSubject = BehaviorSubject<SessionStatistics>();
153-
Stream<SessionStatistics> get onDataUsageUpdated =>
154-
_dataUsageUpdatedSubject.stream;
155-
156-
final _routingRulesAppliedSubject = BehaviorSubject<List<RoutingRule>>();
157-
Stream<List<RoutingRule>> get onRoutingRulesApplied =>
158-
_routingRulesAppliedSubject.stream;
159-
160-
final _killSwitchTriggeredSubject = BehaviorSubject<void>();
161-
Stream<void> get onKillSwitchTriggered => _killSwitchTriggeredSubject.stream;
162-
163-
void _emitError(ErrorCode code, String message) {
164-
_errorSubject.add(ErrorDetails(errorCode: code, errorMessage: message));
165-
}
166-
167-
void initialize() {
168-
print('V2RayCore initialized');
169-
}
170-
171-
void clearSubscriptions() {
172-
_subscriptions.clear();
173-
print('All subscriptions cleared');
174-
}
175-
176-
void addSubscription({required String subscriptionURL}) {
177-
_subscriptions.add(subscriptionURL);
178-
print('Subscription added: $subscriptionURL');
179-
}
180-
181-
void addSubscriptions({required List<String> subscriptionURLs}) {
182-
_subscriptions.addAll(subscriptionURLs);
183-
print('Subscriptions added: ${subscriptionURLs.join(", ")}');
184-
}
185-
186-
Future<void> updateSubscription({required int subscriptionIndex}) async {
187-
if (subscriptionIndex < 0 || subscriptionIndex >= _subscriptions.length) {
188-
print('Invalid subscription index');
189-
return;
190-
}
191-
192-
final url = _subscriptions[subscriptionIndex];
193-
print('Fetching subscription data from: $url');
194-
195-
try {
196-
final response = await http.get(Uri.parse(url));
197-
198-
if (response.statusCode != 200) {
199-
print('Failed to fetch subscription: HTTP ${response.statusCode}');
200-
return;
201-
}
202-
203-
final content = response.body.trim();
204-
205-
List<String> servers = [];
206-
207-
if (content.startsWith('[')) {
208-
final jsonList = jsonDecode(content) as List<dynamic>;
209-
for (var server in jsonList) {
210-
servers.add(server.toString());
211-
}
212-
print('Parsed JSON subscription: ${servers.length} servers loaded');
213-
} else {
214-
servers =
215-
content
216-
.split('\n')
217-
.where((line) => line.trim().isNotEmpty)
218-
.toList();
219-
print('Parsed NEWLINE subscription: ${servers.length} servers loaded');
220-
}
221-
222-
while (_subscriptionServers.length <= subscriptionIndex) {
223-
_subscriptionServers.add([]);
224-
}
225-
226-
_subscriptionServers[subscriptionIndex] = servers;
227-
_subscriptionLoadedSubject.add(SubscriptionDetails());
228-
229-
print('Subscription #$subscriptionIndex servers updated successfully');
230-
} catch (e) {
231-
print('Error updating subscription: $e');
232-
_emitError(ErrorCode.unknownError, 'Error updating subscription: $e');
233-
}
234-
}
235-
236-
@override
237-
Future<void> connect({
238-
required int subscriptionIndex,
239-
required int serverIndex,
240-
}) async {
241-
try {
242-
if (subscriptionIndex < 0 ||
243-
subscriptionIndex >= _subscriptionServers.length) {
244-
print('Invalid subscription index');
245-
return;
246-
}
247-
if (serverIndex < 0 ||
248-
serverIndex >= _subscriptionServers[subscriptionIndex].length) {
249-
print('Invalid server index');
250-
return;
251-
}
252-
253-
await _flutterV2ray.initializeV2Ray();
254-
255-
final serverAddress =
256-
_subscriptionServers[subscriptionIndex][serverIndex];
257-
V2RayURL parser = FlutterV2ray.parseFromURL(serverAddress);
258-
259-
_connectionStatusSubject.add(ConnectionStatus.connecting);
260-
if (await _flutterV2ray.requestPermission()) {
261-
_flutterV2ray.startV2Ray(
262-
remark: parser.remark,
263-
config: parser.getFullConfiguration(),
264-
blockedApps: null,
265-
bypassSubnets: null,
266-
proxyOnly: false,
267-
);
268-
}
269-
_serverSwitchedSubject.add(serverAddress);
270-
_connectionStatusSubject.add(ConnectionStatus.connected);
271-
print('Successfully connected');
272-
} catch (e) {
273-
_emitError(ErrorCode.unknownError, 'Error connecting: $e');
274-
_connectionStatusSubject.add(ConnectionStatus.error);
275-
}
276-
}
277-
278-
@override
279-
Future<void> disconnect() async {
280-
_flutterV2ray.stopV2Ray();
281-
_connectionStatusSubject.add(ConnectionStatus.disconnected);
282-
print('Disconnected successfully');
283-
}
284-
285-
@override
286-
void setRoutingRules({required List<RoutingRule> rules}) {
287-
for (var rule in rules) {
288-
if (rule.appName != null) {
289-
print('Routing rule for app ${rule.appName}: ${rule.action}');
290-
} else if (rule.domain != null) {
291-
print('Routing rule for domain ${rule.domain}: ${rule.action}');
292-
}
293-
}
294-
}
295-
296-
@override
297-
void pingServer({required int subscriptionIndex, required int index}) async {
298-
if (subscriptionIndex < 0 ||
299-
subscriptionIndex >= _subscriptionServers.length) {
300-
print('Invalid subscription index');
301-
_emitError(ErrorCode.unknownError, 'Invalid subscription index');
302-
return;
303-
}
304-
if (index < 0 || index >= _subscriptionServers[subscriptionIndex].length) {
305-
print('Invalid server index');
306-
_emitError(ErrorCode.unknownError, 'Invalid server index');
307-
return;
308-
}
309-
final serverAddress = _subscriptionServers[subscriptionIndex][index];
310-
print('Pinging server: $serverAddress');
311-
try {
312-
final ping = Ping(serverAddress, count: 3);
313-
final pingData = await ping.stream.firstWhere(
314-
(data) => data.response != null,
315-
);
316-
if (pingData.response != null) {
317-
final latency = pingData.response!.time!.inMilliseconds;
318-
final result = PingResult(
319-
subscriptionIndex: subscriptionIndex,
320-
serverIndex: index,
321-
latencyInMs: latency,
322-
);
323-
_pingResultSubject.add(result);
324-
print(
325-
'Ping result: sub=${result.subscriptionIndex}, server=${result.serverIndex}, latency=${result.latencyInMs} ms',
326-
);
327-
} else {
328-
print('Ping failed: No response');
329-
_pingResultSubject.add(
330-
PingResult(
331-
subscriptionIndex: subscriptionIndex,
332-
serverIndex: index,
333-
latencyInMs: -1,
334-
),
335-
);
336-
_emitError(ErrorCode.serverUnavailable, 'Ping failed: No response');
337-
}
338-
} catch (e) {
339-
print('Ping error: $e');
340-
_pingResultSubject.add(
341-
PingResult(
342-
subscriptionIndex: subscriptionIndex,
343-
serverIndex: index,
344-
latencyInMs: -1,
345-
),
346-
);
347-
_emitError(ErrorCode.unknownError, 'Ping error: $e');
348-
}
349-
}
350-
351-
@override
352-
String getConnectionStatus() {
353-
return 'disconnected';
354-
}
355-
356-
@override
357-
List<Server> getServerList() {
358-
return [
359-
Server(
360-
address: 'server1.com',
361-
latency: 50,
362-
location: 'USA',
363-
isPreferred: true,
364-
),
365-
Server(
366-
address: 'server2.com',
367-
latency: 100,
368-
location: 'UK',
369-
isPreferred: false,
370-
),
371-
Server(
372-
address: 'server3.com',
373-
latency: 75,
374-
location: 'Canada',
375-
isPreferred: false,
376-
),
377-
];
378-
}
379-
380-
@override
381-
Future<void> loadSubscriptions({
382-
required List<String> subscriptionLinks,
383-
}) async {
384-
print('loadSubscriptions: ${subscriptionLinks.join(", ")}');
385-
_subscriptions.addAll(subscriptionLinks);
386-
print('Subscriptions added: ${subscriptionLinks.join(", ")}');
387-
for (var index = 0; index < subscriptionLinks.length; index++) {
388-
await updateSubscription(subscriptionIndex: index);
389-
}
390-
}
391-
392-
@override
393-
SessionStatistics getSessionStatistics() {
394-
return SessionStatistics(
395-
sessionDuration: Duration(minutes: 30),
396-
dataInBytes: 1024 * 1024 * 100,
397-
dataOutBytes: 1024 * 1024 * 50,
398-
);
399-
}
400-
401-
@override
402-
void setAutoConnect({required bool enable}) {
403-
print('setAutoConnect: $enable');
404-
}
405-
406-
@override
407-
void setKillSwitch({required bool enable}) {
408-
print('setKillSwitch: $enable');
409-
}
410-
}
411-
412-
class OpenVPNCore implements VpnCore {
413-
@override
414-
Future<void> connect({
415-
required int subscriptionIndex,
416-
required int serverIndex,
417-
}) {
418-
// TODO: implement connect
419-
throw UnimplementedError();
420-
}
421-
}

lib/vpnclient_engine/engine.dart

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ import 'package:dart_ping/dart_ping.dart';
66
import 'package:rxdart/rxdart.dart';
77
import 'package:vpnclient_engine_flutter/vpnclient_engine_flutter.dart';
88
import 'package:vpnclient_engine_flutter/vpnclient_engine/core.dart';
9+
import 'package:vpnclient_engine_flutter/vpnclient_engine/protocols/openvpn.dart';
10+
import 'package:vpnclient_engine_flutter/vpnclient_engine/protocols/v2ray.dart';
11+
import 'package:vpnclient_engine_flutter/vpnclient_engine/protocols/wireguard.dart';
912

1013
enum Action { block, allow, routeThroughVPN, direct, proxy }
1114

@@ -131,7 +134,7 @@ class VPNclientEngine {
131134
_vpnCore ??= V2RayCore();
132135
}
133136

134-
static void ClearSubscriptions() {
137+
static void clearSubscriptions() {
135138
_subscriptions.clear();
136139
print('All subscriptions cleared');
137140
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import 'package:vpnclient_engine_flutter/vpnclient_engine/core.dart';
2+
3+
class OpenVPNCore implements VpnCore {
4+
@override
5+
Future<void> connect({
6+
required int subscriptionIndex,
7+
required int serverIndex,
8+
}) {
9+
// TODO: implement connect
10+
throw UnimplementedError();
11+
}
12+
}

0 commit comments

Comments
 (0)