PageVersionMod.xaml.vb 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569
  1. Public Class PageVersionMod
  2. #Region "初始化"
  3. Private IsLoad As Boolean = False
  4. Public Sub PageOther_Loaded() Handles Me.Loaded
  5. PanBack.ScrollToHome()
  6. AniControlEnabled += 1
  7. SelectedMods.Clear()
  8. RefreshList()
  9. ChangeAllSelected(False)
  10. AniControlEnabled -= 1
  11. '非重复加载部分
  12. If IsLoad Then Exit Sub
  13. IsLoad = True
  14. #If DEBUG Then
  15. BtnManageCheck.Visibility = Visibility.Visible
  16. #End If
  17. End Sub
  18. ''' <summary>
  19. ''' 刷新 Mod 列表。
  20. ''' </summary>
  21. Public Sub RefreshList(Optional ForceReload As Boolean = False)
  22. If McModLoader.State = LoadState.Loading Then Exit Sub
  23. If LoaderFolderRun(McModLoader, PageVersionLeft.Version.PathIndie & "mods\", If(ForceReload, LoaderFolderRunType.ForceRun, LoaderFolderRunType.RunOnUpdated)) Then
  24. Log("[System] 已刷新 Mod 列表")
  25. PanBack.ScrollToHome()
  26. SearchBox.Text = ""
  27. End If
  28. End Sub
  29. Private Sub LoaderInit() Handles Me.Initialized
  30. PageLoaderInit(Load, PanLoad, PanAllBack, Nothing, McModLoader, AddressOf Load_Finish, AutoRun:=False)
  31. End Sub
  32. Private Sub Load_Click(sender As Object, e As MouseButtonEventArgs) Handles Load.Click
  33. If McModLoader.State = LoadState.Failed Then
  34. LoaderFolderRun(McModLoader, PageVersionLeft.Version.PathIndie & "mods\", LoaderFolderRunType.ForceRun)
  35. End If
  36. End Sub
  37. #End Region
  38. #Region "UI 化"
  39. Private PanItems As StackPanel
  40. ''' <summary>
  41. ''' 将 Mod 列表加载为 UI。
  42. ''' </summary>
  43. Private Sub Load_Finish(Loader As LoaderTask(Of String, List(Of McMod)))
  44. Dim List As List(Of McMod) = Loader.Output
  45. Try
  46. PanList.Children.Clear()
  47. '判断应该显示哪一个页面
  48. If List.Count = 0 Then
  49. PanEmpty.Visibility = Visibility.Visible
  50. PanBack.Visibility = Visibility.Collapsed
  51. Exit Sub
  52. Else
  53. PanBack.Visibility = Visibility.Visible
  54. PanEmpty.Visibility = Visibility.Collapsed
  55. End If
  56. SearchBox.Text = ""
  57. '建立 StackPanel
  58. PanItems = New StackPanel With {.Margin = New Thickness(20, 38, 18, If(List.Count > 0, 20, 0)), .VerticalAlignment = VerticalAlignment.Top, .RenderTransform = New TranslateTransform(0, 0)}
  59. For Each ModEntity As McMod In List
  60. PanItems.Children.Add(McModListItem(ModEntity))
  61. Next
  62. '建立 MyCard
  63. Dim NewCard As New MyCard With {.Title = McModGetTitle(List), .Margin = New Thickness(0, 0, 0, 15)}
  64. NewCard.Children.Add(PanItems)
  65. PanList.Children.Add(NewCard)
  66. Catch ex As Exception
  67. Log(ex, "加载 Mod 列表 UI 失败", LogLevel.Feedback)
  68. End Try
  69. End Sub
  70. ''' <summary>
  71. ''' 获取 Card 的标题。
  72. ''' </summary>
  73. Private Function McModGetTitle(List As List(Of McMod)) As String
  74. Dim Counter = {0, 0, 0}
  75. For Each ModEntity As McMod In List
  76. Counter(ModEntity.State) += 1
  77. Next
  78. If List.Count = 0 Then Return "未找到任何 Mod"
  79. Dim TypeList As New List(Of String)
  80. If Counter(McMod.McModState.Fine) > 0 Then TypeList.Add("启用 " & Counter(McMod.McModState.Fine))
  81. If Counter(McMod.McModState.Disabled) > 0 Then TypeList.Add("禁用 " & Counter(McMod.McModState.Disabled))
  82. If Counter(McMod.McModState.Unavaliable) > 0 Then TypeList.Add("错误 " & Counter(McMod.McModState.Unavaliable))
  83. Return "Mod 列表(" & Join(TypeList, ",") & ")"
  84. End Function
  85. Private Function McModListItem(Entry As McMod) As MyLocalModItem
  86. AniControlEnabled += 1
  87. Dim NewItem As New MyLocalModItem With {.SnapsToDevicePixels = True, .Entry = Entry,
  88. .ButtonHandler = AddressOf McModContent, .Checked = SelectedMods.Contains(Entry.RawFileName)}
  89. AddHandler Entry.OnGetCompProject, AddressOf NewItem.Refresh
  90. NewItem.Refresh()
  91. AniControlEnabled -= 1
  92. Return NewItem
  93. End Function
  94. Private Sub McModContent(sender As MyLocalModItem, e As EventArgs)
  95. '点击事件
  96. AddHandler sender.Changed, AddressOf CheckChanged
  97. AddHandler sender.Click, Sub(ss As MyLocalModItem, ee As EventArgs) ss.Checked = Not ss.Checked
  98. '图标按钮
  99. Dim BtnOpen As New MyIconButton With {.LogoScale = 1.15, .Logo = Logo.IconButtonOpen, .Tag = sender}
  100. BtnOpen.ToolTip = "打开文件位置"
  101. ToolTipService.SetPlacement(BtnOpen, Primitives.PlacementMode.Center)
  102. ToolTipService.SetVerticalOffset(BtnOpen, 30)
  103. ToolTipService.SetHorizontalOffset(BtnOpen, 2)
  104. AddHandler BtnOpen.Click, AddressOf Open_Click
  105. Dim BtnCont As New MyIconButton With {.LogoScale = 1.05, .Logo = Logo.IconButtonInfo, .Tag = sender}
  106. BtnCont.ToolTip = "详情"
  107. ToolTipService.SetPlacement(BtnCont, Primitives.PlacementMode.Center)
  108. ToolTipService.SetVerticalOffset(BtnCont, 30)
  109. ToolTipService.SetHorizontalOffset(BtnCont, 2)
  110. AddHandler BtnCont.Click, AddressOf Info_Click
  111. AddHandler sender.MouseRightButtonDown, AddressOf Info_Click
  112. sender.Buttons = {BtnCont, BtnOpen}
  113. End Sub
  114. #End Region
  115. #Region "管理"
  116. ''' <summary>
  117. ''' 打开 Mods 文件夹。
  118. ''' </summary>
  119. Private Sub BtnManageOpen_Click(sender As Object, e As EventArgs) Handles BtnManageOpen.Click, BtnHintOpen.Click
  120. Try
  121. Directory.CreateDirectory(PageVersionLeft.Version.PathIndie & "mods\")
  122. OpenExplorer("""" & PageVersionLeft.Version.PathIndie & "mods\""")
  123. Catch ex As Exception
  124. Log(ex, "打开 Mods 文件夹失败", LogLevel.Msgbox)
  125. End Try
  126. End Sub
  127. #If DEBUG Then
  128. ''' <summary>
  129. ''' 检查 Mod。
  130. ''' </summary>
  131. Private Sub BtnManageCheck_Click(sender As Object, e As EventArgs) Handles BtnManageCheck.Click
  132. Try
  133. Dim Result = McModCheck(PageVersionLeft.Version, McModLoader.Output)
  134. If Result.Count > 0 Then
  135. MyMsgBox(Join(Result, vbCrLf & vbCrLf), "Mod 检查结果")
  136. Else
  137. Hint("Mod 检查完成,未发现任何问题!", HintType.Finish)
  138. End If
  139. Catch ex As Exception
  140. Log(ex, "进行 Mod 检查时出错", LogLevel.Feedback)
  141. End Try
  142. End Sub
  143. #End If
  144. ''' <summary>
  145. ''' 全选。
  146. ''' </summary>
  147. Private Sub BtnManageSelectAll_Click(sender As Object, e As MouseButtonEventArgs) Handles BtnManageSelectAll.Click
  148. If SelectedMods.Count < If(IsSearching, PanSearchList.Children.Count, McModLoader.Output.Count) Then
  149. ChangeAllSelected(True)
  150. Else
  151. ChangeAllSelected(False)
  152. End If
  153. End Sub
  154. #End Region
  155. #Region "选择"
  156. '选择的 Mod 的路径(不含 .disabled)
  157. Public SelectedMods As New List(Of String)
  158. '单项切换选择状态
  159. Public Sub CheckChanged(sender As MyLocalModItem, e As RouteEventArgs)
  160. If AniControlEnabled <> 0 Then Return
  161. '更新选择了的内容
  162. Dim SelectedKey As String = sender.Entry.RawFileName
  163. If sender.Checked Then
  164. If Not SelectedMods.Contains(SelectedKey) Then SelectedMods.Add(SelectedKey)
  165. Else
  166. SelectedMods.Remove(SelectedKey)
  167. End If
  168. '更新下边栏 UI
  169. RefreshBottomBar()
  170. End Sub
  171. '改变下边栏状态
  172. Private ShownCount As Integer = 0
  173. Private Sub RefreshBottomBar()
  174. '计数
  175. Dim NewCount As Integer = SelectedMods.Count
  176. Dim Selected = NewCount > 0
  177. If Selected Then LabSelect.Text = $"已选择 {NewCount} 个文件" '取消所有选择时不更新数字
  178. '按钮可用性
  179. If Selected Then
  180. Dim HasEnabled As Boolean = False
  181. Dim HasDisabled As Boolean = False
  182. For Each ModEntity In McModLoader.Output
  183. If SelectedMods.Contains(ModEntity.RawFileName) Then
  184. If ModEntity.State = McMod.McModState.Fine Then
  185. HasEnabled = True
  186. ElseIf ModEntity.State = McMod.McModState.Disabled Then
  187. HasDisabled = True
  188. End If
  189. End If
  190. Next
  191. BtnSelectDisable.IsEnabled = HasEnabled
  192. BtnSelectEnable.IsEnabled = HasDisabled
  193. End If
  194. '更新显示状态
  195. CardSelect.IsHitTestVisible = Selected
  196. If AniControlEnabled = 0 Then
  197. If Selected Then
  198. '仅在数量增加时播放出现/跳跃动画
  199. If ShownCount >= NewCount Then
  200. ShownCount = NewCount
  201. Return
  202. Else
  203. ShownCount = NewCount
  204. End If
  205. '出现/跳跃动画
  206. CardSelect.Visibility = Visibility.Visible
  207. AniStart({
  208. AaOpacity(CardSelect, 1 - CardSelect.Opacity, 60),
  209. AaTranslateY(CardSelect, -27 - TransSelect.Y, 120, Ease:=New AniEaseOutFluent(AniEasePower.Weak)),
  210. AaTranslateY(CardSelect, 3, 150, 120, Ease:=New AniEaseInoutFluent(AniEasePower.Weak)),
  211. AaTranslateY(CardSelect, -1, 90, 270, Ease:=New AniEaseInoutFluent(AniEasePower.Weak))
  212. }, "Mod Sidebar")
  213. Else
  214. '不重复播放隐藏动画
  215. If ShownCount = 0 Then Return
  216. ShownCount = 0
  217. '隐藏动画
  218. AniStart({
  219. AaOpacity(CardSelect, -CardSelect.Opacity, 90),
  220. AaTranslateY(CardSelect, -10 - TransSelect.Y, 90, Ease:=New AniEaseInFluent(AniEasePower.Weak)),
  221. AaCode(Sub() CardSelect.Visibility = Visibility.Collapsed, After:=True)
  222. }, "Mod Sidebar")
  223. End If
  224. Else
  225. AniStop("Mod Sidebar")
  226. ShownCount = NewCount
  227. If Selected Then
  228. CardSelect.Visibility = Visibility.Visible
  229. CardSelect.Opacity = 1
  230. TransSelect.Y = -25
  231. Else
  232. CardSelect.Visibility = Visibility.Collapsed
  233. CardSelect.Opacity = 0
  234. TransSelect.Y = -10
  235. End If
  236. End If
  237. End Sub
  238. '切换所有项的选择状态
  239. Private Sub ChangeAllSelected(Value As Boolean)
  240. AniControlEnabled += 1
  241. SelectedMods.Clear()
  242. If IsSearching Then
  243. '搜索中
  244. For Each Item As MyLocalModItem In PanSearchList.Children
  245. Item.Checked = Value
  246. If Value Then SelectedMods.Add(Item.Entry.RawFileName)
  247. Next
  248. If Not Value Then '只取消选择
  249. If PanItems IsNot Nothing Then
  250. For Each Item As MyLocalModItem In PanItems.Children
  251. Item.Checked = Value
  252. Next
  253. End If
  254. End If
  255. Else
  256. '非搜索中
  257. If PanItems IsNot Nothing Then
  258. For Each Item As MyLocalModItem In PanItems.Children
  259. Item.Checked = Value
  260. If Value Then SelectedMods.Add(Item.Entry.RawFileName)
  261. Next
  262. End If
  263. End If
  264. AniControlEnabled -= 1
  265. '更新下边栏 UI
  266. RefreshBottomBar()
  267. End Sub
  268. Private Sub UnselectedAllWithAnimation() Handles Load.StateChanged, Me.PageExit
  269. Dim CacheAniControlEnabled = AniControlEnabled
  270. AniControlEnabled = 0
  271. ChangeAllSelected(False)
  272. AniControlEnabled += CacheAniControlEnabled
  273. End Sub
  274. Private Sub PageVersionMod_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
  275. If My.Computer.Keyboard.CtrlKeyDown AndAlso e.Key = Key.A Then ChangeAllSelected(True)
  276. End Sub
  277. #End Region
  278. #Region "下边栏"
  279. '启用 / 禁用
  280. Private Sub BtnSelectEorD_Click(sender As MyIconTextButton, e As RouteEventArgs) Handles BtnSelectEnable.Click, BtnSelectDisable.Click
  281. Dim IsSuccessful As Boolean = True
  282. Dim IsDisable As Boolean = sender.Equals(BtnSelectDisable)
  283. For Each ModEntity In McModLoader.Output.Where(Function(m) SelectedMods.Contains(m.RawFileName)).ToList()
  284. Dim NewPath As String = Nothing
  285. If ModEntity.State = McMod.McModState.Fine And IsDisable Then
  286. '禁用
  287. NewPath = ModEntity.Path & ".disabled"
  288. ElseIf ModEntity.State = McMod.McModState.Disabled AndAlso Not IsDisable Then
  289. '启用
  290. NewPath = ModEntity.Path.Substring(0, ModEntity.Path.Count - ".disabled".Count)
  291. Else
  292. Continue For
  293. End If
  294. '重命名
  295. Try
  296. If File.Exists(NewPath) AndAlso Not File.Exists(ModEntity.Path) Then Continue For '因为未知原因 Mod 的状态已经切换完了
  297. File.Delete(NewPath)
  298. FileSystem.Rename(ModEntity.Path, NewPath)
  299. Catch ex As FileNotFoundException
  300. Log(ex, $"未找到需要重命名的 Mod({If(ModEntity.Path, "null")})", LogLevel.Feedback)
  301. RefreshList(True)
  302. Return
  303. Catch ex As Exception
  304. Log(ex, $"批量重命名 Mod 失败({If(ModEntity.Path, "null")})")
  305. IsSuccessful = False
  306. End Try
  307. '更改 Loader 和 UI 中的列表
  308. Dim NewModEntity As New McMod(NewPath)
  309. NewModEntity.Comp = ModEntity.Comp
  310. Dim IndexOfLoader As Integer = McModLoader.Output.IndexOf(ModEntity)
  311. McModLoader.Output.RemoveAt(IndexOfLoader)
  312. McModLoader.Output.Insert(IndexOfLoader, NewModEntity)
  313. Dim List = If(IsSearching, PanSearchList, PanItems).Children
  314. Dim IndexOfUi As Integer = List.IndexOf(List.OfType(Of MyLocalModItem).FirstOrDefault(Function(i) i.Entry Is ModEntity))
  315. If IndexOfUi = -1 Then Continue For '因为未知原因 Mod 的状态已经切换完了
  316. List.RemoveAt(IndexOfUi)
  317. List.Insert(IndexOfUi, McModListItem(NewModEntity))
  318. Next
  319. If Not IsSearching Then
  320. '改变禁用数量的显示
  321. CType(PanItems.Parent, MyCard).Title = McModGetTitle(McModLoader.Output)
  322. '更新加载器状态
  323. LoaderFolderRun(McModLoader, PageVersionLeft.Version.PathIndie & "mods\", LoaderFolderRunType.UpdateOnly)
  324. End If
  325. If Not IsSuccessful Then
  326. Hint("由于文件被占用,部分 Mod 的状态切换失败,请尝试关闭正在运行的游戏后再试!", HintType.Critical)
  327. RefreshList(True)
  328. Else
  329. ChangeAllSelected(False)
  330. End If
  331. End Sub
  332. '删除
  333. Private Sub BtnSelectDelete_Click() Handles BtnSelectDelete.Click
  334. Dim IsSuccessful As Boolean = True
  335. Dim IsShiftPressed As Boolean = My.Computer.Keyboard.ShiftKeyDown
  336. Dim DeleteList As List(Of McMod) = McModLoader.Output.Where(Function(m) SelectedMods.Contains(m.RawFileName)).ToList()
  337. For Each ModEntity In DeleteList
  338. '删除
  339. Try
  340. If IsShiftPressed Then
  341. File.Delete(ModEntity.Path)
  342. Else
  343. My.Computer.FileSystem.DeleteFile(ModEntity.Path, FileIO.UIOption.OnlyErrorDialogs, FileIO.RecycleOption.SendToRecycleBin)
  344. End If
  345. Catch ex As OperationCanceledException
  346. Log(ex, "批量删除 Mod 被主动取消")
  347. RefreshList(True)
  348. Return
  349. Catch ex As Exception
  350. Log(ex, $"批量删除 Mod 失败({ModEntity.Path})", LogLevel.Msgbox)
  351. IsSuccessful = False
  352. End Try
  353. '更改 Loader 和 UI 中的列表
  354. McModLoader.Output.Remove(ModEntity)
  355. Dim Parent As StackPanel = If(IsSearching, PanSearchList, PanItems)
  356. Dim IndexOfUi As Integer = Parent.Children.IndexOf(Parent.Children.OfType(Of MyLocalModItem).First(Function(i) i.Entry Is ModEntity))
  357. Parent.Children.RemoveAt(IndexOfUi)
  358. Next
  359. If Not IsSearching Then
  360. '改变禁用数量的显示
  361. CType(PanItems.Parent, MyCard).Title = McModGetTitle(McModLoader.Output)
  362. '更新加载器状态
  363. LoaderFolderRun(McModLoader, PageVersionLeft.Version.PathIndie & "mods\", LoaderFolderRunType.UpdateOnly)
  364. End If
  365. If Not IsSuccessful Then
  366. Hint("由于文件被占用,部分 Mod 删除失败,请尝试关闭正在运行的游戏后再试!", HintType.Critical)
  367. RefreshList(True)
  368. ElseIf If(IsSearching, PanSearchList, PanItems).Children.Count = 0 Then
  369. RefreshList(True)
  370. Else
  371. ChangeAllSelected(False)
  372. End If
  373. If IsSuccessful Then
  374. If IsShiftPressed Then
  375. Hint($"已彻底删除 {DeleteList.Count} 个文件!", HintType.Finish)
  376. Else
  377. Hint($"已将 {DeleteList.Count} 个文件删除到回收站!", HintType.Finish)
  378. End If
  379. End If
  380. End Sub
  381. '取消选择
  382. Private Sub BtnSelectCancel_Click() Handles BtnSelectCancel.Click
  383. ChangeAllSelected(False)
  384. End Sub
  385. #End Region
  386. #Region "单个 Mod 项"
  387. '详情
  388. Public Sub Info_Click(sender As Object, e As EventArgs)
  389. Try
  390. Dim ModEntry As McMod = CType(If(TypeOf sender Is MyIconButton, sender.Tag, sender), MyLocalModItem).Entry
  391. '加载失败信息
  392. If ModEntry.State = McMod.McModState.Unavaliable Then
  393. MyMsgBox("无法读取此 Mod 的信息。" & vbCrLf & vbCrLf & "详细的错误信息:" & GetExceptionDetail(ModEntry.FileUnavailableReason), "Mod 读取失败")
  394. Return
  395. End If
  396. If ModEntry.Comp IsNot Nothing Then
  397. '跳转到 Mod 下载页面
  398. FrmMain.PageChange(New FormMain.PageStackData With {.Page = FormMain.PageType.CompDetail,
  399. .Additional = {ModEntry.Comp, New List(Of String), PageVersionLeft.Version.Version.McName,
  400. If(PageVersionLeft.Version.Version.HasForge, CompModLoaderType.Forge, If(PageVersionLeft.Version.Version.HasFabric, CompModLoaderType.Fabric, CompModLoaderType.Any))}})
  401. Else
  402. '获取信息
  403. Dim ContentLines As New List(Of String)
  404. If ModEntry.Description IsNot Nothing Then ContentLines.Add(ModEntry.Description & vbCrLf)
  405. If ModEntry.Authors IsNot Nothing Then ContentLines.Add("作者:" & ModEntry.Authors)
  406. ContentLines.Add("文件:" & ModEntry.FileName & "(" & GetString(New FileInfo(ModEntry.Path).Length) & ")")
  407. If ModEntry.Version IsNot Nothing Then ContentLines.Add("版本:" & ModEntry.Version)
  408. Dim DebugInfo As New List(Of String)
  409. If ModEntry.ModId IsNot Nothing Then
  410. DebugInfo.Add("Mod ID:" & ModEntry.ModId)
  411. End If
  412. If ModEntry.Dependencies.Count > 0 Then
  413. DebugInfo.Add("依赖于:")
  414. For Each Dep In ModEntry.Dependencies
  415. DebugInfo.Add(" - " & Dep.Key & If(Dep.Value Is Nothing, "", ",版本:" & Dep.Value))
  416. Next
  417. End If
  418. If DebugInfo.Count > 0 Then
  419. ContentLines.Add("")
  420. ContentLines.AddRange(DebugInfo)
  421. End If
  422. '获取用于搜索的 Mod 名称
  423. Dim ModOriginalName As String = ModEntry.Name.Replace(" ", "+")
  424. Dim ModSearchName As String = ModOriginalName.Substring(0, 1)
  425. For i = 1 To ModOriginalName.Count - 1
  426. Dim IsLastLower As Boolean = ModOriginalName(i - 1).ToString.ToLower.Equals(ModOriginalName(i - 1).ToString)
  427. Dim IsCurrentLower As Boolean = ModOriginalName(i).ToString.ToLower.Equals(ModOriginalName(i).ToString)
  428. If IsLastLower AndAlso Not IsCurrentLower Then
  429. '上一个字母为小写,这一个字母为大写
  430. ModSearchName += "+"
  431. End If
  432. ModSearchName += ModOriginalName(i)
  433. Next
  434. ModSearchName = ModSearchName.Replace("++", "+").Replace("pti+Fine", "ptiFine")
  435. '显示
  436. If ModEntry.Url Is Nothing Then
  437. If MyMsgBox(Join(ContentLines, vbCrLf), ModEntry.Name, "百科搜索", "返回") = 1 Then
  438. OpenWebsite("https://www.mcmod.cn/s?key=" & ModSearchName & "&site=all&filter=0")
  439. End If
  440. Else
  441. Select Case MyMsgBox(Join(ContentLines, vbCrLf), ModEntry.Name, "打开官网", "百科搜索", "返回")
  442. Case 1
  443. OpenWebsite(ModEntry.Url)
  444. Case 2
  445. OpenWebsite("https://www.mcmod.cn/s?key=" & ModSearchName & "&site=all&filter=0")
  446. End Select
  447. End If
  448. End If
  449. Catch ex As Exception
  450. Log(ex, "获取 Mod 详情失败", LogLevel.Feedback)
  451. End Try
  452. End Sub
  453. '打开文件所在的位置
  454. Public Sub Open_Click(sender As MyIconButton, e As EventArgs)
  455. Try
  456. Dim ListItem As MyLocalModItem = sender.Tag
  457. OpenExplorer("/select,""" & ListItem.Entry.Path & """")
  458. Catch ex As Exception
  459. Log(ex, "打开 Mod 文件位置失败", LogLevel.Feedback)
  460. End Try
  461. End Sub
  462. #End Region
  463. #Region "搜索"
  464. Public ReadOnly Property IsSearching As Boolean
  465. Get
  466. Return Not String.IsNullOrWhiteSpace(SearchBox.Text)
  467. End Get
  468. End Property
  469. Public Sub SearchRun() Handles SearchBox.TextChanged
  470. ChangeAllSelected(False)
  471. If IsSearching Then
  472. '构造请求
  473. Dim QueryList As New List(Of SearchEntry(Of McMod))
  474. For Each Entry As McMod In McModLoader.Output
  475. Dim SearchSource As New List(Of KeyValuePair(Of String, Double))
  476. SearchSource.Add(New KeyValuePair(Of String, Double)(Entry.Name, 1))
  477. SearchSource.Add(New KeyValuePair(Of String, Double)(Entry.FileName, 1))
  478. If Entry.Version IsNot Nothing Then SearchSource.Add(New KeyValuePair(Of String, Double)(Entry.Version, 0.2))
  479. If Entry.Description IsNot Nothing AndAlso Entry.Description <> "" Then
  480. SearchSource.Add(New KeyValuePair(Of String, Double)(Entry.Description, 0.4))
  481. End If
  482. If Entry.Comp IsNot Nothing Then
  483. If Entry.Comp.RawName <> Entry.Name Then SearchSource.Add(New KeyValuePair(Of String, Double)(Entry.Comp.RawName, 1))
  484. If Entry.Comp.TranslatedName <> Entry.Comp.RawName Then SearchSource.Add(New KeyValuePair(Of String, Double)(Entry.Comp.TranslatedName, 1))
  485. If Entry.Comp.Description <> Entry.Description Then SearchSource.Add(New KeyValuePair(Of String, Double)(Entry.Comp.Description, 0.4))
  486. End If
  487. QueryList.Add(New SearchEntry(Of McMod) With {.Item = Entry, .SearchSource = SearchSource})
  488. Next
  489. '进行搜索,构造列表
  490. Dim SearchResult = Search(QueryList, SearchBox.Text, MaxBlurCount:=6, MinBlurSimilarity:=0.35)
  491. PanSearchList.Children.Clear()
  492. If SearchResult.Count = 0 Then
  493. PanSearch.Title = "无搜索结果"
  494. PanSearchList.Visibility = Visibility.Collapsed
  495. Else
  496. PanSearch.Title = "搜索结果"
  497. For Each Result In SearchResult
  498. Dim Item = McModListItem(Result.Item)
  499. If ModeDebug Then Item.Description = If(Result.AbsoluteRight, "完全匹配,", "") & "相似度:" & Math.Round(Result.Similarity, 3) & "," & Item.Description
  500. PanSearchList.Children.Add(Item)
  501. Next
  502. PanSearchList.Visibility = Visibility.Visible
  503. End If
  504. '显示
  505. AniStart({
  506. AaOpacity(PanList, -PanList.Opacity, 100),
  507. AaCode(Sub()
  508. PanList.Visibility = Visibility.Collapsed
  509. PanSearch.Visibility = Visibility.Visible
  510. PanSearch.TriggerForceResize()
  511. End Sub,, True),
  512. AaOpacity(PanSearch, 1 - PanSearch.Opacity, 200, 60)
  513. }, "FrmVersionMod Search Switch", True)
  514. Else
  515. '隐藏
  516. LoaderFolderRun(McModLoader, PageVersionLeft.Version.PathIndie & "mods\", LoaderFolderRunType.RunOnUpdated)
  517. AniStart({
  518. AaOpacity(PanSearch, -PanSearch.Opacity, 100),
  519. AaCode(Sub()
  520. PanSearch.Height = 0
  521. PanSearch.Visibility = Visibility.Collapsed
  522. PanList.Visibility = Visibility.Visible
  523. End Sub,, True),
  524. AaOpacity(PanList, 1 - PanList.Opacity, 150, 30)
  525. }, "FrmVersionMod Search Switch", True)
  526. End If
  527. End Sub
  528. #End Region
  529. End Class