2024-10-07 02:59:13 +00:00
|
|
|
|
namespace ServiceLib.Handler
|
2022-02-24 12:45:24 +00:00
|
|
|
|
{
|
2024-10-07 01:51:41 +00:00
|
|
|
|
public sealed class AppHandler
|
2022-02-24 12:45:24 +00:00
|
|
|
|
{
|
2024-10-07 01:51:41 +00:00
|
|
|
|
private static readonly Lazy<AppHandler> _instance = new(() => new());
|
2022-02-24 12:45:24 +00:00
|
|
|
|
private Config _config;
|
2024-02-12 13:49:57 +00:00
|
|
|
|
private int? _statePort;
|
2024-06-24 07:19:42 +00:00
|
|
|
|
private int? _statePort2;
|
2024-10-07 01:51:41 +00:00
|
|
|
|
private Job? _processJob;
|
|
|
|
|
public static AppHandler Instance => _instance.Value;
|
2024-08-15 13:03:00 +00:00
|
|
|
|
public Config Config => _config;
|
|
|
|
|
|
2024-02-12 13:49:57 +00:00
|
|
|
|
public int StatePort
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
2024-06-24 07:19:42 +00:00
|
|
|
|
_statePort ??= Utils.GetFreePort(GetLocalPort(EInboundProtocol.api));
|
2024-02-12 13:49:57 +00:00
|
|
|
|
return _statePort.Value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-06-24 07:19:42 +00:00
|
|
|
|
public int StatePort2
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
_statePort2 ??= Utils.GetFreePort(GetLocalPort(EInboundProtocol.api2));
|
|
|
|
|
return _statePort2.Value;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-10-07 01:51:41 +00:00
|
|
|
|
#region Init
|
|
|
|
|
|
|
|
|
|
public AppHandler()
|
2024-10-07 02:59:13 +00:00
|
|
|
|
{
|
2024-10-07 01:51:41 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool InitApp()
|
|
|
|
|
{
|
|
|
|
|
if (ConfigHandler.LoadConfig(ref _config) != 0)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
Thread.CurrentThread.CurrentUICulture = new(_config.uiItem.currentLanguage);
|
|
|
|
|
|
|
|
|
|
//Under Win10
|
|
|
|
|
if (Utils.IsWindows() && Environment.OSVersion.Version.Major < 10)
|
|
|
|
|
{
|
|
|
|
|
Environment.SetEnvironmentVariable("DOTNET_EnableWriteXorExecute", "0", EnvironmentVariableTarget.User);
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2024-02-08 06:01:33 +00:00
|
|
|
|
|
2024-10-07 01:51:41 +00:00
|
|
|
|
public bool InitComponents()
|
2023-01-01 11:42:01 +00:00
|
|
|
|
{
|
2024-10-07 01:51:41 +00:00
|
|
|
|
Logging.Setup();
|
|
|
|
|
Logging.LoggingEnabled(true);
|
|
|
|
|
Logging.SaveLog($"v2rayN start up | {Utils.GetVersion()} | {Utils.GetExePath()}");
|
|
|
|
|
Logging.SaveLog($"{Environment.OSVersion} - {(Environment.Is64BitOperatingSystem ? 64 : 32)}");
|
|
|
|
|
Logging.ClearLogs();
|
|
|
|
|
|
2024-02-19 09:43:36 +00:00
|
|
|
|
SQLiteHelper.Instance.CreateTable<SubItem>();
|
|
|
|
|
SQLiteHelper.Instance.CreateTable<ProfileItem>();
|
|
|
|
|
SQLiteHelper.Instance.CreateTable<ServerStatItem>();
|
|
|
|
|
SQLiteHelper.Instance.CreateTable<RoutingItem>();
|
|
|
|
|
SQLiteHelper.Instance.CreateTable<ProfileExItem>();
|
|
|
|
|
SQLiteHelper.Instance.CreateTable<DNSItem>();
|
2024-10-07 01:51:41 +00:00
|
|
|
|
|
|
|
|
|
return true;
|
2023-01-01 11:42:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-10-07 01:51:41 +00:00
|
|
|
|
#endregion Init
|
2023-01-01 11:42:01 +00:00
|
|
|
|
|
2024-10-07 01:51:41 +00:00
|
|
|
|
#region Config
|
2022-03-21 12:20:29 +00:00
|
|
|
|
|
2024-03-09 01:27:55 +00:00
|
|
|
|
public int GetLocalPort(EInboundProtocol protocol)
|
2023-01-01 11:42:01 +00:00
|
|
|
|
{
|
2024-03-09 01:27:55 +00:00
|
|
|
|
var localPort = _config.inbound.FirstOrDefault(t => t.protocol == nameof(EInboundProtocol.socks))?.localPort ?? 10808;
|
|
|
|
|
return localPort + (int)protocol;
|
2023-01-01 11:42:01 +00:00
|
|
|
|
}
|
2024-02-12 13:49:57 +00:00
|
|
|
|
|
2024-02-08 06:01:33 +00:00
|
|
|
|
public void AddProcess(IntPtr processHandle)
|
|
|
|
|
{
|
2024-08-27 11:44:50 +00:00
|
|
|
|
if (Utils.IsWindows())
|
2024-08-20 06:15:29 +00:00
|
|
|
|
{
|
|
|
|
|
_processJob ??= new();
|
|
|
|
|
_processJob?.AddProcess(processHandle);
|
2024-08-20 06:30:45 +00:00
|
|
|
|
}
|
2024-02-08 06:01:33 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion Config
|
|
|
|
|
|
|
|
|
|
#region SqliteHelper
|
2023-01-01 11:42:01 +00:00
|
|
|
|
|
|
|
|
|
public List<SubItem> SubItems()
|
|
|
|
|
{
|
2024-02-19 09:43:36 +00:00
|
|
|
|
return SQLiteHelper.Instance.Table<SubItem>().ToList();
|
2023-01-01 11:42:01 +00:00
|
|
|
|
}
|
2023-04-14 12:49:36 +00:00
|
|
|
|
|
2023-01-01 11:42:01 +00:00
|
|
|
|
public SubItem GetSubItem(string subid)
|
|
|
|
|
{
|
2024-02-19 09:43:36 +00:00
|
|
|
|
return SQLiteHelper.Instance.Table<SubItem>().FirstOrDefault(t => t.id == subid);
|
2023-01-01 11:42:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public List<ProfileItem> ProfileItems(string subid)
|
|
|
|
|
{
|
2024-03-26 06:26:03 +00:00
|
|
|
|
if (Utils.IsNullOrEmpty(subid))
|
2023-01-01 11:42:01 +00:00
|
|
|
|
{
|
2024-02-19 09:43:36 +00:00
|
|
|
|
return SQLiteHelper.Instance.Table<ProfileItem>().ToList();
|
2023-01-01 11:42:01 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2024-02-19 09:43:36 +00:00
|
|
|
|
return SQLiteHelper.Instance.Table<ProfileItem>().Where(t => t.subid == subid).ToList();
|
2023-01-01 11:42:01 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2023-04-14 12:49:36 +00:00
|
|
|
|
|
2024-02-19 09:43:36 +00:00
|
|
|
|
public List<string> ProfileItemIndexes(string subid)
|
2023-02-19 02:43:42 +00:00
|
|
|
|
{
|
2024-03-26 06:26:03 +00:00
|
|
|
|
if (Utils.IsNullOrEmpty(subid))
|
2023-02-19 02:43:42 +00:00
|
|
|
|
{
|
2024-02-19 09:43:36 +00:00
|
|
|
|
return SQLiteHelper.Instance.Table<ProfileItem>().Select(t => t.indexId).ToList();
|
2023-02-19 02:43:42 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2024-02-19 09:43:36 +00:00
|
|
|
|
return SQLiteHelper.Instance.Table<ProfileItem>().Where(t => t.subid == subid).Select(t => t.indexId).ToList();
|
2023-02-19 02:43:42 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2023-01-01 11:42:01 +00:00
|
|
|
|
|
|
|
|
|
public List<ProfileItemModel> ProfileItems(string subid, string filter)
|
2022-03-21 12:20:29 +00:00
|
|
|
|
{
|
2023-04-14 12:49:36 +00:00
|
|
|
|
var sql = @$"select a.*
|
|
|
|
|
,b.remarks subRemarks
|
2023-01-01 11:42:01 +00:00
|
|
|
|
from ProfileItem a
|
2023-04-14 12:49:36 +00:00
|
|
|
|
left join SubItem b on a.subid = b.id
|
2023-01-01 11:42:01 +00:00
|
|
|
|
where 1=1 ";
|
2024-09-17 08:52:41 +00:00
|
|
|
|
if (Utils.IsNotEmpty(subid))
|
2023-01-01 11:42:01 +00:00
|
|
|
|
{
|
2023-01-04 07:47:08 +00:00
|
|
|
|
sql += $" and a.subid = '{subid}'";
|
2023-01-01 11:42:01 +00:00
|
|
|
|
}
|
2024-09-17 08:52:41 +00:00
|
|
|
|
if (Utils.IsNotEmpty(filter))
|
2023-01-01 11:42:01 +00:00
|
|
|
|
{
|
2023-02-20 10:16:30 +00:00
|
|
|
|
if (filter.Contains('\''))
|
2023-01-31 06:13:25 +00:00
|
|
|
|
{
|
|
|
|
|
filter = filter.Replace("'", "");
|
|
|
|
|
}
|
2023-03-08 12:39:50 +00:00
|
|
|
|
sql += String.Format(" and (a.remarks like '%{0}%' or a.address like '%{0}%') ", filter);
|
2023-01-01 11:42:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-02-19 09:43:36 +00:00
|
|
|
|
return SQLiteHelper.Instance.Query<ProfileItemModel>(sql).ToList();
|
2023-01-01 11:42:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-08-17 02:53:02 +00:00
|
|
|
|
public List<ProfileItemModel> ProfileItemsEx(string subid, string filter)
|
|
|
|
|
{
|
|
|
|
|
var lstModel = ProfileItems(_config.subIndexId, filter);
|
|
|
|
|
|
|
|
|
|
ConfigHandler.SetDefaultServer(_config, lstModel);
|
|
|
|
|
|
|
|
|
|
var lstServerStat = (_config.guiItem.enableStatistics ? StatisticsHandler.Instance.ServerStat : null) ?? [];
|
|
|
|
|
var lstProfileExs = ProfileExHandler.Instance.ProfileExs;
|
|
|
|
|
lstModel = (from t in lstModel
|
|
|
|
|
join t2 in lstServerStat on t.indexId equals t2.indexId into t2b
|
|
|
|
|
from t22 in t2b.DefaultIfEmpty()
|
|
|
|
|
join t3 in lstProfileExs on t.indexId equals t3.indexId into t3b
|
|
|
|
|
from t33 in t3b.DefaultIfEmpty()
|
|
|
|
|
select new ProfileItemModel
|
|
|
|
|
{
|
|
|
|
|
indexId = t.indexId,
|
|
|
|
|
configType = t.configType,
|
|
|
|
|
remarks = t.remarks,
|
|
|
|
|
address = t.address,
|
|
|
|
|
port = t.port,
|
|
|
|
|
security = t.security,
|
|
|
|
|
network = t.network,
|
|
|
|
|
streamSecurity = t.streamSecurity,
|
|
|
|
|
subid = t.subid,
|
|
|
|
|
subRemarks = t.subRemarks,
|
|
|
|
|
isActive = t.indexId == _config.indexId,
|
|
|
|
|
sort = t33 == null ? 0 : t33.sort,
|
|
|
|
|
delay = t33 == null ? 0 : t33.delay,
|
|
|
|
|
delayVal = t33?.delay != 0 ? $"{t33?.delay} {Global.DelayUnit}" : string.Empty,
|
|
|
|
|
speedVal = t33?.speed != 0 ? $"{t33?.speed} {Global.SpeedUnit}" : string.Empty,
|
|
|
|
|
todayDown = t22 == null ? "" : Utils.HumanFy(t22.todayDown),
|
|
|
|
|
todayUp = t22 == null ? "" : Utils.HumanFy(t22.todayUp),
|
|
|
|
|
totalDown = t22 == null ? "" : Utils.HumanFy(t22.totalDown),
|
|
|
|
|
totalUp = t22 == null ? "" : Utils.HumanFy(t22.totalUp)
|
|
|
|
|
}).OrderBy(t => t.sort).ToList();
|
|
|
|
|
|
|
|
|
|
return lstModel;
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-19 04:18:08 +00:00
|
|
|
|
public ProfileItem? GetProfileItem(string indexId)
|
2023-01-01 11:42:01 +00:00
|
|
|
|
{
|
2024-03-26 06:26:03 +00:00
|
|
|
|
if (Utils.IsNullOrEmpty(indexId))
|
2023-01-01 11:42:01 +00:00
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
2024-02-19 09:43:36 +00:00
|
|
|
|
return SQLiteHelper.Instance.Table<ProfileItem>().FirstOrDefault(it => it.indexId == indexId);
|
2023-01-01 11:42:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-09-18 11:54:38 +00:00
|
|
|
|
public ProfileItem? GetProfileItemViaRemarks(string? remarks)
|
2023-12-23 12:57:31 +00:00
|
|
|
|
{
|
2024-03-26 06:26:03 +00:00
|
|
|
|
if (Utils.IsNullOrEmpty(remarks))
|
2023-12-23 12:57:31 +00:00
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
2024-02-19 09:43:36 +00:00
|
|
|
|
return SQLiteHelper.Instance.Table<ProfileItem>().FirstOrDefault(it => it.remarks == remarks);
|
2023-12-23 12:57:31 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-01-01 11:42:01 +00:00
|
|
|
|
public List<RoutingItem> RoutingItems()
|
|
|
|
|
{
|
2024-02-19 09:43:36 +00:00
|
|
|
|
return SQLiteHelper.Instance.Table<RoutingItem>().Where(it => it.locked == false).OrderBy(t => t.sort).ToList();
|
2023-01-01 11:42:01 +00:00
|
|
|
|
}
|
2023-04-14 12:49:36 +00:00
|
|
|
|
|
2023-01-01 11:42:01 +00:00
|
|
|
|
public RoutingItem GetRoutingItem(string id)
|
|
|
|
|
{
|
2024-02-19 09:43:36 +00:00
|
|
|
|
return SQLiteHelper.Instance.Table<RoutingItem>().FirstOrDefault(it => it.locked == false && it.id == id);
|
2023-01-01 11:42:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-04-24 03:55:26 +00:00
|
|
|
|
public List<DNSItem> DNSItems()
|
|
|
|
|
{
|
2024-02-19 09:43:36 +00:00
|
|
|
|
return SQLiteHelper.Instance.Table<DNSItem>().ToList();
|
2023-04-24 03:55:26 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public DNSItem GetDNSItem(ECoreType eCoreType)
|
|
|
|
|
{
|
2024-02-19 09:43:36 +00:00
|
|
|
|
return SQLiteHelper.Instance.Table<DNSItem>().FirstOrDefault(it => it.coreType == eCoreType);
|
2023-04-24 03:55:26 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-02-08 06:01:33 +00:00
|
|
|
|
#endregion SqliteHelper
|
2023-01-01 11:42:01 +00:00
|
|
|
|
|
|
|
|
|
#region Core Type
|
|
|
|
|
|
2024-02-19 09:43:36 +00:00
|
|
|
|
public List<string> GetShadowsocksSecurities(ProfileItem profileItem)
|
2023-01-01 11:42:01 +00:00
|
|
|
|
{
|
2024-01-23 04:30:11 +00:00
|
|
|
|
var coreType = GetCoreType(profileItem, EConfigType.Shadowsocks);
|
|
|
|
|
switch (coreType)
|
2022-03-21 12:20:29 +00:00
|
|
|
|
{
|
2024-01-23 04:30:11 +00:00
|
|
|
|
case ECoreType.v2fly:
|
2024-02-19 09:43:36 +00:00
|
|
|
|
return Global.SsSecurities;
|
2022-03-21 12:20:29 +00:00
|
|
|
|
|
2024-01-23 04:30:11 +00:00
|
|
|
|
case ECoreType.Xray:
|
2024-02-19 09:43:36 +00:00
|
|
|
|
return Global.SsSecuritiesInXray;
|
2024-01-23 04:30:11 +00:00
|
|
|
|
|
|
|
|
|
case ECoreType.sing_box:
|
2024-02-19 09:43:36 +00:00
|
|
|
|
return Global.SsSecuritiesInSingbox;
|
2024-01-23 04:30:11 +00:00
|
|
|
|
}
|
2024-02-19 09:43:36 +00:00
|
|
|
|
return Global.SsSecuritiesInSagerNet;
|
2022-03-21 12:20:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-01-01 11:42:01 +00:00
|
|
|
|
public ECoreType GetCoreType(ProfileItem profileItem, EConfigType eConfigType)
|
2022-03-21 12:20:29 +00:00
|
|
|
|
{
|
2023-02-20 10:16:30 +00:00
|
|
|
|
if (profileItem?.coreType != null)
|
2022-03-21 12:20:29 +00:00
|
|
|
|
{
|
2023-01-01 11:42:01 +00:00
|
|
|
|
return (ECoreType)profileItem.coreType;
|
2022-03-21 12:20:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (_config.coreTypeItem == null)
|
|
|
|
|
{
|
|
|
|
|
return ECoreType.Xray;
|
|
|
|
|
}
|
|
|
|
|
var item = _config.coreTypeItem.FirstOrDefault(it => it.configType == eConfigType);
|
|
|
|
|
if (item == null)
|
|
|
|
|
{
|
|
|
|
|
return ECoreType.Xray;
|
|
|
|
|
}
|
|
|
|
|
return item.coreType;
|
|
|
|
|
}
|
2022-03-28 10:54:05 +00:00
|
|
|
|
|
2023-04-14 12:49:36 +00:00
|
|
|
|
#endregion Core Type
|
2022-02-24 12:45:24 +00:00
|
|
|
|
}
|
2023-11-28 08:07:53 +00:00
|
|
|
|
}
|