Code optimization, function asynchrony

pull/5876/head
2dust 2024-10-21 09:45:33 +08:00
parent 394b657fc9
commit a866017b4c
21 changed files with 518 additions and 514 deletions

View File

@ -64,21 +64,11 @@ namespace ServiceLib.Common
return await _dbAsync.ExecuteAsync(sql); return await _dbAsync.ExecuteAsync(sql);
} }
public List<T> Query<T>(string sql) where T : new()
{
return _db.Query<T>(sql);
}
public async Task<List<T>> QueryAsync<T>(string sql) where T : new() public async Task<List<T>> QueryAsync<T>(string sql) where T : new()
{ {
return await _dbAsync.QueryAsync<T>(sql); return await _dbAsync.QueryAsync<T>(sql);
} }
public TableQuery<T> Table<T>() where T : new()
{
return _db.Table<T>();
}
public AsyncTableQuery<T> TableAsync<T>() where T : new() public AsyncTableQuery<T> TableAsync<T>() where T : new()
{ {
return _dbAsync.Table<T>(); return _dbAsync.Table<T>();

View File

@ -102,41 +102,45 @@
#region SqliteHelper #region SqliteHelper
public List<SubItem> SubItems() public async Task<List<SubItem>> SubItems()
{ {
return SQLiteHelper.Instance.Table<SubItem>().ToList(); return await SQLiteHelper.Instance.TableAsync<SubItem>().OrderBy(t => t.sort).ToListAsync();
} }
public SubItem GetSubItem(string subid) public async Task<SubItem> GetSubItem(string subid)
{ {
return SQLiteHelper.Instance.Table<SubItem>().FirstOrDefault(t => t.id == subid); return await SQLiteHelper.Instance.TableAsync<SubItem>().FirstOrDefaultAsync(t => t.id == subid);
} }
public List<ProfileItem> ProfileItems(string subid) public async Task<List<ProfileItem>> ProfileItems(string subid)
{ {
if (Utils.IsNullOrEmpty(subid)) if (Utils.IsNullOrEmpty(subid))
{ {
return SQLiteHelper.Instance.Table<ProfileItem>().ToList(); return await SQLiteHelper.Instance.TableAsync<ProfileItem>().ToListAsync();
} }
else else
{ {
return SQLiteHelper.Instance.Table<ProfileItem>().Where(t => t.subid == subid).ToList(); return await SQLiteHelper.Instance.TableAsync<ProfileItem>().Where(t => t.subid == subid).ToListAsync();
} }
} }
public List<string> ProfileItemIndexes(string subid) public async Task<List<string>> ProfileItemIndexes(string subid)
{ {
if (Utils.IsNullOrEmpty(subid)) if (Utils.IsNullOrEmpty(subid))
{ {
return SQLiteHelper.Instance.Table<ProfileItem>().Select(t => t.indexId).ToList(); return (await SQLiteHelper.Instance.TableAsync<ProfileItem>().ToListAsync())
.Select(t => t.indexId)
.ToList();
} }
else else
{ {
return SQLiteHelper.Instance.Table<ProfileItem>().Where(t => t.subid == subid).Select(t => t.indexId).ToList(); return (await SQLiteHelper.Instance.TableAsync<ProfileItem>().Where(t => t.subid == subid).ToListAsync())
.Select(t => t.indexId)
.ToList();
} }
} }
public List<ProfileItemModel> ProfileItems(string subid, string filter) public async Task<List<ProfileItemModel>> ProfileItems(string subid, string filter)
{ {
var sql = @$"select a.* var sql = @$"select a.*
,b.remarks subRemarks ,b.remarks subRemarks
@ -156,14 +160,14 @@
sql += string.Format(" and (a.remarks like '%{0}%' or a.address like '%{0}%') ", filter); sql += string.Format(" and (a.remarks like '%{0}%' or a.address like '%{0}%') ", filter);
} }
return SQLiteHelper.Instance.Query<ProfileItemModel>(sql).ToList(); return await SQLiteHelper.Instance.QueryAsync<ProfileItemModel>(sql);
} }
public List<ProfileItemModel> ProfileItemsEx(string subid, string filter) public async Task<List<ProfileItemModel>> ProfileItemsEx(string subid, string filter)
{ {
var lstModel = ProfileItems(_config.subIndexId, filter); var lstModel = await ProfileItems(_config.subIndexId, filter);
ConfigHandler.SetDefaultServer(_config, lstModel); await ConfigHandler.SetDefaultServer(_config, lstModel);
var lstServerStat = (_config.guiItem.enableStatistics ? StatisticsHandler.Instance.ServerStat : null) ?? []; var lstServerStat = (_config.guiItem.enableStatistics ? StatisticsHandler.Instance.ServerStat : null) ?? [];
var lstProfileExs = ProfileExHandler.Instance.ProfileExs; var lstProfileExs = ProfileExHandler.Instance.ProfileExs;
@ -198,42 +202,42 @@
return lstModel; return lstModel;
} }
public ProfileItem? GetProfileItem(string indexId) public async Task<ProfileItem?> GetProfileItem(string indexId)
{ {
if (Utils.IsNullOrEmpty(indexId)) if (Utils.IsNullOrEmpty(indexId))
{ {
return null; return null;
} }
return SQLiteHelper.Instance.Table<ProfileItem>().FirstOrDefault(it => it.indexId == indexId); return await SQLiteHelper.Instance.TableAsync<ProfileItem>().FirstOrDefaultAsync(it => it.indexId == indexId);
} }
public ProfileItem? GetProfileItemViaRemarks(string? remarks) public async Task<ProfileItem?> GetProfileItemViaRemarks(string? remarks)
{ {
if (Utils.IsNullOrEmpty(remarks)) if (Utils.IsNullOrEmpty(remarks))
{ {
return null; return null;
} }
return SQLiteHelper.Instance.Table<ProfileItem>().FirstOrDefault(it => it.remarks == remarks); return await SQLiteHelper.Instance.TableAsync<ProfileItem>().FirstOrDefaultAsync(it => it.remarks == remarks);
} }
public List<RoutingItem> RoutingItems() public async Task<List<RoutingItem>> RoutingItems()
{ {
return SQLiteHelper.Instance.Table<RoutingItem>().Where(it => it.locked == false).OrderBy(t => t.sort).ToList(); return await SQLiteHelper.Instance.TableAsync<RoutingItem>().Where(it => it.locked == false).OrderBy(t => t.sort).ToListAsync();
} }
public RoutingItem GetRoutingItem(string id) public async Task<RoutingItem> GetRoutingItem(string id)
{ {
return SQLiteHelper.Instance.Table<RoutingItem>().FirstOrDefault(it => it.locked == false && it.id == id); return await SQLiteHelper.Instance.TableAsync<RoutingItem>().FirstOrDefaultAsync(it => it.locked == false && it.id == id);
} }
public List<DNSItem> DNSItems() public async Task<List<DNSItem>> DNSItems()
{ {
return SQLiteHelper.Instance.Table<DNSItem>().ToList(); return await SQLiteHelper.Instance.TableAsync<DNSItem>().ToListAsync();
} }
public DNSItem GetDNSItem(ECoreType eCoreType) public async Task<DNSItem> GetDNSItem(ECoreType eCoreType)
{ {
return SQLiteHelper.Instance.Table<DNSItem>().FirstOrDefault(it => it.coreType == eCoreType); return await SQLiteHelper.Instance.TableAsync<DNSItem>().FirstOrDefaultAsync(it => it.coreType == eCoreType);
} }
#endregion SqliteHelper #endregion SqliteHelper

View File

