mirror of
https://github.com/2dust/v2rayN.git
synced 2026-11-14 16:35:00 +03:00
Extract database queries from AppManager
Move configuration queries to ConfigDbQuery and profile migrations to ConfigDbManager. Update desktop, Web API, and test callers to use the new locations.
This commit is contained in:
@@ -33,7 +33,7 @@ public class ConfigHandlerCustomSubscriptionTests
|
||||
await SQLiteHelper.Instance.InsertAsync(oldProfile);
|
||||
|
||||
var count = await ConfigDbManager.AddBatchServers(config, FullXrayConfigs, subId, true);
|
||||
var profiles = await AppManager.Instance.ProfileItems(subId) ?? [];
|
||||
var profiles = await ConfigDbQuery.ProfileItems(subId) ?? [];
|
||||
|
||||
await count.Should().BeEqualTo(2);
|
||||
await profiles.Should().HaveCount(2);
|
||||
@@ -67,7 +67,7 @@ public class ConfigHandlerCustomSubscriptionTests
|
||||
|
||||
var invalidSubscription = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes("not a valid profile"));
|
||||
var count = await ConfigDbManager.AddBatchServers(config, invalidSubscription, subId, true);
|
||||
var profiles = await AppManager.Instance.ProfileItems(subId) ?? [];
|
||||
var profiles = await ConfigDbQuery.ProfileItems(subId) ?? [];
|
||||
|
||||
await (count < 1).Should().BeTrue();
|
||||
await profiles.Should().HaveCount(1);
|
||||
|
||||
@@ -41,11 +41,11 @@ public class CoreConfigContextBuilder
|
||||
RunCoreType = runCoreType,
|
||||
AllProxiesMap = [],
|
||||
AppConfig = config,
|
||||
FullConfigTemplate = await AppManager.Instance.GetFullConfigTemplateItem(coreType),
|
||||
FullConfigTemplate = await ConfigDbQuery.GetFullConfigTemplateItem(coreType),
|
||||
IsTunEnabled = config.TunModeItem.EnableTun,
|
||||
SimpleDnsItem = config.SimpleDNSItem,
|
||||
ProtectDomainList = [],
|
||||
RawDnsItem = await AppManager.Instance.GetDNSItem(coreType),
|
||||
RawDnsItem = await ConfigDbQuery.GetDNSItem(coreType),
|
||||
RoutingItem = await ConfigDbManager.GetDefaultRouting(config),
|
||||
IsWindows = Utils.IsWindows(),
|
||||
IsMacOS = Utils.IsMacOS(),
|
||||
@@ -73,7 +73,7 @@ public class CoreConfigContextBuilder
|
||||
ruleItem.OutboundTag = Global.ProxyTag;
|
||||
continue;
|
||||
}
|
||||
var ruleOutboundNode = await AppManager.Instance.GetProfileItemViaRemarks(ruleItem.OutboundTag);
|
||||
var ruleOutboundNode = await ConfigDbQuery.GetProfileItemViaRemarks(ruleItem.OutboundTag);
|
||||
if (ruleOutboundNode == null)
|
||||
{
|
||||
validatorResult.Warnings.Add(string.Format(ResUI.MsgRoutingRuleOutboundNodeNotFound,
|
||||
@@ -277,7 +277,7 @@ public class CoreConfigContextBuilder
|
||||
return (null, result);
|
||||
}
|
||||
|
||||
var subItem = await AppManager.Instance.GetSubItem(node.Subid);
|
||||
var subItem = await ConfigDbQuery.GetSubItem(node.Subid);
|
||||
if (subItem == null)
|
||||
{
|
||||
return (null, result);
|
||||
@@ -288,7 +288,7 @@ public class CoreConfigContextBuilder
|
||||
|
||||
if (!subItem.PrevProfile.IsNullOrEmpty())
|
||||
{
|
||||
prevNode = await AppManager.Instance.GetProfileItemViaRemarks(subItem.PrevProfile);
|
||||
prevNode = await ConfigDbQuery.GetProfileItemViaRemarks(subItem.PrevProfile);
|
||||
if (prevNode == null)
|
||||
{
|
||||
result.Warnings.Add(string.Format(ResUI.MsgSubscriptionPrevProfileNotFound, subItem.PrevProfile));
|
||||
@@ -296,7 +296,7 @@ public class CoreConfigContextBuilder
|
||||
}
|
||||
if (!subItem.NextProfile.IsNullOrEmpty())
|
||||
{
|
||||
nextNode = await AppManager.Instance.GetProfileItemViaRemarks(subItem.NextProfile);
|
||||
nextNode = await ConfigDbQuery.GetProfileItemViaRemarks(subItem.NextProfile);
|
||||
if (nextNode == null)
|
||||
{
|
||||
result.Warnings.Add(string.Format(ResUI.MsgSubscriptionNextProfileNotFound, subItem.NextProfile));
|
||||
|
||||
@@ -13,7 +13,7 @@ public class SubscriptionHandler(
|
||||
public async Task UpdateProcess(string subId)
|
||||
{
|
||||
await updateFunc?.Invoke(false, ResUI.MsgUpdateSubscriptionStart);
|
||||
var subItem = await AppManager.Instance.SubItems();
|
||||
var subItem = await ConfigDbQuery.SubItems();
|
||||
|
||||
if (subItem is not { Count: > 0 })
|
||||
{
|
||||
|
||||
@@ -104,7 +104,7 @@ public sealed class AppManager
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await MigrateProfileExtra();
|
||||
await ConfigDbManager.MigrateProfileExtra();
|
||||
}).Wait();
|
||||
|
||||
return true;
|
||||
@@ -168,480 +168,6 @@ public sealed class AppManager
|
||||
|
||||
#endregion Config
|
||||
|
||||
#region SqliteHelper
|
||||
|
||||
public async Task<List<SubItem>?> SubItems()
|
||||
{
|
||||
return await SQLiteHelper.Instance.TableAsync<SubItem>().OrderBy(t => t.Sort).ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<SubItem?> GetSubItem(string? subid)
|
||||
{
|
||||
return await SQLiteHelper.Instance.TableAsync<SubItem>().FirstOrDefaultAsync(t => t.Id == subid);
|
||||
}
|
||||
|
||||
public async Task<List<ProfileItem>?> ProfileItems(string subid)
|
||||
{
|
||||
if (subid.IsNullOrEmpty())
|
||||
{
|
||||
return await SQLiteHelper.Instance.TableAsync<ProfileItem>().ToListAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
return await SQLiteHelper.Instance.TableAsync<ProfileItem>().Where(t => t.Subid == subid).ToListAsync();
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<List<string>?> ProfileItemIndexes(string subid)
|
||||
{
|
||||
return (await ProfileItems(subid))?.Select(t => t.IndexId)?.ToList();
|
||||
}
|
||||
|
||||
public async Task<List<ProfileItemModel>?> ProfileModels(string subid, string filter)
|
||||
{
|
||||
var sql = @$"select a.IndexId
|
||||
,a.ConfigType
|
||||
,a.Remarks
|
||||
,a.Address
|
||||
,a.Port
|
||||
,a.Network
|
||||
,a.StreamSecurity
|
||||
,a.Subid
|
||||
,b.remarks as subRemarks
|
||||
from ProfileItem a
|
||||
left join SubItem b on a.subid = b.id
|
||||
where 1=1 ";
|
||||
if (subid.IsNotEmpty())
|
||||
{
|
||||
sql += $" and a.subid = '{subid}'";
|
||||
}
|
||||
if (filter.IsNotEmpty())
|
||||
{
|
||||
if (filter.Contains('\''))
|
||||
{
|
||||
filter = filter.Replace("'", "");
|
||||
}
|
||||
sql += string.Format(" and (a.remarks like '%{0}%' or a.address like '%{0}%') ", filter);
|
||||
}
|
||||
|
||||
return await SQLiteHelper.Instance.QueryAsync<ProfileItemModel>(sql);
|
||||
}
|
||||
|
||||
public async Task<ProfileItem?> GetProfileItem(string indexId)
|
||||
{
|
||||
if (indexId.IsNullOrEmpty())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return await SQLiteHelper.Instance.TableAsync<ProfileItem>().FirstOrDefaultAsync(it => it.IndexId == indexId);
|
||||
}
|
||||
|
||||
public async Task<List<ProfileItem>> GetProfileItemsByIndexIds(IEnumerable<string> indexIds)
|
||||
{
|
||||
var ids = indexIds.Where(id => !id.IsNullOrEmpty()).Distinct().ToList();
|
||||
if (ids.Count == 0)
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
if (ids.Count <= Global.SqliteMaxBatchSize)
|
||||
{
|
||||
return await SQLiteHelper.Instance.TableAsync<ProfileItem>()
|
||||
.Where(it => ids.Contains(it.IndexId))
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
var items = new List<ProfileItem>();
|
||||
for (var size = 0; size < ids.Count; size += Global.SqliteMaxBatchSize)
|
||||
{
|
||||
var chunk = ids.Skip(size).Take(Global.SqliteMaxBatchSize).ToList();
|
||||
var chunkItems = await SQLiteHelper.Instance.TableAsync<ProfileItem>()
|
||||
.Where(it => chunk.Contains(it.IndexId))
|
||||
.ToListAsync();
|
||||
|
||||
items.AddRange(chunkItems);
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
public async Task<Dictionary<string, ProfileItem>> GetProfileItemsByIndexIdsAsMap(IEnumerable<string> indexIds)
|
||||
{
|
||||
var items = await GetProfileItemsByIndexIds(indexIds);
|
||||
return items.ToDictionary(it => it.IndexId);
|
||||
}
|
||||
|
||||
public async Task<List<ProfileItem>> GetProfileItemsOrderedByIndexIds(IEnumerable<string> indexIds)
|
||||
{
|
||||
var ids = indexIds.Where(id => !id.IsNullOrEmpty()).Distinct().ToList();
|
||||
var items = await GetProfileItemsByIndexIds(ids);
|
||||
var itemMap = items.ToDictionary(it => it.IndexId);
|
||||
|
||||
return ids.Select(itemMap.GetValueOrDefault)
|
||||
.Where(item => item != null)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
public async Task<ProfileItem?> GetProfileItemViaRemarks(string? remarks)
|
||||
{
|
||||
if (remarks.IsNullOrEmpty())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return await SQLiteHelper.Instance.TableAsync<ProfileItem>().FirstOrDefaultAsync(it => it.Remarks == remarks);
|
||||
}
|
||||
|
||||
public async Task<List<RoutingItem>?> RoutingItems()
|
||||
{
|
||||
return await SQLiteHelper.Instance.TableAsync<RoutingItem>().OrderBy(t => t.Sort).ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<RoutingItem?> GetRoutingItem(string id)
|
||||
{
|
||||
return await SQLiteHelper.Instance.TableAsync<RoutingItem>().FirstOrDefaultAsync(it => it.Id == id);
|
||||
}
|
||||
|
||||
public async Task<List<DNSItem>?> DNSItems()
|
||||
{
|
||||
return await SQLiteHelper.Instance.TableAsync<DNSItem>().ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<DNSItem?> GetDNSItem(ECoreType eCoreType)
|
||||
{
|
||||
return await SQLiteHelper.Instance.TableAsync<DNSItem>().FirstOrDefaultAsync(it => it.CoreType == eCoreType);
|
||||
}
|
||||
|
||||
public async Task<List<FullConfigTemplateItem>?> FullConfigTemplateItem()
|
||||
{
|
||||
return await SQLiteHelper.Instance.TableAsync<FullConfigTemplateItem>().ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<FullConfigTemplateItem?> GetFullConfigTemplateItem(ECoreType eCoreType)
|
||||
{
|
||||
return await SQLiteHelper.Instance.TableAsync<FullConfigTemplateItem>().FirstOrDefaultAsync(it => it.CoreType == eCoreType);
|
||||
}
|
||||
|
||||
#pragma warning disable CS0618
|
||||
|
||||
public async Task MigrateProfileExtra()
|
||||
{
|
||||
await MigrateProfileExtraGroupV2ToV3();
|
||||
|
||||
await MigrateProfileExtraV2ToV3();
|
||||
|
||||
await MigrateProfileTransportV3ToV4();
|
||||
}
|
||||
|
||||
private async Task MigrateProfileExtraV2ToV3()
|
||||
{
|
||||
const int pageSize = 100;
|
||||
var offset = 0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
var sql = $"SELECT * FROM ProfileItem " +
|
||||
$"WHERE ConfigVersion < 3 " +
|
||||
$"AND ConfigType NOT IN ({(int)EConfigType.PolicyGroup}, {(int)EConfigType.ProxyChain}) " +
|
||||
$"LIMIT {pageSize} OFFSET {offset}";
|
||||
var batch = await SQLiteHelper.Instance.QueryAsync<ProfileItem>(sql);
|
||||
if (batch is null || batch.Count == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
var batchSuccessCount = await MigrateProfileExtraV2ToV3Sub(batch);
|
||||
|
||||
// Only increment offset by the number of failed items that remain in the result set
|
||||
// Successfully updated items are automatically excluded from future queries due to ConfigVersion = 3
|
||||
offset += batch.Count - batchSuccessCount;
|
||||
}
|
||||
|
||||
//await ProfileGroupItemManager.Instance.ClearAll();
|
||||
}
|
||||
|
||||
private async Task MigrateProfileTransportV3ToV4()
|
||||
{
|
||||
const int pageSize = 100;
|
||||
var offset = 0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
var sql = $"SELECT * FROM ProfileItem WHERE ConfigVersion = 3 LIMIT {pageSize} OFFSET {offset}";
|
||||
var batch = await SQLiteHelper.Instance.QueryAsync<ProfileItem>(sql);
|
||||
if (batch is null || batch.Count == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
var updateProfileItems = new List<ProfileItem>();
|
||||
foreach (var item in batch)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (item.Network == Global.RawNetworkAlias)
|
||||
{
|
||||
item.Network = nameof(ETransport.raw);
|
||||
}
|
||||
var transport = item.GetTransportExtra();
|
||||
var network = item.GetNetwork();
|
||||
|
||||
switch (network)
|
||||
{
|
||||
case nameof(ETransport.raw):
|
||||
transport = transport with
|
||||
{
|
||||
RawHeaderType = item.HeaderType.NullIfEmpty(),
|
||||
Host = item.RequestHost.NullIfEmpty(),
|
||||
Path = item.Path.NullIfEmpty(),
|
||||
};
|
||||
break;
|
||||
|
||||
case nameof(ETransport.ws):
|
||||
case nameof(ETransport.httpupgrade):
|
||||
transport = transport with
|
||||
{
|
||||
Host = item.RequestHost.NullIfEmpty(),
|
||||
Path = item.Path.NullIfEmpty(),
|
||||
};
|
||||
break;
|
||||
|
||||
case nameof(ETransport.xhttp):
|
||||
transport = transport with
|
||||
{
|
||||
Host = item.RequestHost.NullIfEmpty(),
|
||||
Path = item.Path.NullIfEmpty(),
|
||||
XhttpMode = item.HeaderType.NullIfEmpty(),
|
||||
XhttpExtra = item.Extra.NullIfEmpty(),
|
||||
};
|
||||
break;
|
||||
|
||||
case nameof(ETransport.grpc):
|
||||
transport = transport with
|
||||
{
|
||||
GrpcAuthority = item.RequestHost.NullIfEmpty(),
|
||||
GrpcServiceName = item.Path.NullIfEmpty(),
|
||||
GrpcMode = item.HeaderType.NullIfEmpty(),
|
||||
};
|
||||
break;
|
||||
|
||||
case nameof(ETransport.kcp):
|
||||
transport = transport with
|
||||
{
|
||||
KcpHeaderType = item.HeaderType.NullIfEmpty(),
|
||||
KcpSeed = item.Path.NullIfEmpty(),
|
||||
};
|
||||
break;
|
||||
|
||||
default:
|
||||
item.Network = Global.DefaultNetwork;
|
||||
transport = transport with
|
||||
{
|
||||
RawHeaderType = item.HeaderType.NullIfEmpty(),
|
||||
Host = item.RequestHost.NullIfEmpty(),
|
||||
};
|
||||
break;
|
||||
}
|
||||
|
||||
item.SetTransportExtra(transport);
|
||||
item.ConfigVersion = 4;
|
||||
updateProfileItems.Add(item);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.SaveLog($"MigrateProfileTransportV3ToV4 Error: {ex}");
|
||||
}
|
||||
}
|
||||
|
||||
if (updateProfileItems.Count > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
var count = await SQLiteHelper.Instance.UpdateAllAsync(updateProfileItems);
|
||||
offset += batch.Count - count;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.SaveLog($"MigrateProfileTransportV3ToV4 update error: {ex}");
|
||||
offset += batch.Count;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
offset += batch.Count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<int> MigrateProfileExtraV2ToV3Sub(List<ProfileItem> batch)
|
||||
{
|
||||
var updateProfileItems = new List<ProfileItem>();
|
||||
|
||||
foreach (var item in batch)
|
||||
{
|
||||
try
|
||||
{
|
||||
var extra = item.GetProtocolExtra();
|
||||
switch (item.ConfigType)
|
||||
{
|
||||
case EConfigType.Shadowsocks:
|
||||
extra = extra with { SsMethod = item.Security.NullIfEmpty() };
|
||||
break;
|
||||
|
||||
case EConfigType.VMess:
|
||||
extra = extra with
|
||||
{
|
||||
AlterId = item.AlterId.ToString(),
|
||||
VmessSecurity = item.Security.NullIfEmpty(),
|
||||
};
|
||||
break;
|
||||
|
||||
case EConfigType.VLESS:
|
||||
extra = extra with
|
||||
{
|
||||
Flow = item.Flow.NullIfEmpty(),
|
||||
VlessEncryption = item.Security,
|
||||
};
|
||||
break;
|
||||
|
||||
case EConfigType.Hysteria2:
|
||||
extra = extra with
|
||||
{
|
||||
SalamanderPass = item.Path.NullIfEmpty(),
|
||||
Ports = item.Ports.NullIfEmpty(),
|
||||
UpMbps = _config.HysteriaItem.UpMbps,
|
||||
DownMbps = _config.HysteriaItem.DownMbps,
|
||||
HopInterval = _config.HysteriaItem.HopInterval.ToString(),
|
||||
};
|
||||
break;
|
||||
|
||||
case EConfigType.TUIC:
|
||||
extra = extra with { CongestionControl = item.HeaderType.NullIfEmpty(), };
|
||||
item.Username = item.Id;
|
||||
item.Id = item.Security;
|
||||
item.Password = item.Security;
|
||||
break;
|
||||
|
||||
case EConfigType.HTTP:
|
||||
case EConfigType.SOCKS:
|
||||
item.Username = item.Security;
|
||||
break;
|
||||
|
||||
case EConfigType.WireGuard:
|
||||
extra = extra with
|
||||
{
|
||||
WgPublicKey = item.PublicKey.NullIfEmpty(),
|
||||
WgInterfaceAddress = item.RequestHost.NullIfEmpty(),
|
||||
WgReserved = item.Path.NullIfEmpty(),
|
||||
WgMtu = int.TryParse(item.ShortId, out var mtu) ? mtu : 1280
|
||||
};
|
||||
break;
|
||||
}
|
||||
|
||||
item.SetProtocolExtra(extra);
|
||||
|
||||
item.Password = item.Id;
|
||||
|
||||
item.ConfigVersion = 3;
|
||||
|
||||
updateProfileItems.Add(item);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.SaveLog($"MigrateProfileExtra Error: {ex}");
|
||||
}
|
||||
}
|
||||
|
||||
if (updateProfileItems.Count > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
var count = await SQLiteHelper.Instance.UpdateAllAsync(updateProfileItems);
|
||||
return count;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.SaveLog($"MigrateProfileExtraGroup update error: {ex}");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<bool> MigrateProfileExtraGroupV2ToV3()
|
||||
{
|
||||
var list = await SQLiteHelper.Instance.TableAsync<ProfileGroupItem>().ToListAsync();
|
||||
var groupItems = new ConcurrentDictionary<string, ProfileGroupItem>(list.Where(t => !string.IsNullOrEmpty(t.IndexId)).ToDictionary(t => t.IndexId!));
|
||||
|
||||
var sql = $"SELECT * FROM ProfileItem WHERE ConfigVersion < 3 AND ConfigType IN ({(int)EConfigType.PolicyGroup}, {(int)EConfigType.ProxyChain})";
|
||||
var items = await SQLiteHelper.Instance.QueryAsync<ProfileItem>(sql);
|
||||
|
||||
if (items is null || items.Count == 0)
|
||||
{
|
||||
Logging.SaveLog("MigrateProfileExtraGroup: No items to migrate.");
|
||||
return true;
|
||||
}
|
||||
|
||||
Logging.SaveLog($"MigrateProfileExtraGroup: Found {items.Count} group items to migrate.");
|
||||
|
||||
var updateProfileItems = new List<ProfileItem>();
|
||||
|
||||
foreach (var item in items)
|
||||
{
|
||||
try
|
||||
{
|
||||
var extra = item.GetProtocolExtra();
|
||||
|
||||
extra = extra with { GroupType = nameof(item.ConfigType) };
|
||||
groupItems.TryGetValue(item.IndexId, out var groupItem);
|
||||
if (groupItem != null && !groupItem.NotHasChild())
|
||||
{
|
||||
extra = extra with
|
||||
{
|
||||
ChildItems = groupItem.ChildItems,
|
||||
SubChildItems = groupItem.SubChildItems,
|
||||
Filter = groupItem.Filter,
|
||||
MultipleLoad = groupItem.MultipleLoad,
|
||||
};
|
||||
}
|
||||
|
||||
item.SetProtocolExtra(extra);
|
||||
|
||||
item.ConfigVersion = 3;
|
||||
updateProfileItems.Add(item);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.SaveLog($"MigrateProfileExtraGroup item error [{item.IndexId}]: {ex}");
|
||||
}
|
||||
}
|
||||
|
||||
if (updateProfileItems.Count > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
var count = await SQLiteHelper.Instance.UpdateAllAsync(updateProfileItems);
|
||||
Logging.SaveLog($"MigrateProfileExtraGroup: Successfully updated {updateProfileItems.Count} items.");
|
||||
return updateProfileItems.Count == count;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.SaveLog($"MigrateProfileExtraGroup update error: {ex}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
//await ProfileGroupItemManager.Instance.ClearAll();
|
||||
}
|
||||
|
||||
#pragma warning restore CS0618
|
||||
|
||||
#endregion SqliteHelper
|
||||
|
||||
#region Core Type
|
||||
|
||||
public List<string> GetShadowsocksSecurities(ProfileItem profileItem)
|
||||
|
||||
@@ -134,7 +134,7 @@ public class CoreManager
|
||||
|
||||
public async Task<ProcessService?> LoadCoreConfigSpeedtest(ServerTestItem testItem)
|
||||
{
|
||||
var node = await AppManager.Instance.GetProfileItem(testItem.IndexId);
|
||||
var node = await ConfigDbQuery.GetProfileItem(testItem.IndexId);
|
||||
if (node is null)
|
||||
{
|
||||
return null;
|
||||
|
||||
@@ -20,7 +20,7 @@ public static class ConfigDbManager
|
||||
/// <returns>Result of the operation (0 if successful, -1 if failed)</returns>
|
||||
public static async Task<int> AddServer(Config config, ProfileItem profileItem)
|
||||
{
|
||||
var item = await AppManager.Instance.GetProfileItem(profileItem.IndexId);
|
||||
var item = await ConfigDbQuery.GetProfileItem(profileItem.IndexId);
|
||||
if (item is null)
|
||||
{
|
||||
item = profileItem;
|
||||
@@ -142,7 +142,7 @@ public static class ConfigDbManager
|
||||
{
|
||||
foreach (var it in indexes)
|
||||
{
|
||||
var item = await AppManager.Instance.GetProfileItem(it.IndexId);
|
||||
var item = await ConfigDbQuery.GetProfileItem(it.IndexId);
|
||||
if (item is null)
|
||||
{
|
||||
continue;
|
||||
@@ -231,7 +231,7 @@ public static class ConfigDbManager
|
||||
/// <returns>The default profile item or null if none exists</returns>
|
||||
public static async Task<ProfileItem?> GetDefaultServer(Config config)
|
||||
{
|
||||
var item = await AppManager.Instance.GetProfileItem(config.IndexId);
|
||||
var item = await ConfigDbQuery.GetProfileItem(config.IndexId);
|
||||
if (item is null)
|
||||
{
|
||||
var item2 = await SQLiteHelper.Instance.TableAsync<ProfileItem>().FirstOrDefaultAsync();
|
||||
@@ -470,7 +470,7 @@ public static class ConfigDbManager
|
||||
/// <returns>0 if successful, -1 if failed</returns>
|
||||
public static async Task<int> EditCustomServer(Config config, ProfileItem profileItem)
|
||||
{
|
||||
var item = await AppManager.Instance.GetProfileItem(profileItem.IndexId);
|
||||
var item = await ConfigDbQuery.GetProfileItem(profileItem.IndexId);
|
||||
if (item is null)
|
||||
{
|
||||
item = profileItem;
|
||||
@@ -862,7 +862,7 @@ public static class ConfigDbManager
|
||||
/// <returns>0 if successful, -1 if failed</returns>
|
||||
public static async Task<int> SortServers(Config config, string subId, string colName, bool asc)
|
||||
{
|
||||
var lstModel = await AppManager.Instance.ProfileModels(subId, "");
|
||||
var lstModel = await ConfigDbQuery.ProfileModels(subId, "");
|
||||
if (lstModel.Count <= 0)
|
||||
{
|
||||
return -1;
|
||||
@@ -1014,7 +1014,7 @@ public static class ConfigDbManager
|
||||
/// <returns>Tuple with total count and remaining count after deduplication</returns>
|
||||
public static async Task<Tuple<int, int>> DedupServerList(Config config, string subId)
|
||||
{
|
||||
var lstProfile = await AppManager.Instance.ProfileItems(subId);
|
||||
var lstProfile = await ConfigDbQuery.ProfileItems(subId);
|
||||
if (lstProfile == null)
|
||||
{
|
||||
return new Tuple<int, int>(0, 0);
|
||||
@@ -1251,7 +1251,7 @@ public static class ConfigDbManager
|
||||
{
|
||||
try
|
||||
{
|
||||
var item = await AppManager.Instance.GetProfileItem(indexId);
|
||||
var item = await ConfigDbQuery.GetProfileItem(indexId);
|
||||
if (item == null)
|
||||
{
|
||||
return 0;
|
||||
@@ -1352,7 +1352,7 @@ public static class ConfigDbManager
|
||||
result.Success = false;
|
||||
return result;
|
||||
}
|
||||
var childProfiles = await AppManager.Instance.ProfileItems(subId);
|
||||
var childProfiles = await ConfigDbQuery.ProfileItems(subId);
|
||||
List<string> indexIdList = [];
|
||||
|
||||
foreach (var regionFilter in PolicyGroupRegionFilters)
|
||||
@@ -1453,7 +1453,7 @@ public static class ConfigDbManager
|
||||
/// <returns>Number of removed servers or -1 if failed</returns>
|
||||
public static async Task<int> RemoveInvalidServerResult(Config config, string subid)
|
||||
{
|
||||
var lstModel = await AppManager.Instance.ProfileModels(subid, "");
|
||||
var lstModel = await ConfigDbQuery.ProfileModels(subid, "");
|
||||
lstModel.RemoveAll(t => t.ConfigType.IsComplexType());
|
||||
if (lstModel is { Count: <= 0 })
|
||||
{
|
||||
@@ -1494,8 +1494,8 @@ public static class ConfigDbManager
|
||||
var preResolver = string.Empty;
|
||||
if (isSub && subid.IsNotEmpty())
|
||||
{
|
||||
subFilter = (await AppManager.Instance.GetSubItem(subid))?.Filter ?? "";
|
||||
preResolver = (await AppManager.Instance.GetSubItem(subid))?.PreResolver ?? "";
|
||||
subFilter = (await ConfigDbQuery.GetSubItem(subid))?.Filter ?? "";
|
||||
preResolver = (await ConfigDbQuery.GetSubItem(subid))?.PreResolver ?? "";
|
||||
}
|
||||
|
||||
var dnsClient = preResolver.IsNullOrEmpty() ? null : EndpointResolveManager.BuildDnsClient(preResolver);
|
||||
@@ -1599,7 +1599,7 @@ public static class ConfigDbManager
|
||||
return -1;
|
||||
}
|
||||
|
||||
var subItem = await AppManager.Instance.GetSubItem(subid);
|
||||
var subItem = await ConfigDbQuery.GetSubItem(subid);
|
||||
|
||||
if (subItem?.CustomCoreType is null)
|
||||
{
|
||||
@@ -1926,7 +1926,7 @@ public static class ConfigDbManager
|
||||
ProfileItem? activeProfile = null;
|
||||
if (isSub && subid.IsNotEmpty())
|
||||
{
|
||||
lstOriSub = await AppManager.Instance.ProfileItems(subid);
|
||||
lstOriSub = await ConfigDbQuery.ProfileItems(subid);
|
||||
activeProfile = lstOriSub?.FirstOrDefault(t => t.IndexId == config.IndexId);
|
||||
}
|
||||
|
||||
@@ -1995,7 +1995,7 @@ public static class ConfigDbManager
|
||||
//Select active node
|
||||
if (activeProfile != null)
|
||||
{
|
||||
var lstSub = await AppManager.Instance.ProfileItems(subid);
|
||||
var lstSub = await ConfigDbQuery.ProfileItems(subid);
|
||||
var existItem = FindMatchedProfileItem(lstSub, activeProfile);
|
||||
if (existItem != null)
|
||||
{
|
||||
@@ -2006,7 +2006,7 @@ public static class ConfigDbManager
|
||||
//Keep the last traffic statistics
|
||||
if (lstOriSub != null)
|
||||
{
|
||||
var lstSub = await AppManager.Instance.ProfileItems(subid);
|
||||
var lstSub = await ConfigDbQuery.ProfileItems(subid);
|
||||
foreach (var item in lstSub)
|
||||
{
|
||||
var existItem = FindMatchedProfileItem(lstOriSub, item);
|
||||
@@ -2072,7 +2072,7 @@ public static class ConfigDbManager
|
||||
/// <returns>0 if successful, -1 if failed</returns>
|
||||
public static async Task<int> AddSubItem(Config config, SubItem subItem)
|
||||
{
|
||||
var item = await AppManager.Instance.GetSubItem(subItem.Id);
|
||||
var item = await ConfigDbQuery.GetSubItem(subItem.Id);
|
||||
if (item is null)
|
||||
{
|
||||
item = subItem;
|
||||
@@ -2107,7 +2107,7 @@ public static class ConfigDbManager
|
||||
var maxSort = 0;
|
||||
if (await SQLiteHelper.Instance.TableAsync<SubItem>().CountAsync() > 0)
|
||||
{
|
||||
var lstSubs = await AppManager.Instance.SubItems();
|
||||
var lstSubs = await ConfigDbQuery.SubItems();
|
||||
maxSort = lstSubs.LastOrDefault()?.Sort ?? 0;
|
||||
}
|
||||
item.Sort = maxSort + 1;
|
||||
@@ -2161,7 +2161,7 @@ public static class ConfigDbManager
|
||||
/// <returns>0 if successful</returns>
|
||||
public static async Task<int> DeleteSubItem(Config config, string id)
|
||||
{
|
||||
var item = await AppManager.Instance.GetSubItem(id);
|
||||
var item = await ConfigDbQuery.GetSubItem(id);
|
||||
if (item is null)
|
||||
{
|
||||
return 0;
|
||||
@@ -2171,7 +2171,7 @@ public static class ConfigDbManager
|
||||
|
||||
if (item.Id == config.SubIndexId)
|
||||
{
|
||||
var subs = await AppManager.Instance.SubItems();
|
||||
var subs = await ConfigDbQuery.SubItems();
|
||||
config.SubIndexId = subs.LastOrDefault()?.Id;
|
||||
}
|
||||
|
||||
@@ -2351,7 +2351,7 @@ public static class ConfigDbManager
|
||||
/// <returns>0 if successful</returns>
|
||||
public static async Task<int> SetDefaultRouting(Config config, RoutingItem routingItem)
|
||||
{
|
||||
var items = await AppManager.Instance.RoutingItems();
|
||||
var items = await ConfigDbQuery.RoutingItems();
|
||||
if (items.Any(t => t.Id == routingItem.Id && t.IsActive == true))
|
||||
{
|
||||
return -1;
|
||||
@@ -2435,7 +2435,7 @@ public static class ConfigDbManager
|
||||
return await InitBuiltinRouting(config, blImportAdvancedRules); // fallback
|
||||
}
|
||||
|
||||
var items = await AppManager.Instance.RoutingItems();
|
||||
var items = await ConfigDbQuery.RoutingItems();
|
||||
var maxSort = items.Count;
|
||||
if (!blImportAdvancedRules && items.Where(t => t.Remarks.StartsWith(template.Version)).ToList().Count > 0)
|
||||
{
|
||||
@@ -2486,14 +2486,14 @@ public static class ConfigDbManager
|
||||
public static async Task<int> InitBuiltinRouting(Config config, bool blImportAdvancedRules = false)
|
||||
{
|
||||
var ver = "V4-";
|
||||
var items = await AppManager.Instance.RoutingItems();
|
||||
var items = await ConfigDbQuery.RoutingItems();
|
||||
|
||||
//TODO Temporary code to be removed later
|
||||
var lockItem = items?.FirstOrDefault(t => t.Locked == true);
|
||||
if (lockItem != null)
|
||||
{
|
||||
await ConfigDbManager.RemoveRoutingItem(lockItem);
|
||||
items = await AppManager.Instance.RoutingItems();
|
||||
items = await ConfigDbQuery.RoutingItems();
|
||||
}
|
||||
|
||||
if (!blImportAdvancedRules && items.Count() > 0) // items.Count(u => u.Remarks.StartsWith(ver)) > 0)
|
||||
@@ -2570,7 +2570,7 @@ public static class ConfigDbManager
|
||||
/// <returns>0 if successful</returns>
|
||||
public static async Task<int> InitBuiltinDNS(Config config)
|
||||
{
|
||||
var items = await AppManager.Instance.DNSItems();
|
||||
var items = await ConfigDbQuery.DNSItems();
|
||||
|
||||
// Check existing DNS items and disable those with empty NormalDNS
|
||||
var needsUpdate = false;
|
||||
@@ -2648,7 +2648,7 @@ public static class ConfigDbManager
|
||||
/// <returns>DNS item with configuration from the URL</returns>
|
||||
public static async Task<DNSItem> GetExternalDNSItem(ECoreType type, string url)
|
||||
{
|
||||
var currentItem = await AppManager.Instance.GetDNSItem(type);
|
||||
var currentItem = await ConfigDbQuery.GetDNSItem(type);
|
||||
|
||||
using var downloadHandle = await DownloadService.CreateDownloadServiceWithCheck();
|
||||
var templateContent = await downloadHandle.TryDownloadString(url);
|
||||
@@ -2720,7 +2720,7 @@ public static class ConfigDbManager
|
||||
|
||||
public static async Task<int> InitBuiltinFullConfigTemplate(Config config)
|
||||
{
|
||||
var items = await AppManager.Instance.FullConfigTemplateItem();
|
||||
var items = await ConfigDbQuery.FullConfigTemplateItem();
|
||||
if (items.Count <= 0)
|
||||
{
|
||||
var item = new FullConfigTemplateItem()
|
||||
@@ -2840,4 +2840,328 @@ public static class ConfigDbManager
|
||||
}
|
||||
|
||||
#endregion Regional Presets
|
||||
|
||||
#region SqliteHelper
|
||||
|
||||
#pragma warning disable CS0618
|
||||
|
||||
public static async Task MigrateProfileExtra()
|
||||
{
|
||||
await MigrateProfileExtraGroupV2ToV3();
|
||||
|
||||
await MigrateProfileExtraV2ToV3();
|
||||
|
||||
await MigrateProfileTransportV3ToV4();
|
||||
}
|
||||
|
||||
private static async Task MigrateProfileExtraV2ToV3()
|
||||
{
|
||||
const int pageSize = 100;
|
||||
var offset = 0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
var sql = $"SELECT * FROM ProfileItem " +
|
||||
$"WHERE ConfigVersion < 3 " +
|
||||
$"AND ConfigType NOT IN ({(int)EConfigType.PolicyGroup}, {(int)EConfigType.ProxyChain}) " +
|
||||
$"LIMIT {pageSize} OFFSET {offset}";
|
||||
var batch = await SQLiteHelper.Instance.QueryAsync<ProfileItem>(sql);
|
||||
if (batch is null || batch.Count == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
var batchSuccessCount = await MigrateProfileExtraV2ToV3Sub(batch);
|
||||
|
||||
// Only increment offset by the number of failed items that remain in the result set
|
||||
// Successfully updated items are automatically excluded from future queries due to ConfigVersion = 3
|
||||
offset += batch.Count - batchSuccessCount;
|
||||
}
|
||||
|
||||
//await ProfileGroupItemManager.Instance.ClearAll();
|
||||
}
|
||||
|
||||
private static async Task MigrateProfileTransportV3ToV4()
|
||||
{
|
||||
const int pageSize = 100;
|
||||
var offset = 0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
var sql = $"SELECT * FROM ProfileItem WHERE ConfigVersion = 3 LIMIT {pageSize} OFFSET {offset}";
|
||||
var batch = await SQLiteHelper.Instance.QueryAsync<ProfileItem>(sql);
|
||||
if (batch is null || batch.Count == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
var updateProfileItems = new List<ProfileItem>();
|
||||
foreach (var item in batch)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (item.Network == Global.RawNetworkAlias)
|
||||
{
|
||||
item.Network = nameof(ETransport.raw);
|
||||
}
|
||||
var transport = item.GetTransportExtra();
|
||||
var network = item.GetNetwork();
|
||||
|
||||
switch (network)
|
||||
{
|
||||
case nameof(ETransport.raw):
|
||||
transport = transport with
|
||||
{
|
||||
RawHeaderType = item.HeaderType.NullIfEmpty(),
|
||||
Host = item.RequestHost.NullIfEmpty(),
|
||||
Path = item.Path.NullIfEmpty(),
|
||||
};
|
||||
break;
|
||||
|
||||
case nameof(ETransport.ws):
|
||||
case nameof(ETransport.httpupgrade):
|
||||
transport = transport with
|
||||
{
|
||||
Host = item.RequestHost.NullIfEmpty(),
|
||||
Path = item.Path.NullIfEmpty(),
|
||||
};
|
||||
break;
|
||||
|
||||
case nameof(ETransport.xhttp):
|
||||
transport = transport with
|
||||
{
|
||||
Host = item.RequestHost.NullIfEmpty(),
|
||||
Path = item.Path.NullIfEmpty(),
|
||||
XhttpMode = item.HeaderType.NullIfEmpty(),
|
||||
XhttpExtra = item.Extra.NullIfEmpty(),
|
||||
};
|
||||
break;
|
||||
|
||||
case nameof(ETransport.grpc):
|
||||
transport = transport with
|
||||
{
|
||||
GrpcAuthority = item.RequestHost.NullIfEmpty(),
|
||||
GrpcServiceName = item.Path.NullIfEmpty(),
|
||||
GrpcMode = item.HeaderType.NullIfEmpty(),
|
||||
};
|
||||
break;
|
||||
|
||||
case nameof(ETransport.kcp):
|
||||
transport = transport with
|
||||
{
|
||||
KcpHeaderType = item.HeaderType.NullIfEmpty(),
|
||||
KcpSeed = item.Path.NullIfEmpty(),
|
||||
};
|
||||
break;
|
||||
|
||||
default:
|
||||
item.Network = Global.DefaultNetwork;
|
||||
transport = transport with
|
||||
{
|
||||
RawHeaderType = item.HeaderType.NullIfEmpty(),
|
||||
Host = item.RequestHost.NullIfEmpty(),
|
||||
};
|
||||
break;
|
||||
}
|
||||
|
||||
item.SetTransportExtra(transport);
|
||||
item.ConfigVersion = 4;
|
||||
updateProfileItems.Add(item);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.SaveLog($"MigrateProfileTransportV3ToV4 Error: {ex}");
|
||||
}
|
||||
}
|
||||
|
||||
if (updateProfileItems.Count > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
var count = await SQLiteHelper.Instance.UpdateAllAsync(updateProfileItems);
|
||||
offset += batch.Count - count;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.SaveLog($"MigrateProfileTransportV3ToV4 update error: {ex}");
|
||||
offset += batch.Count;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
offset += batch.Count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task<int> MigrateProfileExtraV2ToV3Sub(List<ProfileItem> batch)
|
||||
{
|
||||
var updateProfileItems = new List<ProfileItem>();
|
||||
var config = ConfigTextManager.Instance.Config;
|
||||
|
||||
foreach (var item in batch)
|
||||
{
|
||||
try
|
||||
{
|
||||
var extra = item.GetProtocolExtra();
|
||||
switch (item.ConfigType)
|
||||
{
|
||||
case EConfigType.Shadowsocks:
|
||||
extra = extra with { SsMethod = item.Security.NullIfEmpty() };
|
||||
break;
|
||||
|
||||
case EConfigType.VMess:
|
||||
extra = extra with
|
||||
{
|
||||
AlterId = item.AlterId.ToString(),
|
||||
VmessSecurity = item.Security.NullIfEmpty(),
|
||||
};
|
||||
break;
|
||||
|
||||
case EConfigType.VLESS:
|
||||
extra = extra with
|
||||
{
|
||||
Flow = item.Flow.NullIfEmpty(),
|
||||
VlessEncryption = item.Security,
|
||||
};
|
||||
break;
|
||||
|
||||
case EConfigType.Hysteria2:
|
||||
extra = extra with
|
||||
{
|
||||
SalamanderPass = item.Path.NullIfEmpty(),
|
||||
Ports = item.Ports.NullIfEmpty(),
|
||||
UpMbps = config.HysteriaItem.UpMbps,
|
||||
DownMbps = config.HysteriaItem.DownMbps,
|
||||
HopInterval = config.HysteriaItem.HopInterval.ToString(),
|
||||
};
|
||||
break;
|
||||
|
||||
case EConfigType.TUIC:
|
||||
extra = extra with { CongestionControl = item.HeaderType.NullIfEmpty(), };
|
||||
item.Username = item.Id;
|
||||
item.Id = item.Security;
|
||||
item.Password = item.Security;
|
||||
break;
|
||||
|
||||
case EConfigType.HTTP:
|
||||
case EConfigType.SOCKS:
|
||||
item.Username = item.Security;
|
||||
break;
|
||||
|
||||
case EConfigType.WireGuard:
|
||||
extra = extra with
|
||||
{
|
||||
WgPublicKey = item.PublicKey.NullIfEmpty(),
|
||||
WgInterfaceAddress = item.RequestHost.NullIfEmpty(),
|
||||
WgReserved = item.Path.NullIfEmpty(),
|
||||
WgMtu = int.TryParse(item.ShortId, out var mtu) ? mtu : 1280
|
||||
};
|
||||
break;
|
||||
}
|
||||
|
||||
item.SetProtocolExtra(extra);
|
||||
|
||||
item.Password = item.Id;
|
||||
|
||||
item.ConfigVersion = 3;
|
||||
|
||||
updateProfileItems.Add(item);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.SaveLog($"MigrateProfileExtra Error: {ex}");
|
||||
}
|
||||
}
|
||||
|
||||
if (updateProfileItems.Count > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
var count = await SQLiteHelper.Instance.UpdateAllAsync(updateProfileItems);
|
||||
return count;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.SaveLog($"MigrateProfileExtraGroup update error: {ex}");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task<bool> MigrateProfileExtraGroupV2ToV3()
|
||||
{
|
||||
var list = await SQLiteHelper.Instance.TableAsync<ProfileGroupItem>().ToListAsync();
|
||||
var groupItems = new ConcurrentDictionary<string, ProfileGroupItem>(list.Where(t => !string.IsNullOrEmpty(t.IndexId)).ToDictionary(t => t.IndexId!));
|
||||
|
||||
var sql = $"SELECT * FROM ProfileItem WHERE ConfigVersion < 3 AND ConfigType IN ({(int)EConfigType.PolicyGroup}, {(int)EConfigType.ProxyChain})";
|
||||
var items = await SQLiteHelper.Instance.QueryAsync<ProfileItem>(sql);
|
||||
|
||||
if (items is null || items.Count == 0)
|
||||
{
|
||||
Logging.SaveLog("MigrateProfileExtraGroup: No items to migrate.");
|
||||
return true;
|
||||
}
|
||||
|
||||
Logging.SaveLog($"MigrateProfileExtraGroup: Found {items.Count} group items to migrate.");
|
||||
|
||||
var updateProfileItems = new List<ProfileItem>();
|
||||
|
||||
foreach (var item in items)
|
||||
{
|
||||
try
|
||||
{
|
||||
var extra = item.GetProtocolExtra();
|
||||
|
||||
extra = extra with { GroupType = nameof(item.ConfigType) };
|
||||
groupItems.TryGetValue(item.IndexId, out var groupItem);
|
||||
if (groupItem != null && !groupItem.NotHasChild())
|
||||
{
|
||||
extra = extra with
|
||||
{
|
||||
ChildItems = groupItem.ChildItems,
|
||||
SubChildItems = groupItem.SubChildItems,
|
||||
Filter = groupItem.Filter,
|
||||
MultipleLoad = groupItem.MultipleLoad,
|
||||
};
|
||||
}
|
||||
|
||||
item.SetProtocolExtra(extra);
|
||||
|
||||
item.ConfigVersion = 3;
|
||||
updateProfileItems.Add(item);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.SaveLog($"MigrateProfileExtraGroup item error [{item.IndexId}]: {ex}");
|
||||
}
|
||||
}
|
||||
|
||||
if (updateProfileItems.Count > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
var count = await SQLiteHelper.Instance.UpdateAllAsync(updateProfileItems);
|
||||
Logging.SaveLog($"MigrateProfileExtraGroup: Successfully updated {updateProfileItems.Count} items.");
|
||||
return updateProfileItems.Count == count;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.SaveLog($"MigrateProfileExtraGroup update error: {ex}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
//await ProfileGroupItemManager.Instance.ClearAll();
|
||||
}
|
||||
|
||||
#pragma warning restore CS0618
|
||||
|
||||
#endregion SqliteHelper
|
||||
}
|
||||
|
||||
@@ -0,0 +1,155 @@
|
||||
namespace ServiceLib.Manager.Data;
|
||||
|
||||
public class ConfigDbQuery
|
||||
{
|
||||
public static async Task<List<SubItem>?> SubItems()
|
||||
{
|
||||
return await SQLiteHelper.Instance.TableAsync<SubItem>().OrderBy(t => t.Sort).ToListAsync();
|
||||
}
|
||||
|
||||
public static async Task<SubItem?> GetSubItem(string? subid)
|
||||
{
|
||||
return await SQLiteHelper.Instance.TableAsync<SubItem>().FirstOrDefaultAsync(t => t.Id == subid);
|
||||
}
|
||||
|
||||
public static async Task<List<ProfileItem>?> ProfileItems(string subid)
|
||||
{
|
||||
if (subid.IsNullOrEmpty())
|
||||
{
|
||||
return await SQLiteHelper.Instance.TableAsync<ProfileItem>().ToListAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
return await SQLiteHelper.Instance.TableAsync<ProfileItem>().Where(t => t.Subid == subid).ToListAsync();
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task<List<string>?> ProfileItemIndexes(string subid)
|
||||
{
|
||||
return (await ProfileItems(subid))?.Select(t => t.IndexId)?.ToList();
|
||||
}
|
||||
|
||||
public static async Task<List<ProfileItemModel>?> ProfileModels(string subid, string filter)
|
||||
{
|
||||
var sql = @$"select a.IndexId
|
||||
,a.ConfigType
|
||||
,a.Remarks
|
||||
,a.Address
|
||||
,a.Port
|
||||
,a.Network
|
||||
,a.StreamSecurity
|
||||
,a.Subid
|
||||
,b.remarks as subRemarks
|
||||
from ProfileItem a
|
||||
left join SubItem b on a.subid = b.id
|
||||
where 1=1 ";
|
||||
if (subid.IsNotEmpty())
|
||||
{
|
||||
sql += $" and a.subid = '{subid}'";
|
||||
}
|
||||
if (filter.IsNotEmpty())
|
||||
{
|
||||
if (filter.Contains('\''))
|
||||
{
|
||||
filter = filter.Replace("'", "");
|
||||
}
|
||||
sql += string.Format(" and (a.remarks like '%{0}%' or a.address like '%{0}%') ", filter);
|
||||
}
|
||||
|
||||
return await SQLiteHelper.Instance.QueryAsync<ProfileItemModel>(sql);
|
||||
}
|
||||
|
||||
public static async Task<ProfileItem?> GetProfileItem(string indexId)
|
||||
{
|
||||
if (indexId.IsNullOrEmpty())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return await SQLiteHelper.Instance.TableAsync<ProfileItem>().FirstOrDefaultAsync(it => it.IndexId == indexId);
|
||||
}
|
||||
|
||||
public static async Task<List<ProfileItem>> GetProfileItemsByIndexIds(IEnumerable<string> indexIds)
|
||||
{
|
||||
var ids = indexIds.Where(id => !id.IsNullOrEmpty()).Distinct().ToList();
|
||||
if (ids.Count == 0)
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
if (ids.Count <= Global.SqliteMaxBatchSize)
|
||||
{
|
||||
return await SQLiteHelper.Instance.TableAsync<ProfileItem>()
|
||||
.Where(it => ids.Contains(it.IndexId))
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
var items = new List<ProfileItem>();
|
||||
for (var size = 0; size < ids.Count; size += Global.SqliteMaxBatchSize)
|
||||
{
|
||||
var chunk = ids.Skip(size).Take(Global.SqliteMaxBatchSize).ToList();
|
||||
var chunkItems = await SQLiteHelper.Instance.TableAsync<ProfileItem>()
|
||||
.Where(it => chunk.Contains(it.IndexId))
|
||||
.ToListAsync();
|
||||
|
||||
items.AddRange(chunkItems);
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
public static async Task<Dictionary<string, ProfileItem>> GetProfileItemsByIndexIdsAsMap(IEnumerable<string> indexIds)
|
||||
{
|
||||
var items = await GetProfileItemsByIndexIds(indexIds);
|
||||
return items.ToDictionary(it => it.IndexId);
|
||||
}
|
||||
|
||||
public static async Task<List<ProfileItem>> GetProfileItemsOrderedByIndexIds(IEnumerable<string> indexIds)
|
||||
{
|
||||
var ids = indexIds.Where(id => !id.IsNullOrEmpty()).Distinct().ToList();
|
||||
var items = await GetProfileItemsByIndexIds(ids);
|
||||
var itemMap = items.ToDictionary(it => it.IndexId);
|
||||
|
||||
return ids.Select(itemMap.GetValueOrDefault)
|
||||
.Where(item => item != null)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
public static async Task<ProfileItem?> GetProfileItemViaRemarks(string? remarks)
|
||||
{
|
||||
if (remarks.IsNullOrEmpty())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return await SQLiteHelper.Instance.TableAsync<ProfileItem>().FirstOrDefaultAsync(it => it.Remarks == remarks);
|
||||
}
|
||||
|
||||
public static async Task<List<RoutingItem>?> RoutingItems()
|
||||
{
|
||||
return await SQLiteHelper.Instance.TableAsync<RoutingItem>().OrderBy(t => t.Sort).ToListAsync();
|
||||
}
|
||||
|
||||
public static async Task<RoutingItem?> GetRoutingItem(string id)
|
||||
{
|
||||
return await SQLiteHelper.Instance.TableAsync<RoutingItem>().FirstOrDefaultAsync(it => it.Id == id);
|
||||
}
|
||||
|
||||
public static async Task<List<DNSItem>?> DNSItems()
|
||||
{
|
||||
return await SQLiteHelper.Instance.TableAsync<DNSItem>().ToListAsync();
|
||||
}
|
||||
|
||||
public static async Task<DNSItem?> GetDNSItem(ECoreType eCoreType)
|
||||
{
|
||||
return await SQLiteHelper.Instance.TableAsync<DNSItem>().FirstOrDefaultAsync(it => it.CoreType == eCoreType);
|
||||
}
|
||||
|
||||
public static async Task<List<FullConfigTemplateItem>?> FullConfigTemplateItem()
|
||||
{
|
||||
return await SQLiteHelper.Instance.TableAsync<FullConfigTemplateItem>().ToListAsync();
|
||||
}
|
||||
|
||||
public static async Task<FullConfigTemplateItem?> GetFullConfigTemplateItem(ECoreType eCoreType)
|
||||
{
|
||||
return await SQLiteHelper.Instance.TableAsync<FullConfigTemplateItem>().FirstOrDefaultAsync(it => it.CoreType == eCoreType);
|
||||
}
|
||||
}
|
||||
@@ -52,7 +52,7 @@ public class GroupProfileManager
|
||||
return false;
|
||||
}
|
||||
|
||||
var childItems = await AppManager.Instance.GetProfileItemsByIndexIds(childIds);
|
||||
var childItems = await ConfigDbQuery.GetProfileItemsByIndexIds(childIds);
|
||||
foreach (var childItem in childItems)
|
||||
{
|
||||
if (await HasCycle(childItem.IndexId, childItem.GetProtocolExtra(), visited, stack))
|
||||
@@ -103,7 +103,7 @@ public class GroupProfileManager
|
||||
return [];
|
||||
}
|
||||
|
||||
var ordered = await AppManager.Instance.GetProfileItemsOrderedByIndexIds(childProfileIds);
|
||||
var ordered = await ConfigDbQuery.GetProfileItemsOrderedByIndexIds(childProfileIds);
|
||||
return ordered;
|
||||
}
|
||||
|
||||
@@ -113,7 +113,7 @@ public class GroupProfileManager
|
||||
{
|
||||
return [];
|
||||
}
|
||||
var childProfiles = await AppManager.Instance.ProfileItems(extra.SubChildItems ?? string.Empty);
|
||||
var childProfiles = await ConfigDbQuery.ProfileItems(extra.SubChildItems ?? string.Empty);
|
||||
|
||||
return childProfiles?.Where(p =>
|
||||
p != null &&
|
||||
|
||||
@@ -89,7 +89,7 @@ public class TaskManager
|
||||
private async Task UpdateTaskRunSubscription()
|
||||
{
|
||||
var updateTime = ((DateTimeOffset)DateTime.Now).ToUnixTimeSeconds();
|
||||
var lstSubs = (await AppManager.Instance.SubItems())?
|
||||
var lstSubs = (await ConfigDbQuery.SubItems())?
|
||||
.Where(t => t.AutoUpdateInterval > 0)
|
||||
.Where(t => updateTime - t.UpdateTime >= t.AutoUpdateInterval * 60)
|
||||
.ToList();
|
||||
|
||||
@@ -137,7 +137,7 @@ public class SpeedtestService(Config config, Func<SpeedTestResult, Task> updateF
|
||||
&& (it.ConfigType.IsComplexType() || it.Port > 0))
|
||||
.Select(it => it.IndexId)
|
||||
.ToList();
|
||||
var profileMap = await AppManager.Instance.GetProfileItemsByIndexIdsAsMap(ids);
|
||||
var profileMap = await ConfigDbQuery.GetProfileItemsByIndexIdsAsMap(ids);
|
||||
for (var i = 0; i < selecteds.Count; i++)
|
||||
{
|
||||
var it = selecteds[i];
|
||||
|
||||
@@ -420,7 +420,7 @@ public partial class UpdateService(DownloadService downloadService, Config confi
|
||||
var geoSiteFiles = new List<string>();
|
||||
|
||||
// Collect from routing rules
|
||||
var routingItems = await AppManager.Instance.RoutingItems();
|
||||
var routingItems = await ConfigDbQuery.RoutingItems();
|
||||
foreach (var routing in routingItems)
|
||||
{
|
||||
var rules = JsonUtils.Deserialize<List<RulesItem>>(routing.RuleSet);
|
||||
@@ -432,7 +432,7 @@ public partial class UpdateService(DownloadService downloadService, Config confi
|
||||
}
|
||||
|
||||
// Collect from DNS configuration
|
||||
var dnsItem = await AppManager.Instance.GetDNSItem(ECoreType.sing_box);
|
||||
var dnsItem = await ConfigDbQuery.GetDNSItem(ECoreType.sing_box);
|
||||
if (dnsItem != null)
|
||||
{
|
||||
ExtractDnsRuleSets(dnsItem.NormalDNS, geoipFiles, geoSiteFiles);
|
||||
|
||||
@@ -97,14 +97,14 @@ public partial class AddGroupServerViewModel : MyReactiveObject, ICloseable
|
||||
_ => ResUI.TbLeastPing,
|
||||
};
|
||||
|
||||
var subs = await AppManager.Instance.SubItems();
|
||||
var subs = await ConfigDbQuery.SubItems();
|
||||
subs.Add(new SubItem());
|
||||
SubItems.AddRange(subs);
|
||||
SelectedSubItem = SubItems.FirstOrDefault(s => s.Id == protocolExtra?.SubChildItems);
|
||||
Filter = protocolExtra?.Filter;
|
||||
|
||||
var childIndexIds = Utils.String2List(protocolExtra?.ChildItems) ?? [];
|
||||
var childItemList = await AppManager.Instance.GetProfileItemsOrderedByIndexIds(childIndexIds);
|
||||
var childItemList = await ConfigDbQuery.GetProfileItemsOrderedByIndexIds(childIndexIds);
|
||||
ChildItemsObs.AddRange(childItemList);
|
||||
}
|
||||
|
||||
|
||||
@@ -89,7 +89,7 @@ public partial class AddServer2ViewModel : MyReactiveObject, ICloseable
|
||||
return;
|
||||
}
|
||||
|
||||
var item = await AppManager.Instance.GetProfileItem(SelectedSource.IndexId);
|
||||
var item = await ConfigDbQuery.GetProfileItem(SelectedSource.IndexId);
|
||||
item ??= SelectedSource;
|
||||
item.Address = fileName;
|
||||
var result = item.ConfigType == EConfigType.Outbound ? await ConfigDbManager.AddCustomOutboundServer(_config, item, false) : await ConfigDbManager.AddCustomServer(_config, item, false);
|
||||
|
||||
@@ -103,7 +103,7 @@ public partial class DNSSettingViewModel : MyReactiveObject, ICloseable
|
||||
ParallelQuery = item.ParallelQuery ?? false;
|
||||
ServeStale = item.ServeStale ?? false;
|
||||
EnableHappyEyeballs = item.EnableHappyEyeballs ?? false;
|
||||
var item1 = await AppManager.Instance.GetDNSItem(ECoreType.Xray);
|
||||
var item1 = await ConfigDbQuery.GetDNSItem(ECoreType.Xray);
|
||||
RayCustomDNSEnableCompatible = item1.Enabled;
|
||||
UseSystemHostsCompatible = item1.UseSystemHosts;
|
||||
DomainStrategy4FreedomCompatible = item1?.DomainStrategy4Freedom ?? string.Empty;
|
||||
@@ -111,7 +111,7 @@ public partial class DNSSettingViewModel : MyReactiveObject, ICloseable
|
||||
NormalDNSCompatible = item1?.NormalDNS ?? string.Empty;
|
||||
TunDNSCompatible = item1?.TunDNS ?? string.Empty;
|
||||
|
||||
var item2 = await AppManager.Instance.GetDNSItem(ECoreType.sing_box);
|
||||
var item2 = await ConfigDbQuery.GetDNSItem(ECoreType.sing_box);
|
||||
SBCustomDNSEnableCompatible = item2.Enabled;
|
||||
DomainStrategy4Freedom2Compatible = item2?.DomainStrategy4Freedom ?? string.Empty;
|
||||
DomainDNSAddress2Compatible = item2?.DomainDNSAddress ?? string.Empty;
|
||||
@@ -200,7 +200,7 @@ public partial class DNSSettingViewModel : MyReactiveObject, ICloseable
|
||||
}
|
||||
}
|
||||
|
||||
var item1 = await AppManager.Instance.GetDNSItem(ECoreType.Xray);
|
||||
var item1 = await ConfigDbQuery.GetDNSItem(ECoreType.Xray);
|
||||
item1.Enabled = RayCustomDNSEnableCompatible;
|
||||
item1.DomainStrategy4Freedom = DomainStrategy4FreedomCompatible;
|
||||
item1.DomainDNSAddress = DomainDNSAddressCompatible;
|
||||
@@ -209,7 +209,7 @@ public partial class DNSSettingViewModel : MyReactiveObject, ICloseable
|
||||
item1.TunDNS = TunDNSCompatible;
|
||||
await ConfigDbManager.SaveDNSItems(_config, item1);
|
||||
|
||||
var item2 = await AppManager.Instance.GetDNSItem(ECoreType.sing_box);
|
||||
var item2 = await ConfigDbQuery.GetDNSItem(ECoreType.sing_box);
|
||||
item2.Enabled = SBCustomDNSEnableCompatible;
|
||||
item2.DomainStrategy4Freedom = DomainStrategy4Freedom2Compatible;
|
||||
item2.DomainDNSAddress = DomainDNSAddress2Compatible;
|
||||
|
||||
@@ -55,7 +55,7 @@ public partial class FullConfigTemplateViewModel : MyReactiveObject, ICloseable
|
||||
|
||||
private async Task Init()
|
||||
{
|
||||
var item = await AppManager.Instance.GetFullConfigTemplateItem(ECoreType.Xray);
|
||||
var item = await ConfigDbQuery.GetFullConfigTemplateItem(ECoreType.Xray);
|
||||
if (item == null)
|
||||
{
|
||||
return;
|
||||
@@ -66,7 +66,7 @@ public partial class FullConfigTemplateViewModel : MyReactiveObject, ICloseable
|
||||
AddProxyOnly4Ray = item.AddProxyOnly ?? false;
|
||||
ProxyDetour4Ray = item.ProxyDetour ?? string.Empty;
|
||||
|
||||
var item2 = await AppManager.Instance.GetFullConfigTemplateItem(ECoreType.sing_box);
|
||||
var item2 = await ConfigDbQuery.GetFullConfigTemplateItem(ECoreType.sing_box);
|
||||
EnableFullConfigTemplate4Singbox = item2?.Enabled ?? false;
|
||||
FullConfigTemplate4Singbox = item2?.Config ?? string.Empty;
|
||||
FullTunConfigTemplate4Singbox = item2?.TunConfig ?? string.Empty;
|
||||
@@ -92,7 +92,7 @@ public partial class FullConfigTemplateViewModel : MyReactiveObject, ICloseable
|
||||
|
||||
private async Task<bool> SaveXrayConfigAsync()
|
||||
{
|
||||
var item = await AppManager.Instance.GetFullConfigTemplateItem(ECoreType.Xray);
|
||||
var item = await ConfigDbQuery.GetFullConfigTemplateItem(ECoreType.Xray);
|
||||
if (item == null)
|
||||
{
|
||||
return false;
|
||||
@@ -110,7 +110,7 @@ public partial class FullConfigTemplateViewModel : MyReactiveObject, ICloseable
|
||||
|
||||
private async Task<bool> SaveSingboxConfigAsync()
|
||||
{
|
||||
var item = await AppManager.Instance.GetFullConfigTemplateItem(ECoreType.sing_box);
|
||||
var item = await ConfigDbQuery.GetFullConfigTemplateItem(ECoreType.sing_box);
|
||||
if (item == null)
|
||||
{
|
||||
return false;
|
||||
|
||||
@@ -377,7 +377,7 @@ public partial class MainWindowViewModel : MyReactiveObject
|
||||
else
|
||||
{
|
||||
// The activity config belongs to the current group.
|
||||
var profile = await AppManager.Instance.GetProfileItem(_config.IndexId);
|
||||
var profile = await ConfigDbQuery.GetProfileItem(_config.IndexId);
|
||||
if (profile != null && profile.Subid == _config.SubIndexId)
|
||||
{
|
||||
await Reload();
|
||||
|
||||
@@ -169,7 +169,7 @@ public partial class ProfilesSelectViewModel : MyReactiveObject, ICloseable
|
||||
|
||||
private async Task RefreshSubscriptions()
|
||||
{
|
||||
var subItems = await AppManager.Instance.SubItems();
|
||||
var subItems = await ConfigDbQuery.SubItems();
|
||||
subItems.Insert(0, new SubItem { Remarks = ResUI.AllGroupServers });
|
||||
|
||||
SubItems.ReplaceRange(subItems);
|
||||
@@ -181,7 +181,7 @@ public partial class ProfilesSelectViewModel : MyReactiveObject, ICloseable
|
||||
|
||||
private async Task<List<ProfileItemModel>?> GetProfileItemsEx(string subid, string filter)
|
||||
{
|
||||
var lstModel = await AppManager.Instance.ProfileModels(_subIndexId, filter);
|
||||
var lstModel = await ConfigDbQuery.ProfileModels(_subIndexId, filter);
|
||||
var lstProfileExs = await ProfileExManager.Instance.GetProfileExs();
|
||||
lstModel = (from t in lstModel
|
||||
join t3 in lstProfileExs on t.IndexId equals t3.IndexId into t3b
|
||||
@@ -230,7 +230,7 @@ public partial class ProfilesSelectViewModel : MyReactiveObject, ICloseable
|
||||
return null;
|
||||
}
|
||||
var indexId = SelectedProfile.IndexId;
|
||||
var item = await AppManager.Instance.GetProfileItem(indexId);
|
||||
var item = await ConfigDbQuery.GetProfileItem(indexId);
|
||||
if (item is null)
|
||||
{
|
||||
NoticeManager.Instance.Enqueue(ResUI.PleaseSelectServer);
|
||||
@@ -245,7 +245,7 @@ public partial class ProfilesSelectViewModel : MyReactiveObject, ICloseable
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var lst = await AppManager.Instance.GetProfileItemsOrderedByIndexIds(SelectedProfiles.Select(sp => sp?.IndexId));
|
||||
var lst = await ConfigDbQuery.GetProfileItemsOrderedByIndexIds(SelectedProfiles.Select(sp => sp?.IndexId));
|
||||
if (lst.Count == 0)
|
||||
{
|
||||
NoticeManager.Instance.Enqueue(ResUI.PleaseSelectServer);
|
||||
|
||||
@@ -382,7 +382,7 @@ public partial class ProfilesViewModel : MyReactiveObject
|
||||
|
||||
public async Task RefreshSubscriptions()
|
||||
{
|
||||
var subItems = await AppManager.Instance.SubItems();
|
||||
var subItems = await ConfigDbQuery.SubItems();
|
||||
subItems.Insert(0, new SubItem { Remarks = ResUI.AllGroupServers });
|
||||
|
||||
SubItems.ReplaceRange(subItems);
|
||||
@@ -399,7 +399,7 @@ public partial class ProfilesViewModel : MyReactiveObject
|
||||
|
||||
private async Task<List<ProfileItemModel>?> GetProfileItemsEx(string subid, string filter)
|
||||
{
|
||||
var lstModel = await AppManager.Instance.ProfileModels(_config.SubIndexId, filter);
|
||||
var lstModel = await ConfigDbQuery.ProfileModels(_config.SubIndexId, filter);
|
||||
|
||||
await ConfigDbManager.SetDefaultServer(_config, lstModel);
|
||||
|
||||
@@ -453,7 +453,7 @@ public partial class ProfilesViewModel : MyReactiveObject
|
||||
var orderProfiles = SelectedProfiles?.OrderBy(t => t.Sort).ToList();
|
||||
if (latest)
|
||||
{
|
||||
lstSelected.AddRange(await AppManager.Instance.GetProfileItemsOrderedByIndexIds(orderProfiles.Select(sp => sp?.IndexId)));
|
||||
lstSelected.AddRange(await ConfigDbQuery.GetProfileItemsOrderedByIndexIds(orderProfiles.Select(sp => sp?.IndexId)));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -469,7 +469,7 @@ public partial class ProfilesViewModel : MyReactiveObject
|
||||
{
|
||||
return;
|
||||
}
|
||||
var item = await AppManager.Instance.GetProfileItem(SelectedProfile.IndexId);
|
||||
var item = await ConfigDbQuery.GetProfileItem(SelectedProfile.IndexId);
|
||||
if (item is null)
|
||||
{
|
||||
NoticeManager.Instance.Enqueue(ResUI.PleaseSelectServer);
|
||||
@@ -578,7 +578,7 @@ public partial class ProfilesViewModel : MyReactiveObject
|
||||
{
|
||||
return;
|
||||
}
|
||||
var item = await AppManager.Instance.GetProfileItem(indexId);
|
||||
var item = await ConfigDbQuery.GetProfileItem(indexId);
|
||||
if (item is null)
|
||||
{
|
||||
NoticeManager.Instance.Enqueue(ResUI.PleaseSelectServer);
|
||||
@@ -594,7 +594,7 @@ public partial class ProfilesViewModel : MyReactiveObject
|
||||
|
||||
public async Task ShareServerAsync()
|
||||
{
|
||||
var item = await AppManager.Instance.GetProfileItem(SelectedProfile.IndexId);
|
||||
var item = await ConfigDbQuery.GetProfileItem(SelectedProfile.IndexId);
|
||||
if (item is null)
|
||||
{
|
||||
NoticeManager.Instance.Enqueue(ResUI.PleaseSelectServer);
|
||||
@@ -771,7 +771,7 @@ public partial class ProfilesViewModel : MyReactiveObject
|
||||
|
||||
private async Task Export2ClientConfigAsync(bool blClipboard)
|
||||
{
|
||||
var item = await AppManager.Instance.GetProfileItem(SelectedProfile.IndexId);
|
||||
var item = await ConfigDbQuery.GetProfileItem(SelectedProfile.IndexId);
|
||||
if (item is null)
|
||||
{
|
||||
NoticeManager.Instance.Enqueue(ResUI.PleaseSelectServer);
|
||||
@@ -897,7 +897,7 @@ public partial class ProfilesViewModel : MyReactiveObject
|
||||
}
|
||||
else
|
||||
{
|
||||
item = await AppManager.Instance.GetSubItem(_config.SubIndexId);
|
||||
item = await ConfigDbQuery.GetSubItem(_config.SubIndexId);
|
||||
if (item is null)
|
||||
{
|
||||
return;
|
||||
@@ -913,7 +913,7 @@ public partial class ProfilesViewModel : MyReactiveObject
|
||||
|
||||
private async Task DeleteSubAsync()
|
||||
{
|
||||
var item = await AppManager.Instance.GetSubItem(_config.SubIndexId);
|
||||
var item = await ConfigDbQuery.GetSubItem(_config.SubIndexId);
|
||||
if (item is null)
|
||||
{
|
||||
return;
|
||||
|
||||
@@ -87,7 +87,7 @@ public partial class RoutingSettingViewModel : MyReactiveObject
|
||||
{
|
||||
var models = new List<RoutingItemModel>();
|
||||
|
||||
var routings = await AppManager.Instance.RoutingItems();
|
||||
var routings = await ConfigDbQuery.RoutingItems();
|
||||
foreach (var item in routings)
|
||||
{
|
||||
var it = new RoutingItemModel()
|
||||
@@ -127,7 +127,7 @@ public partial class RoutingSettingViewModel : MyReactiveObject
|
||||
}
|
||||
else
|
||||
{
|
||||
item = await AppManager.Instance.GetRoutingItem(SelectedSource?.Id);
|
||||
item = await ConfigDbQuery.GetRoutingItem(SelectedSource?.Id);
|
||||
if (item is null)
|
||||
{
|
||||
return;
|
||||
@@ -154,7 +154,7 @@ public partial class RoutingSettingViewModel : MyReactiveObject
|
||||
}
|
||||
foreach (var it in SelectedSources ?? [SelectedSource])
|
||||
{
|
||||
var item = await AppManager.Instance.GetRoutingItem(it?.Id);
|
||||
var item = await ConfigDbQuery.GetRoutingItem(it?.Id);
|
||||
if (item != null)
|
||||
{
|
||||
await ConfigDbManager.RemoveRoutingItem(item);
|
||||
@@ -167,7 +167,7 @@ public partial class RoutingSettingViewModel : MyReactiveObject
|
||||
|
||||
public async Task RoutingAdvancedSetDefault()
|
||||
{
|
||||
var item = await AppManager.Instance.GetRoutingItem(SelectedSource?.Id);
|
||||
var item = await ConfigDbQuery.GetRoutingItem(SelectedSource?.Id);
|
||||
if (item is null)
|
||||
{
|
||||
NoticeManager.Instance.Enqueue(ResUI.PleaseSelectRules);
|
||||
|
||||
@@ -287,7 +287,7 @@ public partial class StatusBarViewModel : MyReactiveObject
|
||||
|
||||
private async Task RefreshServersMenu()
|
||||
{
|
||||
var lstModel = await AppManager.Instance.ProfileModels(_config.SubIndexId, "");
|
||||
var lstModel = await ConfigDbQuery.ProfileModels(_config.SubIndexId, "");
|
||||
|
||||
if (lstModel?.Count > _config.GuiItem.TrayMenuServersLimit)
|
||||
{
|
||||
@@ -393,7 +393,7 @@ public partial class StatusBarViewModel : MyReactiveObject
|
||||
|
||||
public async Task RefreshRoutingsMenu()
|
||||
{
|
||||
var routings = await AppManager.Instance.RoutingItems();
|
||||
var routings = await ConfigDbQuery.RoutingItems();
|
||||
|
||||
RoutingItems.ReplaceRange(routings);
|
||||
|
||||
@@ -407,7 +407,7 @@ public partial class StatusBarViewModel : MyReactiveObject
|
||||
return;
|
||||
}
|
||||
|
||||
var item = await AppManager.Instance.GetRoutingItem(SelectedRouting?.Id);
|
||||
var item = await ConfigDbQuery.GetRoutingItem(SelectedRouting?.Id);
|
||||
if (item is null)
|
||||
{
|
||||
return;
|
||||
|
||||
@@ -57,7 +57,7 @@ public partial class SubSettingViewModel : MyReactiveObject
|
||||
|
||||
public async Task RefreshSubItems()
|
||||
{
|
||||
SubItems.ReplaceRange(await AppManager.Instance.SubItems());
|
||||
SubItems.ReplaceRange(await ConfigDbQuery.SubItems());
|
||||
}
|
||||
|
||||
public async Task EditSubAsync(bool blNew)
|
||||
@@ -69,7 +69,7 @@ public partial class SubSettingViewModel : MyReactiveObject
|
||||
}
|
||||
else
|
||||
{
|
||||
item = await AppManager.Instance.GetSubItem(SelectedSource?.Id);
|
||||
item = await ConfigDbQuery.GetSubItem(SelectedSource?.Id);
|
||||
if (item is null)
|
||||
{
|
||||
return;
|
||||
|
||||
@@ -758,7 +758,7 @@ public sealed partial class V2rayRuntime
|
||||
{
|
||||
if (originalCoreWasRunning)
|
||||
{
|
||||
runningProfile = await AppManager.Instance.GetProfileItem(CurrentCoreRuntime.ProfileId ?? string.Empty);
|
||||
runningProfile = await ConfigDbQuery.GetProfileItem(CurrentCoreRuntime.ProfileId ?? string.Empty);
|
||||
if (runningProfile is null)
|
||||
{
|
||||
return new CoreUpdateApplyResult(false, false, true, "The active profile could not be loaded; the running Core was left unchanged.");
|
||||
@@ -1213,7 +1213,7 @@ public sealed partial class V2rayRuntime
|
||||
var geoipRules = new List<string>();
|
||||
var geositeRules = new List<string>();
|
||||
|
||||
var routingItems = await AppManager.Instance.RoutingItems();
|
||||
var routingItems = await ConfigDbQuery.RoutingItems();
|
||||
foreach (var routing in routingItems ?? [])
|
||||
{
|
||||
var rules = JsonUtils.Deserialize<List<RulesItem>>(routing.RuleSet);
|
||||
@@ -1224,7 +1224,7 @@ public sealed partial class V2rayRuntime
|
||||
}
|
||||
}
|
||||
|
||||
var dnsItem = await AppManager.Instance.GetDNSItem(ECoreType.sing_box);
|
||||
var dnsItem = await ConfigDbQuery.GetDNSItem(ECoreType.sing_box);
|
||||
if (dnsItem is not null)
|
||||
{
|
||||
ExtractDnsRuleSets(dnsItem.NormalDNS, geoipRules, geositeRules);
|
||||
|
||||
@@ -9,8 +9,8 @@ public sealed partial class V2rayRuntime
|
||||
{
|
||||
public async Task<IReadOnlyList<ProfileGroupView>> GetProfileGroupsAsync()
|
||||
{
|
||||
var subscriptions = await AppManager.Instance.SubItems() ?? [];
|
||||
var profiles = await AppManager.Instance.ProfileItems(string.Empty) ?? [];
|
||||
var subscriptions = await ConfigDbQuery.SubItems() ?? [];
|
||||
var profiles = await ConfigDbQuery.ProfileItems(string.Empty) ?? [];
|
||||
var counts = profiles.GroupBy(item => item.Subid).ToDictionary(group => group.Key, group => group.Count());
|
||||
var groups = new List<ProfileGroupView>
|
||||
{
|
||||
@@ -31,7 +31,7 @@ public sealed partial class V2rayRuntime
|
||||
public async Task<OperationView> SelectProfileGroupAsync(string? subscriptionId)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(subscriptionId)
|
||||
&& await AppManager.Instance.GetSubItem(subscriptionId) is null)
|
||||
&& await ConfigDbQuery.GetSubItem(subscriptionId) is null)
|
||||
{
|
||||
return OperationView.Fail("subscription_not_found", ApiMessageKeys.SubscriptionNotFound);
|
||||
}
|
||||
@@ -53,7 +53,7 @@ public sealed partial class V2rayRuntime
|
||||
}
|
||||
|
||||
var groupId = request.SubscriptionId ?? Config.SubIndexId ?? string.Empty;
|
||||
if (!string.IsNullOrEmpty(groupId) && await AppManager.Instance.GetSubItem(groupId) is null)
|
||||
if (!string.IsNullOrEmpty(groupId) && await ConfigDbQuery.GetSubItem(groupId) is null)
|
||||
{
|
||||
return OperationView.Fail("subscription_not_found", ApiMessageKeys.SubscriptionNotFound, new { imported = 0 });
|
||||
}
|
||||
@@ -87,7 +87,7 @@ public sealed partial class V2rayRuntime
|
||||
var isNew = string.IsNullOrWhiteSpace(profileId);
|
||||
if (!isNew)
|
||||
{
|
||||
var existing = await AppManager.Instance.GetProfileItem(profileId!);
|
||||
var existing = await ConfigDbQuery.GetProfileItem(profileId!);
|
||||
if (existing is null)
|
||||
{
|
||||
return OperationView.Fail("profile_not_found", ApiMessageKeys.ProfileNotFound);
|
||||
@@ -106,7 +106,7 @@ public sealed partial class V2rayRuntime
|
||||
profile.Subid = Config.SubIndexId ?? string.Empty;
|
||||
profile.IsSub = false;
|
||||
if (!string.IsNullOrEmpty(profile.Subid)
|
||||
&& await AppManager.Instance.GetSubItem(profile.Subid) is null)
|
||||
&& await ConfigDbQuery.GetSubItem(profile.Subid) is null)
|
||||
{
|
||||
AddLog("profile", $"Rejected profile creation for missing subscription group {profile.Subid}.");
|
||||
return OperationView.Fail("subscription_not_found", ApiMessageKeys.SubscriptionNotFound,
|
||||
@@ -126,11 +126,11 @@ public sealed partial class V2rayRuntime
|
||||
return OperationView.Fail("profile_group_invalid", ApiMessageKeys.ProfileInvalid);
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(protocolExtra.SubChildItems)
|
||||
&& await AppManager.Instance.GetSubItem(protocolExtra.SubChildItems) is null)
|
||||
&& await ConfigDbQuery.GetSubItem(protocolExtra.SubChildItems) is null)
|
||||
{
|
||||
return OperationView.Fail("subscription_not_found", ApiMessageKeys.SubscriptionNotFound);
|
||||
}
|
||||
var children = await AppManager.Instance.GetProfileItemsByIndexIds(childIds);
|
||||
var children = await ConfigDbQuery.GetProfileItemsByIndexIds(childIds);
|
||||
if (children.Count != childIds.Distinct(StringComparer.Ordinal).Count()
|
||||
|| await GroupProfileManager.HasCycle(profile))
|
||||
{
|
||||
@@ -243,7 +243,7 @@ public sealed partial class V2rayRuntime
|
||||
return OperationView.Fail("profile_selection_required", ApiMessageKeys.ProfileSelectRequired);
|
||||
}
|
||||
|
||||
var selected = await AppManager.Instance.GetProfileItemsByIndexIds(ids);
|
||||
var selected = await ConfigDbQuery.GetProfileItemsByIndexIds(ids);
|
||||
if (selected.Count == 0)
|
||||
{
|
||||
return OperationView.Fail("profile_not_found", ApiMessageKeys.ProfileNotFound);
|
||||
@@ -291,7 +291,7 @@ public sealed partial class V2rayRuntime
|
||||
public async Task<OperationView> CopyProfilesAsync(IEnumerable<string> profileIds)
|
||||
{
|
||||
var ids = profileIds.Where(id => !string.IsNullOrWhiteSpace(id)).Distinct(StringComparer.Ordinal).ToArray();
|
||||
var items = await AppManager.Instance.GetProfileItemsOrderedByIndexIds(ids);
|
||||
var items = await ConfigDbQuery.GetProfileItemsOrderedByIndexIds(ids);
|
||||
if (items.Count == 0)
|
||||
{
|
||||
return OperationView.Fail("profile_not_found", ApiMessageKeys.ProfileNotFound);
|
||||
@@ -308,12 +308,12 @@ public sealed partial class V2rayRuntime
|
||||
public async Task<OperationView> MoveProfilesToGroupAsync(MoveProfilesRequest request)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(request.SubscriptionId)
|
||||
&& await AppManager.Instance.GetSubItem(request.SubscriptionId) is null)
|
||||
&& await ConfigDbQuery.GetSubItem(request.SubscriptionId) is null)
|
||||
{
|
||||
return OperationView.Fail("subscription_not_found", ApiMessageKeys.SubscriptionNotFound);
|
||||
}
|
||||
|
||||
var items = await AppManager.Instance.GetProfileItemsByIndexIds(request.ProfileIds);
|
||||
var items = await ConfigDbQuery.GetProfileItemsByIndexIds(request.ProfileIds);
|
||||
if (items.Count == 0)
|
||||
{
|
||||
return OperationView.Fail("profile_not_found", ApiMessageKeys.ProfileNotFound);
|
||||
@@ -381,7 +381,7 @@ public sealed partial class V2rayRuntime
|
||||
SubItem? subscription = null;
|
||||
if (!string.IsNullOrEmpty(subscriptionId))
|
||||
{
|
||||
subscription = await AppManager.Instance.GetSubItem(subscriptionId);
|
||||
subscription = await ConfigDbQuery.GetSubItem(subscriptionId);
|
||||
if (subscription is null)
|
||||
{
|
||||
return OperationView.Fail("subscription_not_found", ApiMessageKeys.SubscriptionNotFound);
|
||||
@@ -402,7 +402,7 @@ public sealed partial class V2rayRuntime
|
||||
|
||||
public async Task<IReadOnlyList<ProfileExportItem>> ExportProfileDataAsync(ProfileExportRequest request)
|
||||
{
|
||||
var items = await AppManager.Instance.GetProfileItemsOrderedByIndexIds(request.ProfileIds);
|
||||
var items = await ConfigDbQuery.GetProfileItemsOrderedByIndexIds(request.ProfileIds);
|
||||
var output = new List<ProfileExportItem>();
|
||||
|
||||
if (request.IncludeShareUris)
|
||||
@@ -445,7 +445,7 @@ public sealed partial class V2rayRuntime
|
||||
|
||||
public async Task<string?> GetSubscriptionShareAsync(string id)
|
||||
{
|
||||
return (await AppManager.Instance.GetSubItem(id))?.Url;
|
||||
return (await ConfigDbQuery.GetSubItem(id))?.Url;
|
||||
}
|
||||
|
||||
public async Task<OperationView> StartSpeedTestAsync(SpeedTestRequest request, CancellationToken cancellationToken)
|
||||
@@ -453,8 +453,8 @@ public sealed partial class V2rayRuntime
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
var action = request.Action == ESpeedActionType.FastRealping ? ESpeedActionType.Realping : request.Action;
|
||||
var profiles = request.ProfileIds is { Length: > 0 }
|
||||
? await AppManager.Instance.GetProfileItemsOrderedByIndexIds(request.ProfileIds)
|
||||
: await AppManager.Instance.ProfileItems(Config.SubIndexId ?? string.Empty) ?? [];
|
||||
? await ConfigDbQuery.GetProfileItemsOrderedByIndexIds(request.ProfileIds)
|
||||
: await ConfigDbQuery.ProfileItems(Config.SubIndexId ?? string.Empty) ?? [];
|
||||
if (profiles.Count == 0)
|
||||
{
|
||||
return OperationView.Fail("speedtest_profile_selection_required", ApiMessageKeys.SpeedTestSelectRequired);
|
||||
|
||||
@@ -114,7 +114,7 @@ public sealed partial class V2rayRuntime
|
||||
IReadOnlyList<SubItem> subscriptions;
|
||||
await using (var operation = await _operations.EnterOperationAsync(cancellationToken))
|
||||
{
|
||||
subscriptions = (await AppManager.Instance.SubItems() ?? [])
|
||||
subscriptions = (await ConfigDbQuery.SubItems() ?? [])
|
||||
.Where(item => item.AutoUpdateInterval > 0
|
||||
&& now - item.UpdateTime >= item.AutoUpdateInterval * 60L)
|
||||
.ToArray();
|
||||
|
||||
@@ -528,7 +528,7 @@ public sealed partial class V2rayRuntime
|
||||
}
|
||||
|
||||
public async Task<IReadOnlyList<DnsProfileView>> GetDnsProfilesAsync() =>
|
||||
(await AppManager.Instance.DNSItems() ?? [])
|
||||
(await ConfigDbQuery.DNSItems() ?? [])
|
||||
.Select(ToDnsProfileView)
|
||||
.ToArray();
|
||||
|
||||
@@ -550,7 +550,7 @@ public sealed partial class V2rayRuntime
|
||||
|
||||
var result = await _mutations.RunAsync(async () =>
|
||||
{
|
||||
var current = await AppManager.Instance.GetDNSItem(coreType);
|
||||
var current = await ConfigDbQuery.GetDNSItem(coreType);
|
||||
if (current is null)
|
||||
{
|
||||
return (Result: -2, Changed: false);
|
||||
@@ -622,7 +622,7 @@ public sealed partial class V2rayRuntime
|
||||
return json is not null && json["servers"] is not null;
|
||||
}
|
||||
|
||||
public async Task<IReadOnlyList<RoutingItem>> GetRoutingProfilesAsync() => await AppManager.Instance.RoutingItems() ?? [];
|
||||
public async Task<IReadOnlyList<RoutingItem>> GetRoutingProfilesAsync() => await ConfigDbQuery.RoutingItems() ?? [];
|
||||
|
||||
public async Task<OperationView> SaveRoutingProfileAsync(RoutingItem input, string? routingId = null)
|
||||
{
|
||||
@@ -656,12 +656,12 @@ public sealed partial class V2rayRuntime
|
||||
item = input;
|
||||
item.Id = string.Empty;
|
||||
item.IsActive = false;
|
||||
var existing = await AppManager.Instance.RoutingItems() ?? [];
|
||||
var existing = await ConfigDbQuery.RoutingItems() ?? [];
|
||||
item.Sort = item.Sort > 0 ? item.Sort : (existing.MaxBy(route => route.Sort)?.Sort ?? 0) + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
var existingItem = await AppManager.Instance.GetRoutingItem(routingId);
|
||||
var existingItem = await ConfigDbQuery.GetRoutingItem(routingId);
|
||||
if (existingItem is null)
|
||||
{
|
||||
return (Result: -2, Item: null, Changed: false);
|
||||
@@ -723,7 +723,7 @@ public sealed partial class V2rayRuntime
|
||||
|
||||
var removed = await _mutations.RunAsync(async () =>
|
||||
{
|
||||
var item = await AppManager.Instance.GetRoutingItem(id);
|
||||
var item = await ConfigDbQuery.GetRoutingItem(id);
|
||||
if (item is null)
|
||||
{
|
||||
return (Removed: false, AffectsCore: false);
|
||||
@@ -731,7 +731,7 @@ public sealed partial class V2rayRuntime
|
||||
await ConfigDbManager.RemoveRoutingItem(item);
|
||||
if (item.IsActive)
|
||||
{
|
||||
var remaining = await AppManager.Instance.RoutingItems() ?? [];
|
||||
var remaining = await ConfigDbQuery.RoutingItems() ?? [];
|
||||
var fallback = remaining.FirstOrDefault();
|
||||
if (fallback is not null)
|
||||
{
|
||||
@@ -766,7 +766,7 @@ public sealed partial class V2rayRuntime
|
||||
|
||||
var result = await _mutations.RunAsync(async () =>
|
||||
{
|
||||
var item = await AppManager.Instance.GetRoutingItem(id);
|
||||
var item = await ConfigDbQuery.GetRoutingItem(id);
|
||||
if (item is null)
|
||||
{
|
||||
return (Result: -2, Changed: false);
|
||||
@@ -788,7 +788,7 @@ public sealed partial class V2rayRuntime
|
||||
|
||||
public async Task<IReadOnlyList<RulesItem>> GetRoutingRulesAsync(string routingId)
|
||||
{
|
||||
var item = await AppManager.Instance.GetRoutingItem(routingId);
|
||||
var item = await ConfigDbQuery.GetRoutingItem(routingId);
|
||||
return JsonUtils.Deserialize<List<RulesItem>>(item?.RuleSet ?? "[]") ?? [];
|
||||
}
|
||||
|
||||
@@ -801,7 +801,7 @@ public sealed partial class V2rayRuntime
|
||||
}
|
||||
|
||||
var items = rules.ToArray();
|
||||
var before = await AppManager.Instance.GetRoutingItem(routingId);
|
||||
var before = await ConfigDbQuery.GetRoutingItem(routingId);
|
||||
var changed = before is not null && before.IsActive
|
||||
&& before.RuleSet != JsonUtils.Serialize(items, false);
|
||||
var saved = await _mutations.RunAsync(() => SaveRoutingRulesLockedAsync(routingId, items));
|
||||
@@ -818,7 +818,7 @@ public sealed partial class V2rayRuntime
|
||||
|
||||
private static async Task<int> SaveRoutingRulesLockedAsync(string routingId, IReadOnlyList<RulesItem> rules)
|
||||
{
|
||||
var item = await AppManager.Instance.GetRoutingItem(routingId);
|
||||
var item = await ConfigDbQuery.GetRoutingItem(routingId);
|
||||
if (item is null)
|
||||
{
|
||||
return -2;
|
||||
@@ -828,7 +828,7 @@ public sealed partial class V2rayRuntime
|
||||
|
||||
private async Task<string> GetActiveRoutingSignatureAsync()
|
||||
{
|
||||
var active = (await AppManager.Instance.RoutingItems() ?? []).FirstOrDefault(item => item.IsActive);
|
||||
var active = (await ConfigDbQuery.RoutingItems() ?? []).FirstOrDefault(item => item.IsActive);
|
||||
return active is null
|
||||
? string.Empty
|
||||
: System.Text.Json.JsonSerializer.Serialize(new
|
||||
@@ -855,13 +855,13 @@ public sealed partial class V2rayRuntime
|
||||
return applyFailure;
|
||||
}
|
||||
|
||||
var activeBefore = await AppManager.Instance.GetRoutingItem(routingId);
|
||||
var activeBefore = await ConfigDbQuery.GetRoutingItem(routingId);
|
||||
var beforeRuleSet = activeBefore?.RuleSet;
|
||||
var saved = await _mutations.RunAsync(async () =>
|
||||
{
|
||||
if (request.Append)
|
||||
{
|
||||
var item = await AppManager.Instance.GetRoutingItem(routingId);
|
||||
var item = await ConfigDbQuery.GetRoutingItem(routingId);
|
||||
if (item is null)
|
||||
{
|
||||
return -2;
|
||||
@@ -880,14 +880,14 @@ public sealed partial class V2rayRuntime
|
||||
{
|
||||
return OperationView.Fail("routing_rules_save_failed", ApiMessageKeys.RoutingSaveFailed);
|
||||
}
|
||||
var activeAfter = await AppManager.Instance.GetRoutingItem(routingId);
|
||||
var activeAfter = await ConfigDbQuery.GetRoutingItem(routingId);
|
||||
var changed = activeBefore?.IsActive == true && activeAfter?.RuleSet != beforeRuleSet;
|
||||
return await CompleteCoreAffectingChangeAsync("routing-rules", changed, applyContext, data: new { routingId });
|
||||
}
|
||||
|
||||
public async Task<OperationView> ImportRoutingRulesFromUrlAsync(string routingId, bool append, CancellationToken cancellationToken)
|
||||
{
|
||||
var item = await AppManager.Instance.GetRoutingItem(routingId);
|
||||
var item = await ConfigDbQuery.GetRoutingItem(routingId);
|
||||
if (item is null)
|
||||
{
|
||||
return OperationView.Fail("routing_profile_not_found", ApiMessageKeys.RoutingProfileNotFound);
|
||||
@@ -916,10 +916,10 @@ public sealed partial class V2rayRuntime
|
||||
return applyFailure;
|
||||
}
|
||||
|
||||
var routeWasActive = (await AppManager.Instance.GetRoutingItem(routingId))?.IsActive == true;
|
||||
var routeWasActive = (await ConfigDbQuery.GetRoutingItem(routingId))?.IsActive == true;
|
||||
var result = await _mutations.RunAsync(async () =>
|
||||
{
|
||||
var item = await AppManager.Instance.GetRoutingItem(routingId);
|
||||
var item = await ConfigDbQuery.GetRoutingItem(routingId);
|
||||
if (item is null)
|
||||
{
|
||||
return -2;
|
||||
@@ -957,10 +957,10 @@ public sealed partial class V2rayRuntime
|
||||
return applyFailure;
|
||||
}
|
||||
|
||||
var routeWasActive = (await AppManager.Instance.GetRoutingItem(routingId))?.IsActive == true;
|
||||
var routeWasActive = (await ConfigDbQuery.GetRoutingItem(routingId))?.IsActive == true;
|
||||
var result = await _mutations.RunAsync(async () =>
|
||||
{
|
||||
var item = await AppManager.Instance.GetRoutingItem(routingId);
|
||||
var item = await ConfigDbQuery.GetRoutingItem(routingId);
|
||||
if (item is null)
|
||||
{
|
||||
return -2;
|
||||
@@ -1003,7 +1003,7 @@ public sealed partial class V2rayRuntime
|
||||
}
|
||||
|
||||
public async Task<IReadOnlyList<CoreConfigTemplateView>> GetFullConfigTemplatesAsync() =>
|
||||
(await AppManager.Instance.FullConfigTemplateItem() ?? [])
|
||||
(await ConfigDbQuery.FullConfigTemplateItem() ?? [])
|
||||
.Select(ToCoreConfigTemplateView)
|
||||
.ToArray();
|
||||
|
||||
@@ -1033,7 +1033,7 @@ public sealed partial class V2rayRuntime
|
||||
return applyFailure;
|
||||
}
|
||||
|
||||
var existingBefore = await AppManager.Instance.GetFullConfigTemplateItem(coreType);
|
||||
var existingBefore = await ConfigDbQuery.GetFullConfigTemplateItem(coreType);
|
||||
var changed = existingBefore is not null
|
||||
&& (existingBefore.Remarks != (input.Remarks ?? existingBefore.Remarks)
|
||||
|| existingBefore.Enabled != input.Enabled
|
||||
@@ -1042,7 +1042,7 @@ public sealed partial class V2rayRuntime
|
||||
|| existingBefore.ProxyDetour != input.ProxyDetour);
|
||||
var result = await _mutations.RunAsync(async () =>
|
||||
{
|
||||
var current = await AppManager.Instance.GetFullConfigTemplateItem(coreType);
|
||||
var current = await ConfigDbQuery.GetFullConfigTemplateItem(coreType);
|
||||
if (current is null)
|
||||
{
|
||||
return -2;
|
||||
@@ -1074,8 +1074,8 @@ public sealed partial class V2rayRuntime
|
||||
await _regionalPresetGate.WaitAsync(cancellationToken);
|
||||
try
|
||||
{
|
||||
var existingDnsItems = await AppManager.Instance.DNSItems() ?? [];
|
||||
var existingRoutingItems = await AppManager.Instance.RoutingItems() ?? [];
|
||||
var existingDnsItems = await ConfigDbQuery.DNSItems() ?? [];
|
||||
var existingRoutingItems = await ConfigDbQuery.RoutingItems() ?? [];
|
||||
var proxy = preset == EPresetType.Default
|
||||
? null
|
||||
: await GetRegionalPresetProxyAsync(cancellationToken);
|
||||
@@ -1185,7 +1185,7 @@ public sealed partial class V2rayRuntime
|
||||
|
||||
foreach (var itemId in stage.Routing.RemoveItemIds ?? [])
|
||||
{
|
||||
var item = await AppManager.Instance.GetRoutingItem(itemId);
|
||||
var item = await ConfigDbQuery.GetRoutingItem(itemId);
|
||||
if (item is not null)
|
||||
{
|
||||
await ConfigDbManager.RemoveRoutingItem(item);
|
||||
@@ -1197,7 +1197,7 @@ public sealed partial class V2rayRuntime
|
||||
Config.RoutingBasicItem.RoutingIndexId = string.Empty;
|
||||
}
|
||||
|
||||
var currentRoutes = await AppManager.Instance.RoutingItems() ?? [];
|
||||
var currentRoutes = await ConfigDbQuery.RoutingItems() ?? [];
|
||||
var hasVersion = stage.Routing.TemplateVersion is { Length: > 0 } version
|
||||
&& currentRoutes.Any(item => item.Remarks?.StartsWith(version, StringComparison.Ordinal) == true);
|
||||
var builtinFallbackAlreadyInitialized = stage.Routing.IsBuiltinFallback && currentRoutes.Count > 0;
|
||||
@@ -1589,9 +1589,9 @@ public sealed partial class V2rayRuntime
|
||||
new { runtimeState = oldRuntime.State.ToString().ToLowerInvariant(), processIds = GetActiveCoreProcessIds() }),
|
||||
_ => null,
|
||||
};
|
||||
var oldRoutingItems = failure is null ? await AppManager.Instance.RoutingItems() ?? [] : [];
|
||||
var oldDnsItems = failure is null ? await AppManager.Instance.DNSItems() ?? [] : [];
|
||||
var oldFullConfigTemplates = failure is null ? await AppManager.Instance.FullConfigTemplateItem() ?? [] : [];
|
||||
var oldRoutingItems = failure is null ? await ConfigDbQuery.RoutingItems() ?? [] : [];
|
||||
var oldDnsItems = failure is null ? await ConfigDbQuery.DNSItems() ?? [] : [];
|
||||
var oldFullConfigTemplates = failure is null ? await ConfigDbQuery.FullConfigTemplateItem() ?? [] : [];
|
||||
return new CoreSettingsApplyContext(_coreGate, oldConfig, oldRuntime, hasActiveChild,
|
||||
oldRoutingItems.ToArray(), oldDnsItems.ToArray(), oldFullConfigTemplates.ToArray(), failure);
|
||||
}
|
||||
@@ -1702,7 +1702,7 @@ public sealed partial class V2rayRuntime
|
||||
|
||||
await CoreManager.Instance.Init(Config, OnCoreMessageAsync);
|
||||
var oldProfileId = context.OldRuntime.ProfileId ?? Config.IndexId;
|
||||
var oldProfile = await AppManager.Instance.GetProfileItem(oldProfileId)
|
||||
var oldProfile = await ConfigDbQuery.GetProfileItem(oldProfileId)
|
||||
?? throw new InvalidOperationException($"The previous Core profile {oldProfileId} no longer exists.");
|
||||
var restored = await StartCoreLockedAsync(oldProfile, CancellationToken.None);
|
||||
if (!restored.Success)
|
||||
|
||||
@@ -250,7 +250,7 @@ public sealed partial class V2rayRuntime(
|
||||
await ConfigDbManager.InitBuiltinDNS(Config);
|
||||
await BuiltinDnsProfileBootstrap.EnsureAsync(
|
||||
Config,
|
||||
async () => await AppManager.Instance.DNSItems() ?? [],
|
||||
async () => await ConfigDbQuery.DNSItems() ?? [],
|
||||
ConfigDbManager.SaveDNSItems);
|
||||
await ConfigDbManager.InitBuiltinFullConfigTemplate(Config);
|
||||
// Keep startup aligned with Desktop's StatusBarViewModel. In particular,
|
||||
@@ -258,7 +258,7 @@ public sealed partial class V2rayRuntime(
|
||||
// run even when a restored Desktop database already has routing rows.
|
||||
await ConfigDbManager.InitBuiltinRouting(Config);
|
||||
_ = await ConfigDbManager.GetDefaultRouting(Config);
|
||||
var restoredSubscriptions = await AppManager.Instance.SubItems() ?? [];
|
||||
var restoredSubscriptions = await ConfigDbQuery.SubItems() ?? [];
|
||||
var normalizedSubIndexId = NormalizeSelectedSubscriptionId(
|
||||
Config.SubIndexId,
|
||||
restoredSubscriptions.Select(item => item.Id).ToArray());
|
||||
@@ -303,7 +303,7 @@ public sealed partial class V2rayRuntime(
|
||||
startupRuntimeIntent,
|
||||
selectedProfileId,
|
||||
defaultProfile?.IndexId,
|
||||
async (profileId, _) => await AppManager.Instance.GetProfileItem(profileId) is not null,
|
||||
async (profileId, _) => await ConfigDbQuery.GetProfileItem(profileId) is not null,
|
||||
StartCoreAsync,
|
||||
message => AddLog(restoreState is not null ? "restore" : "update", message),
|
||||
cancellationToken);
|
||||
@@ -425,7 +425,7 @@ public sealed partial class V2rayRuntime(
|
||||
|
||||
public async Task<IReadOnlyList<SubscriptionView>> GetSubscriptionsAsync()
|
||||
{
|
||||
var items = await AppManager.Instance.SubItems() ?? [];
|
||||
var items = await ConfigDbQuery.SubItems() ?? [];
|
||||
return items.Select(ToSubscriptionView).ToArray();
|
||||
}
|
||||
|
||||
@@ -443,7 +443,7 @@ public sealed partial class V2rayRuntime(
|
||||
return new(false, "subscription_save_failed", ApiMessageKeys.SubscriptionSaveFailed, null);
|
||||
}
|
||||
|
||||
var saved = await AppManager.Instance.GetSubItem(item.Id);
|
||||
var saved = await ConfigDbQuery.GetSubItem(item.Id);
|
||||
return saved is null
|
||||
? new(false, "subscription_save_failed", ApiMessageKeys.SubscriptionSaveFailed, null)
|
||||
: new(true, "ok", ApiMessageKeys.SubscriptionAdded, ToSubscriptionView(saved));
|
||||
@@ -458,7 +458,7 @@ public sealed partial class V2rayRuntime(
|
||||
|
||||
return await _mutations.RunAsync(async () =>
|
||||
{
|
||||
var existing = await AppManager.Instance.GetSubItem(id);
|
||||
var existing = await ConfigDbQuery.GetSubItem(id);
|
||||
if (existing is null)
|
||||
{
|
||||
return new SubscriptionMutationResult(false, "subscription_not_found", ApiMessageKeys.SubscriptionNotFound, null);
|
||||
@@ -472,7 +472,7 @@ public sealed partial class V2rayRuntime(
|
||||
return new SubscriptionMutationResult(false, "subscription_save_failed", ApiMessageKeys.SubscriptionSaveFailed, null);
|
||||
}
|
||||
|
||||
var saved = await AppManager.Instance.GetSubItem(id);
|
||||
var saved = await ConfigDbQuery.GetSubItem(id);
|
||||
return saved is not null
|
||||
? new SubscriptionMutationResult(true, "ok", ApiMessageKeys.SubscriptionSaved, ToSubscriptionView(saved))
|
||||
: new SubscriptionMutationResult(false, "subscription_save_failed", ApiMessageKeys.SubscriptionSaveFailed, null);
|
||||
@@ -481,13 +481,13 @@ public sealed partial class V2rayRuntime(
|
||||
|
||||
public async Task<OperationView> DeleteSubscriptionAsync(string id)
|
||||
{
|
||||
var subscription = await AppManager.Instance.GetSubItem(id);
|
||||
var subscription = await ConfigDbQuery.GetSubItem(id);
|
||||
if (subscription is null)
|
||||
{
|
||||
return OperationView.Fail("subscription_not_found", ApiMessageKeys.SubscriptionNotFound);
|
||||
}
|
||||
|
||||
var selectedProfile = await AppManager.Instance.GetProfileItem(Config.IndexId);
|
||||
var selectedProfile = await ConfigDbQuery.GetProfileItem(Config.IndexId);
|
||||
var removesCurrentProfile = selectedProfile?.Subid == id;
|
||||
if (removesCurrentProfile)
|
||||
{
|
||||
@@ -582,10 +582,10 @@ public sealed partial class V2rayRuntime(
|
||||
public async Task<IReadOnlyList<ProfileView>> GetProfilesAsync(string? subscriptionId, string? filter)
|
||||
{
|
||||
var groupId = subscriptionId ?? Config.SubIndexId ?? string.Empty;
|
||||
var profiles = await AppManager.Instance.ProfileItems(groupId) ?? [];
|
||||
var profileModels = await AppManager.Instance.ProfileModels(groupId, string.Empty) ?? [];
|
||||
var profiles = await ConfigDbQuery.ProfileItems(groupId) ?? [];
|
||||
var profileModels = await ConfigDbQuery.ProfileModels(groupId, string.Empty) ?? [];
|
||||
var modelMap = profileModels.ToDictionary(item => item.IndexId);
|
||||
var subscriptions = (await AppManager.Instance.SubItems() ?? []).ToDictionary(item => item.Id, item => item.Remarks);
|
||||
var subscriptions = (await ConfigDbQuery.SubItems() ?? []).ToDictionary(item => item.Id, item => item.Remarks);
|
||||
var extensions = await ProfileExManager.Instance.GetProfileExs();
|
||||
var extensionMap = extensions.ToDictionary(item => item.IndexId);
|
||||
var statistics = (Config.GuiItem.EnableStatistics ? StatisticsManager.Instance.ServerStat : null) ?? [];
|
||||
@@ -630,13 +630,13 @@ public sealed partial class V2rayRuntime(
|
||||
}
|
||||
|
||||
public async Task<ProfileItem?> GetProfileDetailsAsync(string profileId) =>
|
||||
await AppManager.Instance.GetProfileItem(profileId);
|
||||
await ConfigDbQuery.GetProfileItem(profileId);
|
||||
|
||||
public async Task<StatusView> GetStatusAsync()
|
||||
{
|
||||
var selectedProfile = await AppManager.Instance.GetProfileItem(Config.IndexId);
|
||||
var profileItems = await AppManager.Instance.ProfileItems(string.Empty) ?? [];
|
||||
var subscriptions = await AppManager.Instance.SubItems() ?? [];
|
||||
var selectedProfile = await ConfigDbQuery.GetProfileItem(Config.IndexId);
|
||||
var profileItems = await ConfigDbQuery.ProfileItems(string.Empty) ?? [];
|
||||
var subscriptions = await ConfigDbQuery.SubItems() ?? [];
|
||||
var snapshot = CurrentCoreRuntime;
|
||||
var processIds = GetActiveCoreProcessIds();
|
||||
var listenerDefinitions = snapshot.ProxyPort.HasValue && snapshot.State != CoreRuntimeState.Stopped
|
||||
@@ -674,7 +674,7 @@ public sealed partial class V2rayRuntime(
|
||||
|
||||
var runningProfile = string.IsNullOrEmpty(snapshot.ProfileId)
|
||||
? null
|
||||
: await AppManager.Instance.GetProfileItem(snapshot.ProfileId);
|
||||
: await ConfigDbQuery.GetProfileItem(snapshot.ProfileId);
|
||||
var configuredProxyPort = Config.Inbound.FirstOrDefault()?.LocalPort;
|
||||
return new StatusView(
|
||||
coreRunning,
|
||||
@@ -715,7 +715,7 @@ public sealed partial class V2rayRuntime(
|
||||
|
||||
public async Task<OperationView> SelectProfileAsync(string profileId, CancellationToken cancellationToken)
|
||||
{
|
||||
var profile = await AppManager.Instance.GetProfileItem(profileId);
|
||||
var profile = await ConfigDbQuery.GetProfileItem(profileId);
|
||||
if (profile is null)
|
||||
{
|
||||
return OperationView.Fail("profile_not_found", ApiMessageKeys.ProfileNotFound);
|
||||
@@ -729,7 +729,7 @@ public sealed partial class V2rayRuntime(
|
||||
ProfileItem? profile = null;
|
||||
if (!string.IsNullOrWhiteSpace(profileId))
|
||||
{
|
||||
profile = await AppManager.Instance.GetProfileItem(profileId);
|
||||
profile = await ConfigDbQuery.GetProfileItem(profileId);
|
||||
if (profile is null)
|
||||
{
|
||||
return OperationView.Fail("profile_not_found", ApiMessageKeys.ProfileNotFound);
|
||||
@@ -1055,7 +1055,7 @@ public sealed partial class V2rayRuntime(
|
||||
new { runtimeState = previous.State.ToString(), processIds = GetActiveCoreProcessIds() });
|
||||
}
|
||||
|
||||
var profile = await AppManager.Instance.GetProfileItem(previous.ProfileId);
|
||||
var profile = await ConfigDbQuery.GetProfileItem(previous.ProfileId);
|
||||
if (profile is null)
|
||||
{
|
||||
return OperationView.Fail("profile_not_found", ApiMessageKeys.ProfileNotFound,
|
||||
@@ -1105,7 +1105,7 @@ public sealed partial class V2rayRuntime(
|
||||
|
||||
public async Task<OperationView> StartLatencyTestAsync(string profileId)
|
||||
{
|
||||
var profile = await AppManager.Instance.GetProfileItem(profileId);
|
||||
var profile = await ConfigDbQuery.GetProfileItem(profileId);
|
||||
if (profile is null || profile.IsComplex() || profile.Port <= 0)
|
||||
{
|
||||
return OperationView.Fail("speedtest_invalid_profile", ApiMessageKeys.SpeedTestInvalidProfile);
|
||||
@@ -1174,7 +1174,7 @@ public sealed partial class V2rayRuntime(
|
||||
var updateTime = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
|
||||
if (subscriptionId.Length > 0)
|
||||
{
|
||||
var item = await AppManager.Instance.GetSubItem(subscriptionId);
|
||||
var item = await ConfigDbQuery.GetSubItem(subscriptionId);
|
||||
if (item is not null)
|
||||
{
|
||||
item.UpdateTime = updateTime;
|
||||
@@ -1186,7 +1186,7 @@ public sealed partial class V2rayRuntime(
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var item in await AppManager.Instance.SubItems() ?? [])
|
||||
foreach (var item in await ConfigDbQuery.SubItems() ?? [])
|
||||
{
|
||||
if (item.Enabled)
|
||||
{
|
||||
|
||||
@@ -29,7 +29,7 @@ public class SubscriptionCreationTests
|
||||
|
||||
if (result.Data is not null)
|
||||
{
|
||||
saved = await manager.GetSubItem(result.Data.Id);
|
||||
saved = await ConfigDbQuery.GetSubItem(result.Data.Id);
|
||||
}
|
||||
|
||||
await result.Success.Should().BeTrue();
|
||||
@@ -48,7 +48,7 @@ public class SubscriptionCreationTests
|
||||
await updateResult.Success.Should().BeTrue();
|
||||
await updateResult.Data!.Url.Should().BeEqualTo(string.Empty);
|
||||
|
||||
saved = await manager.GetSubItem(result.Data.Id);
|
||||
saved = await ConfigDbQuery.GetSubItem(result.Data.Id);
|
||||
await (saved is not null).Should().BeTrue();
|
||||
await saved!.Remarks.Should().BeEqualTo("自建(已编辑)");
|
||||
await saved.Url.Should().BeEqualTo(string.Empty);
|
||||
|
||||
Reference in New Issue
Block a user