mirror of
https://github.com/2dust/v2rayN.git
synced 2026-04-16 04:25:45 +00:00
Add LiteConnectionBridge class in Lite directory
This commit is contained in:
parent
55b08de5fe
commit
90fec23835
1 changed files with 244 additions and 0 deletions
244
Lite/LiteConnectionBridge.cs
Normal file
244
Lite/LiteConnectionBridge.cs
Normal file
|
|
@ -0,0 +1,244 @@
|
|||
namespace v2rayN.Lite;
|
||||
|
||||
/// <summary>
|
||||
/// Bridge to v2rayN backend infrastructure for Lite UI
|
||||
/// Handles VLESS profile import, config generation, and connection management
|
||||
/// while reusing existing AppManager, ConfigHandler, CoreManager infrastructure
|
||||
/// </summary>
|
||||
public class LiteConnectionBridge
|
||||
{
|
||||
private const string LiteProfileName = "VPN RUS Client Lite";
|
||||
private string? _currentProfileId;
|
||||
|
||||
public async Task<bool> ConnectAsync(string vlessLink, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Validate VLESS link
|
||||
if (!vlessLink.StartsWith("vless://", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
// Import/update VLESS profile using existing v2rayN infrastructure
|
||||
_currentProfileId = await ImportVlessProfileAsync(vlessLink, cancellationToken);
|
||||
|
||||
if (string.IsNullOrEmpty(_currentProfileId))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
// Set profile as active
|
||||
var profile = AppManager.Instance?.GetProfileById(_currentProfileId);
|
||||
if (profile == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
AppManager.Instance?.SetActiveProfile(_currentProfileId);
|
||||
|
||||
// Enable TUN in the profile configuration
|
||||
profile.EnableTun = true;
|
||||
ConfigHandler.SaveProfile(profile);
|
||||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
// Start the core using existing v2rayN pipeline
|
||||
// This reuses CoreConfigContextBuilder → CoreConfigHandler → CoreManager
|
||||
await Task.Delay(500, cancellationToken);
|
||||
var result = await CoreManager.Instance.StartAsync();
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.SaveLog(nameof(LiteConnectionBridge), ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<bool> DisconnectAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
// Stop core using existing CoreManager
|
||||
var result = await CoreManager.Instance.StopAsync();
|
||||
|
||||
await Task.Delay(300, cancellationToken);
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.SaveLog(nameof(LiteConnectionBridge), ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsConnected()
|
||||
{
|
||||
try
|
||||
{
|
||||
return CoreManager.Instance.IsRunning();
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<string?> ImportVlessProfileAsync(string vlessLink, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
// Check if Lite profile already exists
|
||||
var existingProfile = AppManager.Instance?.GetProfiles()
|
||||
.FirstOrDefault(p => p.Name == LiteProfileName);
|
||||
|
||||
ProfileItem profile;
|
||||
|
||||
if (existingProfile != null)
|
||||
{
|
||||
// Update existing profile
|
||||
profile = existingProfile;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create new profile
|
||||
var groupId = await GetOrCreateLiteGroupAsync(cancellationToken);
|
||||
profile = new ProfileItem
|
||||
{
|
||||
Name = LiteProfileName,
|
||||
GroupId = groupId
|
||||
};
|
||||
}
|
||||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
// Parse VLESS link and update profile
|
||||
if (!ParseVlessLink(vlessLink, profile))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// Save profile
|
||||
ConfigHandler.SaveProfile(profile);
|
||||
|
||||
return profile.Id;
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.SaveLog(nameof(LiteConnectionBridge), ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private bool ParseVlessLink(string vlessLink, ProfileItem profile)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Basic VLESS link parsing
|
||||
// Format: vless://uuid@host:port?encryption=none&security=reality&sni=domain&fp=...
|
||||
|
||||
if (!Uri.TryCreate(vlessLink, UriKind.Absolute, out var uri))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Extract UUID (user info)
|
||||
var userInfo = uri.UserInfo;
|
||||
if (string.IsNullOrEmpty(userInfo))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Extract host and port
|
||||
var host = uri.Host;
|
||||
var port = uri.Port > 0 ? uri.Port : 443;
|
||||
|
||||
if (string.IsNullOrEmpty(host))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Parse query parameters
|
||||
var query = System.Web.HttpUtility.ParseQueryString(uri.Query);
|
||||
var security = query["security"] ?? "reality";
|
||||
var sni = query["sni"] ?? host;
|
||||
var fp = query["fp"] ?? "chrome";
|
||||
|
||||
// Update profile with parsed VLESS data
|
||||
profile.Address = host;
|
||||
profile.Port = port;
|
||||
profile.Security = security;
|
||||
profile.Sni = sni;
|
||||
profile.Fingerprint = fp;
|
||||
profile.Protocol = EProtocol.VLESS;
|
||||
|
||||
// Enable TUN
|
||||
profile.EnableTun = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.SaveLog(nameof(LiteConnectionBridge), ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<string> GetOrCreateLiteGroupAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
var liteGroup = AppManager.Instance?.GetProfileGroups()
|
||||
.FirstOrDefault(g => g.GroupName == LiteProfileName);
|
||||
|
||||
if (liteGroup != null)
|
||||
{
|
||||
return liteGroup.Id;
|
||||
}
|
||||
|
||||
// Create new group
|
||||
var newGroup = new ProfileGroup
|
||||
{
|
||||
GroupName = LiteProfileName
|
||||
};
|
||||
|
||||
ConfigHandler.SaveProfileGroup(newGroup);
|
||||
|
||||
return newGroup.Id;
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.SaveLog(nameof(LiteConnectionBridge), ex);
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue