ProfileItem.cs 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. using ClashDotNetFramework.Models.Enums;
  2. using ClashDotNetFramework.Utils;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.ComponentModel;
  6. using System.IO;
  7. using System.Linq;
  8. using System.Net;
  9. using System.Runtime.CompilerServices;
  10. using System.Text;
  11. using System.Threading.Tasks;
  12. using static ClashDotNetFramework.Utils.ProfileHelper;
  13. namespace ClashDotNetFramework.Models.Items
  14. {
  15. public class ProfileItem : INotifyPropertyChanged
  16. {
  17. #region 属性改变事件
  18. public event PropertyChangedEventHandler PropertyChanged;
  19. private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
  20. {
  21. if (PropertyChanged != null)
  22. {
  23. PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
  24. }
  25. }
  26. #endregion
  27. #region 内部变量
  28. private string _name { get; set; } = "";
  29. private bool _selected { get; set; } = false;
  30. private long _proxyCount { get; set; } = 0;
  31. private long _groupCount { get; set; } = 0;
  32. private long _ruleCount { get; set; } = 0;
  33. private DateTime _lastUpdate { get; set; } = DateTime.Now;
  34. #endregion
  35. #region 通用设置
  36. public string Name
  37. {
  38. get
  39. {
  40. return _name;
  41. }
  42. set
  43. {
  44. if (value != _name)
  45. {
  46. _name = value;
  47. NotifyPropertyChanged();
  48. }
  49. }
  50. }
  51. public string FileName { get; set; } = "";
  52. public bool IsSelected
  53. {
  54. get
  55. {
  56. return _selected;
  57. }
  58. set
  59. {
  60. if (value != _selected)
  61. {
  62. _selected = value;
  63. NotifyPropertyChanged();
  64. }
  65. }
  66. }
  67. public long ProxyCount
  68. {
  69. get
  70. {
  71. return _proxyCount;
  72. }
  73. set
  74. {
  75. if (value != _proxyCount)
  76. {
  77. _proxyCount = value;
  78. NotifyPropertyChanged();
  79. }
  80. }
  81. }
  82. public long GroupCount
  83. {
  84. get
  85. {
  86. return _groupCount;
  87. }
  88. set
  89. {
  90. if (value != _groupCount)
  91. {
  92. _groupCount = value;
  93. NotifyPropertyChanged();
  94. }
  95. }
  96. }
  97. public long RuleCount
  98. {
  99. get
  100. {
  101. return _ruleCount;
  102. }
  103. set
  104. {
  105. if (value != _ruleCount)
  106. {
  107. _ruleCount = value;
  108. NotifyPropertyChanged();
  109. }
  110. }
  111. }
  112. public ProfileType Type { get; set; } = ProfileType.Local;
  113. public DateTime LastUpdate
  114. {
  115. get
  116. {
  117. return _lastUpdate;
  118. }
  119. set
  120. {
  121. if (value != _lastUpdate)
  122. {
  123. _lastUpdate = value;
  124. NotifyPropertyChanged();
  125. }
  126. }
  127. }
  128. #endregion
  129. #region 远程配置文件相关设置
  130. public bool IsRemote { get; set; } = false;
  131. public string Host { get; set; } = "";
  132. public string Url { get; set; } = "";
  133. public int UpdateInterval { get; set; } = 0;
  134. #endregion
  135. #region 内置方法
  136. /// <summary>
  137. /// 更新配置文件
  138. /// </summary>
  139. public bool Update()
  140. {
  141. // 重新获取远程配置文件
  142. if (Type == ProfileType.Remote)
  143. {
  144. try
  145. {
  146. var req = WebUtil.CreateRequest(Url);
  147. string yamlText = string.Empty;
  148. var result = WebUtil.DownloadString(req, out var rep);
  149. if (rep.StatusCode == HttpStatusCode.OK)
  150. {
  151. if (string.IsNullOrWhiteSpace(Name) || string.IsNullOrWhiteSpace(FileName))
  152. {
  153. if (!string.IsNullOrWhiteSpace(rep.Headers["Content-Disposition"]))
  154. {
  155. Name = rep.Headers["Content-Disposition"].Replace("attachment; filename=", String.Empty).Replace("\"", String.Empty);
  156. FileName = Path.Combine(Utils.Utils.GetClashProfilesDir(), Name);
  157. }
  158. else
  159. {
  160. Name = $"Clash_{DateTimeOffset.Now.ToUnixTimeSeconds()}.yaml";
  161. FileName = Path.Combine(Utils.Utils.GetClashProfilesDir(), Name);
  162. }
  163. }
  164. yamlText = result;
  165. File.WriteAllText(FileName, yamlText);
  166. SetProfileDetail(GetProfileDetail(yamlText));
  167. LastUpdate = DateTime.Now;
  168. return true;
  169. }
  170. else
  171. {
  172. // 下载失败了呢
  173. return false;
  174. }
  175. }
  176. catch
  177. {
  178. return false;
  179. }
  180. }
  181. else
  182. {
  183. try
  184. {
  185. // 对于本地文件,我们只重新读取详细统计数据
  186. SetProfileDetail(GetProfileDetail(File.ReadAllText(FileName)));
  187. // 设置上次更新时间
  188. LastUpdate = DateTime.Now;
  189. // 返回成功
  190. return true;
  191. }
  192. catch
  193. {
  194. return false;
  195. }
  196. }
  197. }
  198. /// <summary>
  199. /// 设置配置文件详细
  200. /// </summary>
  201. /// <param name="profileDetail"></param>
  202. public void SetProfileDetail(ProfileDetail profileDetail)
  203. {
  204. ProxyCount = profileDetail.ProxyCount;
  205. GroupCount = profileDetail.GroupCount;
  206. RuleCount = profileDetail.RuleCount;
  207. }
  208. public ProfileItem Copy(string destFileName)
  209. {
  210. string destPath = Path.Combine(Utils.Utils.GetClashProfilesDir(), destFileName); ;
  211. File.Copy(FileName, destPath);
  212. ProfileItem profileItem = new ProfileItem
  213. {
  214. Name = destFileName,
  215. FileName = destPath,
  216. ProxyCount = ProxyCount,
  217. GroupCount = GroupCount,
  218. RuleCount = RuleCount,
  219. Type = Type,
  220. Host = Host,
  221. Url = Url,
  222. LastUpdate = DateTime.Now
  223. };
  224. return profileItem;
  225. }
  226. #endregion
  227. }
  228. }