Settings.vb 24 KB

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