ModSetup.vb 39 KB

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