Settings.vb 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414
  1. Public Class Settings
  2. Private Shared ReadOnly Entries As Dictionary(Of String, Setting) = (New List(Of Setting) From {
  3. New Setting("Identify", "", Source:=Sources.Registry),
  4. New Setting("WindowHeight", 550),
  5. New Setting("WindowWidth", 900),
  6. New Setting("AprilDoneYear", 0, Source:=Sources.Registry),
  7. New Setting("Potatoes", "", Source:=Sources.Registry, Encrypted:=True),
  8. New Setting("HintDownloadThread", False, Source:=Sources.Registry),
  9. New Setting("HintNotice", 0, Source:=Sources.Registry),
  10. New Setting("HintDownload", 0, Source:=Sources.Registry),
  11. New Setting("HintHide", False, Source:=Sources.Registry),
  12. New Setting("HintHandInstall", False, Source:=Sources.Registry),
  13. New Setting("HintBuy", False, Source:=Sources.Registry),
  14. New Setting("HintClearRubbish", 0, Source:=Sources.Registry),
  15. New Setting("HintUpdateMod", False, Source:=Sources.Registry),
  16. New Setting("HintCustomCommand", False, Source:=Sources.Registry),
  17. New Setting("HintCustomWarn", False, Source:=Sources.Registry),
  18. New Setting("HintMoreAdvancedSetup", False, Source:=Sources.Registry),
  19. New Setting("HintIndieSetup", False, Source:=Sources.Registry),
  20. New Setting("HintExportConfig", False, Source:=Sources.Registry),
  21. New Setting("HintSnapshot", False, Source:=Sources.Registry),
  22. New Setting("SystemEulaVersion", 0, Source:=Sources.Registry),
  23. New Setting("SystemCount", 0, Source:=Sources.Registry, Encrypted:=True),
  24. New Setting("SystemLaunchCount", 0, Source:=Sources.Registry, Encrypted:=True),
  25. New Setting("SystemLastVersionReg", 0, Source:=Sources.Registry, Encrypted:=True),
  26. New Setting("SystemHighestSavedBetaVersionReg", 0, Source:=Sources.Registry, Encrypted:=True),
  27. New Setting("SystemHighestBetaVersionReg", 0, Source:=Sources.Registry, Encrypted:=True),
  28. New Setting("SystemHighestAlphaVersionReg", 0, Source:=Sources.Registry, Encrypted:=True),
  29. New Setting("SystemHelpVersion", 0, Source:=Sources.Registry),
  30. New Setting("SystemDebugMode", False, Source:=Sources.Registry),
  31. New Setting("SystemDebugAnim", 9, Source:=Sources.Registry),
  32. New Setting("SystemDebugDelay", False, Source:=Sources.Registry),
  33. New Setting("SystemDebugSkipCopy", False, Source:=Sources.Registry),
  34. New Setting("SystemSystemCache", "", Source:=Sources.Registry),
  35. New Setting("SystemSystemUpdate", 0),
  36. New Setting("SystemSystemActivity", 0),
  37. New Setting("SystemSystemTelemetry", True, Source:=Sources.Registry),
  38. New Setting("CacheDrops", "", Source:=Sources.Registry),
  39. New Setting("CacheConfig", 0, Source:=Sources.Registry),
  40. New Setting("CacheExportConfig", "", Source:=Sources.Registry),
  41. New Setting("CacheSavedPageUrl", "", Source:=Sources.Registry),
  42. New Setting("CacheSavedPageVersion", "", Source:=Sources.Registry),
  43. New Setting("CacheMsOAuthRefresh", "", Source:=Sources.Registry, Encrypted:=True),
  44. New Setting("CacheMsAccess", "", Source:=Sources.Registry, Encrypted:=True),
  45. New Setting("CacheMsProfileJson", "", Source:=Sources.Registry, Encrypted:=True),
  46. New Setting("CacheMsUuid", "", Source:=Sources.Registry, Encrypted:=True),
  47. New Setting("CacheMsName", "", Source:=Sources.Registry, Encrypted:=True),
  48. New Setting("CacheMsV2Migrated", False, Source:=Sources.Registry),
  49. New Setting("CacheMsV2OAuthRefresh", "", Source:=Sources.Registry, Encrypted:=True),
  50. New Setting("CacheMsV2Access", "", Source:=Sources.Registry, Encrypted:=True),
  51. New Setting("CacheMsV2ProfileJson", "", Source:=Sources.Registry, Encrypted:=True),
  52. New Setting("CacheMsV2Uuid", "", Source:=Sources.Registry, Encrypted:=True),
  53. New Setting("CacheMsV2Name", "", Source:=Sources.Registry, Encrypted:=True),
  54. New Setting("CacheNideAccess", "", Source:=Sources.Registry, Encrypted:=True),
  55. New Setting("CacheNideClient", "", Source:=Sources.Registry, Encrypted:=True),
  56. New Setting("CacheNideUuid", "", Source:=Sources.Registry, Encrypted:=True),
  57. New Setting("CacheNideName", "", Source:=Sources.Registry, Encrypted:=True),
  58. New Setting("CacheNideUsername", "", Source:=Sources.Registry, Encrypted:=True),
  59. New Setting("CacheNidePass", "", Source:=Sources.Registry, Encrypted:=True),
  60. New Setting("CacheNideServer", "", Source:=Sources.Registry, Encrypted:=True),
  61. New Setting("CacheAuthAccess", "", Source:=Sources.Registry, Encrypted:=True),
  62. New Setting("CacheAuthClient", "", Source:=Sources.Registry, Encrypted:=True),
  63. New Setting("CacheAuthUuid", "", Source:=Sources.Registry, Encrypted:=True),
  64. New Setting("CacheAuthName", "", Source:=Sources.Registry, Encrypted:=True),
  65. New Setting("CacheAuthUsername", "", Source:=Sources.Registry, Encrypted:=True),
  66. New Setting("CacheAuthPass", "", Source:=Sources.Registry, Encrypted:=True),
  67. New Setting("CacheAuthServerServer", "", Source:=Sources.Registry, Encrypted:=True),
  68. New Setting("CacheAuthServerName", "", Source:=Sources.Registry, Encrypted:=True),
  69. New Setting("CacheAuthServerRegister", "", Source:=Sources.Registry, Encrypted:=True),
  70. New Setting("CacheDownloadFolder", "", Source:=Sources.Registry),
  71. New Setting("CacheJavaListVersion", 0, Source:=Sources.Registry),
  72. New Setting("LoginRemember", True, Source:=Sources.Registry, Encrypted:=True),
  73. New Setting("LoginLegacyName", "", Source:=Sources.Registry, Encrypted:=True),
  74. New Setting("LoginMsJson", "{}", Source:=Sources.Registry, Encrypted:=True), '{UserName: OAuthToken, ...}
  75. New Setting("LoginNideEmail", "", Source:=Sources.Registry, Encrypted:=True),
  76. New Setting("LoginNidePass", "", Source:=Sources.Registry, Encrypted:=True),
  77. New Setting("LoginAuthEmail", "", Source:=Sources.Registry, Encrypted:=True),
  78. New Setting("LoginAuthPass", "", Source:=Sources.Registry, Encrypted:=True),
  79. New Setting("LoginType", McLoginType.Legacy, Source:=Sources.Registry),
  80. New Setting("LoginPageType", 0),
  81. New Setting("LaunchSkinID", "", Source:=Sources.Registry, OnChanged:=Sub() PageLaunchLeft.SkinLegacy.Start()),
  82. New Setting("LaunchSkinType", 0, Source:=Sources.Registry, OnChanged:=AddressOf PageSetupLaunch.UpdateSkinType),
  83. New Setting("LaunchSkinSlim", False, Source:=Sources.Registry),
  84. New Setting("LaunchFolderSelect", ""),
  85. New Setting("LaunchFolders", "", Source:=Sources.Registry),
  86. New Setting("LaunchArgumentTitle", ""),
  87. New Setting("LaunchArgumentInfo", "PCL"),
  88. New Setting("LaunchArgumentJavaSelect", "", Source:=Sources.Registry),
  89. New Setting("LaunchArgumentJavaAll", "[]", Source:=Sources.Registry),
  90. New Setting("LaunchArgumentIndie", 0),
  91. New Setting("LaunchArgumentIndieV2", 4),
  92. New Setting("LaunchArgumentVisible", 5, Source:=Sources.Registry),
  93. New Setting("LaunchArgumentPriority", 1, Source:=Sources.Registry),
  94. New Setting("LaunchArgumentWindowWidth", 854),
  95. New Setting("LaunchArgumentWindowHeight", 480),
  96. New Setting("LaunchArgumentWindowType", 1),
  97. New Setting("LaunchArgumentRam", False, Source:=Sources.Registry),
  98. New Setting("LaunchAdvanceJvm", "-XX:-OmitStackTraceInFastThrow -Djdk.lang.Process.allowAmbiguousCommands=True -Dfml.ignoreInvalidMinecraftCertificates=True -Dfml.ignorePatchDiscrepancies=True"),
  99. New Setting("LaunchAdvanceGame", ""),
  100. New Setting("LaunchAdvanceRun", ""),
  101. New Setting("LaunchAdvanceRunWait", True),
  102. New Setting("LaunchAdvanceDisableJLW", False),
  103. New Setting("LaunchAdvanceDisableLUA", False),
  104. New Setting("LaunchAdvanceGraphicCard", True, Source:=Sources.Registry),
  105. New Setting("LaunchAdvanceGC", 4),
  106. New Setting("LaunchRamType", 0, OnChanged:=AddressOf PageSetupLaunch.UpdateRamType),
  107. New Setting("LaunchRamCustom", 15),
  108. New Setting("LinkLastAutoJoinInviteCode", "", Source:=Sources.Registry),
  109. New Setting("LinkLatencyMode", 0, Source:=Sources.Registry),
  110. New Setting("LinkCustomPeer", ""),
  111. New Setting("LinkEasyTierVersion", -1, Source:=Sources.Registry),
  112. New Setting("ToolHelpChinese", True, Source:=Sources.Registry),
  113. New Setting("ToolDownloadThread", 63, Source:=Sources.Registry),
  114. New Setting("ToolDownloadSpeed", 42, Source:=Sources.Registry, OnChanged:=AddressOf ModNet.UpdateNetTaskSpeedLimitHigh),
  115. New Setting("ToolDownloadSource", 1, Source:=Sources.Registry),
  116. New Setting("ToolDownloadVersion", 1, Source:=Sources.Registry),
  117. New Setting("ToolDownloadTranslate", 0, Source:=Sources.Registry),
  118. New Setting("ToolDownloadTranslateV2", 1, Source:=Sources.Registry),
  119. New Setting("ToolDownloadIgnoreQuilt", True, Source:=Sources.Registry),
  120. New Setting("ToolDownloadCert", False, Source:=Sources.Registry, OnChanged:=AddressOf ModNet.ShouldValidateSslCertificateOnLogin),
  121. New Setting("ToolDownloadMod", 2, Source:=Sources.Registry),
  122. New Setting("ToolModLocalNameStyle", 0, Source:=Sources.Registry),
  123. New Setting("ToolUpdateRelease", False, Source:=Sources.Registry),
  124. New Setting("ToolUpdateSnapshot", False, Source:=Sources.Registry),
  125. New Setting("ToolUpdateReleaseLast", "", Source:=Sources.Registry),
  126. New Setting("ToolUpdateSnapshotLast", "", Source:=Sources.Registry),
  127. New Setting("UiLauncherTransparent", 600, OnChanged:=Sub(Value As Integer) If FrmMain IsNot Nothing Then FrmMain.Opacity = Value / 1000 + 0.4), '避免与 PCL1 设置冲突(UiLauncherOpacity)
  128. New Setting("UiLauncherHue", 180),
  129. New Setting("UiLauncherSat", 80),
  130. New Setting("UiLauncherDelta", 90),
  131. New Setting("UiLauncherLight", 20),
  132. New Setting("UiLauncherTheme", 0, OnChanged:=AddressOf ThemeRefresh),
  133. New Setting("UiLauncherThemeHide", "0|1|2|3|4", Source:=Sources.Registry, Encrypted:=True),
  134. New Setting("UiLauncherThemeHide2", "0|1|2|3|4", Source:=Sources.Registry, Encrypted:=True),
  135. New Setting("UiLauncherLogo", True),
  136. New Setting("UiLauncherEmail", False),
  137. New Setting("UiBackgroundColorful", True, OnChanged:=Sub() ThemeRefresh()), '不传入参数
  138. New Setting("UiBackgroundOpacity", 1000, OnChanged:=AddressOf FormMain.UpdateBackgroundAndTitleBar),
  139. New Setting("UiBackgroundBlur", 0, OnChanged:=AddressOf FormMain.UpdateBackgroundAndTitleBar),
  140. New Setting("UiBackgroundSuit", 0, OnChanged:=AddressOf FormMain.UpdateBackgroundAndTitleBar),
  141. New Setting("UiCustomType", 0, OnChanged:=AddressOf PageSetupUI.OnMainPageTypeChanged),
  142. New Setting("UiCustomPreset", 0),
  143. New Setting("UiCustomNet", ""),
  144. New Setting("UiLogoType", 1, OnChanged:=AddressOf FormMain.UpdateBackgroundAndTitleBar),
  145. New Setting("UiLogoText", "", OnChanged:=AddressOf FormMain.UpdateBackgroundAndTitleBar),
  146. New Setting("UiLogoLeft", False, OnChanged:=AddressOf FormMain.UpdateBackgroundAndTitleBar),
  147. New Setting("UiMusicVolume", 500),
  148. New Setting("UiMusicStop", False),
  149. New Setting("UiMusicStart", False),
  150. New Setting("UiMusicRandom", True),
  151. New Setting("UiMusicAuto", True),
  152. New Setting("UiHiddenPageDownload", False, OnChanged:=AddressOf PageSetupUI.HiddenRefresh),
  153. New Setting("UiHiddenPageLink", False, OnChanged:=AddressOf PageSetupUI.HiddenRefresh),
  154. New Setting("UiHiddenPageSetup", False, OnChanged:=AddressOf PageSetupUI.HiddenRefresh),
  155. New Setting("UiHiddenPageOther", False, OnChanged:=AddressOf PageSetupUI.HiddenRefresh),
  156. New Setting("UiHiddenFunctionSelect", False, OnChanged:=AddressOf PageSetupUI.HiddenRefresh),
  157. New Setting("UiHiddenFunctionModUpdate", False, OnChanged:=AddressOf PageSetupUI.HiddenRefresh),
  158. New Setting("UiHiddenFunctionHidden", False, OnChanged:=AddressOf PageSetupUI.HiddenRefresh),
  159. New Setting("UiHiddenSetupLaunch", False, OnChanged:=AddressOf PageSetupUI.HiddenRefresh),
  160. New Setting("UiHiddenSetupUi", False, OnChanged:=AddressOf PageSetupUI.HiddenRefresh),
  161. New Setting("UiHiddenSetupLink", False, OnChanged:=AddressOf PageSetupUI.HiddenRefresh),
  162. New Setting("UiHiddenSetupSystem", False, OnChanged:=AddressOf PageSetupUI.HiddenRefresh),
  163. New Setting("UiHiddenOtherHelp", False, OnChanged:=AddressOf PageSetupUI.HiddenRefresh),
  164. New Setting("UiHiddenOtherFeedback", False, OnChanged:=AddressOf PageSetupUI.HiddenRefresh),
  165. New Setting("UiHiddenOtherVote", False, OnChanged:=AddressOf PageSetupUI.HiddenRefresh),
  166. New Setting("UiHiddenOtherAbout", False, OnChanged:=AddressOf PageSetupUI.HiddenRefresh),
  167. New Setting("UiHiddenOtherTest", False, OnChanged:=AddressOf PageSetupUI.HiddenRefresh),
  168. New Setting("VersionAdvanceJvm", "", Source:=Sources.Instance),
  169. New Setting("VersionAdvanceGame", "", Source:=Sources.Instance),
  170. New Setting("VersionAdvanceAssets", 0, Source:=Sources.Instance),
  171. New Setting("VersionAdvanceAssetsV2", False, Source:=Sources.Instance),
  172. New Setting("VersionAdvanceJava", False, Source:=Sources.Instance),
  173. New Setting("VersionAdvanceRun", "", Source:=Sources.Instance),
  174. New Setting("VersionAdvanceRunWait", True, Source:=Sources.Instance),
  175. New Setting("VersionAdvanceDisableJLW", False, Source:=Sources.Instance),
  176. New Setting("VersionAdvanceDisableLUA", False, Source:=Sources.Instance),
  177. New Setting("VersionAdvanceDisableModUpdate", False, Source:=Sources.Instance),
  178. New Setting("VersionAdvanceGC", 0, Source:=Sources.Instance),
  179. New Setting("VersionRamType", 2, Source:=Sources.Instance, OnChanged:=AddressOf PageInstanceSetup.OnVersionRamTypeChanged),
  180. New Setting("VersionRamCustom", 15, Source:=Sources.Instance),
  181. New Setting("VersionRamOptimize", 0, Source:=Sources.Instance),
  182. New Setting("VersionArgumentTitle", "", Source:=Sources.Instance),
  183. New Setting("VersionArgumentInfo", "", Source:=Sources.Instance),
  184. New Setting("VersionArgumentIndie", -1, Source:=Sources.Instance),
  185. New Setting("VersionArgumentIndieV2", False, Source:=Sources.Instance),
  186. New Setting("VersionArgumentJavaSelect", "使用全局设置", Source:=Sources.Instance),
  187. New Setting("VersionServerEnter", "", Source:=Sources.Instance),
  188. New Setting("VersionServerLogin", 0, Source:=Sources.Instance, OnChanged:=AddressOf PageInstanceSetup.OnVersionServerLoginChanged),
  189. New Setting("VersionServerNide", "", Source:=Sources.Instance),
  190. New Setting("VersionServerAuthRegister", "", Source:=Sources.Instance),
  191. New Setting("VersionServerAuthName", "", Source:=Sources.Instance),
  192. New Setting("VersionServerAuthServer", "", Source:=Sources.Instance)
  193. }).ToDictionary(Function(e) e.Key)
  194. Private Enum Sources
  195. Normal
  196. Registry
  197. Instance
  198. End Enum
  199. Private Class Setting
  200. Public Key As String
  201. Public Encrypted As Boolean
  202. Public DefaultValue As Object
  203. Public Source As Sources
  204. ''' <summary>
  205. ''' 当设置项的值实际被改变时触发,参数为新值。
  206. ''' </summary>
  207. Public OnChanged As Action(Of Object)
  208. ''' <summary>
  209. ''' 该设置的值的实际类型。
  210. ''' </summary>
  211. Public Type As Type
  212. Public Sub New(Key As String, Value As Object, Optional Source As Sources = Sources.Normal, Optional Encrypted As Boolean = False, Optional OnChanged As Action(Of Object) = Nothing)
  213. Try
  214. Me.Key = Key
  215. Me.DefaultValue = Value
  216. Me.Encrypted = Encrypted
  217. Me.Source = Source
  218. Me.Type = If(Value, "").GetType
  219. Me.OnChanged = OnChanged
  220. Catch ex As Exception
  221. Log(ex, "初始化设置项失败", NotifyLevel.MsgBoxAndFeedback) '#5095 的 fallback
  222. End Try
  223. End Sub
  224. ''' <summary>
  225. ''' 读取过的设置的缓存,若从未读取过则为 Nothing。
  226. ''' 若为版本独立设置,键为版本路径;否则,键为空字符串。
  227. ''' </summary>
  228. Private ValueCache As New Dictionary(Of String, Object)
  229. Public Function GetCache(Instance As McInstance)
  230. Dim Key As String = If(Source = Sources.Instance, Instance.PathVersion, "")
  231. Return If(ValueCache.ContainsKey(Key), ValueCache(Key), Nothing)
  232. End Function
  233. Public Sub [Set](Value As Object, Instance As McInstance)
  234. Dim Key As String = If(Source = Sources.Instance, Instance.PathVersion, "")
  235. ValueCache(Key) = Value
  236. End Sub
  237. ''' <summary>
  238. ''' 立即将当前的 Value 写入对应的注册表或文件。
  239. ''' </summary>
  240. Public Sub Save(Optional Instance As McInstance = Nothing)
  241. Dim Value As String = GetCache(Instance)
  242. If Encrypted Then
  243. Try
  244. If Value Is Nothing Then Value = ""
  245. Value = SecretEncrypt(Value, "PCL" & Identify)
  246. Catch ex As Exception
  247. Log(ex, "加密设置失败:" & Key, NotifyLevel.DevelopOnly)
  248. End Try
  249. End If
  250. Select Case Source
  251. Case Sources.Normal
  252. WriteIni("Setup", Key, Value)
  253. Case Sources.Registry
  254. WriteReg(Key, Value)
  255. Case Sources.Instance
  256. If Instance Is Nothing Then Throw New Exception($"保存版本独立设置 {Key} 时未提供目标版本")
  257. WriteIni(Instance.PathVersion & "PCL\Setup.ini", Key, Value)
  258. End Select
  259. End Sub
  260. End Class
  261. ''' <summary>
  262. ''' 改变某个设置项的值。
  263. ''' </summary>
  264. Public Shared Sub [Set](Key As String, Value As Object, Optional Instance As McInstance = Nothing)
  265. Dim Entry As Setting = Nothing
  266. If Not Entries.TryGetValue(Key, Entry) Then Throw New KeyNotFoundException("未找到设置项:" & Key)
  267. Try
  268. '判断是否一致
  269. Value = CTypeDynamic(Value, Entry.Type)
  270. If Entry.GetCache(Instance) Is Nothing Then [Get](Key, Instance)
  271. If Entry.GetCache(Instance) = Value Then Return
  272. '设置新值
  273. Entry.Set(Value, Instance)
  274. Entry.Save(Instance)
  275. '触发改变事件(必须在保存之后,以保证 VersionServerLogin 之类的在事件中读取到的是最新的值)
  276. If Entry.OnChanged IsNot Nothing Then Entry.OnChanged.Invoke(Value)
  277. Catch ex As Exception
  278. Log(ex, "设置设置项时出错(" & Key & ", " & Value & ")", NotifyLevel.MsgBoxAndFeedback)
  279. End Try
  280. End Sub
  281. ''' <summary>
  282. ''' 写入某个未经加密的设置项。
  283. ''' 若该设置项经过了加密,则会抛出异常。
  284. ''' </summary>
  285. Public Shared Sub SetSafe(Key As String, Value As Object, Optional Instance As McInstance = Nothing)
  286. Dim Entry As Setting = Nothing
  287. If Not Entries.TryGetValue(Key, Entry) Then Throw New KeyNotFoundException("未找到设置项:" & Key)
  288. If Entry.Encrypted Then Throw New InvalidOperationException("禁止写入加密设置项:" & Key)
  289. [Set](Key, Value, Instance)
  290. End Sub
  291. ''' <summary>
  292. ''' 获取某个设置项的值。
  293. ''' </summary>
  294. Public Shared Function [Get](Key As String, Optional Instance As McInstance = Nothing)
  295. Dim Entry As Setting = Nothing
  296. If Not Entries.TryGetValue(Key, Entry) Then Throw New KeyNotFoundException("未找到设置项:" & Key)
  297. Dim Value = Entry.GetCache(Instance)
  298. If Value IsNot Nothing Then Return Value
  299. '对部分设置强制赋值
  300. Static ForcedSettings As New Dictionary(Of String, Object) From {
  301. {"UiHiddenPageLink", True},
  302. {"UiHiddenSetupLink", True}
  303. }
  304. Dim ForcedSetting As Object = Nothing
  305. If ForcedSettings.TryGetValue(Key, ForcedSetting) Then
  306. Entry.Set(ForcedSetting, Instance)
  307. Return ForcedSetting
  308. End If
  309. '正常读取
  310. Try
  311. Dim GotValue As String = Nothing '先用 String 储存,避免类型转换
  312. Dim DefaultValue As String = If(Entry.Encrypted, SecretEncrypt(Entry.DefaultValue, "PCL" & Identify), Entry.DefaultValue)
  313. Select Case Entry.Source
  314. Case Sources.Normal
  315. GotValue = ReadIni("Setup", Key, DefaultValue)
  316. Case Sources.Registry
  317. GotValue = ReadReg(Key, DefaultValue)
  318. Case Sources.Instance
  319. If Instance Is Nothing Then
  320. Throw New Exception($"读取版本设置 {Key} 时未提供目标版本")
  321. Else
  322. GotValue = ReadIni(Instance.PathVersion & "PCL\Setup.ini", Key, DefaultValue)
  323. End If
  324. End Select
  325. If Entry.Encrypted Then
  326. If GotValue = DefaultValue Then
  327. GotValue = Entry.DefaultValue
  328. Else
  329. Try
  330. GotValue = SecretDecrypt(GotValue, "PCL" & Identify)
  331. Catch ex As Exception
  332. Log(ex, "解密设置失败:" & Key, NotifyLevel.DevelopOnly)
  333. GotValue = Entry.DefaultValue
  334. Entry.Set(Entry.DefaultValue, Instance)
  335. Entry.Save(Instance)
  336. End Try
  337. End If
  338. End If
  339. Entry.Set(CTypeDynamic(GotValue, Entry.Type), Instance)
  340. Catch ex As Exception
  341. Log(ex, "读取设置失败:" & Key, NotifyLevel.AllUsers)
  342. Entry.Set(CTypeDynamic(Entry.DefaultValue, Entry.Type), Instance)
  343. End Try
  344. Return Entry.GetCache(Instance)
  345. End Function
  346. ''' <summary>
  347. ''' 获取某个未经加密的设置项的值。
  348. ''' 若该设置项经过了加密,则会抛出异常。
  349. ''' </summary>
  350. Public Shared Function GetSafe(Key As String, Optional Instance As McInstance = Nothing)
  351. Dim Entry As Setting = Nothing
  352. If Not Entries.TryGetValue(Key, Entry) Then Throw New KeyNotFoundException("未找到设置项:" & Key)
  353. If Entry.Encrypted Then Throw New InvalidOperationException("禁止读取加密设置项:" & Key)
  354. Return [Get](Key, Instance)
  355. End Function
  356. ''' <summary>
  357. ''' 初始化某个设置项的值。
  358. ''' </summary>
  359. Public Shared Sub Reset(Key As String, Optional Instance As McInstance = Nothing)
  360. Dim Entry As Setting = Nothing
  361. If Not Entries.TryGetValue(Key, Entry) Then Throw New KeyNotFoundException("未找到设置项:" & Key)
  362. Try
  363. '判断是否一致
  364. If Entry.GetCache(Instance) Is Nothing Then [Get](Key, Instance)
  365. If Entry.GetCache(Instance) = Entry.DefaultValue Then Return
  366. '设置新值
  367. Entry.Set(Entry.DefaultValue, Instance)
  368. Select Case Entry.Source
  369. Case Sources.Normal
  370. DeleteIniKey("Setup", Key)
  371. Case Sources.Registry
  372. DeleteReg(Key)
  373. Case Sources.Instance
  374. If Instance Is Nothing Then Throw New Exception($"重置版本设置 {Key} 时未提供目标版本")
  375. DeleteIniKey(Instance.PathVersion & "PCL\Setup.ini", Key)
  376. End Select
  377. '触发改变事件
  378. If Entry.OnChanged IsNot Nothing Then Entry.OnChanged.Invoke(Entry.DefaultValue)
  379. Catch ex As Exception
  380. Log(ex, "重置设置项时出错(" & Key & ")", NotifyLevel.MsgBoxAndFeedback)
  381. End Try
  382. End Sub
  383. ''' <summary>
  384. ''' 获取某个设置项的默认值。
  385. ''' </summary>
  386. Public Shared Function GetDefault(Key As String) As String
  387. Return Entries(Key).DefaultValue
  388. End Function
  389. ''' <summary>
  390. ''' 对应的注册表或文件是否已经储存了某个设置项。
  391. ''' 若改成了和默认值一样的,在 2.12.3- 会储存更改,在 2.12.4+ 不会储存更改。
  392. ''' </summary>
  393. Public Shared Function HasSaved(Key As String, Optional Instance As McInstance = Nothing) As Boolean
  394. Select Case Entries(Key).Source
  395. Case Sources.Normal
  396. Return HasIniKey("Setup", Key)
  397. Case Sources.Registry
  398. Return HasReg(Key)
  399. Case Else 'Source.Instance
  400. If Instance Is Nothing Then Throw New Exception($"判断版本设置 {Key} 是否存在时未提供目标版本")
  401. Return HasIniKey(Instance.PathVersion & "PCL\Setup.ini", Key)
  402. End Select
  403. End Function
  404. End Class