formDownloadLeft.xaml.vb 56 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043
  1. Imports Ionic.Zip
  2. Public Class formDownloadLeft
  3. '用于加载的Timer
  4. Private Sub timerLoad_Tick() Handles timerLoad.Tick
  5. Try
  6. '获取基本信息
  7. Dim NowState As LoadState
  8. Select Case selecter.SelectIndexName
  9. Case "Minecraft"
  10. NowState = MinecraftState
  11. Case "OptiFine"
  12. NowState = OptiFineState
  13. Case "Forge"
  14. NowState = If(ForgeVersionState = LoadState.Loaded, ForgeState, ForgeVersionState)
  15. Case Else
  16. Exit Sub
  17. End Select
  18. If selecter.SelectIndexName = "Forge" And ForgeVersionState = LoadState.Loaded Then
  19. 'Forge状态处理
  20. Select Case NowState
  21. Case LoadState.Loaded
  22. Exit Sub
  23. Case LoadState.Loading
  24. labRight.Content = "加载中"
  25. Exit Sub
  26. Case LoadState.Failed
  27. labRight.Content = "加载失败"
  28. Exit Sub
  29. Case LoadState.NoConnection
  30. labRight.Content = "没有网络连接"
  31. Exit Sub
  32. Case LoadState.Success
  33. labRight.Content = ""
  34. End Select
  35. Else
  36. '基本事态处理,这里自动控制了两个主UI的切换
  37. Select Case NowState
  38. Case LoadState.Loaded
  39. Exit Sub
  40. Case LoadState.Loading
  41. labLoading.Content = "加载中"
  42. labLoading.Visibility = Visibility.Visible
  43. panFinish.Visibility = Visibility.Hidden
  44. Exit Sub
  45. Case LoadState.Failed
  46. labLoading.Content = "加载失败,点击以重试"
  47. labLoading.Visibility = Visibility.Visible
  48. panFinish.Visibility = Visibility.Hidden
  49. Exit Sub
  50. Case LoadState.NoConnection
  51. labLoading.Content = "没有网络连接"
  52. labLoading.Visibility = Visibility.Visible
  53. panFinish.Visibility = Visibility.Hidden
  54. Exit Sub
  55. Case LoadState.Success
  56. '开始加载,把控件显示出来
  57. labLoading.Visibility = Visibility.Collapsed
  58. panFinish.Visibility = Visibility.Visible
  59. End Select
  60. End If
  61. '加载
  62. Select Case selecter.SelectIndexName
  63. Case "Minecraft"
  64. '结束显示
  65. MinecraftState = LoadState.Loaded
  66. '加载预览版,预览版总是列表第一个
  67. item2.MainText = MinecraftArray(0).id
  68. item2.Tag = MinecraftArray(0)
  69. '是否加载正式版的标记
  70. Dim item1Loaded As Boolean = False
  71. '循环添加
  72. For Each ver As MinecraftVersion In MinecraftArray
  73. '判断正式版
  74. If ver.type = "release" And Not item1Loaded Then
  75. item1Loaded = True
  76. item1.MainText = ver.id
  77. item1.Tag = ver
  78. End If
  79. '判断Logo样式
  80. Dim Photo As String = "Grass"
  81. If ver.type = "snapshot" Then Photo = "CommandBlock"
  82. If ver.type = "fool" Then Photo = "Dirt"
  83. If ver.type.Contains("old") Then Photo = "CobbleStone"
  84. '添加控件
  85. Dim item As ListItem = New ListItem With {.UseLayoutRounding = True, .Tag = ver, .CanCheck = False, .ButtonLogo = New BitmapImage(New Uri("/Images/appbar.inbox.in.png", UriKind.Relative)), .MainText = ver.id, .SubText = ver.time, .Name = "list" & GetUUID(), .Logo = New BitmapImage(New Uri(PATH_IMAGE & "Block-" & Photo & ".png", UriKind.Absolute)), .ToolTip = If(Photo = "Dirt", "该版本由 PCL 特别提供", Nothing)}
  86. AddHandler item.ButtonClick, AddressOf MinecraftDownloadClick
  87. panVersion.Children.Add(item)
  88. Next
  89. '最新正式版与最新预览版一样则隐藏一个
  90. If item1.MainText = item2.MainText Then
  91. item2.Visibility = Visibility.Collapsed
  92. Else
  93. item2.Visibility = Visibility.Visible
  94. End If
  95. Case "OptiFine"
  96. '结束显示
  97. OptiFineState = LoadState.Loaded
  98. '加载预览版,预览版总是列表第一个
  99. item2.MainText = OptiFineArray(0).id.ToString
  100. item2.Tag = OptiFineArray(0)
  101. '是否加载正式版的标记
  102. Dim item1Loaded = False
  103. For Each ver As OptiFineVersion In OptiFineArray
  104. '判断正式版
  105. If Not (ver.id.Contains("pre") Or item1Loaded) Then
  106. item1Loaded = True
  107. item1.MainText = ver.id
  108. item1.Tag = ver
  109. End If
  110. '判断Logo样式
  111. Dim Photo = If(ver.id.Contains("pre"), "CommandBlock", "Grass")
  112. '添加控件
  113. Dim item As ListItem = New ListItem With {.UseLayoutRounding = True, .Tag = ver, .CanCheck = False, .ButtonLogo = New BitmapImage(New Uri("/Images/appbar.inbox.in.png", UriKind.Relative)), .MainText = ver.id, .SubText = ver.time, .Name = "list" & GetUUID(), .Logo = New BitmapImage(New Uri("/Images/Block-" & Photo & ".png", UriKind.Relative))}
  114. AddHandler item.ButtonClick, AddressOf OptiFineDownloadStart
  115. panVersion.Children.Add(item)
  116. Next
  117. '最新正式版与最新预览版一样则隐藏一个
  118. If item1.MainText = item2.MainText Then
  119. item2.Visibility = Visibility.Collapsed
  120. Else
  121. item2.Visibility = Visibility.Visible
  122. End If
  123. ''使用 BMCLAPI 获取 OptiFine 源时进行隐藏
  124. 'If selecter.SelectIndexName = "OptiFine" Then
  125. ' If OptiFineArray.Count > 0 Then
  126. ' item1.Visibility = If(OptiFineArray(0).time = "", Visibility.Collapsed, Visibility.Visible)
  127. ' item2.Visibility = If(OptiFineArray(0).time = "", Visibility.Collapsed, Visibility.Visible)
  128. ' End If
  129. 'End If
  130. Case "Forge"
  131. If ForgeVersionState = LoadState.Success Then 'ForgeVersion
  132. '结束显示
  133. ForgeVersionState = LoadState.Loaded
  134. '加载列表
  135. panForge.Children.Clear()
  136. For Each Version As String In ForgeVersionArray
  137. '添加控件
  138. Dim item As ListItem = New ListItem With {.SubText = "", .ShowButton = False, .UseLayoutRounding = True, .CanCheck = True, .MainText = Version, .Name = "list" & GetUUID(), .Logo = New BitmapImage(New Uri("/Images/Block-Grass.png", UriKind.Relative))}
  139. AddHandler item.Change, AddressOf ChangeForgeVersionSelection
  140. panForge.Children.Add(item)
  141. Next
  142. '引发第一个的改变事件
  143. If panForge.Children.Count > 0 Then
  144. CType(panForge.Children(0), ListItem).Checked = True
  145. ChangeForgeVersionSelection(CType(panForge.Children(0), ListItem), Nothing)
  146. End If
  147. AniStart(AaStack(panForge), "DownloadLeftShowForge")
  148. scrollForge.Value = 0
  149. scrollVersion.Visibility = Visibility.Hidden
  150. Else 'Forge
  151. panVersionHost.Visibility = Visibility.Collapsed
  152. scrollVersion.Visibility = Visibility.Visible
  153. Try
  154. '结束显示
  155. ForgeState = LoadState.Loaded
  156. labRight.Content = ""
  157. Dim array = ForgeArray
  158. panVersion.Children.Clear()
  159. For Each ver As ForgeVersion In array
  160. Dim item As ListItem = New ListItem With {.UseLayoutRounding = True, .Tag = ver, .CanCheck = False, .ButtonLogo = New BitmapImage(New Uri("/Images/appbar.inbox.in.png", UriKind.Relative)), .MainText = "Forge " & ver.version, .SubText = ver.time, .Name = "list" & GetUUID(), .Logo = New BitmapImage(New Uri("/Images/Block-Anvil.png", UriKind.Relative))}
  161. AddHandler item.ButtonClick, AddressOf ForgeDownloadStart
  162. panVersion.Children.Add(item)
  163. Next
  164. Catch
  165. '时不时会出现集合已修改的Exception,事实证明重新加载一次就成了,管它啥原因嘞
  166. ForgeState = LoadState.Success
  167. End Try
  168. End If
  169. panVersionHost.Visibility = Visibility.Visible
  170. End Select
  171. Catch ex As Exception
  172. ExShow(ex, "下载列表检测时钟出错", ErrorLevel.Slient)
  173. End Try
  174. End Sub
  175. '改变左边选择条
  176. Private Sub ChangeSelection(ByVal Selection As String) Handles selecter.SelectionChange
  177. '初始化滚动条
  178. panVersion.Children.Clear()
  179. scrollVersion.ValueMe = 0
  180. '初始化页面
  181. labLoading.Content = "加载中"
  182. labLoading.Visibility = Visibility.Visible
  183. panFinish.Visibility = Visibility.Hidden
  184. scrollVersion.Visibility = Visibility.Visible
  185. '分情况处理
  186. Select Case Selection
  187. Case "Minecraft"
  188. '状态改变
  189. Select Case MinecraftState
  190. Case LoadState.Loaded
  191. '已经加载过了,需要刷新显示
  192. MinecraftState = LoadState.Success
  193. Case LoadState.Failed
  194. '加载失败,自动刷新
  195. MinecraftState = LoadState.Loading
  196. Pool.Add(New Thread(Sub() GetMinecraftBasic(True)))
  197. End Select
  198. '对应页面
  199. panForgeHost.Visibility = Visibility.Collapsed
  200. scrollForge.Visibility = Visibility.Collapsed
  201. item1.Visibility = Visibility.Visible
  202. item2.Visibility = Visibility.Visible
  203. labRight.Content = ""
  204. Case "OptiFine"
  205. '状态改变
  206. Select Case OptiFineState
  207. Case LoadState.Loaded
  208. '已经加载过了,需要刷新显示
  209. OptiFineState = LoadState.Success
  210. Case LoadState.Failed
  211. '加载失败,自动刷新
  212. OptiFineState = LoadState.Loading
  213. Pool.Add(New Thread(AddressOf GetOptiFineBasic))
  214. End Select
  215. '对应页面
  216. panForgeHost.Visibility = Visibility.Collapsed
  217. scrollForge.Visibility = Visibility.Collapsed
  218. item1.Visibility = Visibility.Visible
  219. item2.Visibility = Visibility.Visible
  220. labRight.Content = ""
  221. Case "Forge"
  222. '状态改变
  223. Select Case ForgeVersionState
  224. Case LoadState.Loaded
  225. '已经加载过了,需要刷新显示
  226. ForgeVersionState = LoadState.Success
  227. Case LoadState.Failed
  228. '加载失败,自动刷新
  229. ForgeVersionState = LoadState.Loading
  230. Pool.Add(New Thread(AddressOf GetForgeVersionBasic))
  231. End Select
  232. '对应页面
  233. panForgeHost.Visibility = Visibility.Visible
  234. scrollForge.Visibility = Visibility.Visible
  235. item1.Visibility = Visibility.Collapsed
  236. item2.Visibility = Visibility.Collapsed
  237. labRight.Content = "加载中"
  238. End Select
  239. End Sub
  240. '点击重试
  241. Private Sub labLoading_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Input.MouseButtonEventArgs) Handles labLoading.MouseDown
  242. Select Case selecter.SelectIndexName
  243. Case "Minecraft"
  244. If MinecraftState = LoadState.Failed Then
  245. Dim th As New Thread(Sub() GetMinecraftBasic(True))
  246. th.Start()
  247. End If
  248. Case "OptiFine"
  249. If OptiFineState = LoadState.Failed Then
  250. Dim th As New Thread(AddressOf GetOptiFineBasic)
  251. th.Start()
  252. End If
  253. Case "Forge"
  254. If ForgeVersionState = LoadState.Failed Then
  255. Dim th As New Thread(AddressOf GetForgeVersionBasic)
  256. th.Start()
  257. End If
  258. End Select
  259. End Sub
  260. '加载的状态
  261. Public Enum LoadState As Byte
  262. ''' <summary>
  263. ''' 正在加载
  264. ''' </summary>
  265. ''' <remarks></remarks>
  266. Loading = 0
  267. ''' <summary>
  268. ''' 已经加载结束,但是没有显示
  269. ''' </summary>
  270. ''' <remarks></remarks>
  271. Success = 1
  272. ''' <summary>
  273. ''' 加载失败
  274. ''' </summary>
  275. ''' <remarks></remarks>
  276. Failed = 2
  277. ''' <summary>
  278. ''' 加载失败(没有联网)
  279. ''' </summary>
  280. ''' <remarks></remarks>
  281. NoConnection = 3
  282. ''' <summary>
  283. ''' 已经加载结束,并且已显示,此时不执行Timer代码
  284. ''' </summary>
  285. ''' <remarks></remarks>
  286. Loaded = 4
  287. End Enum
  288. #Region "窗体基础"
  289. Dim PageLoaded As Boolean = False
  290. Private Sub panVersion_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles panVersion.Loaded
  291. Dim EnabledList As New ArrayList
  292. If ReadIni("setup", "UiHiddenMinecraft", "False") = "False" Then EnabledList.Add("Minecraft")
  293. If ReadIni("setup", "UiHiddenOptiFine", "False") = "False" Then EnabledList.Add("OptiFine")
  294. If ReadIni("setup", "UiHiddenForge", "False") = "False" Then EnabledList.Add("Forge")
  295. Select Case EnabledList.Count
  296. Case 0
  297. selecter.ShowList = {"Nothing"}
  298. panMain.Visibility = Visibility.Collapsed
  299. Case 1
  300. selecter.ShowList = EnabledList.ToArray
  301. selecter.Visibility = Visibility.Collapsed
  302. panMain.Visibility = Visibility.Visible
  303. Case 2, 3
  304. selecter.ShowList = EnabledList.ToArray
  305. selecter.Visibility = Visibility.Visible
  306. panMain.Visibility = Visibility.Visible
  307. End Select
  308. If Not PageLoaded Then
  309. PageLoaded = True
  310. panMain.UpdateLayout()
  311. End If
  312. If scrollVersion.SetControl(panVersion, True) Then AddHandler panVersionHost.MouseWheel, AddressOf scrollVersion.RunMouseWheel
  313. End Sub
  314. Private Sub panForge_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles panForge.Loaded
  315. If scrollForge.SetControl(panForge, True) Then AddHandler panForgeHost.MouseWheel, AddressOf scrollForge.RunMouseWheel
  316. End Sub
  317. Private Sub panNew_SizeChanged(ByVal sender As Object, ByVal e As System.Windows.SizeChangedEventArgs) Handles panNew.SizeChanged
  318. item2.Width = Int((panNew.ActualWidth - 9) / 2)
  319. End Sub
  320. #End Region
  321. #Region "Minecraft"
  322. Public MinecraftState As LoadState = LoadState.Failed '加载状态
  323. Public MinecraftArray As New ArrayList '代码分析的数组
  324. Public MinecraftInfo As String = "" '获取的代码
  325. Public Structure MinecraftVersion
  326. Dim id As String
  327. Dim type As String
  328. Dim url As String
  329. Dim time As String
  330. End Structure
  331. Public Sub GetMinecraftBasic(ByVal IsShowHint As Boolean)
  332. '初始化
  333. MinecraftState = LoadState.Loading
  334. MinecraftArray = New ArrayList
  335. If MODE_OFFLINE Then
  336. MinecraftState = LoadState.NoConnection
  337. Exit Sub
  338. End If
  339. '获取版本列表
  340. Try
  341. If ReadIni("setup", "DownVersion", "0") = "0" Then
  342. MinecraftInfo = GetWebsiteCode("https://launchermeta.mojang.com/mc/game/version_manifest.json", Encoding.Default)
  343. If MinecraftInfo = "" Then
  344. MinecraftInfo = GetWebsiteCode("http://bmclapi2.bangbang93.com/mc/game/version_manifest.json", Encoding.Default)
  345. If IsShowHint And Not MinecraftInfo = "" Then ShowHint("获取官方 Minecraft 版本列表失败,自动切换为 BMCLAPI")
  346. End If
  347. Else
  348. MinecraftInfo = GetWebsiteCode("http://bmclapi2.bangbang93.com/mc/game/version_manifest.json", Encoding.Default)
  349. If MinecraftInfo = "" Then
  350. MinecraftInfo = GetWebsiteCode("https://launchermeta.mojang.com/mc/game/version_manifest.json", Encoding.Default)
  351. End If
  352. End If
  353. If Len(MinecraftInfo) < 300 Then Throw New WebException("获取到的列表长度不足:" & MinecraftInfo)
  354. Catch ex As Exception
  355. ExShow(ex, "获取 Minecraft 版本列表失败")
  356. MinecraftInfo = ""
  357. MinecraftState = LoadState.Failed
  358. Exit Sub
  359. End Try
  360. log("[DownloadLeft] 获取 Minecraft 版本列表成功")
  361. '加载版本列表信息
  362. Try
  363. log("[DownloadLeft] 加载 Minecraft 版本列表信息开始")
  364. '预处理
  365. Dim ids As ArrayList = RegexSearch(MinecraftInfo, "(?<=id"": "")[^""]+")
  366. ids.AddRange(RegexSearch(MinecraftInfo, "(?<=id"":"")[^""]+"))
  367. Dim urls As ArrayList = RegexSearch(MinecraftInfo, "(?<=url"": "")[^""]+")
  368. urls.AddRange(RegexSearch(MinecraftInfo, "(?<=url"":"")[^""]+"))
  369. Dim times As ArrayList = RegexSearch(MinecraftInfo, "(?<=releaseTime"": "")[^T]+")
  370. times.AddRange(RegexSearch(MinecraftInfo, "(?<=releaseTime"":"")[^T]+"))
  371. Dim types As ArrayList = RegexSearch(MinecraftInfo, "(?<=type"": "")[^""]+")
  372. types.AddRange(RegexSearch(MinecraftInfo, "(?<=type"":"")[^""]+"))
  373. '长度检查
  374. If Not (ids.Count = urls.Count And urls.Count = times.Count And times.Count = types.Count) Then Throw New WebException("获取到的列表长度不等")
  375. '添加
  376. For i = 0 To ids.Count - 1
  377. MinecraftArray.Add(New MinecraftVersion With {.id = ids(i), .url = urls(i), .time = times(i), .type = types(i)})
  378. Next
  379. '确认最新版本
  380. If MinecraftArray.Count > 0 Then
  381. Select Case ReadIni("setup", "LastMinecraftVersion")
  382. Case ""
  383. '没有执行过,不提醒
  384. WriteIni("setup", "LastMinecraftVersion", CType(MinecraftArray(0), MinecraftVersion).id)
  385. Case CType(MinecraftArray(0), MinecraftVersion).id
  386. '相同,不提醒
  387. Case Else
  388. '不相同,提醒
  389. WriteIni("setup", "LastMinecraftVersion", CType(MinecraftArray(0), MinecraftVersion).id)
  390. If ReadIni("setup", "HomeUpdate", "True") = "True" Then
  391. If Not (ReadIni("setup", "HomeUpdateRelease", "False") = "True" And (CType(MinecraftArray(0), MinecraftVersion).id.Contains("w") Or CType(MinecraftArray(0), MinecraftVersion).id.Contains("pre"))) Then
  392. frmHomeRight.Dispatcher.Invoke(Sub() frmHomeRight.ShowUpdate("发现游戏更新:" & CType(MinecraftArray(0), MinecraftVersion).id, formHomeRight.UpdateType.MINECRAFT))
  393. End If
  394. End If
  395. End Select
  396. End If
  397. Catch ex As Exception
  398. ExShow(ex, "加载 Minecraft 版本列表信息失败")
  399. MinecraftInfo = ""
  400. MinecraftState = LoadState.Failed
  401. Exit Sub
  402. End Try
  403. log("[DownloadLeft] 加载 Minecraft 版本列表信息成功")
  404. MinecraftState = LoadState.Success
  405. End Sub
  406. Private Sub MinecraftDownloadClick(ByVal sender As ListItem, ByVal e As System.Windows.Input.MouseButtonEventArgs) Handles item1.ButtonClick, item2.ButtonClick
  407. If IsNothing(sender.Tag) Or Not selecter.SelectIndexName = "Minecraft" Then Exit Sub
  408. MinecraftDownloadStart(sender.Tag)
  409. End Sub
  410. Private Sub MinecraftDownloadStart(Ver As MinecraftVersion)
  411. Dim realID As String = Ver.id
  412. Dim local As String = PATH_MC & "versions\" & realID & "\"
  413. If WebGroups.ContainsKey("Minecraft " & realID) Or WebGroups.ContainsKey("Minecraft " & realID & " 信息") Then
  414. ShowHint(New HintConverter("正在下载中,请勿重复操作", HintState.Warn))
  415. Exit Sub
  416. End If
  417. If Not Directory.Exists(local) Then Directory.CreateDirectory(local)
  418. '检测已存在版本
  419. If GetFileSize(local & realID & ".jar") > 1024 Then
  420. If MyMsgbox("该版本已存在,是否要删除当前版本并且重新下载?", "提示", "确定", "取消") = 1 Then
  421. Try
  422. File.Delete(local & realID & ".json")
  423. File.Delete(local & realID & ".jar")
  424. Catch ex As Exception
  425. ExShow(ex, "删除版本失败", ErrorLevel.MsgboxWithoutFeedback)
  426. End Try
  427. Else
  428. Exit Sub
  429. End If
  430. End If
  431. '下载
  432. log("[DownloadLeft] 下载版本:" & realID)
  433. ShowHint("Minecraft " & realID & " 开始下载")
  434. SendStat("下载", "Minecraft", realID)
  435. Dim th As New Thread(Sub()
  436. Try
  437. Directory.CreateDirectory(local)
  438. Dim DownloadList As ArrayList
  439. If ReadIni("setup", "DownMinecraft", "1") = "0" Then
  440. '官方源优先
  441. DownloadList = New ArrayList({
  442. Ver.url.Replace("https://launcher.mojang.com", "http://bmclapi2.bangbang93.com").Replace("https://launchermeta.mojang.com", "http://bmclapi2.bangbang93.com"),
  443. Ver.url
  444. })
  445. Else
  446. 'BMCLAPI 优先
  447. DownloadList = New ArrayList({
  448. Ver.url,
  449. Ver.url.Replace("https://launcher.mojang.com", "http://bmclapi2.bangbang93.com").Replace("https://launchermeta.mojang.com", "http://bmclapi2.bangbang93.com")
  450. })
  451. End If
  452. WebStart({
  453. New WebRequireFile With {.WebURLs = DownloadList, .LocalFolder = local, .LocalName = realID & ".json", .KnownFileSize = 1024 * 2}}, "Minecraft " & realID & " 信息",
  454. Sub()
  455. Try
  456. Dim json As JObject = Newtonsoft.Json.JsonConvert.DeserializeObject(ReadFileToEnd(local & realID & ".json"))
  457. Dim size As Integer
  458. Try
  459. size = json("downloads")("client")("size").ToString
  460. Catch
  461. size = 1024 * 50
  462. End Try
  463. Dim url As New ArrayList
  464. If ReadIni("setup", "DownMinecraft", "1") = "0" Then
  465. 'Mojang 优先
  466. url.Add(json("downloads")("client")("url").ToString)
  467. url.Add(json("downloads")("client")("url").ToString.Replace("https://launcher.mojang.com", "http://bmclapi2.bangbang93.com").Replace("https://launchermeta.mojang.com", "http://bmclapi2.bangbang93.com"))
  468. url.Add(json("downloads")("client")("url").ToString)
  469. url.Add(json("downloads")("client")("url").ToString.Replace("https://launcher.mojang.com", "http://bmclapi2.bangbang93.com").Replace("https://launchermeta.mojang.com", "http://bmclapi2.bangbang93.com"))
  470. Else
  471. 'BMCLAPI 优先
  472. url.Add(json("downloads")("client")("url").ToString.Replace("https://launcher.mojang.com", "http://bmclapi2.bangbang93.com").Replace("https://launchermeta.mojang.com", "http://bmclapi2.bangbang93.com"))
  473. url.Add(json("downloads")("client")("url").ToString)
  474. url.Add(json("downloads")("client")("url").ToString.Replace("https://launcher.mojang.com", "http://bmclapi2.bangbang93.com").Replace("https://launchermeta.mojang.com", "http://bmclapi2.bangbang93.com"))
  475. url.Add(json("downloads")("client")("url").ToString)
  476. End If
  477. WebStart({New WebRequireFile With {.WebURLs = url, .LocalFolder = local, .LocalName = realID & ".jar", .KnownFileSize = size}}, "Minecraft " & realID, AddressOf MinecraftDownloadSuccess, AddressOf MinecraftDownloadFail, If(size = 1024 * 50, WebRequireSize.AtLeast, WebRequireSize.Known))
  478. Catch ex As Exception
  479. ExShow(ex, "下载版本失败:" & realID, ErrorLevel.AllUsers)
  480. Try
  481. File.Delete(local & realID & ".json")
  482. File.Delete(local & realID & ".jar")
  483. Catch : End Try
  484. Application.Current.Dispatcher.Invoke(CType(AddressOf MinecraftDownloadFail, ParameterizedThreadStart), realID)
  485. End Try
  486. End Sub,
  487. AddressOf MinecraftDownloadFail,
  488. WebRequireSize.AtLeast)
  489. Catch ex As Exception
  490. ExShow(ex, "下载版本失败:" & realID, ErrorLevel.AllUsers)
  491. Try
  492. File.Delete(local & realID & ".json")
  493. File.Delete(local & realID & ".jar")
  494. Catch : End Try
  495. Application.Current.Dispatcher.Invoke(CType(AddressOf MinecraftDownloadFail, ParameterizedThreadStart), realID)
  496. End Try
  497. End Sub)
  498. th.Start()
  499. End Sub
  500. Private Sub MinecraftDownloadSuccess(ByVal Name As String)
  501. Try
  502. Pool.Add(New Thread(AddressOf PoolVersionList))
  503. ShowHint(New HintConverter(Name & " 下载成功", HintState.Finish))
  504. Catch ex As Exception
  505. ExShow(ex, "Minecraft 下载结束后的处理异常:" & Name)
  506. ShowHint(New HintConverter(Name & " 下载失败:" & GetStringFromException(ex) & "!", HintState.Critical))
  507. End Try
  508. End Sub
  509. Private Sub MinecraftDownloadFail(ByVal Name As String)
  510. ShowHint(New HintConverter(Name & " 下载失败", HintState.Critical))
  511. End Sub
  512. Private Function MinecraftGet(VersionName As String) As MinecraftVersion
  513. If MinecraftArray.Count = 0 Then Return Nothing
  514. If VersionName.EndsWith(".0") And VersionName.StartsWith("1.") Then VersionName = Mid(VersionName, 1, Len(VersionName) - 2)
  515. '获取对应版本
  516. Dim SelectVersion As MinecraftVersion = Nothing
  517. For Each Ver As MinecraftVersion In MinecraftArray
  518. If Ver.id = VersionName Then
  519. SelectVersion = Ver
  520. Exit For
  521. End If
  522. Next
  523. Return SelectVersion
  524. End Function
  525. #End Region
  526. #Region "OptiFine"
  527. Public OptiFineState As LoadState = LoadState.Failed '加载状态
  528. Public OptiFineArray As New ArrayList '代码分析的数组
  529. Public OptiFineInfo As String = "" '获取的代码
  530. Public Structure OptiFineVersion
  531. Dim id As String
  532. Dim url As String
  533. Dim time As String
  534. Dim getByBMCLAPI As Boolean
  535. End Structure
  536. Public Sub GetOptiFineBasic()
  537. '初始化
  538. OptiFineState = LoadState.Loading
  539. OptiFineArray = New ArrayList
  540. OptiFineInfo = ""
  541. If MODE_OFFLINE Then
  542. OptiFineState = LoadState.NoConnection
  543. Exit Sub
  544. End If
  545. '官方源
  546. '获取版本列表
  547. Try
  548. log("[DownloadLeft] 获取 OptiFine 版本列表开始")
  549. OptiFineInfo = GetWebsiteCode("http://www.optifine.net/downloads", Encoding.Default)
  550. If Len(OptiFineInfo) < 200 Then Throw New WebException("获取到的列表长度不足:" & OptiFineInfo)
  551. Catch ex As Exception
  552. ExShow(ex, "获取 OptiFine 版本列表失败")
  553. OptiFineInfo = ""
  554. GoTo BMCLAPI
  555. End Try
  556. log("[DownloadLeft] 获取 OptiFine 版本列表成功")
  557. '加载版本列表信息
  558. Try
  559. '预处理
  560. Dim ids As ArrayList = RegexSearch(OptiFineInfo, "(?<=downloadLineFile(First)?'>)[^<]*")
  561. Dim urls As ArrayList = RegexSearch(OptiFineInfo, "(?<=downloadLineMirror'><a href="")[^""]*")
  562. Dim times As ArrayList = RegexSearch(OptiFineInfo, "(?<=downloadLineDate'>)[^<]*")
  563. '长度检查
  564. If Not (ids.Count = urls.Count And urls.Count = times.Count) Then Throw New WebException("获取到的列表长度不等")
  565. '添加
  566. For i = 0 To ids.Count - 1
  567. OptiFineArray.Add(New OptiFineVersion With {
  568. .id = ids(i).Replace("OptiFine ", ""),
  569. .url = urls(i),
  570. .time = times(i).ToString.Split(".")(2) & "-" & times(i).ToString.Split(".")(1) & "-" & times(i).ToString.Split(".")(0),
  571. .getByBMCLAPI = False})
  572. Next
  573. GoTo Success
  574. Catch ex As Exception
  575. ExShow(ex, "加载 OptiFine 版本列表信息失败")
  576. OptiFineInfo = ""
  577. GoTo BMCLAPI
  578. End Try
  579. 'BMCLAPI 源
  580. BMCLAPI:
  581. '获取版本列表
  582. Try
  583. log("[DownloadLeft] 使用 BMCLAPI 源获取 OptiFine 版本列表开始")
  584. OptiFineInfo = GetWebsiteCode("http://bmclapi2.bangbang93.com/optifine/versionList", Encoding.Default)
  585. If Len(OptiFineInfo) < 200 Then Throw New WebException("获取到的列表长度不足:" & OptiFineInfo)
  586. Catch ex As Exception
  587. ExShow(ex, "使用 BMCLAPI 源获取 OptiFine 版本列表失败")
  588. OptiFineInfo = ""
  589. OptiFineState = LoadState.Failed
  590. Exit Sub
  591. End Try
  592. log("[DownloadLeft] 使用 BMCLAPI 源获取 OptiFine 版本列表成功")
  593. '加载版本列表信息
  594. Try
  595. '预处理
  596. Dim filename As ArrayList = RegexSearch(OptiFineInfo, "(?<=filename"":"")[^""]*")
  597. Dim id As ArrayList = RegexSearch(OptiFineInfo, "(?<=OptiFine_).*?(?=\.jar)")
  598. '添加
  599. For i = 0 To filename.Count - 1
  600. OptiFineArray.Add(New OptiFineVersion With {
  601. .id = id(i).Replace("_", " "),
  602. .url = "http://optifine.net/adloadx?f=" & filename(i),
  603. .time = "",
  604. .getByBMCLAPI = True
  605. })
  606. Next
  607. If selecter.SelectIndexName = "OptiFine" Then ShowHint("OptiFine 官方列表获取失败,列表由 BMCLAPI 提供")
  608. GoTo Success
  609. Catch ex As Exception
  610. ExShow(ex, "加载 OptiFine 版本列表信息失败")
  611. OptiFineInfo = ""
  612. OptiFineState = LoadState.Failed
  613. Exit Sub
  614. End Try
  615. Success:
  616. log("[DownloadLeft] 加载 OptiFine 版本列表信息成功")
  617. OptiFineState = LoadState.Success
  618. End Sub
  619. Private Sub OptiFineDownloadStart(ByVal sender As ListItem, ByVal e As System.Windows.Input.MouseButtonEventArgs) Handles item1.ButtonClick, item2.ButtonClick
  620. If IsNothing(sender.Tag) Or Not selecter.SelectIndexName = "OptiFine" Then Exit Sub
  621. '初始化信息
  622. Dim ver As OptiFineVersion = sender.Tag
  623. If WebGroups.ContainsKey("OptiFine " & ver.id) Then
  624. ShowHint(New HintConverter("正在下载中,请勿重复操作", HintState.Warn))
  625. Exit Sub
  626. End If
  627. '获取数据
  628. Try
  629. sender.ShowButton = False
  630. Dim Version As String = Split(ver.id)(0)
  631. Dim BMCLAPIAddress As String = ""
  632. If ver.id.Contains("pre") Then
  633. BMCLAPIAddress = "http://bmclapi2.bangbang93.com/maven/com/optifine/" & ver.id.Split(" ")(0) & "/preview_OptiFine_" & ver.id.Replace(" ", "_").Replace("_pre", "") & ".jar"
  634. Else
  635. BMCLAPIAddress = "http://bmclapi2.bangbang93.com/maven/com/optifine/" & ver.id.Split(" ")(0) & "/OptiFine_" & ver.id.Replace(" ", "_") & ".jar"
  636. End If
  637. '下载
  638. log("[DownloadLeft] 下载 OptiFine:" & ver.id)
  639. ShowHint("OptiFine " & ver.id & " 开始下载")
  640. SendStat("下载", "OptiFine", ver.id)
  641. Dim th As New Thread(Sub()
  642. Try
  643. If ver.getByBMCLAPI Then
  644. WebStart({New WebRequireFile With {.WebURLs = New ArrayList From {
  645. BMCLAPIAddress,
  646. BMCLAPIAddress
  647. }, .LocalFolder = PATH_DOWNLOAD, .LocalName = "OptiFine_" & ver.id.Replace(" ", "_") & ".jar", .KnownFileSize = 1024 * 64}
  648. }, "OptiFine " & ver.id, AddressOf OptiFineDownloadSuccess, AddressOf OptiFineDownloadFail, WebRequireSize.AtLeast)
  649. Else
  650. Dim OfficialAddress As String = ""
  651. Try
  652. OfficialAddress = RegexSearch(GetWebsiteCode(ver.url, New UTF8Encoding(False)), "(?<=Download[^\\s\\S]+a href="")[^""]+")(0)
  653. Catch
  654. End Try
  655. If ReadIni("setup", "DownOptiFine", "1") = "0" Then
  656. '官方
  657. WebStart({New WebRequireFile With {.WebURLs = New ArrayList From {
  658. "http://optifine.net/" & OfficialAddress,
  659. BMCLAPIAddress,
  660. "http://optifine.net/" & OfficialAddress,
  661. BMCLAPIAddress
  662. }, .LocalFolder = PATH_DOWNLOAD, .LocalName = "OptiFine_" & ver.id.Replace(" ", "_") & ".jar", .KnownFileSize = 1024 * 64}
  663. }, "OptiFine " & ver.id, AddressOf OptiFineDownloadSuccess, AddressOf OptiFineDownloadFail, WebRequireSize.AtLeast)
  664. Else
  665. 'BMCLAPI
  666. WebStart({New WebRequireFile With {.WebURLs = New ArrayList From {
  667. BMCLAPIAddress,
  668. "http://optifine.net/" & OfficialAddress,
  669. BMCLAPIAddress,
  670. "http://optifine.net/" & OfficialAddress
  671. }, .LocalFolder = PATH_DOWNLOAD, .LocalName = "OptiFine_" & ver.id.Replace(" ", "_") & ".jar", .KnownFileSize = 1024 * 64}
  672. }, "OptiFine " & ver.id, AddressOf OptiFineDownloadSuccess, AddressOf OptiFineDownloadFail, WebRequireSize.AtLeast)
  673. End If
  674. End If
  675. Catch ex As Exception
  676. ExShow(ex, "下载 OptiFine 失败:" & ver.id)
  677. Application.Current.Dispatcher.Invoke(CType(AddressOf OptiFineDownloadFail, ParameterizedThreadStart), ver.id)
  678. End Try
  679. frmMain.Dispatcher.Invoke(Sub() sender.ShowButton = True)
  680. End Sub)
  681. th.Start()
  682. '检查引用版本
  683. If GetFileSize(PATH_MC & "versions\" & Version & "\" & Version & ".jar") < 1024 Then
  684. '引用版本不存在
  685. log("[DownloadLeft] OptiFine 对应的引用版本不存在:" & Version)
  686. Dim RequireVersion As MinecraftVersion = MinecraftGet(Version)
  687. If Not IsNothing(RequireVersion.id) Then MinecraftDownloadStart(RequireVersion)
  688. End If
  689. Catch ex As Exception
  690. ExShow(ex, "处理下载地址时出错", ErrorLevel.MsgboxAndFeedback)
  691. Exit Sub
  692. End Try
  693. End Sub
  694. Private Sub OptiFineDownloadSuccess(ByVal Name As String)
  695. Dim Version As String = Name.Replace("OptiFine ", "")
  696. Try
  697. 'If ReadIni("setup", "DownOptiFineOpen", "True") Then RunCMD(PATH_DOWNLOAD & "OptiFine_" & Version.Replace(" ", "_") & ".jar", False)
  698. Process.Start(PATH_DOWNLOAD)
  699. ShowHint(New HintConverter("OptiFine " & Version & " 下载成功", HintState.Finish))
  700. Catch ex As Exception
  701. ExShow(ex, "OptiFine 下载结束后的处理异常")
  702. Try
  703. File.Delete(PATH_DOWNLOAD & "OptiFine_" & Version.Replace(" ", "_") & ".jar")
  704. Catch : End Try
  705. ShowHint(New HintConverter("OptiFine " & Version & " 下载失败:" & GetStringFromException(ex) & "!", HintState.Critical))
  706. End Try
  707. End Sub
  708. Private Sub OptiFineDownloadFail(ByVal Name As String)
  709. Dim Version As String = Name.Replace("OptiFine ", "")
  710. ShowHint(New HintConverter("OptiFine " & Version & " 下载失败", HintState.Critical))
  711. End Sub
  712. #End Region
  713. #Region "ForgeVersion"
  714. Public ForgeVersionState As LoadState = LoadState.Failed '加载状态
  715. Public ForgeVersionArray As New ArrayList '代码分析的数组
  716. Public ForgeVersionInfo As String = "" '获取的代码
  717. Public Sub GetForgeVersionBasic()
  718. '初始化
  719. ForgeVersionState = LoadState.Loading
  720. ForgeVersionArray = New ArrayList
  721. ForgeVersionInfo = ""
  722. If MODE_OFFLINE Then
  723. ForgeVersionState = LoadState.NoConnection
  724. Exit Sub
  725. End If
  726. '获取版本列表
  727. Try
  728. log("[DownloadLeft] 获取Forge可用版本列表开始")
  729. ForgeVersionInfo = GetWebsiteCode("http://bmclapi2.bangbang93.com/forge/minecraft", Encoding.Default)
  730. If Len(ForgeVersionInfo) < 40 Then Throw New WebException("获取到的列表长度不足:" & ForgeVersionInfo)
  731. Catch ex As Exception
  732. ExShow(ex, "获取Forge可用版本列表失败")
  733. ForgeVersionInfo = ""
  734. ForgeVersionState = LoadState.Failed
  735. Exit Sub
  736. End Try
  737. log("[DownloadLeft] 获取Forge可用版本列表成功")
  738. '加载版本列表信息
  739. Try
  740. '添加
  741. 'ForgeVersionArray.AddRange(ForgeVersionInfo.Replace("[", "").Replace("]", "").Replace("""", "").Replace("null", "").Replace(",,", "").Split(",")) 'RegexSearch(ForgeVersionInfo, "1.([7-9]{1}.[0-9]+|[0-9]{2}[0-9.]*)(?="")")
  742. ForgeVersionArray = RegexSearch(ForgeVersionInfo, "1.([0-9]{1,2}.[0-9]+|[0-9]{1,2}[0-9.]*)(?="")")
  743. '排序
  744. Dim CurrentPosition As Integer = 1
  745. ForgeVersionArray.Reverse()
  746. Do While CurrentPosition <= ForgeVersionArray.Count - 1
  747. If CurrentPosition < 1 Then CurrentPosition = 1
  748. Dim Smaller() As String = ForgeVersionArray(CurrentPosition).ToString.Split(".")
  749. Dim Larger() As String = ForgeVersionArray(CurrentPosition - 1).ToString.Split(".")
  750. '比较大小
  751. For i = 0 To 2
  752. Select Case Val(If(Larger.Length >= i + 1, Larger(i), "0"))
  753. Case Val(If(Smaller.Length >= i + 1, Smaller(i), "0"))
  754. '相等则不处理,继续比较下一位
  755. Case Is < Val(If(Smaller.Length >= i + 1, Smaller(i), "0"))
  756. '较小
  757. GoTo Swap
  758. Case Else
  759. '较大
  760. GoTo Finish
  761. End Select
  762. Next
  763. GoTo Finish
  764. Swap:
  765. Dim c As String = ForgeVersionArray(CurrentPosition)
  766. ForgeVersionArray(CurrentPosition) = ForgeVersionArray(CurrentPosition - 1)
  767. ForgeVersionArray(CurrentPosition - 1) = c
  768. CurrentPosition = CurrentPosition - 2
  769. Finish:
  770. CurrentPosition = CurrentPosition + 1
  771. Loop
  772. Catch ex As Exception
  773. ExShow(ex, "加载Forge可用版本列表信息失败")
  774. ForgeVersionInfo = ""
  775. ForgeVersionState = LoadState.Failed
  776. Exit Sub
  777. End Try
  778. log("[DownloadLeft] 加载Forge可用版本列表信息成功")
  779. ForgeVersionState = LoadState.Success
  780. End Sub
  781. Private Sub ChangeForgeVersionSelection(ByVal sender As ListItem, ByVal e As EventArgs)
  782. If Not sender.Checked Then Exit Sub
  783. panVersion.Children.Clear()
  784. scrollVersion.Visibility = Visibility.Collapsed
  785. scrollVersion.Value = 0
  786. labRight.Content = "加载中"
  787. ForgeCurrent = sender.MainText
  788. Dim th = New Thread(AddressOf GetForgeBasic)
  789. th.Start(sender.MainText)
  790. End Sub
  791. #End Region
  792. #Region "Forge"
  793. Public ForgeState As LoadState = LoadState.Loading '加载状态
  794. Public ForgeArray As New ArrayList '代码分析的数组
  795. Public ForgeInfo As String = "" '获取的代码
  796. Public ForgeCurrent As String = "" '目前的加载版本
  797. Public Structure ForgeVersion
  798. Dim version As String
  799. Dim build As String
  800. Dim time As String
  801. Dim branch As String
  802. End Structure
  803. Public Sub GetForgeBasic(ByVal version As String)
  804. Try
  805. '初始化
  806. ForgeState = LoadState.Loading
  807. ForgeArray = New ArrayList
  808. ForgeInfo = ""
  809. If MODE_OFFLINE Then
  810. ForgeState = LoadState.NoConnection
  811. Exit Sub
  812. End If
  813. '获取版本列表
  814. Try
  815. log("[DownloadLeft] 获取Forge版本列表开始:" & version)
  816. Dim Data = GetWebsiteCode("http://bmclapi2.bangbang93.com/forge/minecraft/" & version, Encoding.Default)
  817. If Not ForgeCurrent = version Then Exit Sub
  818. ForgeInfo = Data
  819. If Len(ForgeInfo) < 400 Then Throw New WebException("获取到的列表长度不足:" & ForgeInfo)
  820. Catch ex As Exception
  821. ExShow(ex, "获取Forge版本列表失败:" & version)
  822. ForgeInfo = ""
  823. ForgeState = LoadState.Failed
  824. Exit Sub
  825. End Try
  826. log("[DownloadLeft] 获取Forge版本列表成功")
  827. '加载版本列表信息
  828. Try
  829. log("[DownloadLeft] 加载Forge版本列表信息开始")
  830. '预处理
  831. Dim builds As ArrayList = RegexSearch(ForgeInfo, "(?<=""build"":)[0-9]*")
  832. Dim versions As ArrayList = RegexSearch(ForgeInfo, "(?<=""version"":"")[0-9.]*")
  833. Dim branchs As ArrayList = RegexSearch(ForgeInfo, "(?<=""branch"":)[^,]*")
  834. Dim times As ArrayList = RegexSearch(ForgeInfo, "(?<=modified"":"")[0-9.\-]*")
  835. '检查
  836. If Not (builds.Count = versions.Count And versions.Count = times.Count And branchs.Count = times.Count) Then Throw New WebException("获取到的列表长度不等")
  837. If Not ForgeCurrent = version Then Exit Sub
  838. '添加
  839. For i = builds.Count - 1 To 0 Step -1
  840. ForgeArray.Add(New ForgeVersion With {.build = builds(i), .version = versions(i), .time = times(i), .branch = branchs(i)})
  841. Next
  842. Catch ex As Exception
  843. ExShow(ex, "加载Forge版本列表信息失败:" & version)
  844. ForgeInfo = ""
  845. ForgeState = LoadState.Failed
  846. Exit Sub
  847. End Try
  848. log("[DownloadLeft] 加载Forge版本列表信息成功")
  849. ForgeState = LoadState.Success
  850. Catch
  851. End Try
  852. End Sub
  853. Private Sub ForgeDownloadStart(ByVal sender As ListItem, ByVal e As System.Windows.Input.MouseButtonEventArgs)
  854. If IsNothing(sender.Tag) Or Not selecter.SelectIndexName = "Forge" Then Exit Sub
  855. '初始化信息
  856. Dim ver As ForgeVersion = sender.Tag
  857. If WebGroups.ContainsKey("Forge " & ver.version) Then
  858. ShowHint(New HintConverter("正在下载中,请勿重复操作", HintState.Warn))
  859. Exit Sub
  860. End If
  861. '选择操作
  862. If Val(ReadIni("setup", "DownForgeAction", "-1")) = "-1" Then
  863. WriteIni("setup", "DownForgeAction", MyMsgbox("在 Forge 下载结束后,是自动安装该版本,还是打开下载文件夹但是不安装?你稍候可以在设置页面中再修改这个设置。" & vbCrLf & "如果你不清楚如何手动安装 Forge,建议选择自动安装。", "选择默认动作", "自动安装", "只打开文件夹") - 1)
  864. End If
  865. '下载
  866. log("[DownloadLeft] 下载Forge:" & ver.build)
  867. ShowHint("Forge " & ver.version & " 开始下载")
  868. SendStat("下载", "Forge", ver.version, ver.build)
  869. Dim th As New Thread(Sub()
  870. Try
  871. Dim FileName As String = ForgeCurrent & "-" & ver.version & If(ver.branch = "null", "", "-" & ver.branch.Replace("""", ""))
  872. WebStart({New WebRequireFile With {
  873. .WebURLs = New ArrayList From {
  874. "http://bmclapi2.bangbang93.com/forge/download/" & ver.build,
  875. "http://bmclapi2.bangbang93.com/maven/net/minecraftforge/forge/" & FileName & "/forge-" & FileName & "-installer.jar",
  876. "http://files.minecraftforge.net/maven/net/minecraftforge/forge/" & FileName & "/forge-" & FileName & "-installer.jar",
  877. "http://bmclapi2.bangbang93.com/maven/net/minecraftforge/forge/" & FileName & "/forge-" & FileName & "-universal.zip",
  878. "http://files.minecraftforge.net/maven/net/minecraftforge/forge/" & FileName & "/forge-" & FileName & "-universal.zip",
  879. "http://bmclapi2.bangbang93.com/maven/net/minecraftforge/forge/" & FileName & "/forge-" & FileName & "-universal.jar",
  880. "http://files.minecraftforge.net/maven/net/minecraftforge/forge/" & FileName & "/forge-" & FileName & "-universal.jar",
  881. "http://bmclapi2.bangbang93.com/maven/net/minecraftforge/forge/" & FileName & "/forge-" & FileName & "-client.zip",
  882. "http://files.minecraftforge.net/maven/net/minecraftforge/forge/" & FileName & "/forge-" & FileName & "-client.zip"},
  883. .LocalFolder = PATH_DOWNLOAD, .KnownFileSize = 1024 * 16
  884. }}, "Forge " & ver.version, AddressOf ForgeDownloadSuccess, AddressOf ForgeDownloadFail, WebRequireSize.AtLeast)
  885. Catch ex As Exception
  886. ExShow(ex, "下载Forge失败:" & ver.version)
  887. Application.Current.Dispatcher.Invoke(CType(AddressOf ForgeDownloadFail, ParameterizedThreadStart), ver.version)
  888. End Try
  889. End Sub)
  890. th.Start()
  891. '检查引用版本
  892. If GetFileSize(PATH_MC & "versions\" & ForgeCurrent & "\" & ForgeCurrent & ".jar") < 1024 Then
  893. '引用版本不存在
  894. log("[DownloadLeft] Forge 对应的引用版本不存在:" & ForgeCurrent)
  895. Dim RequireVersion As MinecraftVersion = MinecraftGet(ForgeCurrent)
  896. If Not IsNothing(RequireVersion.id) Then MinecraftDownloadStart(RequireVersion)
  897. End If
  898. End Sub
  899. Private Sub ForgeDownloadSuccess(ByVal Name As String)
  900. Dim Version = Name.Replace("Forge ", "")
  901. Try
  902. If Val(ReadIni("setup", "DownForgeAction", "1")) = 0 Then
  903. '自动安装
  904. Try
  905. Dim FoundFile As Boolean = False
  906. For Each File As FileInfo In New DirectoryInfo(PATH_DOWNLOAD).EnumerateFiles
  907. If File.Name.Contains(Version) Then
  908. log("[DownloadLeft] 自动安装目标文件:" & File.FullName)
  909. FoundFile = True
  910. If Not File.Name.Contains("installer") Then
  911. NotSupport:
  912. ShowHint(New HintConverter("Forge " & Version & " 下载成功,但该版本过老,不支持自动安装", HintState.Finish))
  913. Process.Start(PATH_DOWNLOAD)
  914. Exit Sub
  915. End If
  916. '自动安装
  917. Dim InstallDir As String = PATH & "PCL\cache\forgeinstall\" & Version
  918. Directory.CreateDirectory(InstallDir)
  919. Using zip As New ZipFile(File.FullName)
  920. zip.ExtractSelectedEntries("install_profile.json", "", InstallDir, ExtractExistingFileAction.OverwriteSilently)
  921. Dim Json As JObject = ReadJson(ReadFileToEnd(InstallDir & "\install_profile.json"))
  922. '判断是否为 1.5-1.6 的 Forge
  923. Dim FilePath As String = Json("install")("filePath").ToString
  924. If FilePath.Contains("-1.5") Or FilePath.Contains("-1.6") Then
  925. Directory.Delete(InstallDir, True)
  926. GoTo NotSupport
  927. End If
  928. ShowHint(New HintConverter("Forge " & Version & " 下载成功", HintState.Finish))
  929. '解压Forge主文件
  930. Dim LibPath As String = GetPathFromFullPath(GetPathFromLibrary(Json("install")("path")))
  931. Directory.CreateDirectory(LibPath)
  932. zip.ExtractSelectedEntries(FilePath, "", LibPath, ExtractExistingFileAction.OverwriteSilently)
  933. IO.File.Delete(GetPathFromLibrary(Json("install")("path")))
  934. FileSystem.Rename(LibPath & FilePath, GetPathFromLibrary(Json("install")("path")))
  935. '输出Json
  936. Dim VersionId As String = Json("versionInfo")("id")
  937. Dim VersionPath As String = PATH_MC & "versions\" & VersionId & "\"
  938. Directory.CreateDirectory(VersionPath)
  939. WriteFile(VersionPath & VersionId & ".json", Json("versionInfo").ToString)
  940. '删除缓存文件夹
  941. Directory.Delete(InstallDir, True)
  942. '刷新版本列表
  943. Dim th As New Thread(AddressOf PoolVersionList)
  944. th.Start()
  945. End Using
  946. ShowHint(New HintConverter("Forge " & Version & " 安装成功", HintState.Finish))
  947. End If
  948. If FoundFile Then GoTo FoundFile
  949. Next
  950. ShowHint(New HintConverter("Forge " & Version & " 下载成功,但未找到自动安装文件", HintState.Finish))
  951. FoundFile:
  952. Catch ex As Exception
  953. ExShow(ex, "Forge " & Version & " 安装失败", ErrorLevel.AllUsers)
  954. End Try
  955. Else
  956. '只打开文件夹
  957. Process.Start(PATH_DOWNLOAD)
  958. ShowHint(New HintConverter("Forge " & Version & " 下载成功", HintState.Finish))
  959. End If
  960. Catch ex As Exception
  961. ExShow(ex, "Forge下载结束后的处理异常:" & Version)
  962. Try
  963. File.Delete(PATH_DOWNLOAD & "Forge_" & Version & ".jar")
  964. Catch : End Try
  965. ShowHint(New HintConverter("Forge " & Version & " 下载失败:" & GetStringFromException(ex) & "!", HintState.Critical))
  966. End Try
  967. End Sub
  968. Private Sub ForgeDownloadFail(ByVal Name As String)
  969. Dim Version As String = Name.Replace("Forge ", "")
  970. ShowHint(New HintConverter("Forge " & Version & " 下载失败", HintState.Critical))
  971. End Sub
  972. #End Region
  973. End Class