@ -218,7 +218,7 @@ namespace ServiceLib.Handler
public static async Task<int> AddServer(Config config, ProfileItem profileItem) public static async Task<int> AddServer(Config config, ProfileItem profileItem)
{ {
var item = AppHandler.Instance.GetProfileItem(profileItem.indexId); var item = await AppHandler.Instance.GetProfileItem(profileItem.indexId);
if (item is null) if (item is null)
{ {
item = profileItem; item = profileItem;
@ -330,7 +330,7 @@ namespace ServiceLib.Handler
{ {
foreach (var it in indexes) foreach (var it in indexes)
{ {
var item = AppHandler.Instance.GetProfileItem(it.indexId); var item = await AppHandler.Instance.GetProfileItem(it.indexId);
if (item is null) if (item is null)
{ {
continue; continue;
@ -382,23 +382,26 @@ namespace ServiceLib.Handler
{ {
return 0; return 0;
} }
if (SQLiteHelper.Instance.Table<ProfileItem>().Where(t => t.indexId == config.indexId).Any()) var count = await SQLiteHelper.Instance.TableAsync<ProfileItem>().CountAsync(t => t.indexId == config.indexId);
if (count > 0)
{ {
return 0; return 0;
} }
if (lstProfile.Count > 0) if (lstProfile.Count > 0)
{ {
return await SetDefaultServerIndex(config, lstProfile.Where(t => t.port > 0).FirstOrDefault()?.indexId); return await SetDefaultServerIndex(config, lstProfile.FirstOrDefault(t => t.port > 0)?.indexId);
} }
return await SetDefaultServerIndex(config, SQLiteHelper.Instance.Table<ProfileItem>().Where(t => t.port > 0).Select(t => t.indexId).FirstOrDefault());
var item = await SQLiteHelper.Instance.TableAsync<ProfileItem>().Where(t => t.port > 0).FirstOrDefaultAsync();
return await SetDefaultServerIndex(config, item.indexId);
} }
public static async Task<ProfileItem?> GetDefaultServer(Config config) public static async Task<ProfileItem?> GetDefaultServer(Config config)
{ {
var item = AppHandler.Instance.GetProfileItem(config.indexId); var item = await AppHandler.Instance.GetProfileItem(config.indexId);
if (item is null) if (item is null)
{ {
var item2 = SQLiteHelper.Instance.Table<ProfileItem>().FirstOrDefault(); var item2 = await SQLiteHelper.Instance.TableAsync<ProfileItem>().FirstOrDefaultAsync();
await SetDefaultServerIndex(config, item2?.indexId); await SetDefaultServerIndex(config, item2?.indexId);
return item2; return item2;
} }
@ -531,7 +534,7 @@ namespace ServiceLib.Handler
/// <returns></returns> /// <returns></returns>
public static async Task<int> EditCustomServer(Config config, ProfileItem profileItem) public static async Task<int> EditCustomServer(Config config, ProfileItem profileItem)
{ {
var item = AppHandler.Instance.GetProfileItem(profileItem.indexId); var item = await AppHandler.Instance.GetProfileItem(profileItem.indexId);
if (item is null) if (item is null)
{ {
item = profileItem; item = profileItem;
@ -748,7 +751,7 @@ namespace ServiceLib.Handler
public static async Task<int> SortServers(Config config, string subId, string colName, bool asc) public static async Task<int> SortServers(Config config, string subId, string colName, bool asc)
{ {
var lstModel = AppHandler.Instance.ProfileItems(subId, ""); var lstModel = await AppHandler.Instance.ProfileItems(subId, "");
if (lstModel.Count <= 0) if (lstModel.Count <= 0)
{ {
return -1; return -1;
@ -880,7 +883,7 @@ namespace ServiceLib.Handler
public static async Task<Tuple<int, int>> DedupServerList(Config config, string subId) public static async Task<Tuple<int, int>> DedupServerList(Config config, string subId)
{ {
var lstProfile = AppHandler.Instance.ProfileItems(subId); var lstProfile = await AppHandler.Instance.ProfileItems(subId);
List<ProfileItem> lstKeep = new(); List<ProfileItem> lstKeep = new();
List<ProfileItem> lstRemove = new(); List<ProfileItem> lstRemove = new();
@ -980,7 +983,7 @@ namespace ServiceLib.Handler
{ {
try try
{ {
var item = AppHandler.Instance.GetProfileItem(indexId); var item = await AppHandler.Instance.GetProfileItem(indexId);
if (item == null) if (item == null)
{ {
return 0; return 0;
@ -1000,22 +1003,24 @@ namespace ServiceLib.Handler
return 0; return 0;
} }
public static async Task<Tuple<int, string>> AddCustomServer4Multiple(Config config, List<ProfileItem> selecteds, ECoreType coreType) public static async Task<RetResult> AddCustomServer4Multiple(Config config, List<ProfileItem> selecteds, ECoreType coreType)
{ {
var indexId = Utils.GetMd5(Global.CoreMultipleLoadConfigFileName); var indexId = Utils.GetMd5(Global.CoreMultipleLoadConfigFileName);
string configPath = Utils.GetConfigPath(Global.CoreMultipleLoadConfigFileName); var configPath = Utils.GetConfigPath(Global.CoreMultipleLoadConfigFileName);
if (CoreConfigHandler.GenerateClientMultipleLoadConfig(config, configPath, selecteds, coreType, out string msg) != 0)
var result = await CoreConfigHandler.GenerateClientMultipleLoadConfig(config, configPath, selecteds, coreType);
if (result.Code != 0)
{ {
return new Tuple<int, string>(-1, ""); return result;
} }
var fileName = configPath; var fileName = configPath;
if (!File.Exists(fileName)) if (!File.Exists(fileName))
{ {
return new Tuple<int, string>(-1, ""); return result;
} }
var profileItem = AppHandler.Instance.GetProfileItem(indexId) ?? new(); var profileItem = await AppHandler.Instance.GetProfileItem(indexId) ?? new();
profileItem.indexId = indexId; profileItem.indexId = indexId;
profileItem.remarks = coreType == ECoreType.sing_box ? ResUI.menuSetDefaultMultipleServer : ResUI.menuSetDefaultLoadBalanceServer; profileItem.remarks = coreType == ECoreType.sing_box ? ResUI.menuSetDefaultMultipleServer : ResUI.menuSetDefaultLoadBalanceServer;
profileItem.address = Global.CoreMultipleLoadConfigFileName; profileItem.address = Global.CoreMultipleLoadConfigFileName;
@ -1024,7 +1029,8 @@ namespace ServiceLib.Handler
await AddServerCommon(config, profileItem, true); await AddServerCommon(config, profileItem, true);
return new Tuple<int, string>(0, indexId); result.Data = indexId;
return result;
} }
#endregion Server #endregion Server
@ -1050,7 +1056,7 @@ namespace ServiceLib.Handler
if (isSub && Utils.IsNotEmpty(subid)) if (isSub && Utils.IsNotEmpty(subid))
{ {
await RemoveServerViaSubid(config, subid, isSub); await RemoveServerViaSubid(config, subid, isSub);
subFilter = AppHandler.Instance.GetSubItem(subid)?.filter ?? ""; subFilter = (await AppHandler.Instance.GetSubItem(subid))?.filter ?? "";
} }
int countServers = 0; int countServers = 0;
@ -1089,7 +1095,7 @@ namespace ServiceLib.Handler
//Check for duplicate indexId //Check for duplicate indexId
if (lstDbIndexId is null) if (lstDbIndexId is null)
{ {
lstDbIndexId = AppHandler.Instance.ProfileItemIndexes(""); lstDbIndexId = await AppHandler.Instance.ProfileItemIndexes("");
} }
if (lstAdd.Any(t => t.indexId == existItem.indexId) if (lstAdd.Any(t => t.indexId == existItem.indexId)
|| lstDbIndexId.Any(t => t == existItem.indexId)) || lstDbIndexId.Any(t => t == existItem.indexId))
@ -1149,7 +1155,7 @@ namespace ServiceLib.Handler
return -1; return -1;
} }
var subItem = AppHandler.Instance.GetSubItem(subid); var subItem = await AppHandler.Instance.GetSubItem(subid);
var subRemarks = subItem?.remarks; var subRemarks = subItem?.remarks;
var preSocksPort = subItem?.preSocksPort; var preSocksPort = subItem?.preSocksPort;
@ -1284,7 +1290,7 @@ namespace ServiceLib.Handler
List<ProfileItem>? lstOriSub = null; List<ProfileItem>? lstOriSub = null;
if (isSub && Utils.IsNotEmpty(subid)) if (isSub && Utils.IsNotEmpty(subid))
{ {
lstOriSub = AppHandler.Instance.ProfileItems(subid); lstOriSub = await AppHandler.Instance.ProfileItems(subid);
} }
var counter = 0; var counter = 0;
@ -1328,7 +1334,8 @@ namespace ServiceLib.Handler
public static async Task<int> AddSubItem(Config config, string url) public static async Task<int> AddSubItem(Config config, string url)
{ {
//already exists //already exists
if (SQLiteHelper.Instance.Table<SubItem>().Any(e => e.url == url)) var count = await SQLiteHelper.Instance.TableAsync<SubItem>().CountAsync(e => e.url == url);
if (count > 0)
{ {
return 0; return 0;
} }
@ -1354,7 +1361,7 @@ namespace ServiceLib.Handler
public static async Task<int> AddSubItem(Config config, SubItem subItem) public static async Task<int> AddSubItem(Config config, SubItem subItem)
{ {
var item = AppHandler.Instance.GetSubItem(subItem.id); var item = await AppHandler.Instance.GetSubItem(subItem.id);
if (item is null) if (item is null)
{ {
item = subItem; item = subItem;
@ -1383,9 +1390,10 @@ namespace ServiceLib.Handler
if (item.sort <= 0) if (item.sort <= 0)
{ {
var maxSort = 0; var maxSort = 0;
if (SQLiteHelper.Instance.Table<SubItem>().Count() > 0) if (await SQLiteHelper.Instance.TableAsync<SubItem>().CountAsync() > 0)
{ {
maxSort = SQLiteHelper.Instance.Table<SubItem>().Max(t => t == null ? 0 : t.sort); var lstSubs = (await AppHandler.Instance.SubItems());
maxSort = lstSubs.LastOrDefault()?.sort ?? 0;
} }
item.sort = maxSort + 1; item.sort = maxSort + 1;
} }
@ -1412,7 +1420,7 @@ namespace ServiceLib.Handler
{ {
return -1; return -1;
} }
var customProfile = SQLiteHelper.Instance.Table<ProfileItem>().Where(t => t.subid == subid && t.configType == EConfigType.Custom).ToList(); var customProfile = await SQLiteHelper.Instance.TableAsync<ProfileItem>().Where(t => t.subid == subid && t.configType == EConfigType.Custom).ToListAsync();
if (isSub) if (isSub)
{ {
await SQLiteHelper.Instance.ExecuteAsync($"delete from ProfileItem where isSub = 1 and subid = '{subid}'"); await SQLiteHelper.Instance.ExecuteAsync($"delete from ProfileItem where isSub = 1 and subid = '{subid}'");
@ -1431,7 +1439,7 @@ namespace ServiceLib.Handler
public static async Task<int> DeleteSubItem(Config config, string id) public static async Task<int> DeleteSubItem(Config config, string id)
{ {
var item = AppHandler.Instance.GetSubItem(id); var item = await AppHandler.Instance.GetSubItem(id);
if (item is null) if (item is null)
{ {
return 0; return 0;
@ -1594,7 +1602,7 @@ namespace ServiceLib.Handler
public static async Task<int> SetDefaultRouting(Config config, RoutingItem routingItem) public static async Task<int> SetDefaultRouting(Config config, RoutingItem routingItem)
{ {
if (SQLiteHelper.Instance.Table<RoutingItem>().Where(t => t.id == routingItem.id).Count() > 0) if (await SQLiteHelper.Instance.TableAsync<RoutingItem>().Where(t => t.id == routingItem.id).CountAsync() > 0)
{ {
config.routingBasicItem.routingIndexId = routingItem.id; config.routingBasicItem.routingIndexId = routingItem.id;
} }
@ -1606,10 +1614,10 @@ namespace ServiceLib.Handler
public static async Task<RoutingItem> GetDefaultRouting(Config config) public static async Task<RoutingItem> GetDefaultRouting(Config config)
{ {
var item = AppHandler.Instance.GetRoutingItem(config.routingBasicItem.routingIndexId); var item = await AppHandler.Instance.GetRoutingItem(config.routingBasicItem.routingIndexId);
if (item is null) if (item is null)
{ {
var item2 = SQLiteHelper.Instance.Table<RoutingItem>().FirstOrDefault(t => t.locked == false); var item2 = await SQLiteHelper.Instance.TableAsync<RoutingItem>().FirstOrDefaultAsync(t => t.locked == false);
await SetDefaultRouting(config, item2); await SetDefaultRouting(config, item2);
return item2; return item2;
} }
@ -1642,7 +1650,7 @@ namespace ServiceLib.Handler
if (template == null) if (template == null)
return await InitBuiltinRouting(config, blImportAdvancedRules); // fallback return await InitBuiltinRouting(config, blImportAdvancedRules); // fallback
var items = AppHandler.Instance.RoutingItems(); var items = await AppHandler.Instance.RoutingItems();
var maxSort = items.Count; var maxSort = items.Count;
if (!blImportAdvancedRules && items.Where(t => t.remarks.StartsWith(template.version)).ToList().Count > 0) if (!blImportAdvancedRules && items.Where(t => t.remarks.StartsWith(template.version)).ToList().Count > 0)
{ {
@ -1682,7 +1690,7 @@ namespace ServiceLib.Handler
public static async Task<int> InitBuiltinRouting(Config config, bool blImportAdvancedRules = false) public static async Task<int> InitBuiltinRouting(Config config, bool blImportAdvancedRules = false)
{ {
var ver = "V3-"; var ver = "V3-";
var items = AppHandler.Instance.RoutingItems(); var items = await AppHandler.Instance.RoutingItems();
if (!blImportAdvancedRules && items.Where(t => t.remarks.StartsWith(ver)).ToList().Count > 0) if (!blImportAdvancedRules && items.Where(t => t.remarks.StartsWith(ver)).ToList().Count > 0)
{ {
return 0; return 0;
@ -1723,9 +1731,9 @@ namespace ServiceLib.Handler
return 0; return 0;
} }
public static RoutingItem? GetLockedRoutingItem(Config config) public static async Task<RoutingItem?> GetLockedRoutingItem(Config config)
{ {
return SQLiteHelper.Instance.Table<RoutingItem>().FirstOrDefault(it => it.locked == true); return await SQLiteHelper.Instance.TableAsync<RoutingItem>().FirstOrDefaultAsync(it => it.locked == true);
} }
public static async Task RemoveRoutingItem(RoutingItem routingItem) public static async Task RemoveRoutingItem(RoutingItem routingItem)
@ -1739,7 +1747,7 @@ namespace ServiceLib.Handler
public static async Task<int> InitBuiltinDNS(Config config) public static async Task<int> InitBuiltinDNS(Config config)
{ {
var items = AppHandler.Instance.DNSItems(); var items = await AppHandler.Instance.DNSItems();
if (items.Count <= 0) if (items.Count <= 0)
{ {
var item = new DNSItem() var item = new DNSItem()
@ -1782,9 +1790,9 @@ namespace ServiceLib.Handler
} }
} }
public static DNSItem GetExternalDNSItem(ECoreType type, string url) public static async Task<DNSItem> GetExternalDNSItem(ECoreType type, string url)
{ {
var currentItem = AppHandler.Instance.GetDNSItem(type); var currentItem = await AppHandler.Instance.GetDNSItem(type);
var downloadHandle = new DownloadService(); var downloadHandle = new DownloadService();
var templateContent = Task.Run(() => downloadHandle.TryDownloadString(url, true, "")).Result; var templateContent = Task.Run(() => downloadHandle.TryDownloadString(url, true, "")).Result;
@ -1832,8 +1840,8 @@ namespace ServiceLib.Handler
config.constItem.srsSourceUrl = Global.SingboxRulesetSources[1]; config.constItem.srsSourceUrl = Global.SingboxRulesetSources[1];
config.constItem.routeRulesTemplateSourceUrl = Global.RoutingRulesSources[1]; config.constItem.routeRulesTemplateSourceUrl = Global.RoutingRulesSources[1];
await SaveDNSItems(config, GetExternalDNSItem(ECoreType.Xray, Global.DNSTemplateSources[1] + "v2ray.json")); await SaveDNSItems(config, await GetExternalDNSItem(ECoreType.Xray, Global.DNSTemplateSources[1] + "v2ray.json"));
await SaveDNSItems(config, GetExternalDNSItem(ECoreType.sing_box, Global.DNSTemplateSources[1] + "sing_box.json")); await SaveDNSItems(config, await GetExternalDNSItem(ECoreType.sing_box, Global.DNSTemplateSources[1] + "sing_box.json"));
return true; return true;
} }

View File

@ -5,86 +5,55 @@
/// </summary> /// </summary>
public class CoreConfigHandler public class CoreConfigHandler
{ {
public static int GenerateClientConfig(ProfileItem node, string? fileName, out string msg, out string content) public static async Task<RetResult> GenerateClientConfig(ProfileItem node, string? fileName)
{ {
content = string.Empty;
try
{
if (node == null)
{
msg = ResUI.CheckServerSettings;
return -1;
}
var config = AppHandler.Instance.Config; var config = AppHandler.Instance.Config;
var result = new RetResult(-1);
msg = ResUI.InitialConfiguration;
if (node.configType == EConfigType.Custom) if (node.configType == EConfigType.Custom)
{ {
if (node.coreType is ECoreType.mihomo) if (node.coreType is ECoreType.mihomo)
{ {
var configGenClash = new CoreConfigClashService(config); result = await new CoreConfigClashService(config).GenerateClientCustomConfig(node, fileName);
return configGenClash.GenerateClientCustomConfig(node, fileName, out msg);
} }
if (node.coreType is ECoreType.sing_box) if (node.coreType is ECoreType.sing_box)
{ {
var configGenSingbox = new CoreConfigSingboxService(config); result = await new CoreConfigSingboxService(config).GenerateClientCustomConfig(node, fileName);
return configGenSingbox.GenerateClientCustomConfig(node, fileName, out msg);
} }
else else
{ {
return GenerateClientCustomConfig(node, fileName, out msg); result = await GenerateClientCustomConfig(node, fileName);
} }
} }
else if (AppHandler.Instance.GetCoreType(node, node.configType) == ECoreType.sing_box) else if (AppHandler.Instance.GetCoreType(node, node.configType) == ECoreType.sing_box)
{ {
var configGenSingbox = new CoreConfigSingboxService(config); result = await new CoreConfigSingboxService(config).GenerateClientConfigContent(node);
if (configGenSingbox.GenerateClientConfigContent(node, out SingboxConfig? singboxConfig, out msg) != 0)
{
return -1;
}
if (Utils.IsNullOrEmpty(fileName))
{
content = JsonUtils.Serialize(singboxConfig);
} }
else else
{ {
JsonUtils.ToFile(singboxConfig, fileName, false); result = await new CoreConfigV2rayService(config).GenerateClientConfigContent(node);
} }
} if (result.Code != 0)
else
{ {
var coreConfigV2ray = new CoreConfigV2rayService(config); return result;
if (coreConfigV2ray.GenerateClientConfigContent(node, out V2rayConfig? v2rayConfig, out msg) != 0) }
if (Utils.IsNotEmpty(fileName) && result.Data != null)
{ {
return -1; await File.WriteAllTextAsync(fileName, result.Data.ToString());
}
if (Utils.IsNullOrEmpty(fileName))
{
content = JsonUtils.Serialize(v2rayConfig);
}
else
{
JsonUtils.ToFile(v2rayConfig, fileName, false);
}
}
}
catch (Exception ex)
{
Logging.SaveLog("GenerateClientConfig", ex);
msg = ResUI.FailedGenDefaultConfiguration;
return -1;
}
return 0;
} }
private static int GenerateClientCustomConfig(ProfileItem node, string? fileName, out string msg) return result;
}
private static async Task<RetResult> GenerateClientCustomConfig(ProfileItem node, string? fileName)
{ {
var ret = new RetResult(-1);
try try
{ {
if (node == null || fileName is null) if (node == null || fileName is null)
{ {
msg = ResUI.CheckServerSettings; ret.Msg = ResUI.CheckServerSettings;
return -1; return ret;
} }
if (File.Exists(fileName)) if (File.Exists(fileName))
@ -100,8 +69,8 @@
} }
if (!File.Exists(addressFileName)) if (!File.Exists(addressFileName))
{ {
msg = ResUI.FailedGenDefaultConfiguration; ret.Msg = ResUI.FailedGenDefaultConfiguration;
return -1; return ret;
} }
File.Copy(addressFileName, fileName); File.Copy(addressFileName, fileName);
File.SetAttributes(fileName, FileAttributes.Normal); //Copy will keep the attributes of addressFileName, so we need to add write permissions to fileName just in case of addressFileName is a read-only file. File.SetAttributes(fileName, FileAttributes.Normal); //Copy will keep the attributes of addressFileName, so we need to add write permissions to fileName just in case of addressFileName is a read-only file.
@ -109,63 +78,59 @@
//check again //check again
if (!File.Exists(fileName)) if (!File.Exists(fileName))
{ {
msg = ResUI.FailedGenDefaultConfiguration; ret.Msg = ResUI.FailedGenDefaultConfiguration;
return -1; return ret;
} }
msg = string.Format(ResUI.SuccessfulConfiguration, ""); ret.Msg = string.Format(ResUI.SuccessfulConfiguration, "");
ret.Code = 0;
return ret;
} }
catch (Exception ex) catch (Exception ex)
{ {
Logging.SaveLog("GenerateClientCustomConfig", ex); Logging.SaveLog("GenerateClientCustomConfig", ex);
msg = ResUI.FailedGenDefaultConfiguration; ret.Msg = ResUI.FailedGenDefaultConfiguration;
return -1; return ret;
} }
return 0;
} }
public static int GenerateClientSpeedtestConfig(Config config, string fileName, List<ServerTestItem> selecteds, ECoreType coreType, out string msg) public static async Task<RetResult> GenerateClientSpeedtestConfig(Config config, string fileName, List<ServerTestItem> selecteds, ECoreType coreType)
{ {
var result = new RetResult(-1);
if (coreType == ECoreType.sing_box) if (coreType == ECoreType.sing_box)
{ {
if (new CoreConfigSingboxService(config).GenerateClientSpeedtestConfig(selecteds, out SingboxConfig? singboxConfig, out msg) != 0) result = await new CoreConfigSingboxService(config).GenerateClientSpeedtestConfig(selecteds);
{
return -1;
}
JsonUtils.ToFile(singboxConfig, fileName, false);
}
else
{
if (new CoreConfigV2rayService(config).GenerateClientSpeedtestConfig(selecteds, out V2rayConfig? v2rayConfig, out msg) != 0)
{
return -1;
}
JsonUtils.ToFile(v2rayConfig, fileName, false);
}
return 0;
}
public static int GenerateClientMultipleLoadConfig(Config config, string fileName, List<ProfileItem> selecteds, ECoreType coreType, out string msg)
{
msg = ResUI.CheckServerSettings;
if (coreType == ECoreType.sing_box)
{
if (new CoreConfigSingboxService(config).GenerateClientMultipleLoadConfig(selecteds, out SingboxConfig? singboxConfig, out msg) != 0)
{
return -1;
}
JsonUtils.ToFile(singboxConfig, fileName, false);
} }
else if (coreType == ECoreType.Xray) else if (coreType == ECoreType.Xray)
{ {
if (new CoreConfigV2rayService(config).GenerateClientMultipleLoadConfig(selecteds, out V2rayConfig? v2rayConfig, out msg) != 0) result = await new CoreConfigV2rayService(config).GenerateClientSpeedtestConfig(selecteds);
{
return -1;
} }
JsonUtils.ToFile(v2rayConfig, fileName, false); if (result.Code != 0)
{
return result;
}
await File.WriteAllTextAsync(fileName, result.Data.ToString());
return result;
} }
return 0; public static async Task<RetResult> GenerateClientMultipleLoadConfig(Config config, string fileName, List<ProfileItem> selecteds, ECoreType coreType)
{
var result = new RetResult(-1);
if (coreType == ECoreType.sing_box)
{
result = await new CoreConfigSingboxService(config).GenerateClientMultipleLoadConfig(selecteds);
}
else if (coreType == ECoreType.Xray)
{
result = await new CoreConfigV2rayService(config).GenerateClientMultipleLoadConfig(selecteds);
}
if (result.Code != 0)
{
return result;
}
await File.WriteAllTextAsync(fileName, result.Data.ToString());
return result;
} }
} }
} }

View File

@ -24,7 +24,7 @@ namespace ServiceLib.Handler
Environment.SetEnvironmentVariable("xray.location.asset", Utils.GetBinPath(""), EnvironmentVariableTarget.Process); Environment.SetEnvironmentVariable("xray.location.asset", Utils.GetBinPath(""), EnvironmentVariableTarget.Process);
} }
public void LoadCore(ProfileItem? node) public async Task LoadCore(ProfileItem? node)
{ {
if (node == null) if (node == null)
{ {
@ -32,18 +32,18 @@ namespace ServiceLib.Handler
return; return;
} }
string fileName = Utils.GetConfigPath(Global.CoreConfigFileName); var fileName = Utils.GetConfigPath(Global.CoreConfigFileName);
if (CoreConfigHandler.GenerateClientConfig(node, fileName, out string msg, out string content) != 0) var result = await CoreConfigHandler.GenerateClientConfig(node, fileName);
ShowMsg(false, result.Msg);
if (result.Code != 0)
{ {
ShowMsg(false, msg);
return; return;
} }
else else
{ {
ShowMsg(false, msg);
ShowMsg(true, $"{node.GetSummary()}"); ShowMsg(true, $"{node.GetSummary()}");
CoreStop(); CoreStop();
CoreStart(node); await CoreStart(node);
//In tun mode, do a delay check and restart the core //In tun mode, do a delay check and restart the core
//if (_config.tunModeItem.enableTun) //if (_config.tunModeItem.enableTun)
@ -65,18 +65,15 @@ namespace ServiceLib.Handler
} }
} }
public int LoadCoreConfigSpeedtest(List<ServerTestItem> selecteds) public async Task<int> LoadCoreConfigSpeedtest(List<ServerTestItem> selecteds)
{ {
int pid = -1; var pid = -1;
var coreType = selecteds.Exists(t => t.ConfigType == EConfigType.Hysteria2 || t.ConfigType == EConfigType.TUIC || t.ConfigType == EConfigType.WireGuard) ? ECoreType.sing_box : ECoreType.Xray; var coreType = selecteds.Exists(t => t.ConfigType is EConfigType.Hysteria2 or EConfigType.TUIC or EConfigType.WireGuard) ? ECoreType.sing_box : ECoreType.Xray;
string configPath = Utils.GetConfigPath(Global.CoreSpeedtestConfigFileName); var configPath = Utils.GetConfigPath(Global.CoreSpeedtestConfigFileName);
if (CoreConfigHandler.GenerateClientSpeedtestConfig(_config, configPath, selecteds, coreType, out string msg) != 0) var result = await CoreConfigHandler.GenerateClientSpeedtestConfig(_config, configPath, selecteds, coreType);
ShowMsg(false, result.Msg);
if (result.Code == 0)
{ {
ShowMsg(false, msg);
}
else
{
ShowMsg(false, msg);
pid = CoreStartSpeedtest(configPath, coreType); pid = CoreStartSpeedtest(configPath, coreType);
} }
return pid; return pid;
@ -170,7 +167,7 @@ namespace ServiceLib.Handler
return fileName; return fileName;
} }
private void CoreStart(ProfileItem node) private async Task CoreStart(ProfileItem node)
{ {
ShowMsg(false, $"{Environment.OSVersion} - {(Environment.Is64BitOperatingSystem ? 64 : 32)}"); ShowMsg(false, $"{Environment.OSVersion} - {(Environment.Is64BitOperatingSystem ? 64 : 32)}");
ShowMsg(false, string.Format(ResUI.StartService, DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"))); ShowMsg(false, string.Format(ResUI.StartService, DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")));
@ -227,7 +224,8 @@ namespace ServiceLib.Handler
if (itemSocks != null) if (itemSocks != null)
{ {
string fileName2 = Utils.GetConfigPath(Global.CorePreConfigFileName); string fileName2 = Utils.GetConfigPath(Global.CorePreConfigFileName);
if (CoreConfigHandler.GenerateClientConfig(itemSocks, fileName2, out string msg2, out string configStr) == 0) var result = await CoreConfigHandler.GenerateClientConfig(itemSocks, fileName2);
if (result.Code == 0)
{ {
var coreInfo2 = CoreInfoHandler.Instance.GetCoreInfo(preCoreType); var coreInfo2 = CoreInfoHandler.Instance.GetCoreInfo(preCoreType);
var proc2 = RunProcess(node, coreInfo2, $" -c {Global.CorePreConfigFileName}", true); var proc2 = RunProcess(node, coreInfo2, $" -c {Global.CorePreConfigFileName}", true);

View File

@ -29,7 +29,7 @@ namespace ServiceLib.Handler
{ {
await SQLiteHelper.Instance.ExecuteAsync($"delete from ProfileExItem where indexId not in ( select indexId from ProfileItem )"); await SQLiteHelper.Instance.ExecuteAsync($"delete from ProfileExItem where indexId not in ( select indexId from ProfileItem )");
_lstProfileEx = new(SQLiteHelper.Instance.Table<ProfileExItem>()); _lstProfileEx = new(await SQLiteHelper.Instance.TableAsync<ProfileExItem>().ToListAsync());
} }
private void IndexIdEnqueue(string indexId) private void IndexIdEnqueue(string indexId)
@ -45,7 +45,7 @@ namespace ServiceLib.Handler
var cnt = _queIndexIds.Count; var cnt = _queIndexIds.Count;
if (cnt > 0) if (cnt > 0)
{ {
var lstExists = SQLiteHelper.Instance.Table<ProfileExItem>(); var lstExists = await SQLiteHelper.Instance.TableAsync<ProfileExItem>().ToListAsync();
List<ProfileExItem> lstInserts = []; List<ProfileExItem> lstInserts = [];
List<ProfileExItem> lstUpdates = []; List<ProfileExItem> lstUpdates = [];

View File

@ -71,7 +71,7 @@
long ticks = DateTime.Now.Date.Ticks; long ticks = DateTime.Now.Date.Ticks;
await SQLiteHelper.Instance.ExecuteAsync($"update ServerStatItem set todayUp = 0,todayDown=0,dateNow={ticks} where dateNow<>{ticks}"); await SQLiteHelper.Instance.ExecuteAsync($"update ServerStatItem set todayUp = 0,todayDown=0,dateNow={ticks} where dateNow<>{ticks}");
_lstServerStat = SQLiteHelper.Instance.Table<ServerStatItem>().ToList(); _lstServerStat = await SQLiteHelper.Instance.TableAsync<ServerStatItem>().ToListAsync();
} }
private void UpdateServerStatHandler(ServerSpeedItem server) private void UpdateServerStatHandler(ServerSpeedItem server)

View File

@ -24,7 +24,7 @@
while (true) while (true)
{ {
var updateTime = ((DateTimeOffset)DateTime.Now).ToUnixTimeSeconds(); var updateTime = ((DateTimeOffset)DateTime.Now).ToUnixTimeSeconds();
var lstSubs = AppHandler.Instance.SubItems() var lstSubs = (await AppHandler.Instance.SubItems())
.Where(t => t.autoUpdateInterval > 0) .Where(t => t.autoUpdateInterval > 0)
.Where(t => updateTime - t.updateTime >= t.autoUpdateInterval * 60) .Where(t => updateTime - t.updateTime >= t.autoUpdateInterval * 60)
.ToList(); .ToList();

View File

@ -0,0 +1,14 @@
namespace ServiceLib.Models
{
public class RetResult
{
public int Code { get; set; }
public string? Msg { get; set; }
public object? Data { get; set; }
public RetResult(int code)
{
Code = code;
}
}
}

View File

@ -19,22 +19,23 @@
/// <param name="fileName"></param> /// <param name="fileName"></param>
/// <param name="msg"></param> /// <param name="msg"></param>
/// <returns></returns> /// <returns></returns>
public int GenerateClientCustomConfig(ProfileItem node, string? fileName, out string msg) public async Task<RetResult> GenerateClientCustomConfig(ProfileItem node, string? fileName)
{ {
var ret = new RetResult(-1);
if (node == null || fileName is null) if (node == null || fileName is null)
{ {
msg = ResUI.CheckServerSettings; ret.Msg = ResUI.CheckServerSettings;
return -1; return ret;
} }
msg = ResUI.InitialConfiguration; ret.Msg = ResUI.InitialConfiguration;
try try
{ {
if (node == null) if (node == null)
{ {
msg = ResUI.CheckServerSettings; ret.Msg = ResUI.CheckServerSettings;
return -1; return ret;
} }
if (File.Exists(fileName)) if (File.Exists(fileName))
@ -45,8 +46,8 @@
string addressFileName = node.address; string addressFileName = node.address;
if (Utils.IsNullOrEmpty(addressFileName)) if (Utils.IsNullOrEmpty(addressFileName))
{ {
msg = ResUI.FailedGetDefaultConfiguration; ret.Msg = ResUI.FailedGetDefaultConfiguration;
return -1; return ret;
} }
if (!File.Exists(addressFileName)) if (!File.Exists(addressFileName))
{ {
@ -54,8 +55,8 @@
} }
if (!File.Exists(addressFileName)) if (!File.Exists(addressFileName))
{ {
msg = ResUI.FailedReadConfiguration + "1"; ret.Msg = ResUI.FailedReadConfiguration + "1";
return -1; return ret;
} }
string tagYamlStr1 = "!<str>"; string tagYamlStr1 = "!<str>";
@ -73,8 +74,8 @@
var fileContent = YamlUtils.FromYaml<Dictionary<string, object>>(txtFile); var fileContent = YamlUtils.FromYaml<Dictionary<string, object>>(txtFile);
if (fileContent == null) if (fileContent == null)
{ {
msg = ResUI.FailedConversionConfiguration; ret.Msg = ResUI.FailedConversionConfiguration;
return -1; return ret;
} }
//port //port
@ -136,25 +137,26 @@
} }
var txtFileNew = YamlUtils.ToYaml(fileContent).Replace(tagYamlStr2, tagYamlStr3); var txtFileNew = YamlUtils.ToYaml(fileContent).Replace(tagYamlStr2, tagYamlStr3);
File.WriteAllText(fileName, txtFileNew); await File.WriteAllTextAsync(fileName, txtFileNew);
//check again //check again
if (!File.Exists(fileName)) if (!File.Exists(fileName))
{ {
msg = ResUI.FailedReadConfiguration + "2"; ret.Msg = ResUI.FailedReadConfiguration + "2";
return -1; return ret;
} }
ClashApiHandler.Instance.ProfileContent = fileContent; ClashApiHandler.Instance.ProfileContent = fileContent;
msg = string.Format(ResUI.SuccessfulConfiguration, $"{node.GetSummary()}"); ret.Msg = string.Format(ResUI.SuccessfulConfiguration, $"{node.GetSummary()}");
ret.Code = 0;
return ret;
} }
catch (Exception ex) catch (Exception ex)
{ {
Logging.SaveLog("GenerateClientConfigClash", ex); Logging.SaveLog("GenerateClientConfigClash", ex);
msg = ResUI.FailedGenDefaultConfiguration; ret.Msg = ResUI.FailedGenDefaultConfiguration;
return -1; return ret;
} }
return 0;
} }
private void MixinContent(Dictionary<string, object> fileContent, ProfileItem node) private void MixinContent(Dictionary<string, object> fileContent, ProfileItem node)

View File

@ -15,92 +15,94 @@ namespace ServiceLib.Services.CoreConfig
#region public gen function #region public gen function
public int GenerateClientConfigContent(ProfileItem node, out SingboxConfig? singboxConfig, out string msg) public async Task<RetResult> GenerateClientConfigContent(ProfileItem node)
{ {
singboxConfig = null; var ret = new RetResult(-1);
try try
{ {
if (node == null if (node == null
|| node.port <= 0) || node.port <= 0)
{ {
msg = ResUI.CheckServerSettings; ret.Msg = ResUI.CheckServerSettings;
return -1; return ret;
} }
if (node.GetNetwork() is nameof(ETransport.kcp) or nameof(ETransport.splithttp)) if (node.GetNetwork() is nameof(ETransport.kcp) or nameof(ETransport.splithttp))
{ {
msg = ResUI.Incorrectconfiguration + $" - {node.GetNetwork()}"; ret.Msg = ResUI.Incorrectconfiguration + $" - {node.GetNetwork()}";
return -1; return ret;
} }
msg = ResUI.InitialConfiguration; ret.Msg = ResUI.InitialConfiguration;
string result = Utils.GetEmbedText(Global.SingboxSampleClient); string result = Utils.GetEmbedText(Global.SingboxSampleClient);
if (Utils.IsNullOrEmpty(result)) if (Utils.IsNullOrEmpty(result))
{ {
msg = ResUI.FailedGetDefaultConfiguration; ret.Msg = ResUI.FailedGetDefaultConfiguration;
return -1; return ret;
} }
singboxConfig = JsonUtils.Deserialize<SingboxConfig>(result); var singboxConfig = JsonUtils.Deserialize<SingboxConfig>(result);
if (singboxConfig == null) if (singboxConfig == null)
{ {
msg = ResUI.FailedGenDefaultConfiguration; ret.Msg = ResUI.FailedGenDefaultConfiguration;
return -1; return ret;
} }
GenLog(singboxConfig); await GenLog(singboxConfig);
GenInbounds(singboxConfig); await GenInbounds(singboxConfig);
GenOutbound(node, singboxConfig.outbounds[0]); await GenOutbound(node, singboxConfig.outbounds[0]);
GenMoreOutbounds(node, singboxConfig); await GenMoreOutbounds(node, singboxConfig);
GenRouting(singboxConfig); await GenRouting(singboxConfig);
GenDns(node, singboxConfig); await GenDns(node, singboxConfig);
GenExperimental(singboxConfig); await GenExperimental(singboxConfig);
ConvertGeo2Ruleset(singboxConfig); await ConvertGeo2Ruleset(singboxConfig);
msg = string.Format(ResUI.SuccessfulConfiguration, ""); ret.Msg = string.Format(ResUI.SuccessfulConfiguration, "");
ret.Code = 0;
ret.Data = JsonUtils.Serialize(singboxConfig);
return ret;
} }
catch (Exception ex) catch (Exception ex)
{ {
Logging.SaveLog("GenerateClientConfig4Singbox", ex); Logging.SaveLog("GenerateClientConfig4Singbox", ex);
msg = ResUI.FailedGenDefaultConfiguration; ret.Msg = ResUI.FailedGenDefaultConfiguration;
return -1; return ret;
} }
return 0;
} }
public int GenerateClientSpeedtestConfig(List<ServerTestItem> selecteds, out SingboxConfig? singboxConfig, out string msg) public async Task<RetResult> GenerateClientSpeedtestConfig(List<ServerTestItem> selecteds)
{ {
singboxConfig = null; var ret = new RetResult(-1);
try try
{ {
if (_config == null) if (_config == null)
{ {
msg = ResUI.CheckServerSettings; ret.Msg = ResUI.CheckServerSettings;
return -1; return ret;
} }
msg = ResUI.InitialConfiguration; ret.Msg = ResUI.InitialConfiguration;
string result = Utils.GetEmbedText(Global.SingboxSampleClient); string result = Utils.GetEmbedText(Global.SingboxSampleClient);
string txtOutbound = Utils.GetEmbedText(Global.SingboxSampleOutbound); string txtOutbound = Utils.GetEmbedText(Global.SingboxSampleOutbound);
if (Utils.IsNullOrEmpty(result) || txtOutbound.IsNullOrEmpty()) if (Utils.IsNullOrEmpty(result) || txtOutbound.IsNullOrEmpty())
{ {
msg = ResUI.FailedGetDefaultConfiguration; ret.Msg = ResUI.FailedGetDefaultConfiguration;
return -1; return ret;
} }
singboxConfig = JsonUtils.Deserialize<SingboxConfig>(result); var singboxConfig = JsonUtils.Deserialize<SingboxConfig>(result);
if (singboxConfig == null) if (singboxConfig == null)
{ {
msg = ResUI.FailedGenDefaultConfiguration; ret.Msg = ResUI.FailedGenDefaultConfiguration;
return -1; return ret;
} }
List<IPEndPoint> lstIpEndPoints = new(); List<IPEndPoint> lstIpEndPoints = new();
List<TcpConnectionInformation> lstTcpConns = new(); List<TcpConnectionInformation> lstTcpConns = new();
@ -115,7 +117,7 @@ namespace ServiceLib.Services.CoreConfig
Logging.SaveLog(ex.Message, ex); Logging.SaveLog(ex.Message, ex);
} }
GenLog(singboxConfig); await GenLog(singboxConfig);
//GenDns(new(), singboxConfig); //GenDns(new(), singboxConfig);
singboxConfig.inbounds.Clear(); // Remove "proxy" service for speedtest, avoiding port conflicts. singboxConfig.inbounds.Clear(); // Remove "proxy" service for speedtest, avoiding port conflicts.
singboxConfig.outbounds.RemoveAt(0); singboxConfig.outbounds.RemoveAt(0);
@ -132,7 +134,7 @@ namespace ServiceLib.Services.CoreConfig
{ {
continue; continue;
} }
var item = AppHandler.Instance.GetProfileItem(it.IndexId); var item = await AppHandler.Instance.GetProfileItem(it.IndexId);
if (it.ConfigType is EConfigType.VMess or EConfigType.VLESS) if (it.ConfigType is EConfigType.VMess or EConfigType.VLESS)
{ {
if (item is null || Utils.IsNullOrEmpty(item.id) || !Utils.IsGuidByParse(item.id)) if (item is null || Utils.IsNullOrEmpty(item.id) || !Utils.IsGuidByParse(item.id))
@ -200,7 +202,7 @@ namespace ServiceLib.Services.CoreConfig
} }
var outbound = JsonUtils.Deserialize<Outbound4Sbox>(txtOutbound); var outbound = JsonUtils.Deserialize<Outbound4Sbox>(txtOutbound);
GenOutbound(item, outbound); await GenOutbound(item, outbound);
outbound.tag = Global.ProxyTag + inbound.listen_port.ToString(); outbound.tag = Global.ProxyTag + inbound.listen_port.ToString();
singboxConfig.outbounds.Add(outbound); singboxConfig.outbounds.Add(outbound);
@ -213,7 +215,7 @@ namespace ServiceLib.Services.CoreConfig
singboxConfig.route.rules.Add(rule); singboxConfig.route.rules.Add(rule);
} }
GenDnsDomains(null, singboxConfig, null); await GenDnsDomains(null, singboxConfig, null);
//var dnsServer = singboxConfig.dns?.servers.FirstOrDefault(); //var dnsServer = singboxConfig.dns?.servers.FirstOrDefault();
//if (dnsServer != null) //if (dnsServer != null)
//{ //{
@ -226,49 +228,51 @@ namespace ServiceLib.Services.CoreConfig
// singboxConfig.dns.rules.Add(dnsRule); // singboxConfig.dns.rules.Add(dnsRule);
//} //}
//msg = string.Format(ResUI.SuccessfulConfiguration"), node.getSummary()); //ret.Msg =string.Format(ResUI.SuccessfulConfiguration"), node.getSummary());
return 0; ret.Code = 0;
ret.Data = JsonUtils.Serialize(singboxConfig);
return ret;
} }
catch (Exception ex) catch (Exception ex)
{ {
Logging.SaveLog(ex.Message, ex); Logging.SaveLog(ex.Message, ex);
msg = ResUI.FailedGenDefaultConfiguration; ret.Msg = ResUI.FailedGenDefaultConfiguration;
return -1; return ret;
} }
} }
public int GenerateClientMultipleLoadConfig(List<ProfileItem> selecteds, out SingboxConfig? singboxConfig, out string msg) public async Task<RetResult> GenerateClientMultipleLoadConfig(List<ProfileItem> selecteds)
{ {
singboxConfig = null; var ret = new RetResult(-1);
try try
{ {
if (_config == null) if (_config == null)
{ {
msg = ResUI.CheckServerSettings; ret.Msg = ResUI.CheckServerSettings;
return -1; return ret;
} }
msg = ResUI.InitialConfiguration; ret.Msg = ResUI.InitialConfiguration;
string result = Utils.GetEmbedText(Global.SingboxSampleClient); string result = Utils.GetEmbedText(Global.SingboxSampleClient);
string txtOutbound = Utils.GetEmbedText(Global.SingboxSampleOutbound); string txtOutbound = Utils.GetEmbedText(Global.SingboxSampleOutbound);
if (Utils.IsNullOrEmpty(result) || txtOutbound.IsNullOrEmpty()) if (Utils.IsNullOrEmpty(result) || txtOutbound.IsNullOrEmpty())
{ {
msg = ResUI.FailedGetDefaultConfiguration; ret.Msg = ResUI.FailedGetDefaultConfiguration;
return -1; return ret;
} }
singboxConfig = JsonUtils.Deserialize<SingboxConfig>(result); var singboxConfig = JsonUtils.Deserialize<SingboxConfig>(result);
if (singboxConfig == null) if (singboxConfig == null)
{ {
msg = ResUI.FailedGenDefaultConfiguration; ret.Msg = ResUI.FailedGenDefaultConfiguration;
return -1; return ret;
} }
GenLog(singboxConfig); await GenLog(singboxConfig);
GenInbounds(singboxConfig); await GenInbounds(singboxConfig);
GenRouting(singboxConfig); await GenRouting(singboxConfig);
GenExperimental(singboxConfig); await GenExperimental(singboxConfig);
singboxConfig.outbounds.RemoveAt(0); singboxConfig.outbounds.RemoveAt(0);
var tagProxy = new List<string>(); var tagProxy = new List<string>();
@ -282,7 +286,7 @@ namespace ServiceLib.Services.CoreConfig
{ {
continue; continue;
} }
var item = AppHandler.Instance.GetProfileItem(it.indexId); var item = await AppHandler.Instance.GetProfileItem(it.indexId);
if (item is null) if (item is null)
{ {
continue; continue;
@ -306,19 +310,19 @@ namespace ServiceLib.Services.CoreConfig
//outbound //outbound
var outbound = JsonUtils.Deserialize<Outbound4Sbox>(txtOutbound); var outbound = JsonUtils.Deserialize<Outbound4Sbox>(txtOutbound);
GenOutbound(item, outbound); await GenOutbound(item, outbound);
outbound.tag = $"{Global.ProxyTag}-{tagProxy.Count + 1}"; outbound.tag = $"{Global.ProxyTag}-{tagProxy.Count + 1}";
singboxConfig.outbounds.Add(outbound); singboxConfig.outbounds.Add(outbound);
tagProxy.Add(outbound.tag); tagProxy.Add(outbound.tag);
} }
if (tagProxy.Count <= 0) if (tagProxy.Count <= 0)
{ {
msg = ResUI.FailedGenDefaultConfiguration; ret.Msg = ResUI.FailedGenDefaultConfiguration;
return -1; return ret;
} }
GenDns(null, singboxConfig); await GenDns(null, singboxConfig);
ConvertGeo2Ruleset(singboxConfig); await ConvertGeo2Ruleset(singboxConfig);
//add urltest outbound //add urltest outbound
var outUrltest = new Outbound4Sbox var outUrltest = new Outbound4Sbox
@ -341,32 +345,35 @@ namespace ServiceLib.Services.CoreConfig
outSelector.outbounds.Insert(0, outUrltest.tag); outSelector.outbounds.Insert(0, outUrltest.tag);
singboxConfig.outbounds.Add(outSelector); singboxConfig.outbounds.Add(outSelector);
return 0; ret.Code = 0;
ret.Data = JsonUtils.Serialize(singboxConfig);
return ret;
} }
catch (Exception ex) catch (Exception ex)
{ {
Logging.SaveLog(ex.Message, ex); Logging.SaveLog(ex.Message, ex);
msg = ResUI.FailedGenDefaultConfiguration; ret.Msg = ResUI.FailedGenDefaultConfiguration;
return -1; return ret;
} }
} }
public int GenerateClientCustomConfig(ProfileItem node, string? fileName, out string msg) public async Task<RetResult> GenerateClientCustomConfig(ProfileItem node, string? fileName)
{ {
var ret = new RetResult(-1);
if (node == null || fileName is null) if (node == null || fileName is null)
{ {
msg = ResUI.CheckServerSettings; ret.Msg = ResUI.CheckServerSettings;
return -1; return ret;
} }
msg = ResUI.InitialConfiguration; ret.Msg = ResUI.InitialConfiguration;
try try
{ {
if (node == null) if (node == null)
{ {
msg = ResUI.CheckServerSettings; ret.Msg = ResUI.CheckServerSettings;
return -1; return ret;
} }
if (File.Exists(fileName)) if (File.Exists(fileName))
@ -377,8 +384,8 @@ namespace ServiceLib.Services.CoreConfig
string addressFileName = node.address; string addressFileName = node.address;
if (Utils.IsNullOrEmpty(addressFileName)) if (Utils.IsNullOrEmpty(addressFileName))
{ {
msg = ResUI.FailedGetDefaultConfiguration; ret.Msg = ResUI.FailedGetDefaultConfiguration;
return -1; return ret;
} }
if (!File.Exists(addressFileName)) if (!File.Exists(addressFileName))
{ {
@ -386,8 +393,8 @@ namespace ServiceLib.Services.CoreConfig
} }
if (!File.Exists(addressFileName)) if (!File.Exists(addressFileName))
{ {
msg = ResUI.FailedReadConfiguration + "1"; ret.Msg = ResUI.FailedReadConfiguration + "1";
return -1; return ret;
} }
if (node.address == Global.CoreMultipleLoadConfigFileName) if (node.address == Global.CoreMultipleLoadConfigFileName)
@ -400,8 +407,8 @@ namespace ServiceLib.Services.CoreConfig
} }
else else
{ {
GenInbounds(singboxConfig); await GenInbounds(singboxConfig);
GenExperimental(singboxConfig); await GenExperimental(singboxConfig);
JsonUtils.ToFile(singboxConfig, fileName, false); JsonUtils.ToFile(singboxConfig, fileName, false);
} }
} }
@ -413,26 +420,27 @@ namespace ServiceLib.Services.CoreConfig
//check again //check again
if (!File.Exists(fileName)) if (!File.Exists(fileName))
{ {
msg = ResUI.FailedReadConfiguration + "2"; ret.Msg = ResUI.FailedReadConfiguration + "2";
return -1; return ret;
} }
msg = string.Format(ResUI.SuccessfulConfiguration, $"{node.GetSummary()}"); ret.Msg = string.Format(ResUI.SuccessfulConfiguration, "");
ret.Code = 0;
return ret;
} }
catch (Exception ex) catch (Exception ex)
{ {
Logging.SaveLog(ex.Message, ex); Logging.SaveLog(ex.Message, ex);
msg = ResUI.FailedGenDefaultConfiguration; ret.Msg = ResUI.FailedGenDefaultConfiguration;
return -1; return ret;
} }
return 0;
} }
#endregion public gen function #endregion public gen function
#region private gen function #region private gen function
private int GenLog(SingboxConfig singboxConfig) public async Task<int> GenLog(SingboxConfig singboxConfig)
{ {
try try
{ {
@ -572,7 +580,7 @@ namespace ServiceLib.Services.CoreConfig
return inbound; return inbound;
} }
private int GenOutbound(ProfileItem node, Outbound4Sbox outbound) public async Task<int> GenOutbound(ProfileItem node, Outbound4Sbox outbound)
{ {
try try
{ {
@ -595,7 +603,7 @@ namespace ServiceLib.Services.CoreConfig
outbound.security = Global.DefaultSecurity; outbound.security = Global.DefaultSecurity;
} }
GenOutboundMux(node, outbound); await GenOutboundMux(node, outbound);
break; break;
} }
case EConfigType.Shadowsocks: case EConfigType.Shadowsocks:
@ -603,7 +611,7 @@ namespace ServiceLib.Services.CoreConfig
outbound.method = AppHandler.Instance.GetShadowsocksSecurities(node).Contains(node.security) ? node.security : Global.None; outbound.method = AppHandler.Instance.GetShadowsocksSecurities(node).Contains(node.security) ? node.security : Global.None;
outbound.password = node.id; outbound.password = node.id;
GenOutboundMux(node, outbound); await GenOutboundMux(node, outbound);
break; break;
} }
case EConfigType.SOCKS: case EConfigType.SOCKS:
@ -635,7 +643,7 @@ namespace ServiceLib.Services.CoreConfig
if (Utils.IsNullOrEmpty(node.flow)) if (Utils.IsNullOrEmpty(node.flow))
{ {
GenOutboundMux(node, outbound); await GenOutboundMux(node, outbound);
} }
else else
{ {
@ -647,7 +655,7 @@ namespace ServiceLib.Services.CoreConfig
{ {
outbound.password = node.id; outbound.password = node.id;
GenOutboundMux(node, outbound); await GenOutboundMux(node, outbound);
break; break;
} }
case EConfigType.Hysteria2: case EConfigType.Hysteria2:
@ -685,9 +693,9 @@ namespace ServiceLib.Services.CoreConfig
} }
} }
GenOutboundTls(node, outbound); await GenOutboundTls(node, outbound);
GenOutboundTransport(node, outbound); await GenOutboundTransport(node, outbound);
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -696,7 +704,7 @@ namespace ServiceLib.Services.CoreConfig
return 0; return 0;
} }
private int GenOutboundMux(ProfileItem node, Outbound4Sbox outbound) public async Task<int> GenOutboundMux(ProfileItem node, Outbound4Sbox outbound)
{ {
try try
{ {
@ -719,7 +727,7 @@ namespace ServiceLib.Services.CoreConfig
return 0; return 0;
} }
private int GenOutboundTls(ProfileItem node, Outbound4Sbox outbound) public async Task<int> GenOutboundTls(ProfileItem node, Outbound4Sbox outbound)
{ {
try try
{ {
@ -769,7 +777,7 @@ namespace ServiceLib.Services.CoreConfig
return 0; return 0;
} }
private int GenOutboundTransport(ProfileItem node, Outbound4Sbox outbound) public async Task<int> GenOutboundTransport(ProfileItem node, Outbound4Sbox outbound)
{ {
try try
{ {
@ -846,7 +854,7 @@ namespace ServiceLib.Services.CoreConfig
return 0; return 0;
} }
private int GenMoreOutbounds(ProfileItem node, SingboxConfig singboxConfig) private async Task<int> GenMoreOutbounds(ProfileItem node, SingboxConfig singboxConfig)
{ {
if (node.subid.IsNullOrEmpty()) if (node.subid.IsNullOrEmpty())
{ {
@ -854,7 +862,7 @@ namespace ServiceLib.Services.CoreConfig
} }
try try
{ {
var subItem = AppHandler.Instance.GetSubItem(node.subid); var subItem = await AppHandler.Instance.GetSubItem(node.subid);
if (subItem is null) if (subItem is null)
{ {
return 0; return 0;
@ -865,12 +873,12 @@ namespace ServiceLib.Services.CoreConfig
var txtOutbound = Utils.GetEmbedText(Global.SingboxSampleOutbound); var txtOutbound = Utils.GetEmbedText(Global.SingboxSampleOutbound);
//Previous proxy //Previous proxy
var prevNode = AppHandler.Instance.GetProfileItemViaRemarks(subItem.prevProfile); var prevNode = await AppHandler.Instance.GetProfileItemViaRemarks(subItem.prevProfile);
if (prevNode is not null if (prevNode is not null
&& prevNode.configType != EConfigType.Custom) && prevNode.configType != EConfigType.Custom)
{ {
var prevOutbound = JsonUtils.Deserialize<Outbound4Sbox>(txtOutbound); var prevOutbound = JsonUtils.Deserialize<Outbound4Sbox>(txtOutbound);
GenOutbound(prevNode, prevOutbound); await GenOutbound(prevNode, prevOutbound);
prevOutbound.tag = $"{Global.ProxyTag}2"; prevOutbound.tag = $"{Global.ProxyTag}2";
singboxConfig.outbounds.Add(prevOutbound); singboxConfig.outbounds.Add(prevOutbound);
@ -878,12 +886,12 @@ namespace ServiceLib.Services.CoreConfig
} }
//Next proxy //Next proxy
var nextNode = AppHandler.Instance.GetProfileItemViaRemarks(subItem.nextProfile); var nextNode = await AppHandler.Instance.GetProfileItemViaRemarks(subItem.nextProfile);
if (nextNode is not null if (nextNode is not null
&& nextNode.configType != EConfigType.Custom) && nextNode.configType != EConfigType.Custom)
{ {
var nextOutbound = JsonUtils.Deserialize<Outbound4Sbox>(txtOutbound); var nextOutbound = JsonUtils.Deserialize<Outbound4Sbox>(txtOutbound);
GenOutbound(nextNode, nextOutbound); await GenOutbound(nextNode, nextOutbound);
nextOutbound.tag = Global.ProxyTag; nextOutbound.tag = Global.ProxyTag;
singboxConfig.outbounds.Insert(0, nextOutbound); singboxConfig.outbounds.Insert(0, nextOutbound);
@ -960,20 +968,20 @@ namespace ServiceLib.Services.CoreConfig
{ {
if (item.enabled) if (item.enabled)
{ {
GenRoutingUserRule(item, singboxConfig.route.rules); await GenRoutingUserRule(item, singboxConfig.route.rules);
} }
} }
} }
} }
else else
{ {
var lockedItem = ConfigHandler.GetLockedRoutingItem(_config); var lockedItem = await ConfigHandler.GetLockedRoutingItem(_config);
if (lockedItem != null) if (lockedItem != null)
{ {
var rules = JsonUtils.Deserialize<List<RulesItem>>(lockedItem.ruleSet); var rules = JsonUtils.Deserialize<List<RulesItem>>(lockedItem.ruleSet);
foreach (var item in rules ?? []) foreach (var item in rules ?? [])
{ {
GenRoutingUserRule(item, singboxConfig.route.rules); await GenRoutingUserRule(item, singboxConfig.route.rules);
} }
} }
} }
@ -1011,7 +1019,7 @@ namespace ServiceLib.Services.CoreConfig
} }
} }
private int GenRoutingUserRule(RulesItem item, List<Rule4Sbox> rules) public async Task<int> GenRoutingUserRule(RulesItem item, List<Rule4Sbox> rules)
{ {
try try
{ {
@ -1169,11 +1177,11 @@ namespace ServiceLib.Services.CoreConfig
return true; return true;
} }
private int GenDns(ProfileItem? node, SingboxConfig singboxConfig) public async Task<int> GenDns(ProfileItem? node, SingboxConfig singboxConfig)
{ {
try try
{ {
var item = AppHandler.Instance.GetDNSItem(ECoreType.sing_box); var item = await AppHandler.Instance.GetDNSItem(ECoreType.sing_box);
var strDNS = string.Empty; var strDNS = string.Empty;
if (_config.tunModeItem.enableTun) if (_config.tunModeItem.enableTun)
{ {
@ -1191,7 +1199,7 @@ namespace ServiceLib.Services.CoreConfig
} }
singboxConfig.dns = dns4Sbox; singboxConfig.dns = dns4Sbox;
GenDnsDomains(node, singboxConfig, item); await GenDnsDomains(node, singboxConfig, item);
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -1200,7 +1208,7 @@ namespace ServiceLib.Services.CoreConfig
return 0; return 0;
} }
private int GenDnsDomains(ProfileItem? node, SingboxConfig singboxConfig, DNSItem? dNSItem) public async Task<int> GenDnsDomains(ProfileItem? node, SingboxConfig singboxConfig, DNSItem? dNSItem)
{ {
var dns4Sbox = singboxConfig.dns ?? new(); var dns4Sbox = singboxConfig.dns ?? new();
dns4Sbox.servers ??= []; dns4Sbox.servers ??= [];
@ -1253,7 +1261,7 @@ namespace ServiceLib.Services.CoreConfig
return 0; return 0;
} }
private int GenExperimental(SingboxConfig singboxConfig) public async Task<int> GenExperimental(SingboxConfig singboxConfig)
{ {
//if (_config.guiItem.enableStatistics) //if (_config.guiItem.enableStatistics)
{ {

View File

@ -15,92 +15,95 @@ namespace ServiceLib.Services.CoreConfig
#region public gen function #region public gen function
public int GenerateClientConfigContent(ProfileItem node, out V2rayConfig? v2rayConfig, out string msg) public async Task<RetResult> GenerateClientConfigContent(ProfileItem node)
{ {
v2rayConfig = null; var ret = new RetResult(-1);
try try
{ {
if (node == null if (node == null
|| node.port <= 0) || node.port <= 0)
{ {
msg = ResUI.CheckServerSettings; ret.Msg = ResUI.CheckServerSettings;
return -1; return ret;
} }
msg = ResUI.InitialConfiguration; ret.Msg = ResUI.InitialConfiguration;
string result = Utils.GetEmbedText(Global.V2raySampleClient); var result = Utils.GetEmbedText(Global.V2raySampleClient);
if (Utils.IsNullOrEmpty(result)) if (Utils.IsNullOrEmpty(result))
{ {
msg = ResUI.FailedGetDefaultConfiguration; ret.Msg = ResUI.FailedGetDefaultConfiguration;
return -1; return ret;
} }
v2rayConfig = JsonUtils.Deserialize<V2rayConfig>(result); var v2rayConfig = JsonUtils.Deserialize<V2rayConfig>(result);
if (v2rayConfig == null) if (v2rayConfig == null)
{ {
msg = ResUI.FailedGenDefaultConfiguration; ret.Msg = ResUI.FailedGenDefaultConfiguration;
return -1; return ret;
} }
GenLog(v2rayConfig); await GenLog(v2rayConfig);
GenInbounds(v2rayConfig); await GenInbounds(v2rayConfig);
GenRouting(v2rayConfig); await GenRouting(v2rayConfig);
GenOutbound(node, v2rayConfig.outbounds[0]); await GenOutbound(node, v2rayConfig.outbounds[0]);
GenMoreOutbounds(node, v2rayConfig); await GenMoreOutbounds(node, v2rayConfig);
GenDns(node, v2rayConfig); await GenDns(node, v2rayConfig);
GenStatistic(v2rayConfig); await GenStatistic(v2rayConfig);
msg = string.Format(ResUI.SuccessfulConfiguration, ""); ret.Msg = string.Format(ResUI.SuccessfulConfiguration, "");
ret.Code = 0;
ret.Data = JsonUtils.Serialize(v2rayConfig);
return ret;
} }
catch (Exception ex) catch (Exception ex)
{ {
Logging.SaveLog("GenerateClientConfig4V2ray", ex); Logging.SaveLog("GenerateClientConfig4V2ray", ex);
msg = ResUI.FailedGenDefaultConfiguration; ret.Msg = ResUI.FailedGenDefaultConfiguration;
return -1; return ret;
} }
return 0;
} }
public int GenerateClientMultipleLoadConfig(List<ProfileItem> selecteds, out V2rayConfig? v2rayConfig, out string msg) public async Task<RetResult> GenerateClientMultipleLoadConfig(List<ProfileItem> selecteds)
{ {
v2rayConfig = null; var ret = new RetResult(-1);
try try
{ {
if (_config == null) if (_config == null)
{ {
msg = ResUI.CheckServerSettings; ret.Msg = ResUI.CheckServerSettings;
return -1; return ret;
} }
msg = ResUI.InitialConfiguration; ret.Msg = ResUI.InitialConfiguration;
string result = Utils.GetEmbedText(Global.V2raySampleClient); string result = Utils.GetEmbedText(Global.V2raySampleClient);
string txtOutbound = Utils.GetEmbedText(Global.V2raySampleOutbound); string txtOutbound = Utils.GetEmbedText(Global.V2raySampleOutbound);
if (Utils.IsNullOrEmpty(result) || txtOutbound.IsNullOrEmpty()) if (Utils.IsNullOrEmpty(result) || txtOutbound.IsNullOrEmpty())
{ {
msg = ResUI.FailedGetDefaultConfiguration; ret.Msg = ResUI.FailedGetDefaultConfiguration;
return -1; return ret;
} }
v2rayConfig = JsonUtils.Deserialize<V2rayConfig>(result); var v2rayConfig = JsonUtils.Deserialize<V2rayConfig>(result);
if (v2rayConfig == null) if (v2rayConfig == null)
{ {
msg = ResUI.FailedGenDefaultConfiguration; ret.Msg = ResUI.FailedGenDefaultConfiguration;
return -1; return ret;
} }
GenLog(v2rayConfig); await GenLog(v2rayConfig);
GenInbounds(v2rayConfig); await GenInbounds(v2rayConfig);
GenRouting(v2rayConfig); await GenRouting(v2rayConfig);
GenDns(null, v2rayConfig); await GenDns(null, v2rayConfig);
GenStatistic(v2rayConfig); await GenStatistic(v2rayConfig);
v2rayConfig.outbounds.RemoveAt(0); v2rayConfig.outbounds.RemoveAt(0);
var tagProxy = new List<string>(); var tagProxy = new List<string>();
@ -118,7 +121,7 @@ namespace ServiceLib.Services.CoreConfig
{ {
continue; continue;
} }
var item = AppHandler.Instance.GetProfileItem(it.indexId); var item = await AppHandler.Instance.GetProfileItem(it.indexId);
if (item is null) if (item is null)
{ {
continue; continue;
@ -142,15 +145,15 @@ namespace ServiceLib.Services.CoreConfig
//outbound //outbound
var outbound = JsonUtils.Deserialize<Outbounds4Ray>(txtOutbound); var outbound = JsonUtils.Deserialize<Outbounds4Ray>(txtOutbound);
GenOutbound(item, outbound); await GenOutbound(item, outbound);
outbound.tag = $"{Global.ProxyTag}-{tagProxy.Count + 1}"; outbound.tag = $"{Global.ProxyTag}-{tagProxy.Count + 1}";
v2rayConfig.outbounds.Add(outbound); v2rayConfig.outbounds.Add(outbound);
tagProxy.Add(outbound.tag); tagProxy.Add(outbound.tag);
} }
if (tagProxy.Count <= 0) if (tagProxy.Count <= 0)
{ {
msg = ResUI.FailedGenDefaultConfiguration; ret.Msg = ResUI.FailedGenDefaultConfiguration;
return -1; return ret;
} }
//add balancers //add balancers
@ -182,42 +185,44 @@ namespace ServiceLib.Services.CoreConfig
}); });
} }
return 0; ret.Code = 0;
ret.Data = JsonUtils.Serialize(v2rayConfig);
return ret;
} }
catch (Exception ex) catch (Exception ex)
{ {
Logging.SaveLog(ex.Message, ex); Logging.SaveLog(ex.Message, ex);
msg = ResUI.FailedGenDefaultConfiguration; ret.Msg = ResUI.FailedGenDefaultConfiguration;
return -1; return ret;
} }
} }
public int GenerateClientSpeedtestConfig(List<ServerTestItem> selecteds, out V2rayConfig? v2rayConfig, out string msg) public async Task<RetResult> GenerateClientSpeedtestConfig(List<ServerTestItem> selecteds)
{ {
v2rayConfig = null; var ret = new RetResult(-1);
try try
{ {
if (_config == null) if (_config == null)
{ {
msg = ResUI.CheckServerSettings; ret.Msg = ResUI.CheckServerSettings;
return -1; return ret;
} }
msg = ResUI.InitialConfiguration; ret.Msg = ResUI.InitialConfiguration;
string result = Utils.GetEmbedText(Global.V2raySampleClient); string result = Utils.GetEmbedText(Global.V2raySampleClient);
string txtOutbound = Utils.GetEmbedText(Global.V2raySampleOutbound); string txtOutbound = Utils.GetEmbedText(Global.V2raySampleOutbound);
if (Utils.IsNullOrEmpty(result) || txtOutbound.IsNullOrEmpty()) if (Utils.IsNullOrEmpty(result) || txtOutbound.IsNullOrEmpty())
{ {
msg = ResUI.FailedGetDefaultConfiguration; ret.Msg = ResUI.FailedGetDefaultConfiguration;
return -1; return ret;
} }
v2rayConfig = JsonUtils.Deserialize<V2rayConfig>(result); var v2rayConfig = JsonUtils.Deserialize<V2rayConfig>(result);
if (v2rayConfig == null) if (v2rayConfig == null)
{ {
msg = ResUI.FailedGenDefaultConfiguration; ret.Msg = ResUI.FailedGenDefaultConfiguration;
return -1; return ret;
} }
List<IPEndPoint> lstIpEndPoints = new(); List<IPEndPoint> lstIpEndPoints = new();
List<TcpConnectionInformation> lstTcpConns = new(); List<TcpConnectionInformation> lstTcpConns = new();
@ -232,7 +237,7 @@ namespace ServiceLib.Services.CoreConfig
Logging.SaveLog(ex.Message, ex); Logging.SaveLog(ex.Message, ex);
} }
GenLog(v2rayConfig); await GenLog(v2rayConfig);
v2rayConfig.inbounds.Clear(); // Remove "proxy" service for speedtest, avoiding port conflicts. v2rayConfig.inbounds.Clear(); // Remove "proxy" service for speedtest, avoiding port conflicts.
v2rayConfig.outbounds.RemoveAt(0); v2rayConfig.outbounds.RemoveAt(0);
@ -248,7 +253,7 @@ namespace ServiceLib.Services.CoreConfig
{ {
continue; continue;
} }
var item = AppHandler.Instance.GetProfileItem(it.IndexId); var item = await AppHandler.Instance.GetProfileItem(it.IndexId);
if (it.ConfigType is EConfigType.VMess or EConfigType.VLESS) if (it.ConfigType is EConfigType.VMess or EConfigType.VLESS)
{ {
if (item is null || Utils.IsNullOrEmpty(item.id) || !Utils.IsGuidByParse(item.id)) if (item is null || Utils.IsNullOrEmpty(item.id) || !Utils.IsGuidByParse(item.id))
@ -316,7 +321,7 @@ namespace ServiceLib.Services.CoreConfig
} }
var outbound = JsonUtils.Deserialize<Outbounds4Ray>(txtOutbound); var outbound = JsonUtils.Deserialize<Outbounds4Ray>(txtOutbound);
GenOutbound(item, outbound); await GenOutbound(item, outbound);
outbound.tag = Global.ProxyTag + inbound.port.ToString(); outbound.tag = Global.ProxyTag + inbound.port.ToString();
v2rayConfig.outbounds.Add(outbound); v2rayConfig.outbounds.Add(outbound);
@ -330,14 +335,16 @@ namespace ServiceLib.Services.CoreConfig
v2rayConfig.routing.rules.Add(rule); v2rayConfig.routing.rules.Add(rule);
} }
//msg = string.Format(ResUI.SuccessfulConfiguration"), node.getSummary()); //ret.Msg =string.Format(ResUI.SuccessfulConfiguration"), node.getSummary());
return 0; ret.Code = 0;
ret.Data = JsonUtils.Serialize(v2rayConfig);
return ret;
} }
catch (Exception ex) catch (Exception ex)
{ {
Logging.SaveLog(ex.Message, ex); Logging.SaveLog(ex.Message, ex);
msg = ResUI.FailedGenDefaultConfiguration; ret.Msg = ResUI.FailedGenDefaultConfiguration;
return -1; return ret;
} }
} }
@ -345,7 +352,7 @@ namespace ServiceLib.Services.CoreConfig
#region private gen function #region private gen function
private int GenLog(V2rayConfig v2rayConfig) public async Task<int> GenLog(V2rayConfig v2rayConfig)
{ {
try try
{ {
@ -370,7 +377,7 @@ namespace ServiceLib.Services.CoreConfig
return 0; return 0;
} }
private int GenInbounds(V2rayConfig v2rayConfig) public async Task<int> GenInbounds(V2rayConfig v2rayConfig)
{ {
try try
{ {
@ -468,21 +475,21 @@ namespace ServiceLib.Services.CoreConfig
if (item.enabled) if (item.enabled)
{ {
var item2 = JsonUtils.Deserialize<RulesItem4Ray>(JsonUtils.Serialize(item)); var item2 = JsonUtils.Deserialize<RulesItem4Ray>(JsonUtils.Serialize(item));
GenRoutingUserRule(item2, v2rayConfig); await GenRoutingUserRule(item2, v2rayConfig);
} }
} }
} }
} }
else else
{ {
var lockedItem = ConfigHandler.GetLockedRoutingItem(_config); var lockedItem = await ConfigHandler.GetLockedRoutingItem(_config);
if (lockedItem != null) if (lockedItem != null)
{ {
var rules = JsonUtils.Deserialize<List<RulesItem>>(lockedItem.ruleSet); var rules = JsonUtils.Deserialize<List<RulesItem>>(lockedItem.ruleSet);
foreach (var item in rules) foreach (var item in rules)
{ {
var item2 = JsonUtils.Deserialize<RulesItem4Ray>(JsonUtils.Serialize(item)); var item2 = JsonUtils.Deserialize<RulesItem4Ray>(JsonUtils.Serialize(item));
GenRoutingUserRule(item2, v2rayConfig); await GenRoutingUserRule(item2, v2rayConfig);
} }
} }
} }
@ -495,7 +502,7 @@ namespace ServiceLib.Services.CoreConfig
return 0; return 0;
} }
private int GenRoutingUserRule(RulesItem4Ray? rule, V2rayConfig v2rayConfig) public async Task<int> GenRoutingUserRule(RulesItem4Ray? rule, V2rayConfig v2rayConfig)
{ {
try try
{ {
@ -573,7 +580,7 @@ namespace ServiceLib.Services.CoreConfig
return 0; return 0;
} }
private int GenOutbound(ProfileItem node, Outbounds4Ray outbound) public async Task<int> GenOutbound(ProfileItem node, Outbounds4Ray outbound)
{ {
try try
{ {
@ -617,7 +624,7 @@ namespace ServiceLib.Services.CoreConfig
usersItem.security = Global.DefaultSecurity; usersItem.security = Global.DefaultSecurity;
} }
GenOutboundMux(node, outbound, _config.coreBasicItem.muxEnabled); await GenOutboundMux(node, outbound, _config.coreBasicItem.muxEnabled);
outbound.settings.servers = null; outbound.settings.servers = null;
break; break;
@ -642,7 +649,7 @@ namespace ServiceLib.Services.CoreConfig
serversItem.ota = false; serversItem.ota = false;
serversItem.level = 1; serversItem.level = 1;
GenOutboundMux(node, outbound, false); await GenOutboundMux(node, outbound, false);
outbound.settings.vnext = null; outbound.settings.vnext = null;
break; break;
@ -678,7 +685,7 @@ namespace ServiceLib.Services.CoreConfig
serversItem.users = new List<SocksUsersItem4Ray>() { socksUsersItem }; serversItem.users = new List<SocksUsersItem4Ray>() { socksUsersItem };
} }
GenOutboundMux(node, outbound, false); await GenOutboundMux(node, outbound, false);
outbound.settings.vnext = null; outbound.settings.vnext = null;
break; break;
@ -712,7 +719,7 @@ namespace ServiceLib.Services.CoreConfig
usersItem.email = Global.UserEMail; usersItem.email = Global.UserEMail;
usersItem.encryption = node.security; usersItem.encryption = node.security;
GenOutboundMux(node, outbound, _config.coreBasicItem.muxEnabled); await GenOutboundMux(node, outbound, _config.coreBasicItem.muxEnabled);
if (node.streamSecurity == Global.StreamSecurityReality if (node.streamSecurity == Global.StreamSecurityReality
|| node.streamSecurity == Global.StreamSecurity) || node.streamSecurity == Global.StreamSecurity)
@ -721,12 +728,12 @@ namespace ServiceLib.Services.CoreConfig
{ {
usersItem.flow = node.flow; usersItem.flow = node.flow;
GenOutboundMux(node, outbound, false); await GenOutboundMux(node, outbound, false);
} }
} }
if (node.streamSecurity == Global.StreamSecurityReality && Utils.IsNullOrEmpty(node.flow)) if (node.streamSecurity == Global.StreamSecurityReality && Utils.IsNullOrEmpty(node.flow))
{ {
GenOutboundMux(node, outbound, _config.coreBasicItem.muxEnabled); await GenOutboundMux(node, outbound, _config.coreBasicItem.muxEnabled);
} }
outbound.settings.servers = null; outbound.settings.servers = null;
@ -751,7 +758,7 @@ namespace ServiceLib.Services.CoreConfig
serversItem.ota = false; serversItem.ota = false;
serversItem.level = 1; serversItem.level = 1;
GenOutboundMux(node, outbound, false); await GenOutboundMux(node, outbound, false);
outbound.settings.vnext = null; outbound.settings.vnext = null;
break; break;
@ -759,7 +766,7 @@ namespace ServiceLib.Services.CoreConfig
} }
outbound.protocol = Global.ProtocolTypes[node.configType]; outbound.protocol = Global.ProtocolTypes[node.configType];
GenBoundStreamSettings(node, outbound.streamSettings); await GenBoundStreamSettings(node, outbound.streamSettings);
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -768,7 +775,7 @@ namespace ServiceLib.Services.CoreConfig
return 0; return 0;
} }
private int GenOutboundMux(ProfileItem node, Outbounds4Ray outbound, bool enabled) public async Task<int> GenOutboundMux(ProfileItem node, Outbounds4Ray outbound, bool enabled)
{ {
try try
{ {
@ -792,7 +799,7 @@ namespace ServiceLib.Services.CoreConfig
return 0; return 0;
} }
private int GenBoundStreamSettings(ProfileItem node, StreamSettings4Ray streamSettings) public async Task<int> GenBoundStreamSettings(ProfileItem node, StreamSettings4Ray streamSettings)
{ {
try try
{ {
@ -1025,11 +1032,11 @@ namespace ServiceLib.Services.CoreConfig
return 0; return 0;
} }
private int GenDns(ProfileItem? node, V2rayConfig v2rayConfig) public async Task<int> GenDns(ProfileItem? node, V2rayConfig v2rayConfig)
{ {
try try
{ {
var item = AppHandler.Instance.GetDNSItem(ECoreType.Xray); var item = await AppHandler.Instance.GetDNSItem(ECoreType.Xray);
var normalDNS = item?.normalDNS; var normalDNS = item?.normalDNS;
var domainStrategy4Freedom = item?.domainStrategy4Freedom; var domainStrategy4Freedom = item?.domainStrategy4Freedom;
if (Utils.IsNullOrEmpty(normalDNS)) if (Utils.IsNullOrEmpty(normalDNS))
@ -1077,7 +1084,7 @@ namespace ServiceLib.Services.CoreConfig
} }
} }
GenDnsDomains(node, obj, item); await GenDnsDomains(node, obj, item);
v2rayConfig.dns = obj; v2rayConfig.dns = obj;
} }
@ -1088,7 +1095,7 @@ namespace ServiceLib.Services.CoreConfig
return 0; return 0;
} }
private int GenDnsDomains(ProfileItem? node, JsonNode dns, DNSItem? dNSItem) public async Task<int> GenDnsDomains(ProfileItem? node, JsonNode dns, DNSItem? dNSItem)
{ {
if (node == null) if (node == null)
{ return 0; } { return 0; }
@ -1108,7 +1115,7 @@ namespace ServiceLib.Services.CoreConfig
return 0; return 0;
} }
private int GenStatistic(V2rayConfig v2rayConfig) public async Task<int> GenStatistic(V2rayConfig v2rayConfig)
{ {
if (_config.guiItem.enableStatistics) if (_config.guiItem.enableStatistics)
{ {
@ -1158,7 +1165,7 @@ namespace ServiceLib.Services.CoreConfig
return 0; return 0;
} }
private int GenMoreOutbounds(ProfileItem node, V2rayConfig v2rayConfig) private async Task<int> GenMoreOutbounds(ProfileItem node, V2rayConfig v2rayConfig)
{ {
//fragment proxy //fragment proxy
if (_config.coreBasicItem.enableFragment if (_config.coreBasicItem.enableFragment
@ -1193,7 +1200,7 @@ namespace ServiceLib.Services.CoreConfig
} }
try try
{ {
var subItem = AppHandler.Instance.GetSubItem(node.subid); var subItem = await AppHandler.Instance.GetSubItem(node.subid);
if (subItem is null) if (subItem is null)
{ {
return 0; return 0;
@ -1204,7 +1211,7 @@ namespace ServiceLib.Services.CoreConfig
var txtOutbound = Utils.GetEmbedText(Global.V2raySampleOutbound); var txtOutbound = Utils.GetEmbedText(Global.V2raySampleOutbound);
//Previous proxy //Previous proxy
var prevNode = AppHandler.Instance.GetProfileItemViaRemarks(subItem.prevProfile); var prevNode = await AppHandler.Instance.GetProfileItemViaRemarks(subItem.prevProfile);
if (prevNode is not null if (prevNode is not null
&& prevNode.configType != EConfigType.Custom && prevNode.configType != EConfigType.Custom
&& prevNode.configType != EConfigType.Hysteria2 && prevNode.configType != EConfigType.Hysteria2
@ -1212,7 +1219,7 @@ namespace ServiceLib.Services.CoreConfig
&& prevNode.configType != EConfigType.WireGuard) && prevNode.configType != EConfigType.WireGuard)
{ {
var prevOutbound = JsonUtils.Deserialize<Outbounds4Ray>(txtOutbound); var prevOutbound = JsonUtils.Deserialize<Outbounds4Ray>(txtOutbound);
GenOutbound(prevNode, prevOutbound); await GenOutbound(prevNode, prevOutbound);
prevOutbound.tag = $"{Global.ProxyTag}2"; prevOutbound.tag = $"{Global.ProxyTag}2";
v2rayConfig.outbounds.Add(prevOutbound); v2rayConfig.outbounds.Add(prevOutbound);
@ -1223,7 +1230,7 @@ namespace ServiceLib.Services.CoreConfig
} }
//Next proxy //Next proxy
var nextNode = AppHandler.Instance.GetProfileItemViaRemarks(subItem.nextProfile); var nextNode = await AppHandler.Instance.GetProfileItemViaRemarks(subItem.nextProfile);
if (nextNode is not null if (nextNode is not null
&& nextNode.configType != EConfigType.Custom && nextNode.configType != EConfigType.Custom
&& nextNode.configType != EConfigType.Hysteria2 && nextNode.configType != EConfigType.Hysteria2
@ -1231,7 +1238,7 @@ namespace ServiceLib.Services.CoreConfig
&& nextNode.configType != EConfigType.WireGuard) && nextNode.configType != EConfigType.WireGuard)
{ {
var nextOutbound = JsonUtils.Deserialize<Outbounds4Ray>(txtOutbound); var nextOutbound = JsonUtils.Deserialize<Outbounds4Ray>(txtOutbound);
GenOutbound(nextNode, nextOutbound); await GenOutbound(nextNode, nextOutbound);
nextOutbound.tag = Global.ProxyTag; nextOutbound.tag = Global.ProxyTag;
v2rayConfig.outbounds.Insert(0, nextOutbound); v2rayConfig.outbounds.Insert(0, nextOutbound);

View File

@ -134,7 +134,7 @@ namespace ServiceLib.Services
{ {
string msg = string.Empty; string msg = string.Empty;
pid = CoreHandler.Instance.LoadCoreConfigSpeedtest(_selecteds); pid = await CoreHandler.Instance.LoadCoreConfigSpeedtest(_selecteds);
if (pid < 0) if (pid < 0)
{ {
UpdateFunc("", ResUI.FailedToRunCore); UpdateFunc("", ResUI.FailedToRunCore);
@ -196,7 +196,7 @@ namespace ServiceLib.Services
// _selecteds = _selecteds.OrderBy(t => t.delay).ToList(); // _selecteds = _selecteds.OrderBy(t => t.delay).ToList();
//} //}
pid = CoreHandler.Instance.LoadCoreConfigSpeedtest(_selecteds); pid = await CoreHandler.Instance.LoadCoreConfigSpeedtest(_selecteds);
if (pid < 0) if (pid < 0)
{ {
UpdateFunc("", ResUI.FailedToRunCore); UpdateFunc("", ResUI.FailedToRunCore);
@ -231,7 +231,7 @@ namespace ServiceLib.Services
ProfileExHandler.Instance.SetTestSpeed(it.IndexId, "-1"); ProfileExHandler.Instance.SetTestSpeed(it.IndexId, "-1");
UpdateFunc(it.IndexId, "", ResUI.Speedtesting); UpdateFunc(it.IndexId, "", ResUI.Speedtesting);
var item = AppHandler.Instance.GetProfileItem(it.IndexId); var item = await AppHandler.Instance.GetProfileItem(it.IndexId);
if (item is null) continue; if (item is null) continue;
WebProxy webProxy = new(Global.Loopback, it.Port); WebProxy webProxy = new(Global.Loopback, it.Port);
@ -252,13 +252,13 @@ namespace ServiceLib.Services
CoreHandler.Instance.CoreStopPid(pid); CoreHandler.Instance.CoreStopPid(pid);
} }
UpdateFunc("", ResUI.SpeedtestingCompleted); UpdateFunc("", ResUI.SpeedtestingCompleted);
ProfileExHandler.Instance.SaveTo(); await ProfileExHandler.Instance.SaveTo();
} }
private async Task RunSpeedTestMulti() private async Task RunSpeedTestMulti()
{ {
int pid = -1; int pid = -1;
pid = CoreHandler.Instance.LoadCoreConfigSpeedtest(_selecteds); pid = await CoreHandler.Instance.LoadCoreConfigSpeedtest(_selecteds);
if (pid < 0) if (pid < 0)
{ {
UpdateFunc("", ResUI.FailedToRunCore); UpdateFunc("", ResUI.FailedToRunCore);
@ -294,7 +294,7 @@ namespace ServiceLib.Services
ProfileExHandler.Instance.SetTestSpeed(it.IndexId, "-1"); ProfileExHandler.Instance.SetTestSpeed(it.IndexId, "-1");
UpdateFunc(it.IndexId, "", ResUI.Speedtesting); UpdateFunc(it.IndexId, "", ResUI.Speedtesting);
var item = AppHandler.Instance.GetProfileItem(it.IndexId); var item = await AppHandler.Instance.GetProfileItem(it.IndexId);
if (item is null) continue; if (item is null) continue;
WebProxy webProxy = new(Global.Loopback, it.Port); WebProxy webProxy = new(Global.Loopback, it.Port);

View File

@ -126,7 +126,7 @@ namespace ServiceLib.Services
_updateFunc = updateFunc; _updateFunc = updateFunc;
_updateFunc?.Invoke(false, ResUI.MsgUpdateSubscriptionStart); _updateFunc?.Invoke(false, ResUI.MsgUpdateSubscriptionStart);
var subItem = AppHandler.Instance.SubItems().OrderBy(t => t.sort).ToList(); var subItem = await AppHandler.Instance.SubItems();
if (subItem == null || subItem.Count <= 0) if (subItem == null || subItem.Count <= 0)
{ {
@ -469,7 +469,7 @@ namespace ServiceLib.Services
var geoSiteFiles = new List<string>(); var geoSiteFiles = new List<string>();
//Collect used files list //Collect used files list
var routingItems = AppHandler.Instance.RoutingItems(); var routingItems = await AppHandler.Instance.RoutingItems();
foreach (var routing in routingItems) foreach (var routing in routingItems)
{ {
var rules = JsonUtils.Deserialize<List<RulesItem>>(routing.ruleSet); var rules = JsonUtils.Deserialize<List<RulesItem>>(routing.ruleSet);

View File

@ -82,7 +82,7 @@ namespace ServiceLib.ViewModels
return; return;
} }
var item = AppHandler.Instance.GetProfileItem(SelectedSource.indexId); var item = await AppHandler.Instance.GetProfileItem(SelectedSource.indexId);
item ??= SelectedSource; item ??= SelectedSource;
item.address = fileName; item.address = fileName;
if (await ConfigHandler.AddCustomServer(_config, item, false) == 0) if (await ConfigHandler.AddCustomServer(_config, item, false) == 0)

View File

@ -26,13 +26,13 @@ namespace ServiceLib.ViewModels
_updateView = updateView; _updateView = updateView;
var item = AppHandler.Instance.GetDNSItem(ECoreType.Xray); var item = AppHandler.Instance.GetDNSItem(ECoreType.Xray).Result;
useSystemHosts = item.useSystemHosts; useSystemHosts = item.useSystemHosts;
domainStrategy4Freedom = item?.domainStrategy4Freedom ?? string.Empty; domainStrategy4Freedom = item?.domainStrategy4Freedom ?? string.Empty;
domainDNSAddress = item?.domainDNSAddress ?? string.Empty; domainDNSAddress = item?.domainDNSAddress ?? string.Empty;
normalDNS = item?.normalDNS ?? string.Empty; normalDNS = item?.normalDNS ?? string.Empty;
var item2 = AppHandler.Instance.GetDNSItem(ECoreType.sing_box); var item2 = AppHandler.Instance.GetDNSItem(ECoreType.sing_box).Result;
domainStrategy4Freedom2 = item2?.domainStrategy4Freedom ?? string.Empty; domainStrategy4Freedom2 = item2?.domainStrategy4Freedom ?? string.Empty;
domainDNSAddress2 = item2?.domainDNSAddress ?? string.Empty; domainDNSAddress2 = item2?.domainDNSAddress ?? string.Empty;
normalDNS2 = item2?.normalDNS ?? string.Empty; normalDNS2 = item2?.normalDNS ?? string.Empty;
@ -91,19 +91,19 @@ namespace ServiceLib.ViewModels
} }
} }
var item = AppHandler.Instance.GetDNSItem(ECoreType.Xray); var item = await AppHandler.Instance.GetDNSItem(ECoreType.Xray);
item.domainStrategy4Freedom = domainStrategy4Freedom; item.domainStrategy4Freedom = domainStrategy4Freedom;
item.domainDNSAddress = domainDNSAddress; item.domainDNSAddress = domainDNSAddress;
item.useSystemHosts = useSystemHosts; item.useSystemHosts = useSystemHosts;
item.normalDNS = normalDNS; item.normalDNS = normalDNS;
ConfigHandler.SaveDNSItems(_config, item); await ConfigHandler.SaveDNSItems(_config, item);
var item2 = AppHandler.Instance.GetDNSItem(ECoreType.sing_box); var item2 = await AppHandler.Instance.GetDNSItem(ECoreType.sing_box);
item2.domainStrategy4Freedom = domainStrategy4Freedom2; item2.domainStrategy4Freedom = domainStrategy4Freedom2;
item2.domainDNSAddress = domainDNSAddress2; item2.domainDNSAddress = domainDNSAddress2;
item2.normalDNS = JsonUtils.Serialize(JsonUtils.ParseJson(normalDNS2)); item2.normalDNS = JsonUtils.Serialize(JsonUtils.ParseJson(normalDNS2));
item2.tunDNS = JsonUtils.Serialize(JsonUtils.ParseJson(tunDNS2)); ; item2.tunDNS = JsonUtils.Serialize(JsonUtils.ParseJson(tunDNS2)); ;
ConfigHandler.SaveDNSItems(_config, item2); await ConfigHandler.SaveDNSItems(_config, item2);
NoticeHandler.Instance.Enqueue(ResUI.OperationSuccess); NoticeHandler.Instance.Enqueue(ResUI.OperationSuccess);
_updateView?.Invoke(EViewAction.CloseWindow, null); _updateView?.Invoke(EViewAction.CloseWindow, null);

View File

@ -206,10 +206,10 @@ namespace ServiceLib.ViewModels
AutoHideStartup(); AutoHideStartup();
} }
private void Init() private async Task Init()
{ {
ConfigHandler.InitBuiltinRouting(_config); await ConfigHandler.InitBuiltinRouting(_config);
ConfigHandler.InitBuiltinDNS(_config); await ConfigHandler.InitBuiltinDNS(_config);
CoreHandler.Instance.Init(_config, UpdateHandler); CoreHandler.Instance.Init(_config, UpdateHandler);
TaskHandler.Instance.RegUpdateTask(_config, UpdateTaskHandler); TaskHandler.Instance.RegUpdateTask(_config, UpdateTaskHandler);
@ -218,7 +218,7 @@ namespace ServiceLib.ViewModels
StatisticsHandler.Instance.Init(_config, UpdateStatisticsHandler); StatisticsHandler.Instance.Init(_config, UpdateStatisticsHandler);
} }
Reload(); await Reload();
} }
#endregion Init #endregion Init
@ -285,7 +285,7 @@ namespace ServiceLib.ViewModels
//if (blWindowsShutDown) //if (blWindowsShutDown)
await SysProxyHandler.UpdateSysProxy(_config, true); await SysProxyHandler.UpdateSysProxy(_config, true);
ConfigHandler.SaveConfig(_config); await ConfigHandler.SaveConfig(_config);
await ProfileExHandler.Instance.SaveTo(); await ProfileExHandler.Instance.SaveTo();
await StatisticsHandler.Instance.SaveTo(); await StatisticsHandler.Instance.SaveTo();
StatisticsHandler.Instance.Close(); StatisticsHandler.Instance.Close();
@ -371,7 +371,7 @@ namespace ServiceLib.ViewModels
RefreshServers(); RefreshServers();
if (item.indexId == _config.indexId) if (item.indexId == _config.indexId)
{ {
Reload(); await Reload();
} }
} }
} }
@ -464,7 +464,7 @@ namespace ServiceLib.ViewModels
if (ret == true) if (ret == true)
{ {
Locator.Current.GetService<StatusBarViewModel>()?.InboundDisplayStatus(); Locator.Current.GetService<StatusBarViewModel>()?.InboundDisplayStatus();
Reload(); await Reload();
} }
} }
@ -473,9 +473,9 @@ namespace ServiceLib.ViewModels
var ret = await _updateView?.Invoke(EViewAction.RoutingSettingWindow, null); var ret = await _updateView?.Invoke(EViewAction.RoutingSettingWindow, null);
if (ret == true) if (ret == true)
{ {
ConfigHandler.InitBuiltinRouting(_config); await ConfigHandler.InitBuiltinRouting(_config);
Locator.Current.GetService<StatusBarViewModel>()?.RefreshRoutingsMenu(); Locator.Current.GetService<StatusBarViewModel>()?.RefreshRoutingsMenu();
Reload(); await Reload();
} }
} }
@ -484,7 +484,7 @@ namespace ServiceLib.ViewModels
var ret = await _updateView?.Invoke(EViewAction.DNSSettingWindow, null); var ret = await _updateView?.Invoke(EViewAction.DNSSettingWindow, null);
if (ret == true) if (ret == true)
{ {
Reload(); await Reload();
} }
} }
@ -508,7 +508,7 @@ namespace ServiceLib.ViewModels
private async Task ClearServerStatistics() private async Task ClearServerStatistics()
{ {
StatisticsHandler.Instance.ClearAllServerStatistics(); await StatisticsHandler.Instance.ClearAllServerStatistics();
RefreshServers(); RefreshServers();
} }
@ -535,6 +535,7 @@ namespace ServiceLib.ViewModels
await LoadCore(); await LoadCore();
Locator.Current.GetService<StatusBarViewModel>()?.TestServerAvailability(); Locator.Current.GetService<StatusBarViewModel>()?.TestServerAvailability();
await SysProxyHandler.UpdateSysProxy(_config, false); await SysProxyHandler.UpdateSysProxy(_config, false);
_updateView?.Invoke(EViewAction.DispatcherReload, null); _updateView?.Invoke(EViewAction.DispatcherReload, null);
} }
@ -551,23 +552,22 @@ namespace ServiceLib.ViewModels
} }
private async Task LoadCore() private async Task LoadCore()
{
await Task.Run(async () =>
{ {
//if (_config.tunModeItem.enableTun) //if (_config.tunModeItem.enableTun)
//{ //{
// Task.Delay(1000).Wait(); // Task.Delay(1000).Wait();
// WindowsUtils.RemoveTunDevice(); // WindowsUtils.RemoveTunDevice();
//} //}
await Task.Run(async () =>
{
var node = await ConfigHandler.GetDefaultServer(_config); var node = await ConfigHandler.GetDefaultServer(_config);
CoreHandler.Instance.LoadCore(node); await CoreHandler.Instance.LoadCore(node);
}); });
} }
public void CloseCore() public async Task CloseCore()
{ {
ConfigHandler.SaveConfig(_config, false); await ConfigHandler.SaveConfig(_config, false);
CoreHandler.Instance.CoreStop(); CoreHandler.Instance.CoreStop();
} }
@ -591,12 +591,12 @@ namespace ServiceLib.ViewModels
public async Task ApplyRegionalPreset(EPresetType type) public async Task ApplyRegionalPreset(EPresetType type)
{ {
await ConfigHandler.ApplyRegionalPreset(_config, type); await ConfigHandler.ApplyRegionalPreset(_config, type);
ConfigHandler.InitRouting(_config); await ConfigHandler.InitRouting(_config);
Locator.Current.GetService<StatusBarViewModel>()?.RefreshRoutingsMenu(); Locator.Current.GetService<StatusBarViewModel>()?.RefreshRoutingsMenu();
ConfigHandler.SaveConfig(_config, false); await ConfigHandler.SaveConfig(_config, false);
await new UpdateService().UpdateGeoFileAll(_config, UpdateHandler); await new UpdateService().UpdateGeoFileAll(_config, UpdateHandler);
Reload(); await Reload();
} }
#endregion Presets #endregion Presets

View File

@ -350,9 +350,9 @@ namespace ServiceLib.ViewModels
MessageBus.Current.SendMessage("", EMsgCommand.RefreshProfiles.ToString()); MessageBus.Current.SendMessage("", EMsgCommand.RefreshProfiles.ToString());
} }
public void RefreshServersBiz() public async Task RefreshServersBiz()
{ {
var lstModel = AppHandler.Instance.ProfileItemsEx(_config.subIndexId, _serverFilter); var lstModel = await AppHandler.Instance.ProfileItemsEx(_config.subIndexId, _serverFilter);
_lstProfile = JsonUtils.Deserialize<List<ProfileItem>>(JsonUtils.Serialize(lstModel)) ?? []; _lstProfile = JsonUtils.Deserialize<List<ProfileItem>>(JsonUtils.Serialize(lstModel)) ?? [];
_profileItems.Clear(); _profileItems.Clear();
@ -371,12 +371,13 @@ namespace ServiceLib.ViewModels
} }
} }
public void RefreshSubscriptions() public async Task RefreshSubscriptions()
{ {
_subItems.Clear(); _subItems.Clear();
_subItems.Add(new SubItem { remarks = ResUI.AllGroupServers }); _subItems.Add(new SubItem { remarks = ResUI.AllGroupServers });
foreach (var item in AppHandler.Instance.SubItems().OrderBy(t => t.sort))
foreach (var item in await AppHandler.Instance.SubItems())
{ {
_subItems.Add(item); _subItems.Add(item);
} }
@ -394,12 +395,12 @@ namespace ServiceLib.ViewModels
#region Add Servers #region Add Servers
private int GetProfileItems(out List<ProfileItem> lstSelecteds, bool latest) private async Task<List<ProfileItem>?> GetProfileItems(bool latest)
{ {
lstSelecteds = new List<ProfileItem>(); var lstSelecteds = new List<ProfileItem>();
if (SelectedProfiles == null || SelectedProfiles.Count <= 0) if (SelectedProfiles == null || SelectedProfiles.Count <= 0)
{ {
return -1; return null;
} }
var orderProfiles = SelectedProfiles?.OrderBy(t => t.sort); var orderProfiles = SelectedProfiles?.OrderBy(t => t.sort);
@ -407,7 +408,7 @@ namespace ServiceLib.ViewModels
{ {
foreach (var profile in orderProfiles) foreach (var profile in orderProfiles)
{ {
var item = AppHandler.Instance.GetProfileItem(profile.indexId); var item = await AppHandler.Instance.GetProfileItem(profile.indexId);
if (item is not null) if (item is not null)
{ {
lstSelecteds.Add(item); lstSelecteds.Add(item);
@ -419,7 +420,7 @@ namespace ServiceLib.ViewModels
lstSelecteds = JsonUtils.Deserialize<List<ProfileItem>>(JsonUtils.Serialize(orderProfiles)); lstSelecteds = JsonUtils.Deserialize<List<ProfileItem>>(JsonUtils.Serialize(orderProfiles));
} }
return 0; return lstSelecteds;
} }
public async Task EditServerAsync(EConfigType eConfigType) public async Task EditServerAsync(EConfigType eConfigType)
@ -428,7 +429,7 @@ namespace ServiceLib.ViewModels
{ {
return; return;
} }
var item = AppHandler.Instance.GetProfileItem(SelectedProfile.indexId); var item = await AppHandler.Instance.GetProfileItem(SelectedProfile.indexId);
if (item is null) if (item is null)
{ {
NoticeHandler.Instance.Enqueue(ResUI.PleaseSelectServer); NoticeHandler.Instance.Enqueue(ResUI.PleaseSelectServer);
@ -457,7 +458,8 @@ namespace ServiceLib.ViewModels
public async Task RemoveServerAsync() public async Task RemoveServerAsync()
{ {
if (GetProfileItems(out List<ProfileItem> lstSelecteds, true) < 0) var lstSelecteds = await GetProfileItems(true);
if (lstSelecteds == null)
{ {
return; return;
} }
@ -467,7 +469,7 @@ namespace ServiceLib.ViewModels
} }
var exists = lstSelecteds.Exists(t => t.indexId == _config.indexId); var exists = lstSelecteds.Exists(t => t.indexId == _config.indexId);
ConfigHandler.RemoveServer(_config, lstSelecteds); await ConfigHandler.RemoveServer(_config, lstSelecteds);
NoticeHandler.Instance.Enqueue(ResUI.OperationSuccess); NoticeHandler.Instance.Enqueue(ResUI.OperationSuccess);
RefreshServers(); RefreshServers();
@ -487,7 +489,8 @@ namespace ServiceLib.ViewModels
private async Task CopyServer() private async Task CopyServer()
{ {
if (GetProfileItems(out List<ProfileItem> lstSelecteds, false) < 0) var lstSelecteds = await GetProfileItems(false);
if (lstSelecteds == null)
{ {
return; return;
} }
@ -504,7 +507,7 @@ namespace ServiceLib.ViewModels
{ {
return; return;
} }
SetDefaultServer(SelectedProfile.indexId); await SetDefaultServer(SelectedProfile.indexId);
} }
public async Task SetDefaultServer(string indexId) public async Task SetDefaultServer(string indexId)
@ -517,7 +520,7 @@ namespace ServiceLib.ViewModels
{ {
return; return;
} }
var item = AppHandler.Instance.GetProfileItem(indexId); var item = await AppHandler.Instance.GetProfileItem(indexId);
if (item is null) if (item is null)
{ {
NoticeHandler.Instance.Enqueue(ResUI.PleaseSelectServer); NoticeHandler.Instance.Enqueue(ResUI.PleaseSelectServer);
@ -550,7 +553,7 @@ namespace ServiceLib.ViewModels
public async Task ShareServerAsync() public async Task ShareServerAsync()
{ {
var item = AppHandler.Instance.GetProfileItem(SelectedProfile.indexId); var item = await AppHandler.Instance.GetProfileItem(SelectedProfile.indexId);
if (item is null) if (item is null)
{ {
NoticeHandler.Instance.Enqueue(ResUI.PleaseSelectServer); NoticeHandler.Instance.Enqueue(ResUI.PleaseSelectServer);
@ -567,25 +570,26 @@ namespace ServiceLib.ViewModels
private async Task SetDefaultMultipleServer(ECoreType coreType) private async Task SetDefaultMultipleServer(ECoreType coreType)
{ {
if (GetProfileItems(out List<ProfileItem> lstSelecteds, true) < 0) var lstSelecteds = await GetProfileItems(true);
if (lstSelecteds == null)
{ {
return; return;
} }
var ret = await ConfigHandler.AddCustomServer4Multiple(_config, lstSelecteds, coreType); var ret = await ConfigHandler.AddCustomServer4Multiple(_config, lstSelecteds, coreType);
if (ret.Item1 != 0) if (ret.Code != 0)
{ {
NoticeHandler.Instance.Enqueue(ResUI.OperationFailed); NoticeHandler.Instance.Enqueue(ResUI.OperationFailed);
return; return;
} }
if (ret.Item2 == _config.indexId) if (ret?.Data?.ToString() == _config.indexId)
{ {
RefreshServers(); RefreshServers();
Reload(); Reload();
} }
else else
{ {
await SetDefaultServer(ret.Item2); await SetDefaultServer(ret?.Data?.ToString());
} }
} }
@ -607,19 +611,20 @@ namespace ServiceLib.ViewModels
} }
//move server //move server
private void MoveToGroup(bool c) private async Task MoveToGroup(bool c)
{ {
if (!c) if (!c)
{ {
return; return;
} }
if (GetProfileItems(out List<ProfileItem> lstSelecteds, true) < 0) var lstSelecteds = await GetProfileItems(true);
if (lstSelecteds == null)
{ {
return; return;
} }
ConfigHandler.MoveToGroup(_config, lstSelecteds, SelectedMoveToGroup.id); await ConfigHandler.MoveToGroup(_config, lstSelecteds, SelectedMoveToGroup.id);
NoticeHandler.Instance.Enqueue(ResUI.OperationSuccess); NoticeHandler.Instance.Enqueue(ResUI.OperationSuccess);
RefreshServers(); RefreshServers();
@ -665,7 +670,8 @@ namespace ServiceLib.ViewModels
{ {
SelectedProfiles = _profileItems; SelectedProfiles = _profileItems;
} }
if (GetProfileItems(out List<ProfileItem> lstSelecteds, false) < 0) var lstSelecteds = await GetProfileItems(false);
if (lstSelecteds == null)
{ {
return; return;
} }
@ -681,7 +687,7 @@ namespace ServiceLib.ViewModels
private async Task Export2ClientConfigAsync(bool blClipboard) private async Task Export2ClientConfigAsync(bool blClipboard)
{ {
var item = AppHandler.Instance.GetProfileItem(SelectedProfile.indexId); var item = await AppHandler.Instance.GetProfileItem(SelectedProfile.indexId);
if (item is null) if (item is null)
{ {
NoticeHandler.Instance.Enqueue(ResUI.PleaseSelectServer); NoticeHandler.Instance.Enqueue(ResUI.PleaseSelectServer);
@ -689,13 +695,14 @@ namespace ServiceLib.ViewModels
} }
if (blClipboard) if (blClipboard)
{ {
if (CoreConfigHandler.GenerateClientConfig(item, null, out string msg, out string content) != 0) var result = await CoreConfigHandler.GenerateClientConfig(item, null);
if (result.Code != 0)
{ {
NoticeHandler.Instance.Enqueue(msg); NoticeHandler.Instance.Enqueue(result.Msg);
} }
else else
{ {
await _updateView?.Invoke(EViewAction.SetClipboardData, content); await _updateView?.Invoke(EViewAction.SetClipboardData, result.Data);
NoticeHandler.Instance.SendMessage(ResUI.OperationSuccess); NoticeHandler.Instance.SendMessage(ResUI.OperationSuccess);
} }
} }
@ -705,26 +712,27 @@ namespace ServiceLib.ViewModels
} }
} }
public void Export2ClientConfigResult(string fileName, ProfileItem item) public async Task Export2ClientConfigResult(string fileName, ProfileItem item)
{ {
if (Utils.IsNullOrEmpty(fileName)) if (Utils.IsNullOrEmpty(fileName))
{ {
return; return;
} }
if (CoreConfigHandler.GenerateClientConfig(item, fileName, out string msg, out string content) != 0) var result = await CoreConfigHandler.GenerateClientConfig(item, null);
if (result.Code != 0)
{ {
NoticeHandler.Instance.Enqueue(msg); NoticeHandler.Instance.Enqueue(result.Msg);
} }
else else
{ {
msg = string.Format(ResUI.SaveClientConfigurationIn, fileName); NoticeHandler.Instance.SendMessageAndEnqueue(string.Format(ResUI.SaveClientConfigurationIn, fileName));
NoticeHandler.Instance.SendMessageAndEnqueue(msg);
} }
} }
public async Task Export2ShareUrlAsync(bool blEncode) public async Task Export2ShareUrlAsync(bool blEncode)
{ {
if (GetProfileItems(out List<ProfileItem> lstSelecteds, true) < 0) var lstSelecteds = await GetProfileItems(true);
if (lstSelecteds == null)
{ {
return; return;
} }
@ -767,7 +775,7 @@ namespace ServiceLib.ViewModels
} }
else else
{ {
item = AppHandler.Instance.GetSubItem(_config.subIndexId); item = await AppHandler.Instance.GetSubItem(_config.subIndexId);
if (item is null) if (item is null)
{ {
return; return;
@ -775,8 +783,8 @@ namespace ServiceLib.ViewModels
} }
if (await _updateView?.Invoke(EViewAction.SubEditWindow, item) == true) if (await _updateView?.Invoke(EViewAction.SubEditWindow, item) == true)
{ {
RefreshSubscriptions(); await RefreshSubscriptions();
SubSelectedChangedAsync(true); await SubSelectedChangedAsync(true);
} }
} }

View File

@ -122,7 +122,7 @@ namespace ServiceLib.ViewModels
private async Task BindingLockedData() private async Task BindingLockedData()
{ {
_lockedItem = ConfigHandler.GetLockedRoutingItem(_config); _lockedItem = await ConfigHandler.GetLockedRoutingItem(_config);
if (_lockedItem == null) if (_lockedItem == null)
{ {
_lockedItem = new RoutingItem() _lockedItem = new RoutingItem()
@ -171,11 +171,11 @@ namespace ServiceLib.ViewModels
#region Refresh Save #region Refresh Save
public void RefreshRoutingItems() public async Task RefreshRoutingItems()
{ {
_routingItems.Clear(); _routingItems.Clear();
var routings = AppHandler.Instance.RoutingItems(); var routings = await AppHandler.Instance.RoutingItems();
foreach (var item in routings) foreach (var item in routings)
{ {
bool def = false; bool def = false;
@ -242,7 +242,7 @@ namespace ServiceLib.ViewModels
} }
else else
{ {
item = AppHandler.Instance.GetRoutingItem(SelectedSource?.id); item = await AppHandler.Instance.GetRoutingItem(SelectedSource?.id);
if (item is null) if (item is null)
{ {
return; return;
@ -268,7 +268,7 @@ namespace ServiceLib.ViewModels
} }
foreach (var it in SelectedSources ?? [SelectedSource]) foreach (var it in SelectedSources ?? [SelectedSource])
{ {
var item = AppHandler.Instance.GetRoutingItem(it?.id); var item = await AppHandler.Instance.GetRoutingItem(it?.id);
if (item != null) if (item != null)
{ {
ConfigHandler.RemoveRoutingItem(item); ConfigHandler.RemoveRoutingItem(item);
@ -281,7 +281,7 @@ namespace ServiceLib.ViewModels
public async Task RoutingAdvancedSetDefault() public async Task RoutingAdvancedSetDefault()
{ {
var item = AppHandler.Instance.GetRoutingItem(SelectedSource?.id); var item = await AppHandler.Instance.GetRoutingItem(SelectedSource?.id);
if (item is null) if (item is null)
{ {
NoticeHandler.Instance.Enqueue(ResUI.PleaseSelectRules); NoticeHandler.Instance.Enqueue(ResUI.PleaseSelectRules);

View File

@ -222,7 +222,7 @@ namespace ServiceLib.ViewModels
public async Task RefreshServersBiz() public async Task RefreshServersBiz()
{ {
RefreshServersMenu(); await RefreshServersMenu();
//display running server //display running server
var running = await ConfigHandler.GetDefaultServer(_config); var running = await ConfigHandler.GetDefaultServer(_config);
@ -238,9 +238,9 @@ namespace ServiceLib.ViewModels
} }
} }
private void RefreshServersMenu() private async Task RefreshServersMenu()
{ {
var lstModel = AppHandler.Instance.ProfileItems(_config.subIndexId, ""); var lstModel = await AppHandler.Instance.ProfileItems(_config.subIndexId, "");
_servers.Clear(); _servers.Clear();
if (lstModel.Count > _config.guiItem.trayMenuServersLimit) if (lstModel.Count > _config.guiItem.trayMenuServersLimit)
@ -309,11 +309,11 @@ namespace ServiceLib.ViewModels
return; return;
} }
_config.systemProxyItem.sysProxyType = type; _config.systemProxyItem.sysProxyType = type;
ChangeSystemProxyAsync(type, true); await ChangeSystemProxyAsync(type, true);
NoticeHandler.Instance.SendMessageEx($"{ResUI.TipChangeSystemProxy} - {_config.systemProxyItem.sysProxyType.ToString()}"); NoticeHandler.Instance.SendMessageEx($"{ResUI.TipChangeSystemProxy} - {_config.systemProxyItem.sysProxyType.ToString()}");
SystemProxySelected = (int)_config.systemProxyItem.sysProxyType; SystemProxySelected = (int)_config.systemProxyItem.sysProxyType;
ConfigHandler.SaveConfig(_config, false); await ConfigHandler.SaveConfig(_config, false);
} }
public async Task ChangeSystemProxyAsync(ESysProxyType type, bool blChange) public async Task ChangeSystemProxyAsync(ESysProxyType type, bool blChange)
@ -336,7 +336,7 @@ namespace ServiceLib.ViewModels
} }
} }
public void RefreshRoutingsMenu() public async Task RefreshRoutingsMenu()
{ {
_routingItems.Clear(); _routingItems.Clear();
if (!_config.routingBasicItem.enableRoutingAdvanced) if (!_config.routingBasicItem.enableRoutingAdvanced)
@ -346,7 +346,7 @@ namespace ServiceLib.ViewModels
} }
BlRouting = true; BlRouting = true;
var routings = AppHandler.Instance.RoutingItems(); var routings = await AppHandler.Instance.RoutingItems();
foreach (var item in routings) foreach (var item in routings)
{ {
_routingItems.Add(item); _routingItems.Add(item);
@ -369,7 +369,7 @@ namespace ServiceLib.ViewModels
return; return;
} }
var item = AppHandler.Instance.GetRoutingItem(SelectedRouting?.id); var item = await AppHandler.Instance.GetRoutingItem(SelectedRouting?.id);
if (item is null) if (item is null)
{ {
return; return;

View File

@ -54,10 +54,10 @@ namespace ServiceLib.ViewModels
}, canEditRemove); }, canEditRemove);
} }
public void RefreshSubItems() public async Task RefreshSubItems()
{ {
_subItems.Clear(); _subItems.Clear();
_subItems.AddRange(AppHandler.Instance.SubItems().OrderBy(t => t.sort)); _subItems.AddRange(await AppHandler.Instance.SubItems());
} }
public async Task EditSubAsync(bool blNew) public async Task EditSubAsync(bool blNew)
@ -69,7 +69,7 @@ namespace ServiceLib.ViewModels
} }
else else
{ {
item = AppHandler.Instance.GetSubItem(SelectedSource?.id); item = await AppHandler.Instance.GetSubItem(SelectedSource?.id);
if (item is null) if (item is null)
{ {
return; return;
@ -77,7 +77,7 @@ namespace ServiceLib.ViewModels
} }
if (await _updateView?.Invoke(EViewAction.SubEditWindow, item) == true) if (await _updateView?.Invoke(EViewAction.SubEditWindow, item) == true)
{ {
RefreshSubItems(); await RefreshSubItems();
IsModified = true; IsModified = true;
} }
} }
@ -91,9 +91,9 @@ namespace ServiceLib.ViewModels
foreach (var it in SelectedSources ?? [SelectedSource]) foreach (var it in SelectedSources ?? [SelectedSource])
{ {
ConfigHandler.DeleteSubItem(_config, it.id); await ConfigHandler.DeleteSubItem(_config, it.id);
} }
RefreshSubItems(); await RefreshSubItems();
NoticeHandler.Instance.Enqueue(ResUI.OperationSuccess); NoticeHandler.Instance.Enqueue(ResUI.OperationSuccess);
IsModified = true; IsModified = true;
} }