Advertisement
amonnoris

app_state.dart

Oct 5th, 2024
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Dart 9.60 KB | Source Code | 0 0
  1. // lib/providers/app_state.dart
  2.  
  3. import 'package:flutter/material.dart';
  4. import '../models/v2ray_config.dart';
  5. import '../models/connection_log.dart';
  6. import '../utils/storage_helper.dart';
  7. import 'dart:async';
  8. import 'package:flutter_v2ray/flutter_v2ray.dart';
  9. import 'package:http/http.dart' as http;
  10. import 'dart:convert';
  11.  
  12. class AppState extends ChangeNotifier {
  13.   // **VPN Configuration Management**
  14.   List<V2RayConfig> _configs = [];
  15.   V2RayConfig? _selectedConfig;
  16.   List<ConnectionLog> _connectionLogs = [];
  17.  
  18.   List<V2RayConfig> get configs => _configs;
  19.   V2RayConfig? get selectedConfig => _selectedConfig;
  20.   List<ConnectionLog> get connectionLogs => _connectionLogs;
  21.  
  22.   AppState() {
  23.     loadConfigs();
  24.     loadConnectionLogs();
  25.     initializeV2Ray();
  26.   }
  27.  
  28.   // Load VPN configurations from storage
  29.   Future<void> loadConfigs() async {
  30.     _configs = await StorageHelper.loadConfigs();
  31.     notifyListeners();
  32.   }
  33.  
  34.   // Add a new VPN configuration
  35.   Future<void> addConfig(V2RayConfig config) async {
  36.     _configs.add(config);
  37.     await StorageHelper.saveConfig(config);
  38.     notifyListeners();
  39.   }
  40.  
  41.   // Select a VPN configuration
  42.   void selectConfig(V2RayConfig config) {
  43.     _selectedConfig = config;
  44.     notifyListeners();
  45.   }
  46.  
  47.   // Delete a VPN configuration
  48.   Future<void> deleteConfig(V2RayConfig config) async {
  49.     _configs.remove(config);
  50.     await StorageHelper.deleteConfig(config.name);
  51.     notifyListeners();
  52.   }
  53.  
  54.   // **Connection Log Management**
  55.  
  56.   // Load connection logs from storage
  57.   Future<void> loadConnectionLogs() async {
  58.     _connectionLogs = await StorageHelper.loadLogs();
  59.     notifyListeners();
  60.   }
  61.  
  62.   // Add a new connection log
  63.   Future<void> addConnectionLog(ConnectionLog log) async {
  64.     _connectionLogs.add(log);
  65.     await StorageHelper.saveLog(log);
  66.     notifyListeners();
  67.   }
  68.  
  69.   // Update the last connection log with duration and data usage
  70.   Future<void> updateLastConnectionLog(
  71.       Duration duration, int uploaded, int downloaded) async {
  72.     if (_connectionLogs.isNotEmpty) {
  73.       ConnectionLog lastLog = _connectionLogs.last;
  74.       if (lastLog.duration == Duration.zero) {
  75.         // Option 1: Mutable duration
  76.         lastLog.duration = duration;
  77.         _connectionLogs[_connectionLogs.length - 1] = lastLog;
  78.         await StorageHelper.saveLog(lastLog);
  79.  
  80.         // Option 2: Immutable duration with copyWith
  81.         /*
  82.         ConnectionLog updatedLog = lastLog.copyWith(duration: duration);
  83.         _connectionLogs[_connectionLogs.length - 1] = updatedLog;
  84.         await StorageHelper.saveLog(updatedLog);
  85.         */
  86.  
  87.         notifyListeners();
  88.       }
  89.     }
  90.   }
  91.  
  92.   // Clear all connection logs
  93.   Future<void> clearConnectionLogs() async {
  94.     _connectionLogs.clear();
  95.     await StorageHelper.clearLogs();
  96.     notifyListeners();
  97.   }
  98.  
  99.   // **VPN Connection and Timer Management**
  100.  
  101.   // Timer related variables
  102.   bool isConnected = false;
  103.   final int totalDuration = 360; // Total duration in seconds (6 minutes)
  104.   int remainingTime = 360; // Remaining time in seconds
  105.   Timer? timer;
  106.   Timer? latencyTimer;
  107.   int latency = 0;
  108.  
  109.   // V2Ray instance
  110.   late FlutterV2ray flutterV2ray;
  111.  
  112.   // V2Ray status notifier
  113.   ValueNotifier<V2RayStatus> v2rayStatus =
  114.       ValueNotifier<V2RayStatus>(V2RayStatus());
  115.  
  116.   // IP and location variables
  117.   String currentIp = "Fetching IP...";
  118.   String country = "Fetching location...";
  119.   String network = "Fetching network...";
  120.   String? coreVersion;
  121.  
  122.   // Initialize V2Ray and set up status listener
  123.   void initializeV2Ray() async {
  124.     flutterV2ray = FlutterV2ray(
  125.       onStatusChanged: (status) {
  126.         v2rayStatus.value = status;
  127.         handleConnectionStatus(status);
  128.       },
  129.     );
  130.  
  131.     try {
  132.       await flutterV2ray.initializeV2Ray();
  133.       coreVersion = await flutterV2ray.getCoreVersion();
  134.       print('V2Ray Core Version: $coreVersion'); // Debug print
  135.       notifyListeners();
  136.     } catch (e) {
  137.       print('Error initializing V2Ray: $e'); // Debug print
  138.     }
  139.  
  140.     // Start latency updates
  141.     latencyTimer = Timer.periodic(const Duration(seconds: 10), (timer) {
  142.       updateLatency();
  143.     });
  144.   }
  145.  
  146.   // Handle connection status changes
  147.   void handleConnectionStatus(V2RayStatus status) {
  148.     if (status.state == 'CONNECTED' && !isConnected) {
  149.       isConnected = true;
  150.       startTimer();
  151.       fetchIpAndLocation();
  152.       logConnectionStart();
  153.     } else if (status.state == 'DISCONNECTED' && isConnected) {
  154.       isConnected = false;
  155.       pauseTimer();
  156.       fetchIpAndLocation();
  157.       logConnectionEnd();
  158.     }
  159.     notifyListeners();
  160.   }
  161.  
  162.   // Connect to VPN
  163.   Future<void> connect() async {
  164.     if (_selectedConfig == null || _selectedConfig!.configText.trim().isEmpty) {
  165.       // Handle error: no config selected
  166.       print('No configuration selected');
  167.       // Optionally, notify UI to show a message
  168.       return;
  169.     }
  170.  
  171.     try {
  172.       if (await flutterV2ray.requestPermission()) {
  173.         flutterV2ray.startV2Ray(
  174.           remark: _selectedConfig!.remark,
  175.           config: _selectedConfig!.configText,
  176.           proxyOnly: false,
  177.           bypassSubnets: [], // Your logic for split tunneling
  178.         );
  179.         print('VPN Connection Initiated'); // Debug
  180.       } else {
  181.         print('Permission Denied for VPN Connection'); // Debug
  182.         // Optionally, notify UI to show a message
  183.       }
  184.     } catch (e) {
  185.       print('Error connecting VPN: $e'); // Debug
  186.       // Optionally, notify UI to show a message
  187.     }
  188.   }
  189.  
  190.   // Disconnect from VPN
  191.   void disconnect() {
  192.     try {
  193.       flutterV2ray.stopV2Ray();
  194.       print('VPN Disconnected'); // Debug
  195.     } catch (e) {
  196.       print('Error disconnecting VPN: $e'); // Debug
  197.       // Optionally, notify UI to show a message
  198.     }
  199.   }
  200.  
  201.   // Start the timer
  202.   void startTimer() {
  203.     // If the remainingTime is zero or less, reset to totalDuration
  204.     if (remainingTime <= 0) {
  205.       remainingTime = totalDuration;
  206.     }
  207.  
  208.     timer?.cancel();
  209.     timer = Timer.periodic(const Duration(seconds: 1), (timer) {
  210.       if (remainingTime > 0) {
  211.         remainingTime--;
  212.         notifyListeners();
  213.       } else {
  214.         // Time is up, stop V2Ray connection
  215.         disconnect();
  216.         timer.cancel();
  217.         isConnected = false;
  218.         notifyListeners();
  219.       }
  220.     });
  221.   }
  222.  
  223.   // Pause the timer
  224.   void pauseTimer() {
  225.     timer?.cancel();
  226.     // Do not reset remainingTime
  227.     notifyListeners();
  228.   }
  229.  
  230.   // Resume the timer
  231.   void resumeTimer() {
  232.     if (remainingTime > 0 && isConnected) {
  233.       startTimer();
  234.     }
  235.   }
  236.  
  237.   // Stop the timer and reset remainingTime
  238.   void stopTimer() {
  239.     timer?.cancel();
  240.     remainingTime = totalDuration;
  241.     notifyListeners();
  242.   }
  243.  
  244.   // Update latency
  245.   void updateLatency() async {
  246.     if (isConnected) {
  247.       try {
  248.         latency = await flutterV2ray.getConnectedServerDelay();
  249.       } catch (e) {
  250.         latency = 0;
  251.       }
  252.       notifyListeners();
  253.     }
  254.   }
  255.  
  256.   // Connection logging functions
  257.   void logConnectionStart() async {
  258.     if (_selectedConfig != null) {
  259.       ConnectionLog log = ConnectionLog(
  260.         serverName: _selectedConfig!.remark,
  261.         startTime: DateTime.now(),
  262.         duration: Duration.zero,
  263.         dataUploaded: 0,
  264.         dataDownloaded: 0,
  265.       );
  266.       _connectionLogs.add(log);
  267.       await StorageHelper.saveLog(log);
  268.       notifyListeners();
  269.     }
  270.   }
  271.  
  272.   void logConnectionEnd() async {
  273.     if (_connectionLogs.isNotEmpty) {
  274.       ConnectionLog lastLog = _connectionLogs.last;
  275.       if (lastLog.duration == Duration.zero) {
  276.         // Option 1: Mutable duration
  277.         lastLog.duration = Duration(seconds: totalDuration - remainingTime);
  278.         _connectionLogs[_connectionLogs.length - 1] = lastLog;
  279.         await StorageHelper.saveLog(lastLog);
  280.  
  281.         // Option 2: Immutable duration with copyWith
  282.         /*
  283.         ConnectionLog updatedLog = lastLog.copyWith(
  284.           duration: Duration(seconds: totalDuration - remainingTime),
  285.         );
  286.         _connectionLogs[_connectionLogs.length - 1] = updatedLog;
  287.         await StorageHelper.saveLog(updatedLog);
  288.         */
  289.  
  290.         notifyListeners();
  291.       }
  292.     }
  293.   }
  294.  
  295.   // **IP and Location Fetching**
  296.  
  297.   // Fetch IP and Location
  298.   Future<void> fetchIpAndLocation() async {
  299.     final url = Uri.parse('http://ip-api.com/json/');
  300.     try {
  301.       final response = await http.get(url);
  302.       if (response.statusCode == 200) {
  303.         final data = jsonDecode(response.body);
  304.         currentIp = data['query'] ?? 'Unknown IP';
  305.         country = data['country'] ?? 'Unknown Location';
  306.         network = data['as'] ?? 'Unknown Network';
  307.         notifyListeners();
  308.       } else {
  309.         throw Exception('Failed to fetch IP');
  310.       }
  311.     } catch (e) {
  312.       currentIp = 'Error fetching IP';
  313.       country = 'Error fetching location';
  314.       network = 'Error fetching network';
  315.       notifyListeners();
  316.       print('Error fetching IP and location: $e');
  317.     }
  318.   }
  319.  
  320.   // **Server Delay Testing**
  321.  
  322.   // Server Delay Function
  323.   void delay() async {
  324.     if (_selectedConfig == null || _selectedConfig!.configText.trim().isEmpty) {
  325.       print('No configuration selected for delay test');
  326.       // Optionally, notify UI to show a message
  327.       return;
  328.     }
  329.  
  330.     try {
  331.       int delayMs = await flutterV2ray.getServerDelay(
  332.           config: _selectedConfig!.configText);
  333.       print('Server Delay: $delayMs ms'); // Debug
  334.       // Optionally, notify UI to show the delay
  335.     } catch (e) {
  336.       print('Error fetching server delay: $e'); // Debug
  337.       // Optionally, notify UI to show a message
  338.     }
  339.   }
  340. }
  341.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement