Settings.vb 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411
  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("HintDownloadThread", False, Source:=Sources.Registry),
  8. New Setting("HintNotice", 0, Source:=Sources.Registry),
  9. New Setting("HintDownload", 0, Source:=Sources.Registry),
  10. New Setting("HintHide", False, Source:=Sources.Registry),
  11. New Setting("HintHandInstall", False, Source:=Sources.Registry),
  12. New Setting("HintBuy", False, Source:=Sources.Registry),
  13. New Setting("HintClearRubbish", 0, Source:=Sources.Registry),
  14. New Setting("HintUpdateMod", False, Source:=Sources.Registry),
  15. New Setting("HintCustomCommand", False, Source:=Sources.Registry),
  16. New Setting("HintCustomWarn", False, Source:=Sources.Registry),
  17. New Setting("HintMoreAdvancedSetup", False, Source:=Sources.Registry),
  18. New Setting("HintIndieSetup", False, Source:=Sources.Registry),
  19. New Setting("HintExportConfig", False, Source:=Sources.Registry),
  20. New Setting("SystemEulaVersion", 0, Source:=Sources.Registry),
  21. New Setting("SystemCount", 0, Source:=Sources.Registry, Encrypted:=True),
  22. New Setting("SystemLaunchCount", 0, Source:=Sources.Registry, Encrypted:=True),
  23. New Setting("SystemLastVersionReg", 0, Source:=Sources.Registry, Encrypted:=True),
  24. New Setting("SystemHighestSavedBetaVersionReg", 0, Source:=Sources.Registry, Encrypted:=True),
  25. New Setting("SystemHighestBetaVersionReg", 0, Source:=Sources.Registry, Encrypted:=True),
  26. New Setting("SystemHighestAlphaVersionReg", 0, Source:=Sources.Registry, Encrypted:=True),
  27. New Setting("SystemHelpVersion", 0, Source:=Sources.Registry),
  28. New Setting("SystemDebugMode", False, Source:=Sources.Registry),
  29. New Setting("SystemDebugAnim", 9, Source:=Sources.Registry),
  30. New Setting("SystemDebugDelay", False, Source:=Sources.Registry),
  31. New Setting("SystemDebugSkipCopy", False, Source:=Sources.Registry),
  32. New Setting("SystemSystemCache", "", Source:=Sources.Registry),
  33. New Setting("SystemSystemUpdate", 0),
  34. New Setting("SystemSystemActivity", 0),
  35. New Setting("SystemSystemTelemetry", True, Source:=Sources.Registry),
  36. New Setting("CacheDrops", "", Source:=Sources.Registry),
  37. New Setting("CacheConfig", 0, Source:=Sources.Registry),
  38. New Setting("CacheExportConfig", "", Source:=Sources.Registry),
  39. New Setting("CacheSavedPageUrl", "", Source:=Sources.Registry),
  40. New Setting("CacheSavedPageVersion", "", Source:=Sources.Registry),
  41. New Setting("CacheMsOAuthRefresh", "", Source:=Sources.Registry, Encrypted:=True),
  42. New Setting("CacheMsAccess", "", Source:=Sources.Registry, Encrypted:=True),
  43. New Setting("CacheMsProfileJson", "", Source:=Sources.Registry, Encrypted:=True),
  44. New Setting("CacheMsUuid", "", Source:=Sources.Registry, Encrypted:=True),
  45. New Setting("CacheMsName", "", Source:=Sources.Registry, Encrypted:=True),
  46. New Setting("CacheMsV2Migrated", False, Source:=Sources.Registry),
  47. New Setting("CacheMsV2OAuthRefresh", "", Source:=Sources.Registry, Encrypted:=True),
  48. New Setting("CacheMsV2OAuthExpires", 0, Source:=Sources.Registry),
  49. New Setting("CacheMsV2Access", "", Source:=Sources.Registry, Encrypted:=True),
  50. New Setting("CacheMsV2ProfileJson", "", Source:=Sources.Registry, Encrypted:=True),
  51. New Setting("CacheMsV2Uuid", "", Source:=Sources.Registry, Encrypted:=True),
  52. New Setting("CacheMsV2Name", "", Source:=Sources.Registry, Encrypted:=True),
  53. New Setting("CacheNideAccess", "", Source:=Sources.Registry, Encrypted:=True),
  54. New Setting("CacheNideClient", "", Source:=Sources.Registry, Encrypted:=True),
  55. New Setting("CacheNideUuid", "", Source:=Sources.Registry, Encrypted:=True),
  56. New Setting("CacheNideName", "", Source:=Sources.Registry, Encrypted:=True),
  57. New Setting("CacheNideUsername", "", Source:=Sources.Registry, Encrypted:=True),
  58. New Setting("CacheNidePass", "", Source:=Sources.Registry, Encrypted:=True),
  59. New Setting("CacheNideServer", "", Source:=Sources.Registry, Encrypted:=True),
  60. New Setting("CacheAuthAccess", "", Source:=Sources.Registry, Encrypted:=True),
  61. New Setting("CacheAuthClient", "", Source:=Sources.Registry, Encrypted:=True),
  62. New Setting("CacheAuthUuid", "", Source:=Sources.Registry, Encrypted:=True),
  63. New Setting("CacheAuthName", "", Source:=Sources.Registry, Encrypted:=True),
  64. New Setting("CacheAuthUsername", "", Source:=Sources.Registry, Encrypted:=True),
  65. New Setting("CacheAuthPass", "", Source:=Sources.Registry, Encrypted:=True),
  66. New Setting("CacheAuthServerServer", "", Source:=Sources.Registry, Encrypted:=True),
  67. New Setting("CacheAuthServerName", "", Source:=Sources.Registry, Encrypted:=True),
  68. New Setting("CacheAuthServerRegister", "", Source:=Sources.Registry, Encrypted:=True),
  69. New Setting("CacheDownloadFolder", "", Source:=Sources.Registry),
  70. New Setting("CacheJavaListVersion", 0, Source:=Sources.Registry),
  71. New Setting("LoginRemember", True, Source:=Sources.Registry, Encrypted:=True),
  72. New Setting("LoginLegacyName", "", Source:=Sources.Registry, Encrypted:=True),
  73. New Setting("LoginMsJson", "{}", Source:=Sources.Registry, Encrypted:=True), '{UserName: OAuthToken, ...}
  74. New Setting("LoginNideEmail", "", Source:=Sources.Registry, Encrypted:=True),
  75. New Setting("LoginNidePass", "", Source:=Sources.Registry, Encrypted:=True),
  76. New Setting("LoginAuthEmail", "", Source:=Sources.Registry, Encrypted:=True),
  77. New Setting("LoginAuthPass", "", Source:=Sources.Registry, Encrypted:=True),
  78. New Setting("LoginType", McLoginType.Legacy, Source:=Sources.Registry),
  79. New Setting("LoginPageType", 0),
  80. New Setting("LaunchSkinID", "", Source:=Sources.Registry, OnChanged:=Sub() PageLaunchLeft.SkinLegacy.Start()),
  81. New Setting("LaunchSkinType", 0, Source:=Sources.Registry, OnChanged:=AddressOf PageSetupLaunch.UpdateSkinType),
  82. New Setting("LaunchSkinSlim", False, Source:=Sources.Registry),
  83. New Setting("LaunchFolderSelect", ""),
  84. New Setting("LaunchFolders", "", Source:=Sources.Registry),
  85. New Setting("LaunchArgumentTitle", ""),
  86. New Setting("LaunchArgumentInfo", "PCL"),
  87. New Setting("LaunchArgumentJavaSelect", "", Source:=Sources.Registry),
  88. New Setting("LaunchArgumentJavaAll", "[]", Source:=Sources.Registry),
  89. New Setting("LaunchArgumentIndie", 0),
  90. New Setting("LaunchArgumentIndieV2", 4),
  91. New Setting("LaunchArgumentVisible", 5, Source:=Sources.Registry),
  92. New Setting("LaunchArgumentPriority", 1, Source:=Sources.Registry),
  93. New Setting("LaunchArgumentWindowWidth", 854),
  94. New Setting("LaunchArgumentWindowHeight", 480),
  95. New Setting("LaunchArgumentWindowType", 1),
  96. New Setting("LaunchArgumentRam", False, Source:=Sources.Registry),
  97. New Setting("LaunchAdvanceJvm", "-XX:-OmitStackTraceInFastThrow -Djdk.lang.Process.allowAmbiguousCommands=True -Dfml.ignoreInvalidMinecraftCertificates=True -Dfml.ignorePatchDiscrepancies=True"),
  98. New Setting("LaunchAdvanceGame", ""),
  99. New Setting("LaunchAdvanceRun", ""),
  100. New Setting("LaunchAdvanceRunWait", True),
  101. New Setting("LaunchAdvanceDisableJLW", False),
  102. New Setting("LaunchAdvanceDisableLUA", False),
  103. New Setting("LaunchAdvanceGraphicCard", True, Source:=Sources.Registry),
  104. New Setting("LaunchAdvanceGC", 4),
  105. New Setting("LaunchRamType", 0, OnChanged:=AddressOf PageSetupLaunch.UpdateRamType),
  106. New Setting("LaunchRamCustom", 15),
  107. New Setting("LinkLastAutoJoinInviteCode", "", Source:=Sources.Registry),
  108. New Setting("LinkLatencyMode", 0, Source:=Sources.Registry),
  109. New Setting("LinkCustomPeer", ""),
  110. New Setting("LinkEasyTierVersion", -1, Source:=Sources.Registry),
  111. New Setting("ToolHelpChinese", True, Source:=Sources.Registry),
  112. New Setting("ToolDownloadThread", 63, Source:=Sources.Registry),
  113. New Setting("ToolDownloadSpeed", 42, Source:=Sources.Registry, OnChanged:=AddressOf ModNet.UpdateNetTaskSpeedLimitHigh),
  114. New Setting("ToolDownloadSource", 1, Source:=Sources.Registry),
  115. New Setting("ToolDownloadVersion", 1, Source:=Sources.Registry),
  116. New Setting("ToolDownloadTranslate", 0, Source:=Sources.Registry),
  117. New Setting("ToolDownloadTranslateV2", 1, Source:=Sources.Registry),
  118. New Setting("ToolDownloadIgnoreQuilt", True, Source:=Sources.Registry),
  119. New Setting("ToolDownloadCert", False, Source:=Sources.Registry, OnChanged:=AddressOf ModNet.ShouldValidateSslCertificateOnLogin),
  120. New Setting("ToolDownloadMod", 2, Source:=Sources.Registry),
  121. New Setting("ToolModLocalNameStyle", 0, Source:=Sources.Registry),
  122. New Setting("ToolUpdateRelease", False, Source:=Sources.Registry),
  123. New Setting("ToolUpdateSnapshot", False, Source:=Sources.Registry),
  124. New Setting("ToolUpdateReleaseLast", "", Source:=Sources.Registry),
  125. New Setting("ToolUpdateSnapshotLast", "", Source:=Sources.Registry),
  126. New Setting("UiLauncherTransparent", 600, OnChanged:=Sub(Value As Integer) If FrmMain IsNot Nothing Then FrmMain.Opacity = Value / 1000 + 0.4), '避免与 PCL1 设置冲突(UiLauncherOpacity)
  127. New Setting("UiLauncherHue", 180),
  128. New Setting("UiLauncherSat", 80),
  129. New Setting("UiLauncherDelta", 90),
  130. New Setting("UiLauncherLight", 20),
  131. New Setting("UiLauncherTheme", 0, OnChanged:=AddressOf ThemeRefresh),
  132. New Setting("UiLauncherThemeGold", "", Source:=Sources.Registry, Encrypted:=True),
  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.OnUiCustomTypeChanged),
  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. ''' <summary>
  202. ''' 若已调用过 Get 方法,则为当前值;否则为 Nothing。
  203. ''' </summary>
  204. Public Value = Nothing
  205. Public Encrypted As Boolean
  206. Public DefaultValue
  207. Public Source As Sources
  208. ''' <summary>
  209. ''' 当设置项的值实际被改变时触发,参数为新值。
  210. ''' </summary>
  211. Public OnChanged As Action(Of Object)
  212. ''' <summary>
  213. ''' 该设置的值的实际类型。
  214. ''' </summary>
  215. Public Type As Type
  216. 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)
  217. Try
  218. Me.Key = Key
  219. Me.DefaultValue = Value
  220. Me.Encrypted = Encrypted
  221. Me.Source = Source
  222. Me.Type = If(Value, "").GetType
  223. Me.OnChanged = OnChanged
  224. Catch ex As Exception
  225. Log(ex, "初始化设置项失败", LogLevel.Feedback) '#5095 的 fallback
  226. End Try
  227. End Sub
  228. ''' <summary>
  229. ''' 立即将当前的 Value 写入对应的注册表或文件。
  230. ''' </summary>
  231. Public Sub Save(Optional Instance As McInstance = Nothing)
  232. Dim Value As String = Me.Value
  233. If Encrypted Then
  234. Try
  235. If Value Is Nothing Then Value = ""
  236. Value = SecretEncrypt(Value, "PCL" & Identify)
  237. Catch ex As Exception
  238. Log(ex, "加密设置失败:" & Key, LogLevel.Developer)
  239. End Try
  240. End If
  241. Select Case Source
  242. Case Sources.Normal
  243. WriteIni("Setup", Key, Value)
  244. Case Sources.Registry
  245. WriteReg(Key, Value)
  246. Case Sources.Instance
  247. If Instance Is Nothing Then Throw New Exception($"保存版本独立设置 {Key} 时未提供目标版本")
  248. WriteIni(Instance.PathVersion & "PCL\Setup.ini", Key, Value)
  249. End Select
  250. End Sub
  251. End Class
  252. ''' <summary>
  253. ''' 改变某个设置项的值。
  254. ''' </summary>
  255. Public Shared Sub [Set](Key As String, Value As Object, Optional Instance As McInstance = Nothing)
  256. Dim Entry As Setting = Nothing
  257. If Not Entries.TryGetValue(Key, Entry) Then Throw New KeyNotFoundException("未找到设置项:" & Key)
  258. Try
  259. '判断是否一致
  260. If Entry.Value Is Nothing Then [Get](Key, Instance)
  261. Value = CTypeDynamic(Value, Entry.Type)
  262. If Entry.Value = Value Then Return
  263. '设置新值
  264. Entry.Value = Value
  265. Entry.Save(Instance)
  266. '触发改变事件(必须在保存之后,以保证 VersionServerLogin 之类的在事件中读取到的是最新的值)
  267. If Entry.OnChanged IsNot Nothing Then Entry.OnChanged.Invoke(Entry.Value)
  268. Catch ex As Exception
  269. Log(ex, "设置设置项时出错(" & Key & ", " & Value & ")", LogLevel.Feedback)
  270. End Try
  271. End Sub
  272. ''' <summary>
  273. ''' 写入某个未经加密的设置项。
  274. ''' 若该设置项经过了加密,则会抛出异常。
  275. ''' </summary>
  276. Public Shared Sub SetSafe(Key As String, Value As Object, Optional Instance As McInstance = Nothing)
  277. Dim Entry As Setting = Nothing
  278. If Not Entries.TryGetValue(Key, Entry) Then Throw New KeyNotFoundException("未找到设置项:" & Key)
  279. If Entry.Encrypted Then Throw New InvalidOperationException("禁止写入加密设置项:" & Key)
  280. [Set](Key, Instance, Instance)
  281. End Sub
  282. ''' <summary>
  283. ''' 获取某个设置项的值。
  284. ''' </summary>
  285. Public Shared Function [Get](Key As String, 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.Value IsNot Nothing Then Return Entry.Value
  289. '对部分设置强制赋值
  290. Static ForcedSettings As New Dictionary(Of String, Object) From {
  291. {"UiHiddenPageLink", True},
  292. {"UiHiddenSetupLink", True}
  293. }
  294. Dim ForcedSetting As Object = Nothing
  295. If ForcedSettings.TryGetValue(Key, ForcedSetting) Then
  296. Entry.Value = ForcedSetting
  297. Return Entry.Value
  298. End If
  299. '正常读取
  300. Try
  301. Dim GotValue As String = Nothing '先用 String 储存,避免类型转换
  302. Dim DefaultValue As String = If(Entry.Encrypted, SecretEncrypt(Entry.DefaultValue, "PCL" & Identify), Entry.DefaultValue)
  303. Select Case Entry.Source
  304. Case Sources.Normal
  305. GotValue = ReadIni("Setup", Key, DefaultValue)
  306. Case Sources.Registry
  307. GotValue = ReadReg(Key, DefaultValue)
  308. Case Sources.Instance
  309. If Instance Is Nothing Then
  310. Throw New Exception($"读取版本设置 {Key} 时未提供目标版本")
  311. Else
  312. GotValue = ReadIni(Instance.PathVersion & "PCL\Setup.ini", Key, DefaultValue)
  313. End If
  314. End Select
  315. If Entry.Encrypted Then
  316. If GotValue = DefaultValue Then
  317. GotValue = Entry.DefaultValue
  318. Else
  319. Try
  320. GotValue = SecretDecrypt(GotValue, "PCL" & Identify)
  321. Catch ex As Exception
  322. Log(ex, "解密设置失败:" & Key, LogLevel.Developer)
  323. GotValue = Entry.DefaultValue
  324. Entry.Value = Entry.DefaultValue
  325. Entry.Save(Instance)
  326. End Try
  327. End If
  328. End If
  329. Entry.Value = CTypeDynamic(GotValue, Entry.Type)
  330. Catch ex As Exception
  331. Log(ex, "读取设置失败:" & Key, LogLevel.Hint)
  332. Entry.Value = CTypeDynamic(Entry.DefaultValue, Entry.Type)
  333. End Try
  334. Return Entry.Value
  335. End Function
  336. ''' <summary>
  337. ''' 获取某个未经加密的设置项的值。
  338. ''' 若该设置项经过了加密,则会抛出异常。
  339. ''' </summary>
  340. Public Shared Function GetSafe(Key As String, Optional Instance As McInstance = Nothing)
  341. Dim Entry As Setting = Nothing
  342. If Not Entries.TryGetValue(Key, Entry) Then Throw New KeyNotFoundException("未找到设置项:" & Key)
  343. If Entry.Encrypted Then Throw New InvalidOperationException("禁止读取加密设置项:" & Key)
  344. Return [Get](Key, Instance)
  345. End Function
  346. ''' <summary>
  347. ''' 初始化某个设置项的值。
  348. ''' </summary>
  349. Public Shared Sub Reset(Key As String, Optional Instance As McInstance = Nothing)
  350. Dim Entry As Setting = Nothing
  351. If Not Entries.TryGetValue(Key, Entry) Then Throw New KeyNotFoundException("未找到设置项:" & Key)
  352. Try
  353. '判断是否一致
  354. If Entry.Value Is Nothing Then [Get](Key, Instance)
  355. If Entry.Value = Entry.DefaultValue Then Return
  356. '设置新值
  357. Entry.Value = Entry.DefaultValue
  358. Select Case Entry.Source
  359. Case Sources.Normal
  360. DeleteIniKey("Setup", Key)
  361. Case Sources.Registry
  362. DeleteReg(Key)
  363. Case Sources.Instance
  364. If Instance Is Nothing Then Throw New Exception($"重置版本设置 {Key} 时未提供目标版本")
  365. DeleteIniKey(Instance.PathVersion & "PCL\Setup.ini", Key)
  366. End Select
  367. '触发改变事件
  368. If Entry.OnChanged IsNot Nothing Then Entry.OnChanged.Invoke(Entry.Value)
  369. Catch ex As Exception
  370. Log(ex, "重置设置项时出错(" & Key & ")", LogLevel.Feedback)
  371. End Try
  372. End Sub
  373. ''' <summary>
  374. ''' 获取某个设置项的默认值。
  375. ''' </summary>
  376. Public Shared Function GetDefault(Key As String) As String
  377. Return Entries(Key).DefaultValue
  378. End Function
  379. ''' <summary>
  380. ''' 对应的注册表或文件是否已经储存了某个设置项。
  381. ''' 若改成了和默认值一样的,在 2.12.3- 会储存更改,在 2.12.4+ 不会储存更改。
  382. ''' </summary>
  383. Public Shared Function HasSaved(Key As String, Optional Instance As McInstance = Nothing) As Boolean
  384. Select Case Entries(Key).Source
  385. Case Sources.Normal
  386. Return HasIniKey("Setup", Key)
  387. Case Sources.Registry
  388. Return HasReg(Key)
  389. Case Else 'Source.Instance
  390. If Instance Is Nothing Then Throw New Exception($"判断版本设置 {Key} 是否存在时未提供目标版本")
  391. Return HasIniKey(Instance.PathVersion & "PCL\Setup.ini", Key)
  392. End Select
  393. End Function
  394. ''' <summary>
  395. ''' 当前版本改变时,要求所有版本独立设置需要重新读取。
  396. ''' </summary>
  397. Public Shared Sub MakeInstanceDirty()
  398. For Each Entry In Entries.Values
  399. If Entry.Source = Sources.Instance Then Entry.Value = Nothing
  400. Next
  401. End Sub
  402. End Class