ModSetup.vb 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772
  1. Public Class ModSetup
  2. ''' <summary>
  3. ''' 设置的更新号。
  4. ''' </summary>
  5. Public Const VersionSetup As Integer = 1
  6. ''' <summary>
  7. ''' 设置列表。
  8. ''' </summary>
  9. Private ReadOnly SetupDict As New Dictionary(Of String, SetupEntry) From {
  10. {"Identify", New SetupEntry("", Source:=SetupSource.Registry)},
  11. {"WindowHeight", New SetupEntry(550)},
  12. {"WindowWidth", New SetupEntry(900)},
  13. {"HintDownloadThread", New SetupEntry(False, Source:=SetupSource.Registry)},
  14. {"HintNotice", New SetupEntry(0, Source:=SetupSource.Registry)},
  15. {"HintDownload", New SetupEntry(0, Source:=SetupSource.Registry)},
  16. {"HintHide", New SetupEntry(False, Source:=SetupSource.Registry)},
  17. {"HintHandInstall", New SetupEntry(False, Source:=SetupSource.Registry)},
  18. {"HintBuy", New SetupEntry(False, Source:=SetupSource.Registry)},
  19. {"HintClearRubbish", New SetupEntry(0, Source:=SetupSource.Registry)},
  20. {"HintUpdateMod", New SetupEntry(False, Source:=SetupSource.Registry)},
  21. {"HintCustomCommand", New SetupEntry(False, Source:=SetupSource.Registry)},
  22. {"HintCustomWarn", New SetupEntry(False, Source:=SetupSource.Registry)},
  23. {"HintMoreAdvancedSetup", New SetupEntry(False, Source:=SetupSource.Registry)},
  24. {"HintIndieSetup", New SetupEntry(False, Source:=SetupSource.Registry)},
  25. {"HintExportConfig", New SetupEntry(False, Source:=SetupSource.Registry)},
  26. {"SystemEula", New SetupEntry(False, Source:=SetupSource.Registry)},
  27. {"SystemCount", New SetupEntry(0, Source:=SetupSource.Registry, Encoded:=True)},
  28. {"SystemLaunchCount", New SetupEntry(0, Source:=SetupSource.Registry, Encoded:=True)},
  29. {"SystemLastVersionReg", New SetupEntry(0, Source:=SetupSource.Registry, Encoded:=True)},
  30. {"SystemHighestSavedBetaVersionReg", New SetupEntry(0, Source:=SetupSource.Registry, Encoded:=True)},
  31. {"SystemHighestBetaVersionReg", New SetupEntry(0, Source:=SetupSource.Registry, Encoded:=True)},
  32. {"SystemHighestAlphaVersionReg", New SetupEntry(0, Source:=SetupSource.Registry, Encoded:=True)},
  33. {"SystemSetupVersionReg", New SetupEntry(VersionSetup, Source:=SetupSource.Registry)},
  34. {"SystemSetupVersionIni", New SetupEntry(VersionSetup)},
  35. {"SystemHelpVersion", New SetupEntry(0, Source:=SetupSource.Registry)},
  36. {"SystemDebugMode", New SetupEntry(False, Source:=SetupSource.Registry)},
  37. {"SystemDebugAnim", New SetupEntry(9, Source:=SetupSource.Registry)},
  38. {"SystemDebugDelay", New SetupEntry(False, Source:=SetupSource.Registry)},
  39. {"SystemDebugSkipCopy", New SetupEntry(False, Source:=SetupSource.Registry)},
  40. {"SystemSystemCache", New SetupEntry("", Source:=SetupSource.Registry)},
  41. {"SystemSystemUpdate", New SetupEntry(0)},
  42. {"SystemSystemActivity", New SetupEntry(0)},
  43. {"CacheExportConfig", New SetupEntry("", Source:=SetupSource.Registry)},
  44. {"CacheSavedPageUrl", New SetupEntry("", Source:=SetupSource.Registry)},
  45. {"CacheSavedPageVersion", New SetupEntry("", Source:=SetupSource.Registry)},
  46. {"CacheMsOAuthRefresh", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)},
  47. {"CacheMsAccess", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)},
  48. {"CacheMsProfileJson", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)},
  49. {"CacheMsUuid", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)},
  50. {"CacheMsName", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)},
  51. {"CacheMsV2Migrated", New SetupEntry(False, Source:=SetupSource.Registry)},
  52. {"CacheMsV2OAuthRefresh", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)},
  53. {"CacheMsV2Access", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)},
  54. {"CacheMsV2ProfileJson", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)},
  55. {"CacheMsV2Uuid", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)},
  56. {"CacheMsV2Name", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)},
  57. {"CacheNideAccess", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)},
  58. {"CacheNideClient", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)},
  59. {"CacheNideUuid", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)},
  60. {"CacheNideName", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)},
  61. {"CacheNideUsername", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)},
  62. {"CacheNidePass", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)},
  63. {"CacheNideServer", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)},
  64. {"CacheAuthAccess", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)},
  65. {"CacheAuthClient", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)},
  66. {"CacheAuthUuid", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)},
  67. {"CacheAuthName", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)},
  68. {"CacheAuthUsername", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)},
  69. {"CacheAuthPass", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)},
  70. {"CacheAuthServerServer", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)},
  71. {"CacheAuthServerName", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)},
  72. {"CacheAuthServerRegister", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)},
  73. {"CacheDownloadFolder", New SetupEntry("", Source:=SetupSource.Registry)},
  74. {"CacheJavaListVersion", New SetupEntry(0, Source:=SetupSource.Registry)},
  75. {"LoginRemember", New SetupEntry(True, Source:=SetupSource.Registry, Encoded:=True)},
  76. {"LoginLegacyName", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)},
  77. {"LoginMsJson", New SetupEntry("{}", Source:=SetupSource.Registry, Encoded:=True)}, '{UserName: OAuthToken, ...}
  78. {"LoginNideEmail", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)},
  79. {"LoginNidePass", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)},
  80. {"LoginAuthEmail", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)},
  81. {"LoginAuthPass", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)},
  82. {"LoginType", New SetupEntry(McLoginType.Legacy, Source:=SetupSource.Registry)},
  83. {"LoginPageType", New SetupEntry(0)},
  84. {"LaunchSkinID", New SetupEntry("", Source:=SetupSource.Registry)},
  85. {"LaunchSkinType", New SetupEntry(0, Source:=SetupSource.Registry)},
  86. {"LaunchSkinSlim", New SetupEntry(False, Source:=SetupSource.Registry)},
  87. {"LaunchVersionSelect", New SetupEntry("")},
  88. {"LaunchFolderSelect", New SetupEntry("")},
  89. {"LaunchFolders", New SetupEntry("", Source:=SetupSource.Registry)},
  90. {"LaunchArgumentTitle", New SetupEntry("")},
  91. {"LaunchArgumentInfo", New SetupEntry("PCL")},
  92. {"LaunchArgumentJavaSelect", New SetupEntry("", Source:=SetupSource.Registry)},
  93. {"LaunchArgumentJavaAll", New SetupEntry("[]", Source:=SetupSource.Registry)},
  94. {"LaunchArgumentIndie", New SetupEntry(0)},
  95. {"LaunchArgumentIndieV2", New SetupEntry(4)},
  96. {"LaunchArgumentVisible", New SetupEntry(5, Source:=SetupSource.Registry)},
  97. {"LaunchArgumentPriority", New SetupEntry(1, Source:=SetupSource.Registry)},
  98. {"LaunchArgumentWindowWidth", New SetupEntry(854)},
  99. {"LaunchArgumentWindowHeight", New SetupEntry(480)},
  100. {"LaunchArgumentWindowType", New SetupEntry(1)},
  101. {"LaunchArgumentRam", New SetupEntry(False, Source:=SetupSource.Registry)},
  102. {"LaunchAdvanceJvm", New SetupEntry("-XX:+UseG1GC -XX:-UseAdaptiveSizePolicy -XX:-OmitStackTraceInFastThrow -Djdk.lang.Process.allowAmbiguousCommands=true -Dfml.ignoreInvalidMinecraftCertificates=True -Dfml.ignorePatchDiscrepancies=True -Dlog4j2.formatMsgNoLookups=true")},
  103. {"LaunchAdvanceGame", New SetupEntry("")},
  104. {"LaunchAdvanceRun", New SetupEntry("")},
  105. {"LaunchAdvanceRunWait", New SetupEntry(True)},
  106. {"LaunchAdvanceDisableJLW", New SetupEntry(False)},
  107. {"LaunchAdvanceGraphicCard", New SetupEntry(True, Source:=SetupSource.Registry)},
  108. {"LaunchRamType", New SetupEntry(0)},
  109. {"LaunchRamCustom", New SetupEntry(15)},
  110. {"LinkEula", New SetupEntry(False, Source:=SetupSource.Registry)},
  111. {"LinkName", New SetupEntry("", Source:=SetupSource.Registry)},
  112. {"LinkHiperCertLast", New SetupEntry("", Source:=SetupSource.Registry)},
  113. {"LinkHiperCertTime", New SetupEntry("", Source:=SetupSource.Registry)},
  114. {"LinkHiperCertWarn", New SetupEntry(True, Source:=SetupSource.Registry)},
  115. {"LinkIoiVersion", New SetupEntry(0, Source:=SetupSource.Registry, Encoded:=True)},
  116. {"ToolHelpChinese", New SetupEntry(True, Source:=SetupSource.Registry)},
  117. {"ToolDownloadThread", New SetupEntry(63, Source:=SetupSource.Registry)},
  118. {"ToolDownloadSpeed", New SetupEntry(42, Source:=SetupSource.Registry)},
  119. {"ToolDownloadSource", New SetupEntry(1, Source:=SetupSource.Registry)},
  120. {"ToolDownloadVersion", New SetupEntry(1, Source:=SetupSource.Registry)},
  121. {"ToolDownloadTranslate", New SetupEntry(0, Source:=SetupSource.Registry)},
  122. {"ToolDownloadTranslateV2", New SetupEntry(1, Source:=SetupSource.Registry)},
  123. {"ToolDownloadIgnoreQuilt", New SetupEntry(True, Source:=SetupSource.Registry)},
  124. {"ToolDownloadCert", New SetupEntry(False, Source:=SetupSource.Registry)},
  125. {"ToolDownloadMod", New SetupEntry(1, Source:=SetupSource.Registry)},
  126. {"ToolModLocalNameStyle", New SetupEntry(0, Source:=SetupSource.Registry)},
  127. {"ToolUpdateAlpha", New SetupEntry(0, Source:=SetupSource.Registry, Encoded:=True)},
  128. {"ToolUpdateRelease", New SetupEntry(False, Source:=SetupSource.Registry)},
  129. {"ToolUpdateSnapshot", New SetupEntry(False, Source:=SetupSource.Registry)},
  130. {"ToolUpdateReleaseLast", New SetupEntry("", Source:=SetupSource.Registry)},
  131. {"ToolUpdateSnapshotLast", New SetupEntry("", Source:=SetupSource.Registry)},
  132. {"UiLauncherTransparent", New SetupEntry(600)}, '避免与 PCL1 设置冲突(UiLauncherOpacity)
  133. {"UiLauncherHue", New SetupEntry(180)},
  134. {"UiLauncherSat", New SetupEntry(80)},
  135. {"UiLauncherDelta", New SetupEntry(90)},
  136. {"UiLauncherLight", New SetupEntry(20)},
  137. {"UiLauncherTheme", New SetupEntry(0)},
  138. {"UiLauncherThemeGold", New SetupEntry("", Source:=SetupSource.Registry, Encoded:=True)},
  139. {"UiLauncherThemeHide", New SetupEntry("0|1|2|3|4", Source:=SetupSource.Registry, Encoded:=True)},
  140. {"UiLauncherThemeHide2", New SetupEntry("0|1|2|3|4", Source:=SetupSource.Registry, Encoded:=True)},
  141. {"UiLauncherLogo", New SetupEntry(True)},
  142. {"UiLauncherEmail", New SetupEntry(False)},
  143. {"UiBackgroundColorful", New SetupEntry(True)},
  144. {"UiBackgroundOpacity", New SetupEntry(1000)},
  145. {"UiBackgroundBlur", New SetupEntry(0)},
  146. {"UiBackgroundSuit", New SetupEntry(0)},
  147. {"UiCustomType", New SetupEntry(0)},
  148. {"UiCustomPreset", New SetupEntry(0)},
  149. {"UiCustomNet", New SetupEntry("")},
  150. {"UiLogoType", New SetupEntry(1)},
  151. {"UiLogoText", New SetupEntry("")},
  152. {"UiLogoLeft", New SetupEntry(False)},
  153. {"UiMusicVolume", New SetupEntry(500)},
  154. {"UiMusicStop", New SetupEntry(False)},
  155. {"UiMusicStart", New SetupEntry(False)},
  156. {"UiMusicRandom", New SetupEntry(True)},
  157. {"UiMusicAuto", New SetupEntry(True)},
  158. {"UiHiddenPageDownload", New SetupEntry(False)},
  159. {"UiHiddenPageLink", New SetupEntry(False)},
  160. {"UiHiddenPageSetup", New SetupEntry(False)},
  161. {"UiHiddenPageOther", New SetupEntry(False)},
  162. {"UiHiddenFunctionSelect", New SetupEntry(False)},
  163. {"UiHiddenFunctionModUpdate", New SetupEntry(False)},
  164. {"UiHiddenFunctionHidden", New SetupEntry(False)},
  165. {"UiHiddenSetupLaunch", New SetupEntry(False)},
  166. {"UiHiddenSetupUi", New SetupEntry(False)},
  167. {"UiHiddenSetupLink", New SetupEntry(False)},
  168. {"UiHiddenSetupSystem", New SetupEntry(False)},
  169. {"UiHiddenOtherHelp", New SetupEntry(False)},
  170. {"UiHiddenOtherFeedback", New SetupEntry(False)},
  171. {"UiHiddenOtherVote", New SetupEntry(False)},
  172. {"UiHiddenOtherAbout", New SetupEntry(False)},
  173. {"UiHiddenOtherTest", New SetupEntry(False)},
  174. {"VersionAdvanceJvm", New SetupEntry("", Source:=SetupSource.Version)},
  175. {"VersionAdvanceGame", New SetupEntry("", Source:=SetupSource.Version)},
  176. {"VersionAdvanceAssets", New SetupEntry(0, Source:=SetupSource.Version)},
  177. {"VersionAdvanceAssetsV2", New SetupEntry(False, Source:=SetupSource.Version)},
  178. {"VersionAdvanceJava", New SetupEntry(False, Source:=SetupSource.Version)},
  179. {"VersionAdvanceRun", New SetupEntry("", Source:=SetupSource.Version)},
  180. {"VersionAdvanceRunWait", New SetupEntry(True, Source:=SetupSource.Version)},
  181. {"VersionAdvanceDisableJLW", New SetupEntry(False, Source:=SetupSource.Version)},
  182. {"VersionRamType", New SetupEntry(2, Source:=SetupSource.Version)},
  183. {"VersionRamCustom", New SetupEntry(15, Source:=SetupSource.Version)},
  184. {"VersionRamOptimize", New SetupEntry(0, Source:=SetupSource.Version)},
  185. {"VersionArgumentTitle", New SetupEntry("", Source:=SetupSource.Version)},
  186. {"VersionArgumentInfo", New SetupEntry("", Source:=SetupSource.Version)},
  187. {"VersionArgumentIndie", New SetupEntry(-1, Source:=SetupSource.Version)},
  188. {"VersionArgumentIndieV2", New SetupEntry(False, Source:=SetupSource.Version)},
  189. {"VersionArgumentJavaSelect", New SetupEntry("使用全局设置", Source:=SetupSource.Version)},
  190. {"VersionServerEnter", New SetupEntry("", Source:=SetupSource.Version)},
  191. {"VersionServerLogin", New SetupEntry(0, Source:=SetupSource.Version)},
  192. {"VersionServerNide", New SetupEntry("", Source:=SetupSource.Version)},
  193. {"VersionServerAuthRegister", New SetupEntry("", Source:=SetupSource.Version)},
  194. {"VersionServerAuthName", New SetupEntry("", Source:=SetupSource.Version)},
  195. {"VersionServerAuthServer", New SetupEntry("", Source:=SetupSource.Version)}
  196. }
  197. #Region "基础"
  198. Private Enum SetupSource
  199. Normal
  200. Registry
  201. Version
  202. End Enum
  203. Private Class SetupEntry
  204. Public Encoded As Boolean
  205. Public DefaultValue
  206. Public DefaultValueEncoded
  207. Public Value
  208. Public Source As SetupSource
  209. ''' <summary>
  210. ''' 加载状态:0/未读取 1/已读取未处理 2/已处理
  211. ''' 我也不知道当年写这坨的时候为啥没用 Enum……
  212. ''' </summary>
  213. Public State As Byte = 0
  214. Public Type As Type
  215. Public Sub New(Value, Optional Source = SetupSource.Normal, Optional Encoded = False)
  216. Try
  217. Me.DefaultValue = Value
  218. Me.Encoded = Encoded
  219. Me.Value = Value
  220. Me.Source = Source
  221. Me.Type = If(Value, New Object).GetType
  222. Me.DefaultValueEncoded = If(Encoded, SecretEncrypt(Value, "PCL" & UniqueAddress), Value)
  223. Catch ex As Exception
  224. Log(ex, "初始化 SetupEntry 失败", LogLevel.Feedback) '#5095 的 fallback
  225. End Try
  226. End Sub
  227. End Class
  228. ''' <summary>
  229. ''' 改变某个设置项的值。
  230. ''' </summary>
  231. Public Sub [Set](Key As String, Value As Object, Optional ForceReload As Boolean = False, Optional Version As McVersion = Nothing)
  232. [Set](Key, Value, SetupDict(Key), ForceReload, Version)
  233. End Sub
  234. Private Sub [Set](Key As String, Value As Object, E As SetupEntry, ForceReload As Boolean, Version As McVersion)
  235. Try
  236. Value = CTypeDynamic(Value, E.Type)
  237. If E.State = 2 Then
  238. '如果已应用,且值相同,则无需再次更改
  239. If E.Value = Value AndAlso Not ForceReload Then Return
  240. Else
  241. '如果未应用,则直接更改并应用
  242. If E.Source <> SetupSource.Version Then E.State = 2
  243. End If
  244. '设置新值
  245. E.Value = Value
  246. '写入值
  247. If E.Encoded Then
  248. Try
  249. If Value Is Nothing Then Value = ""
  250. Value = SecretEncrypt(Value, "PCL" & UniqueAddress)
  251. Catch ex As Exception
  252. Log(ex, "加密设置失败:" & Key, LogLevel.Developer)
  253. End Try
  254. End If
  255. Select Case E.Source
  256. Case SetupSource.Normal
  257. WriteIni("Setup", Key, Value)
  258. Case SetupSource.Registry
  259. WriteReg(Key, Value)
  260. Case SetupSource.Version
  261. If Version Is Nothing Then Throw New Exception($"更改版本设置 {Key} 时未提供目标版本")
  262. WriteIni(Version.Path & "PCL\Setup.ini", Key, Value)
  263. End Select
  264. '应用
  265. '例如 VersionServerLogin 要求在设置之后再引发事件
  266. Dim Method As Reflection.MethodInfo = GetType(ModSetup).GetMethod(Key)
  267. If Method IsNot Nothing Then Method.Invoke(Me, {Value})
  268. Catch ex As Exception
  269. Log(ex, "设置设置项时出错(" & Key & ", " & Value & ")", LogLevel.Feedback)
  270. End Try
  271. End Sub
  272. ''' <summary>
  273. ''' 应用某个设置项的值。
  274. ''' </summary>
  275. Public Function Load(Key As String, Optional ForceReload As Boolean = False, Optional Version As McVersion = Nothing)
  276. Return Load(Key, SetupDict(Key), ForceReload, Version)
  277. End Function
  278. Private Function Load(Key As String, E As SetupEntry, ForceReload As Boolean, Version As McVersion)
  279. '如果已经应用过,则什么也不干
  280. If E.State = 2 AndAlso Not ForceReload Then Return E.Value
  281. '读取,应用并设置状态
  282. Read(Key, E, Version)
  283. If E.Source <> SetupSource.Version Then E.State = 2
  284. Dim Method As Reflection.MethodInfo = GetType(ModSetup).GetMethod(Key)
  285. If Method IsNot Nothing Then Method.Invoke(Me, {E.Value})
  286. Return E.Value
  287. End Function
  288. ''' <summary>
  289. ''' 获取某个设置项的值。
  290. ''' </summary>
  291. Public Function [Get](Key As String, Optional Version As McVersion = Nothing)
  292. If Not SetupDict.ContainsKey(Key) Then Throw New KeyNotFoundException("未找到设置项:" & Key) With {.Source = Key}
  293. Return [Get](Key, SetupDict(Key), Version)
  294. End Function
  295. Private Function [Get](Key As String, E As SetupEntry, Version As McVersion)
  296. '获取强制值
  297. Dim Force As String = ForceValue(Key)
  298. If Force IsNot Nothing Then
  299. E.Value = CTypeDynamic(Force, E.Type)
  300. E.State = 1
  301. End If
  302. '如果尚未读取过,则读取
  303. If E.State = 0 Then
  304. Read(Key, E, Version)
  305. If E.Source <> SetupSource.Version Then E.State = 1
  306. End If
  307. '返回现在的值
  308. Return E.Value
  309. End Function
  310. ''' <summary>
  311. ''' 初始化某个设置项的值。
  312. ''' </summary>
  313. Public Sub Reset(Key As String, Optional ForceReload As Boolean = False, Optional Version As McVersion = Nothing)
  314. Dim E As SetupEntry = SetupDict(Key)
  315. [Set](Key, E.DefaultValue, E, ForceReload, Version)
  316. Select Case SetupDict(Key).Source
  317. Case SetupSource.Normal
  318. DeleteIniKey("Setup", Key)
  319. Case SetupSource.Registry
  320. DeleteReg(Key)
  321. Case Else 'SetupSource.Version
  322. If Version Is Nothing Then Throw New Exception($"重置版本设置 {Key} 时未提供目标版本")
  323. DeleteIniKey(Version.Path & "PCL\Setup.ini", Key)
  324. End Select
  325. End Sub
  326. ''' <summary>
  327. ''' 获取某个设置项的默认值。
  328. ''' </summary>
  329. Public Function GetDefault(Key As String) As String
  330. Return SetupDict(Key).DefaultValue
  331. End Function
  332. ''' <summary>
  333. ''' 某个设置项是否从未被设置过。
  334. ''' </summary>
  335. Public Function IsUnset(Key As String, Optional Version As McVersion = Nothing) As Boolean
  336. Select Case SetupDict(Key).Source
  337. Case SetupSource.Normal
  338. Return Not HasIniKey("Setup", Key)
  339. Case SetupSource.Registry
  340. Return Not HasReg(Key)
  341. Case Else 'SetupSource.Version
  342. If Version Is Nothing Then Throw New Exception($"判断版本设置 {Key} 是否存在时未提供目标版本")
  343. Return Not HasIniKey(Version.Path & "PCL\Setup.ini", Key)
  344. End Select
  345. End Function
  346. ''' <summary>
  347. ''' 某个设置项是否加密。
  348. ''' </summary>
  349. Public Function IsEncoded(Key As String) As Boolean
  350. If Not SetupDict.ContainsKey(Key) Then Throw New KeyNotFoundException("未找到设置项:" & Key) With {.Source = Key}
  351. Return SetupDict(Key).Encoded
  352. End Function
  353. ''' <summary>
  354. ''' 读取设置。
  355. ''' </summary>
  356. Private Sub Read(Key As String, ByRef E As SetupEntry, Version As McVersion)
  357. Try
  358. If Not E.State = 0 Then Return
  359. Dim SourceValue As String = Nothing '先用 String 储存,避免类型转换
  360. Select Case E.Source
  361. Case SetupSource.Normal
  362. SourceValue = ReadIni("Setup", Key, E.DefaultValueEncoded)
  363. Case SetupSource.Registry
  364. SourceValue = ReadReg(Key, E.DefaultValueEncoded)
  365. Case SetupSource.Version
  366. If Version Is Nothing Then
  367. Throw New Exception("读取版本设置 " & Key & " 时未提供目标版本")
  368. Else
  369. SourceValue = ReadIni(Version.Path & "PCL\Setup.ini", Key, E.DefaultValueEncoded)
  370. End If
  371. End Select
  372. If E.Encoded Then
  373. If SourceValue.Equals(E.DefaultValueEncoded) Then
  374. SourceValue = E.DefaultValue
  375. Else
  376. Try
  377. SourceValue = SecretDecrypt(SourceValue, "PCL" & UniqueAddress)
  378. Catch ex As Exception
  379. Log(ex, "解密设置失败:" & Key, LogLevel.Developer)
  380. SourceValue = E.DefaultValue
  381. Setup.Set(Key, E.DefaultValue, True)
  382. End Try
  383. End If
  384. End If
  385. E.Value = CTypeDynamic(SourceValue, E.Type)
  386. Catch ex As Exception
  387. Log(ex, "读取设置失败:" & Key, LogLevel.Hint)
  388. E.Value = CTypeDynamic(E.DefaultValue, E.Type)
  389. End Try
  390. End Sub
  391. '对部分设置强制赋值
  392. Private Function ForceValue(Key As String) As String
  393. #If BETA Then
  394. If Key = "UiLauncherTheme" Then Return "0"
  395. #End If
  396. If Key = "UiHiddenPageLink" Then Return True
  397. If Key = "UiHiddenSetupLink" Then Return True
  398. Return Nothing
  399. End Function
  400. #End Region
  401. #Region "Launch"
  402. '切换选择
  403. Public Sub LaunchVersionSelect(Value As String)
  404. Log("[Setup] 当前选择的 Minecraft 版本:" & Value)
  405. WriteIni(PathMcFolder & "PCL.ini", "Version", If(IsNothing(McVersionCurrent), "", McVersionCurrent.Name))
  406. End Sub
  407. Public Sub LaunchFolderSelect(Value As String)
  408. Log("[Setup] 当前选择的 Minecraft 文件夹:" & Value.ToString.Replace("$", Path))
  409. PathMcFolder = Value.ToString.Replace("$", Path)
  410. End Sub
  411. '游戏内存
  412. Public Sub LaunchRamType(Type As Integer)
  413. If FrmSetupLaunch Is Nothing Then Return
  414. FrmSetupLaunch.RamType(Type)
  415. End Sub
  416. '离线皮肤
  417. Public Sub LaunchSkinType(Value As Integer)
  418. RunInUi(Sub()
  419. If Not IsNothing(FrmSetupLaunch) Then
  420. Select Case Value
  421. Case 0, 1, 2 '默认
  422. FrmSetupLaunch.PanSkinID.Visibility = Visibility.Collapsed
  423. FrmSetupLaunch.PanSkinChange.Visibility = Visibility.Collapsed
  424. Case 3 '正版
  425. FrmSetupLaunch.PanSkinID.Visibility = Visibility.Visible
  426. FrmSetupLaunch.PanSkinChange.Visibility = Visibility.Collapsed
  427. Case 4 '自定义
  428. FrmSetupLaunch.PanSkinID.Visibility = Visibility.Collapsed
  429. FrmSetupLaunch.PanSkinChange.Visibility = Visibility.Visible
  430. End Select
  431. FrmSetupLaunch.CardSkin.TriggerForceResize()
  432. End If
  433. PageLaunchLeft.SkinLegacy.Start()
  434. End Sub)
  435. End Sub
  436. Public Sub LaunchSkinID(Value As String)
  437. PageLaunchLeft.SkinLegacy.Start()
  438. End Sub
  439. #End Region
  440. #Region "Tool"
  441. Public Sub ToolDownloadThread(Value As Integer)
  442. NetTaskThreadLimit = Value + 1
  443. End Sub
  444. Public Sub ToolDownloadCert(Value As Boolean)
  445. ServicePointManager.ServerCertificateValidationCallback =
  446. Function(Sender, Certificate, Chain, Failure)
  447. Dim Request As HttpWebRequest = TryCast(Sender, HttpWebRequest)
  448. If Failure = Net.Security.SslPolicyErrors.None Then Return True '已通过验证
  449. '基于 #3018 和 #5879,只在访问正版登录 API 时跳过证书验证
  450. Log($"[System] 未通过 SSL 证书验证({Failure}),提供的证书为 {Certificate?.Subject},URL:{Request?.Address}", LogLevel.Debug)
  451. If Request Is Nothing Then
  452. Return Not Value
  453. ElseIf Request.Address.Host.Contains("xboxlive") OrElse Request.Address.Host.Contains("minecraftservices") Then
  454. Return Not Value '根据设置决定是否忽略错误
  455. Else
  456. Return False
  457. End If
  458. End Function
  459. End Sub
  460. Public Sub ToolDownloadSpeed(Value As Integer)
  461. If Value <= 14 Then
  462. NetTaskSpeedLimitHigh = (Value + 1) * 0.1 * 1024 * 1024L
  463. ElseIf Value <= 31 Then
  464. NetTaskSpeedLimitHigh = (Value - 11) * 0.5 * 1024 * 1024L
  465. ElseIf Value <= 41 Then
  466. NetTaskSpeedLimitHigh = (Value - 21) * 1024 * 1024L
  467. Else
  468. NetTaskSpeedLimitHigh = -1
  469. End If
  470. End Sub
  471. #End Region
  472. #Region "UI"
  473. '启动器
  474. Public Sub UiLauncherTransparent(Value As Integer)
  475. FrmMain.Opacity = Value / 1000 + 0.4
  476. End Sub
  477. Public Sub UiLauncherTheme(Value As Integer)
  478. ThemeRefresh(Value)
  479. End Sub
  480. Public Sub UiBackgroundColorful(Value As Boolean)
  481. ThemeRefresh()
  482. End Sub
  483. '背景图片
  484. Public Sub UiBackgroundOpacity(Value As Integer)
  485. FrmMain.ImgBack.Opacity = Value / 1000
  486. End Sub
  487. Public Sub UiBackgroundBlur(Value As Integer)
  488. If Value = 0 Then
  489. FrmMain.ImgBack.Effect = Nothing
  490. Else
  491. FrmMain.ImgBack.Effect = New Effects.BlurEffect With {.Radius = Value + 1}
  492. End If
  493. FrmMain.ImgBack.Margin = New Thickness(-(Value + 1) / 1.8)
  494. End Sub
  495. Public Sub UiBackgroundSuit(Value As Integer)
  496. If IsNothing(FrmMain.ImgBack.Background) Then Return
  497. Dim Width As Double = CType(FrmMain.ImgBack.Background, ImageBrush).ImageSource.Width
  498. Dim Height As Double = CType(FrmMain.ImgBack.Background, ImageBrush).ImageSource.Height
  499. If Value = 0 Then
  500. '智能:当图片较小时平铺,较大时适应
  501. If Width < FrmMain.PanMain.ActualWidth / 2 AndAlso Height < FrmMain.PanMain.ActualHeight / 2 Then
  502. Value = 4 '平铺
  503. Else
  504. Value = 2 '适应
  505. End If
  506. End If
  507. CType(FrmMain.ImgBack.Background, ImageBrush).TileMode = TileMode.None
  508. CType(FrmMain.ImgBack.Background, ImageBrush).Viewport = New Rect(0, 0, 1, 1)
  509. CType(FrmMain.ImgBack.Background, ImageBrush).ViewportUnits = BrushMappingMode.RelativeToBoundingBox
  510. Select Case Value
  511. Case 1 '居中
  512. FrmMain.ImgBack.HorizontalAlignment = HorizontalAlignment.Center
  513. FrmMain.ImgBack.VerticalAlignment = VerticalAlignment.Center
  514. CType(FrmMain.ImgBack.Background, ImageBrush).Stretch = Stretch.None
  515. FrmMain.ImgBack.Width = CType(FrmMain.ImgBack.Background, ImageBrush).ImageSource.Width
  516. FrmMain.ImgBack.Height = CType(FrmMain.ImgBack.Background, ImageBrush).ImageSource.Height
  517. Case 2 '适应
  518. FrmMain.ImgBack.HorizontalAlignment = HorizontalAlignment.Stretch
  519. FrmMain.ImgBack.VerticalAlignment = VerticalAlignment.Stretch
  520. CType(FrmMain.ImgBack.Background, ImageBrush).Stretch = Stretch.UniformToFill
  521. FrmMain.ImgBack.Width = Double.NaN
  522. FrmMain.ImgBack.Height = Double.NaN
  523. Case 3 '拉伸
  524. FrmMain.ImgBack.HorizontalAlignment = HorizontalAlignment.Stretch
  525. FrmMain.ImgBack.VerticalAlignment = VerticalAlignment.Stretch
  526. CType(FrmMain.ImgBack.Background, ImageBrush).Stretch = Stretch.Fill
  527. FrmMain.ImgBack.Width = Double.NaN
  528. FrmMain.ImgBack.Height = Double.NaN
  529. Case 4 '平铺
  530. FrmMain.ImgBack.HorizontalAlignment = HorizontalAlignment.Stretch
  531. FrmMain.ImgBack.VerticalAlignment = VerticalAlignment.Stretch
  532. CType(FrmMain.ImgBack.Background, ImageBrush).Stretch = Stretch.None
  533. CType(FrmMain.ImgBack.Background, ImageBrush).TileMode = TileMode.Tile
  534. CType(FrmMain.ImgBack.Background, ImageBrush).Viewport = New Rect(0, 0, CType(FrmMain.ImgBack.Background, ImageBrush).ImageSource.Width, CType(FrmMain.ImgBack.Background, ImageBrush).ImageSource.Height)
  535. CType(FrmMain.ImgBack.Background, ImageBrush).ViewportUnits = BrushMappingMode.Absolute
  536. FrmMain.ImgBack.Width = Double.NaN
  537. FrmMain.ImgBack.Height = Double.NaN
  538. Case 5 '左上
  539. FrmMain.ImgBack.HorizontalAlignment = HorizontalAlignment.Left
  540. FrmMain.ImgBack.VerticalAlignment = VerticalAlignment.Top
  541. CType(FrmMain.ImgBack.Background, ImageBrush).Stretch = Stretch.None
  542. FrmMain.ImgBack.Width = CType(FrmMain.ImgBack.Background, ImageBrush).ImageSource.Width
  543. FrmMain.ImgBack.Height = CType(FrmMain.ImgBack.Background, ImageBrush).ImageSource.Height
  544. Case 6 '右上
  545. FrmMain.ImgBack.HorizontalAlignment = HorizontalAlignment.Right
  546. FrmMain.ImgBack.VerticalAlignment = VerticalAlignment.Top
  547. CType(FrmMain.ImgBack.Background, ImageBrush).Stretch = Stretch.None
  548. FrmMain.ImgBack.Width = CType(FrmMain.ImgBack.Background, ImageBrush).ImageSource.Width
  549. FrmMain.ImgBack.Height = CType(FrmMain.ImgBack.Background, ImageBrush).ImageSource.Height
  550. Case 7 '左下
  551. FrmMain.ImgBack.HorizontalAlignment = HorizontalAlignment.Left
  552. FrmMain.ImgBack.VerticalAlignment = VerticalAlignment.Bottom
  553. CType(FrmMain.ImgBack.Background, ImageBrush).Stretch = Stretch.None
  554. FrmMain.ImgBack.Width = CType(FrmMain.ImgBack.Background, ImageBrush).ImageSource.Width
  555. FrmMain.ImgBack.Height = CType(FrmMain.ImgBack.Background, ImageBrush).ImageSource.Height
  556. Case 8 '右下
  557. FrmMain.ImgBack.HorizontalAlignment = HorizontalAlignment.Right
  558. FrmMain.ImgBack.VerticalAlignment = VerticalAlignment.Bottom
  559. CType(FrmMain.ImgBack.Background, ImageBrush).Stretch = Stretch.None
  560. FrmMain.ImgBack.Width = CType(FrmMain.ImgBack.Background, ImageBrush).ImageSource.Width
  561. FrmMain.ImgBack.Height = CType(FrmMain.ImgBack.Background, ImageBrush).ImageSource.Height
  562. End Select
  563. End Sub
  564. '主页
  565. Public Sub UiCustomType(Value As Integer)
  566. If FrmSetupUI Is Nothing Then Return
  567. Select Case Value
  568. Case 0 '无
  569. FrmSetupUI.PanCustomPreset.Visibility = Visibility.Collapsed
  570. FrmSetupUI.PanCustomLocal.Visibility = Visibility.Collapsed
  571. FrmSetupUI.PanCustomNet.Visibility = Visibility.Collapsed
  572. FrmSetupUI.HintCustom.Visibility = Visibility.Collapsed
  573. FrmSetupUI.HintCustomWarn.Visibility = Visibility.Collapsed
  574. Case 1 '本地
  575. FrmSetupUI.PanCustomPreset.Visibility = Visibility.Collapsed
  576. FrmSetupUI.PanCustomLocal.Visibility = Visibility.Visible
  577. FrmSetupUI.PanCustomNet.Visibility = Visibility.Collapsed
  578. FrmSetupUI.HintCustom.Visibility = Visibility.Visible
  579. FrmSetupUI.HintCustomWarn.Visibility = If(Setup.Get("HintCustomWarn"), Visibility.Collapsed, Visibility.Visible)
  580. FrmSetupUI.HintCustom.Text = $"从 PCL 文件夹下的 Custom.xaml 读取主页内容。{vbCrLf}你可以手动编辑该文件,向主页添加文本、图片、常用网站、快捷启动等功能。"
  581. FrmSetupUI.HintCustom.EventType = ""
  582. FrmSetupUI.HintCustom.EventData = ""
  583. Case 2 '联网
  584. FrmSetupUI.PanCustomPreset.Visibility = Visibility.Collapsed
  585. FrmSetupUI.PanCustomLocal.Visibility = Visibility.Collapsed
  586. FrmSetupUI.PanCustomNet.Visibility = Visibility.Visible
  587. FrmSetupUI.HintCustom.Visibility = Visibility.Visible
  588. FrmSetupUI.HintCustomWarn.Visibility = If(Setup.Get("HintCustomWarn"), Visibility.Collapsed, Visibility.Visible)
  589. FrmSetupUI.HintCustom.Text = $"从指定网址联网获取主页内容。服主也可以用于动态更新服务器公告。{vbCrLf}如果你制作了稳定运行的联网主页,可以点击这条提示投稿,若合格即可加入预设!"
  590. FrmSetupUI.HintCustom.EventType = "打开网页"
  591. FrmSetupUI.HintCustom.EventData = "https://github.com/Meloong-Git/PCL/discussions/2528"
  592. Case 3 '预设
  593. FrmSetupUI.PanCustomPreset.Visibility = Visibility.Visible
  594. FrmSetupUI.PanCustomLocal.Visibility = Visibility.Collapsed
  595. FrmSetupUI.PanCustomNet.Visibility = Visibility.Collapsed
  596. FrmSetupUI.HintCustom.Visibility = Visibility.Collapsed
  597. FrmSetupUI.HintCustomWarn.Visibility = Visibility.Collapsed
  598. End Select
  599. FrmSetupUI.CardCustom.TriggerForceResize()
  600. End Sub
  601. '顶部栏
  602. Public Sub UiLogoType(Value As Integer)
  603. Select Case Value
  604. Case 0 '无
  605. FrmMain.ShapeTitleLogo.Visibility = Visibility.Collapsed
  606. FrmMain.LabTitleLogo.Visibility = Visibility.Collapsed
  607. FrmMain.ImageTitleLogo.Visibility = Visibility.Collapsed
  608. If Not IsNothing(FrmSetupUI) Then
  609. FrmSetupUI.CheckLogoLeft.Visibility = Visibility.Visible
  610. FrmSetupUI.PanLogoText.Visibility = Visibility.Collapsed
  611. FrmSetupUI.PanLogoChange.Visibility = Visibility.Collapsed
  612. End If
  613. Case 1 '默认
  614. FrmMain.ShapeTitleLogo.Visibility = Visibility.Visible
  615. FrmMain.LabTitleLogo.Visibility = Visibility.Collapsed
  616. FrmMain.ImageTitleLogo.Visibility = Visibility.Collapsed
  617. If Not IsNothing(FrmSetupUI) Then
  618. FrmSetupUI.CheckLogoLeft.Visibility = Visibility.Collapsed
  619. FrmSetupUI.PanLogoText.Visibility = Visibility.Collapsed
  620. FrmSetupUI.PanLogoChange.Visibility = Visibility.Collapsed
  621. End If
  622. Case 2 '文本
  623. FrmMain.ShapeTitleLogo.Visibility = Visibility.Collapsed
  624. FrmMain.LabTitleLogo.Visibility = Visibility.Visible
  625. FrmMain.ImageTitleLogo.Visibility = Visibility.Collapsed
  626. If Not IsNothing(FrmSetupUI) Then
  627. FrmSetupUI.CheckLogoLeft.Visibility = Visibility.Collapsed
  628. FrmSetupUI.PanLogoText.Visibility = Visibility.Visible
  629. FrmSetupUI.PanLogoChange.Visibility = Visibility.Collapsed
  630. End If
  631. Setup.Load("UiLogoText", True)
  632. Case 3 '图片
  633. FrmMain.ShapeTitleLogo.Visibility = Visibility.Collapsed
  634. FrmMain.LabTitleLogo.Visibility = Visibility.Collapsed
  635. FrmMain.ImageTitleLogo.Visibility = Visibility.Visible
  636. If Not IsNothing(FrmSetupUI) Then
  637. FrmSetupUI.CheckLogoLeft.Visibility = Visibility.Collapsed
  638. FrmSetupUI.PanLogoText.Visibility = Visibility.Collapsed
  639. FrmSetupUI.PanLogoChange.Visibility = Visibility.Visible
  640. End If
  641. Try
  642. FrmMain.ImageTitleLogo.Source = Path & "PCL\Logo.png"
  643. Catch ex As Exception
  644. FrmMain.ImageTitleLogo.Source = Nothing
  645. Log(ex, "显示标题栏图片失败", LogLevel.Msgbox)
  646. End Try
  647. End Select
  648. Setup.Load("UiLogoLeft", True)
  649. If Not IsNothing(FrmSetupUI) Then FrmSetupUI.CardLogo.TriggerForceResize()
  650. End Sub
  651. Public Sub UiLogoText(Value As String)
  652. FrmMain.LabTitleLogo.Text = Value
  653. End Sub
  654. Public Sub UiLogoLeft(Value As Boolean)
  655. FrmMain.PanTitleMain.ColumnDefinitions(0).Width = New GridLength(If(Value AndAlso (Setup.Get("UiLogoType") = 0), 0, 1), GridUnitType.Star)
  656. End Sub
  657. '功能隐藏
  658. Public Sub UiHiddenPageLink(Value As Boolean)
  659. PageSetupUI.HiddenRefresh()
  660. End Sub
  661. Public Sub UiHiddenPageDownload(Value As Boolean)
  662. PageSetupUI.HiddenRefresh()
  663. End Sub
  664. Public Sub UiHiddenPageSetup(Value As Boolean)
  665. PageSetupUI.HiddenRefresh()
  666. End Sub
  667. Public Sub UiHiddenPageOther(Value As Boolean)
  668. PageSetupUI.HiddenRefresh()
  669. End Sub
  670. Public Sub UiHiddenFunctionSelect(Value As Boolean)
  671. PageSetupUI.HiddenRefresh()
  672. End Sub
  673. Public Sub UiHiddenFunctionModUpdate(Value As Boolean)
  674. PageSetupUI.HiddenRefresh()
  675. End Sub
  676. Public Sub UiHiddenFunctionHidden(Value As Boolean)
  677. PageSetupUI.HiddenRefresh()
  678. End Sub
  679. Public Sub UiHiddenSetupLaunch(Value As Boolean)
  680. PageSetupUI.HiddenRefresh()
  681. End Sub
  682. Public Sub UiHiddenSetupUi(Value As Boolean)
  683. PageSetupUI.HiddenRefresh()
  684. End Sub
  685. Public Sub UiHiddenSetupLink(Value As Boolean)
  686. PageSetupUI.HiddenRefresh()
  687. End Sub
  688. Public Sub UiHiddenSetupSystem(Value As Boolean)
  689. PageSetupUI.HiddenRefresh()
  690. End Sub
  691. Public Sub UiHiddenOtherHelp(Value As Boolean)
  692. PageSetupUI.HiddenRefresh()
  693. End Sub
  694. Public Sub UiHiddenOtherFeedback(Value As Boolean)
  695. PageSetupUI.HiddenRefresh()
  696. End Sub
  697. Public Sub UiHiddenOtherVote(Value As Boolean)
  698. PageSetupUI.HiddenRefresh()
  699. End Sub
  700. Public Sub UiHiddenOtherAbout(Value As Boolean)
  701. PageSetupUI.HiddenRefresh()
  702. End Sub
  703. Public Sub UiHiddenOtherTest(Value As Boolean)
  704. PageSetupUI.HiddenRefresh()
  705. End Sub
  706. #End Region
  707. #Region "System"
  708. '调试选项
  709. Public Sub SystemDebugMode(Value As Boolean)
  710. ModeDebug = Value
  711. End Sub
  712. Public Sub SystemDebugAnim(Value As Integer)
  713. AniSpeed = If(Value >= 30, 200, MathClamp(Value * 0.1 + 0.1, 0.1, 3))
  714. End Sub
  715. #End Region
  716. #Region "Version"
  717. '游戏内存
  718. Public Sub VersionRamType(Type As Integer)
  719. If FrmVersionSetup Is Nothing Then Return
  720. FrmVersionSetup.RamType(Type)
  721. End Sub
  722. '服务器
  723. Public Sub VersionServerLogin(Type As Integer)
  724. If FrmVersionSetup Is Nothing Then Return
  725. '为第三方登录清空缓存以更新描述
  726. WriteIni(PathMcFolder & "PCL.ini", "VersionCache", "")
  727. If PageVersionLeft.Version Is Nothing Then Return
  728. PageVersionLeft.Version = New McVersion(PageVersionLeft.Version.Name).Load()
  729. LoaderFolderRun(McVersionListLoader, PathMcFolder, LoaderFolderRunType.ForceRun, MaxDepth:=1, ExtraPath:="versions\")
  730. End Sub
  731. #End Region
  732. End Class