上传公开代码

This commit is contained in:
龙腾猫跃
2022-07-27 18:48:13 +08:00
parent 6a3f4d35d4
commit b0b02291cc
208 changed files with 38567 additions and 0 deletions
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,45 @@
<Grid x:Class="MyCfItem"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Name="PanBack" Height="57"
RenderTransformOrigin="0.5,0.5" Background="{StaticResource ColorBrushSemiTransparent}" SnapsToDevicePixels="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="6" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="9" />
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="7" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="1*" />
<RowDefinition Height="17" />
<RowDefinition Height="14" />
<RowDefinition Height="14" />
<RowDefinition Height="1*" />
</Grid.RowDefinitions>
<!--<Rectangle Height="45" Width="45" RadiusX="4" RadiusY="4" Fill="White" Grid.Column="1" Grid.Row="1" IsHitTestVisible="False" SnapsToDevicePixels="True" UseLayoutRounding="False" Grid.RowSpan="3" />-->
<Border Height="45" Width="45" Grid.Column="1" Grid.Row="1" IsHitTestVisible="False" SnapsToDevicePixels="True" UseLayoutRounding="True" Grid.RowSpan="3">
<Border.Clip>
<RectangleGeometry Rect="0,0,45,45" RadiusX="4" RadiusY="4" />
</Border.Clip>
<Image x:Name="PathLogo" RenderOptions.BitmapScalingMode="HighQuality" />
</Border>
<TextBlock x:Name="LabTitle" Grid.Row="1" Grid.Column="3" Grid.ColumnSpan="2" IsHitTestVisible="False" SnapsToDevicePixels="False" UseLayoutRounding="False"
Margin="0,0,0,1" HorizontalAlignment="Left" VerticalAlignment="Center" TextTrimming="CharacterEllipsis"
FontSize="14" Foreground="{StaticResource ColorBrush1}" />
<TextBlock x:Name="LabLeft" Grid.Row="2" Grid.Column="3" IsHitTestVisible="False" SnapsToDevicePixels="False" UseLayoutRounding="False"
HorizontalAlignment="Left" VerticalAlignment="Center" TextTrimming="CharacterEllipsis"
FontSize="12" Foreground="{StaticResource ColorBrushGray3}" />
<!--<TextBlock x:Name="LabRight" Grid.Row="2" Grid.Column="4" IsHitTestVisible="False" SnapsToDevicePixels="False" UseLayoutRounding="False"
HorizontalAlignment="Right" VerticalAlignment="Center" TextTrimming="CharacterEllipsis"
FontSize="12" Foreground="{StaticResource ColorBrushGray3}" />-->
<TextBlock x:Name="LabInfo" Grid.Row="3" Grid.Column="3" Grid.ColumnSpan="2" IsHitTestVisible="True" SnapsToDevicePixels="False" UseLayoutRounding="False"
HorizontalAlignment="Left" VerticalAlignment="Center" TextTrimming="CharacterEllipsis"
FontSize="12" Foreground="{StaticResource ColorBrushGray3}"
ToolTipService.InitialShowDelay="80" ToolTipService.Placement="Relative" ToolTipService.PlacementRectangle="-8,-6,500,10000">
<TextBlock.ToolTip>
<ToolTip x:Name="ToolTipInfo" Style="{StaticResource ExtendTextToolTip}" />
</TextBlock.ToolTip>
</TextBlock>
</Grid>
@@ -0,0 +1,200 @@
Public Class MyCfItem
Public Uuid As Integer = GetUuid()
#Region "Logo"
'Public CacheLogo As Boolean = True '是否缓存 Logo:通过下载量确定是否为默认页
Private _Logo As String = ""
Public Property Logo As String
Get
Return _Logo
End Get
Set(value As String)
If _Logo = value OrElse value Is Nothing Then Exit Property
_Logo = value
Dim FileAddress = PathTemp & "CFLogo\" & GetHash(_Logo) & ".png"
Try
If _Logo.ToLower.StartsWith("http") Then
'网络图片
If File.Exists(FileAddress) Then
PathLogo.Source = New MyBitmap(FileAddress)
Else
PathLogo.Source = New MyBitmap("pack://application:,,,/images/Icons/NoIcon.png")
RunInNewThread(Sub() LogoLoader(FileAddress), "CurseForge Logo Loader " & Uuid & "#", ThreadPriority.BelowNormal)
End If
Else
'位图
PathLogo.Source = New MyBitmap(_Logo)
End If
Catch ex As IOException
Log(ex, "加载 CurseForge 工程图标时读取失败(" & FileAddress & ")")
Catch ex As ArgumentException
'考虑缓存的图片本身可能有误
Log(ex, "可视化 CurseForge 工程图标失败(" & FileAddress & ")")
Try
File.Delete(FileAddress)
Log("[Download] 已清理损坏的 CurseForge 工程图标:" & FileAddress)
Catch exx As Exception
Log(exx, "清理损坏的 CurseForge 工程图标缓存失败(" & FileAddress & ")", LogLevel.Hint)
End Try
Catch ex As Exception
Log(ex, "加载 CurseForge 工程图标失败(" & value & ")")
End Try
End Set
End Property
Private Sub LogoLoader(Address As String)
Dim Retry As Boolean = False
Dim DownloadEnd As String = GetUuid()
RetryStart:
Try
NetDownload(_Logo, Address & DownloadEnd)
RunInUiWait(Sub()
Try
'在地址更换时取消加载
If Not Address = PathTemp & "CFLogo\" & GetHash(_Logo) & ".png" Then Exit Sub
'在完成正常加载后才保存缓存图片
PathLogo.Source = New MyBitmap(Address & DownloadEnd)
Catch ex As Exception
Log(ex, "读取 CurseForge 工程图标失败(" & Address & ")", LogLevel.Hint)
End Try
End Sub)
If File.Exists(Address) Then
File.Delete(Address & DownloadEnd)
Else
FileIO.FileSystem.MoveFile(Address & DownloadEnd, Address)
End If
Catch ex As Exception
If Not Retry Then
Retry = True
GoTo RetryStart
Else
Log(ex, "下载 CurseForge 工程图标失败")
End If
End Try
End Sub
#End Region
#Region "点击"
'触发点击事件
Public Event Click(sender As Object, e As MouseButtonEventArgs)
Private Sub Button_MouseUp(sender As Object, e As MouseButtonEventArgs) Handles Me.PreviewMouseLeftButtonUp
If IsMouseDown Then
RaiseEvent Click(sender, e)
If e.Handled Then Exit Sub
Log("[Control] 按下 CurseForge 工程列表项:" & LabTitle.Text)
End If
End Sub
'鼠标点击判定
Private IsMouseDown As Boolean = False
Private Sub Button_MouseDown(sender As Object, e As MouseButtonEventArgs) Handles Me.PreviewMouseLeftButtonDown
If IsMouseOver Then IsMouseDown = True
End Sub
Private Sub Button_MouseLeave(sender As Object, e As Object) Handles Me.MouseLeave, Me.PreviewMouseLeftButtonUp
IsMouseDown = False
End Sub
#End Region
#Region "后加载指向背景"
Private _RectBack As Border = Nothing
Public ReadOnly Property RectBack As Border
Get
If _RectBack Is Nothing Then
Dim Rect As New Border With {
.Name = "RectBack",
.CornerRadius = New CornerRadius(3),
.RenderTransform = New ScaleTransform(0.8, 0.8),
.RenderTransformOrigin = New Point(0.5, 0.5),
.BorderThickness = New Thickness(GetWPFSize(1)),
.SnapsToDevicePixels = True,
.IsHitTestVisible = False,
.Opacity = 0
}
Rect.SetResourceReference(Border.BackgroundProperty, "ColorBrush7")
Rect.SetResourceReference(Border.BorderBrushProperty, "ColorBrush6")
SetColumnSpan(Rect, 999)
SetRowSpan(Rect, 999)
Children.Insert(0, Rect)
_RectBack = Rect
'<!--<Border x:Name = "RectBack" CornerRadius="3" RenderTransformOrigin="0.5,0.5" SnapsToDevicePixels="True"
'IsHitTestVisible = "False" Opacity="0" BorderThickness="1"
'Grid.ColumnSpan = "4" Background="{DynamicResource ColorBrush7}" BorderBrush="{DynamicResource ColorBrush6}"/>-->
End If
Return _RectBack
End Get
End Property
#End Region
Private StateLast As String
Public HasAnimation As Boolean = True
Public Sub RefreshColor(sender As Object, e As EventArgs) Handles Me.MouseEnter, Me.MouseLeave, Me.MouseLeftButtonDown, Me.MouseLeftButtonUp
If Not HasAnimation Then Exit Sub
'判断当前颜色
Dim StateNew As String, Time As Integer
If IsMouseOver Then
If IsMouseDown Then
StateNew = "MouseDown"
Time = 120
Else
StateNew = "MouseOver"
Time = 120
End If
Else
StateNew = "Idle"
Time = 180
End If
If StateLast = StateNew Then Exit Sub
StateLast = StateNew
'触发颜色动画
If IsLoaded AndAlso AniControlEnabled = 0 Then '防止默认属性变更触发动画
'有动画
Dim Ani As New List(Of AniData)
If IsMouseOver Then
Ani.AddRange({
AaColor(RectBack, Border.BackgroundProperty, If(IsMouseDown, "ColorBrush6", "ColorBrush9"), Time),
AaOpacity(RectBack, 1 - RectBack.Opacity, Time,, New AniEaseOutFluent)
})
If IsMouseDown Then
Ani.Add(AaScaleTransform(RectBack, 0.996 - CType(RectBack.RenderTransform, ScaleTransform).ScaleX, Time * 1.2,, New AniEaseOutFluent))
Else
Ani.Add(AaScaleTransform(RectBack, 1 - CType(RectBack.RenderTransform, ScaleTransform).ScaleX, Time * 1.2,, New AniEaseOutFluent))
End If
Else
Ani.AddRange({
AaOpacity(RectBack, -RectBack.Opacity, Time),
AaColor(RectBack, Border.BackgroundProperty, If(IsMouseDown, "ColorBrush6", "ColorBrush7"), Time),
AaScaleTransform(RectBack, 0.996 - CType(RectBack.RenderTransform, ScaleTransform).ScaleX, Time,, New AniEaseOutFluent),
AaScaleTransform(RectBack, -0.196, 1,,, True)
})
End If
AniStart(Ani, "CfItem Color " & Uuid)
Else
'无动画
AniStop("CfItem Color " & Uuid)
If _RectBack IsNot Nothing Then RectBack.Opacity = 0
End If
End Sub
'指向时扩展描述
Private Sub LabInfo_MouseEnter(sender As Object, e As MouseEventArgs) Handles LabInfo.MouseEnter
If IsTextTrimmed(LabInfo) Then
ToolTipInfo.Content = LabInfo.Text
ToolTipInfo.Width = LabInfo.ActualWidth + 25
LabInfo.ToolTip = ToolTipInfo
Else
LabInfo.ToolTip = Nothing
End If
End Sub
Private Function IsTextTrimmed(textBlock As TextBlock) As Boolean
Dim typeface As New Typeface(textBlock.FontFamily, textBlock.FontStyle, textBlock.FontWeight, textBlock.FontStretch)
Dim formattedText As New FormattedText(textBlock.Text, Thread.CurrentThread.CurrentCulture, textBlock.FlowDirection, typeface, textBlock.FontSize, textBlock.Foreground, DPI)
Return formattedText.Width > textBlock.ActualWidth
End Function
End Class
@@ -0,0 +1,34 @@
<local:MyPageRight
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:PCL" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" x:Class="PageDownloadCfDetail"
d:DesignWidth="778.571" d:DesignHeight="90.857">
<local:MyScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" x:Name="PanBack">
<Grid Margin="25,25,25,10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="1*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<local:MyCard Margin="0,0,0,25" x:Name="CardIntro">
<StackPanel Margin="22,22,22,19" x:Name="PanIntro">
<Grid Height="35">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
</Grid.ColumnDefinitions>
<local:MyButton x:Name="BtnIntroCf" Grid.Column="0" MinWidth="140" Text="查看 CurseForge" Padding="13,0" Margin="0,0,20,0" HorizontalAlignment="Left" ColorType="Highlight" />
<local:MyButton x:Name="BtnIntroWiki" Grid.Column="1" MinWidth="140" Text="查看百科" Padding="13,0" Margin="0,0,20,0" HorizontalAlignment="Left" />
<local:MyButton x:Name="BtnIntroMCBBS" Grid.Column="2" MinWidth="140" Text="查看 MCBBS" Padding="13,0" Margin="0,0,20,0" HorizontalAlignment="Left" />
</Grid>
</StackPanel>
</local:MyCard>
<StackPanel Grid.Row="1" Grid.RowSpan="2" Name="PanMain" Grid.IsSharedSizeScope="True" />
<local:MyCard Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center" SnapsToDevicePixels="True" x:Name="PanLoad" UseAnimation="False" Margin="0,0,0,8">
<local:MyLoading Text="正在获取版本列表" Margin="20,20,20,17" x:Name="Load" HorizontalAlignment="Center" VerticalAlignment="Center" />
</local:MyCard>
</Grid>
</local:MyScrollViewer>
</local:MyPageRight>
@@ -0,0 +1,261 @@
Public Class PageDownloadCfDetail
Private CfItem As MyCfItem = Nothing
Private Project As DlCfProject
#Region "加载器"
'初始化加载器信息
Private Sub PageDownloadCfDetail_Inited(sender As Object, e As EventArgs) Handles Me.Initialized
Project = FrmMain.PageCurrent.Additional
PageLoaderInit(Load, PanLoad, PanMain, CardIntro, DlCfFileLoader, AddressOf Load_OnFinish, AddressOf LoaderInput)
End Sub
Private Function LoaderInput() As KeyValuePair(Of Integer, Boolean)
Return New KeyValuePair(Of Integer, Boolean)(Project.Id, Project.IsModPack)
End Function
'自动重试
Private Sub Load_State(sender As Object, state As MyLoading.MyLoadingState, oldState As MyLoading.MyLoadingState) Handles Load.StateChanged
Select Case DlCfFileLoader.State
Case LoadState.Failed
Dim ErrorMessage As String = ""
If DlCfFileLoader.Error IsNot Nothing Then ErrorMessage = DlCfFileLoader.Error.Message
If ErrorMessage.Contains("不是有效的 Json 文件") Then
Log("[Download] 下载的 Mod 列表 Json 文件损坏,已自动重试", LogLevel.Debug)
PageLoaderRestart()
End If
End Select
End Sub
'结果 UI 化
Private Class VersionSorterWithSelect
Implements IComparer(Of String)
Public Top As String = ""
Public Function Compare(x As String, y As String) As Integer Implements IComparer(Of String).Compare
If x = y Then Return 0
If x = Top Then Return -1
If y = Top Then Return 1
Return -VersionSortInteger(x, y)
End Function
Public Sub New(Optional Top As String = "")
Me.Top = If(Top, "")
End Sub
End Class
Private Sub Load_OnFinish()
'初始化字典,并将当前版本排在最上面
Dim TopVersion As String
If Project.IsModPack Then
TopVersion = If(PageDownloadPack.Loader.Input.GameVersion, "")
Else
TopVersion = If(PageDownloadMod.Loader.Input.GameVersion, "")
End If
Dim Dict As New SortedDictionary(Of String, List(Of DlCfFile))(New VersionSorterWithSelect(TopVersion))
'PCL#8826 汇报了奇怪的这个 Try 块里出现 NPE 的问题,但实在找不到,就瞎加点检测
Try
Dict.Add("未知版本", New List(Of DlCfFile))
If DlCfFileLoader.Output Is Nothing Then
Log("[Download] 列表加载输出为 Nothing,请反馈此问题", LogLevel.Feedback)
Exit Try
End If
For Each Version As DlCfFile In DlCfFileLoader.Output
If Version Is Nothing Then
Log("[Download] 列表中的一个版本为 Nothing,请反馈此问题", LogLevel.Feedback)
Continue For
End If
If Version.GameVersion Is Nothing Then
Log("[Download] 列表中的一个版本没有任何适配的游戏版本,返回为 Nothing,请反馈此问题", LogLevel.Feedback)
Continue For
End If
For Each GameVersion In Version.GameVersion
'决定添加到哪个版本
Dim TargetVersion As String
If GameVersion Is Nothing OrElse GameVersion.Split(".").Count < 2 Then
TargetVersion = "未知版本"
Else
TargetVersion = GameVersion
End If
'实际进行添加
If Not Dict.ContainsKey(TargetVersion) Then Dict.Add(TargetVersion, New List(Of DlCfFile))
If Not Dict(TargetVersion).Contains(Version) Then Dict(TargetVersion).Add(Version)
Next
Next
Catch ex As Exception
Log(ex, "准备工程下载列表出错", LogLevel.Feedback)
End Try
#Region "转化为 UI"
Try
'清空当前
PanMain.Children.Clear()
'转化为 UI
For Each Pair As KeyValuePair(Of String, List(Of DlCfFile)) In Dict
If Pair.Value.Count = 0 Then Continue For
'增加卡片
Dim NewCard As New MyCard With {.Title = Pair.Key, .Margin = New Thickness(0, 0, 0, 15), .SwapType = If(Project.IsModPack, 9, 8)}
Dim NewStack As New StackPanel With {.Margin = New Thickness(20, MyCard.SwapedHeight, 18, 0), .VerticalAlignment = VerticalAlignment.Top, .RenderTransform = New TranslateTransform(0, 0), .Tag = Pair.Value}
NewCard.Children.Add(NewStack)
NewCard.SwapControl = NewStack
PanMain.Children.Add(NewCard)
'确定卡片是否展开
If Pair.Key = TopVersion Then
MyCard.StackInstall(NewStack, 8, Pair.Key)
Else
NewCard.IsSwaped = True
End If
'增加提示
If Pair.Key = "未知版本" Then
NewStack.Children.Add(New MyHint With {.Text = "由于 API 的版本信息更新缓慢,可能无法识别刚更新不久的 MC 版本,只需等待几天即可自动恢复正常。", .IsWarn = False, .Margin = New Thickness(0, 0, 0, 7)})
End If
Next
'如果只有一张卡片,展开第一张卡片
If PanMain.Children.Count = 1 Then
CType(PanMain.Children(0), MyCard).IsSwaped = False
End If
Catch ex As Exception
Log(ex, "可视化工程下载列表出错", LogLevel.Feedback)
End Try
#End Region
End Sub
#End Region
Private IsFirstInit As Boolean = True
Public Sub Init() Handles Me.OnPageEnter
AniControlEnabled += 1
Project = FrmMain.PageCurrent.Additional
PanBack.ScrollToHome()
'重启加载器
If IsFirstInit Then
'在 Me.Initialized 已经初始化了加载器,不再重复初始化
IsFirstInit = False
Else
PageLoaderRestart(IsForceRestart:=True)
End If
'放置当前工程
If CfItem IsNot Nothing Then PanIntro.Children.Remove(CfItem)
CfItem = Project.ToCfItem(True, True)
CfItem.Margin = New Thickness(-7, -7, 0, 8)
PanIntro.Children.Insert(0, CfItem)
'决定按钮显示
BtnIntroWiki.Visibility = If(Project.McWikiId = 0, Visibility.Collapsed, Visibility.Visible)
BtnIntroMCBBS.Visibility = If(Project.MCBBS Is Nothing, Visibility.Collapsed, Visibility.Visible)
AniControlEnabled -= 1
End Sub
'整合包下载(安装)
Public Sub Install_Click(sender As MyListItem, e As EventArgs)
Try
'获取基本信息
Dim File As DlCfFile = sender.Tag
Dim LoaderName As String = "CurseForge 整合包下载:" & Project.ChineseName & " "
'获取版本名
Dim PackName As String = Project.ChineseName.Replace(".zip", "").Replace(".rar", "").Replace("\", "\").Replace("/", "/").Replace("|", "|").Replace(":", ":").Replace("<", "<").Replace(">", ">").Replace("*", "*").Replace("?", "?").Replace("""", "").Replace(": ", ":")
Dim Validate As New ValidateFolderName(PathMcFolder & "versions")
If Validate.Validate(PackName) <> "" Then PackName = ""
Dim VersionName As String = MyMsgBoxInput(PackName, New ObjectModel.Collection(Of Validate) From {Validate},
Title:="输入版本名", Button2:="取消")
If String.IsNullOrEmpty(VersionName) Then Exit Sub
'构造步骤加载器
Dim Loaders As New List(Of LoaderBase)
Dim Target As String = PathMcFolder & "versions\" & VersionName & "\原始整合包.zip"
Loaders.Add(New LoaderDownload("下载整合包文件", New List(Of NetFile) From {File.GetDownloadFile(Target, True)}) With {.ProgressWeight = 10, .Block = True})
Loaders.Add(New LoaderTask(Of Integer, Integer)("准备安装整合包", Sub() ModpackInstall(Target, VersionName)) With {.ProgressWeight = 0.1})
'启动
Dim Loader As New LoaderCombo(Of String)(LoaderName, Loaders) With {.OnStateChanged = Sub(MyLoader)
Select Case MyLoader.State
Case LoadState.Failed
Hint(MyLoader.Name & "失败:" & GetString(MyLoader.Error), HintType.Critical)
Case LoadState.Aborted
Hint(MyLoader.Name & "已取消!", HintType.Info)
Case LoadState.Loading
Exit Sub '不重新加载版本列表
End Select
McInstallFailedClearFolder(MyLoader)
End Sub}
Loader.Start(PathMcFolder & "versions\" & VersionName & "\")
LoaderTaskbarAdd(Loader)
FrmMain.BtnExtraDownload.ShowRefresh()
FrmMain.BtnExtraDownload.Ribble()
Catch ex As Exception
Log(ex, "下载 CurseForge 整合包失败", LogLevel.Feedback)
End Try
End Sub
'Mod 下载;整合包另存为
Public Shared DownloadFolder = Nothing '仅在本次缓存的下载文件夹
Public Sub Save_Click(sender As Object, e As EventArgs)
Try
Dim Desc As String = If(Project.IsModPack, "整合包", "Mod ")
'确认默认保存位置
Dim DefaultFolder As String = Nothing
If Not Project.IsModPack Then
DefaultFolder = DownloadFolder
If McVersionCurrent IsNot Nothing Then
If Not McVersionCurrent.IsLoaded Then McVersionCurrent.Load()
If McVersionCurrent.Version.Modable Then
DefaultFolder = McVersionCurrent.PathIndie & "mods\"
Directory.CreateDirectory(DefaultFolder)
End If
End If
If String.IsNullOrEmpty(DefaultFolder) Then DefaultFolder = Nothing
End If
'获取基本信息
Dim File As DlCfFile = If(TypeOf sender Is MyListItem, sender, sender.Parent).Tag
Dim ChineseName As String = If(Project.ChineseName = Project.Name, "",
Project.ChineseName.Replace(" (", "Å").Split("Å").First.Replace("\", "\").Replace("/", "/").Replace("|", "|").Replace(":", ":").Replace("<", "<").Replace(">", ">").Replace("*", "*").Replace("?", "?").Replace("""", "").Replace(": ", ":"))
Dim FileName As String
Select Case Setup.Get("ToolDownloadTranslate")
Case 0
FileName = If(ChineseName = "", "", "[" & ChineseName & "] ") & File.FileName
Case 1
FileName = If(ChineseName = "", "", ChineseName & "-") & File.FileName
Case 2
FileName = File.FileName & If(ChineseName = "", "", "-" & ChineseName)
Case Else
FileName = File.FileName
End Select
Dim Target As String
If File.FileName.EndsWith(".litemod") Then
Target = SelectAs("选择保存位置", FileName, Desc & "文件|" & If(Project.IsModPack, "*.zip", "*.litemod"), DefaultFolder)
Else
Target = SelectAs("选择保存位置", FileName, Desc & "文件|" & If(Project.IsModPack, "*.zip", "*.jar"), DefaultFolder)
End If
If Not Target.Contains("\") Then Exit Sub
Dim LoaderName As String = Desc & "下载:" & File.DisplayName & " "
If Target <> DefaultFolder AndAlso Not Project.IsModPack Then DownloadFolder = GetPathFromFullPath(Target)
'构造步骤加载器
Dim Loaders As New List(Of LoaderBase)
Loaders.Add(New LoaderDownload("下载文件", New List(Of NetFile) From {File.GetDownloadFile(Target, True)}) With {.ProgressWeight = 6, .Block = True})
'启动
Dim Loader As New LoaderCombo(Of Integer)(LoaderName, Loaders) With {.OnStateChanged = AddressOf DownloadStateSave}
Loader.Start(1)
LoaderTaskbarAdd(Loader)
FrmMain.BtnExtraDownload.ShowRefresh()
FrmMain.BtnExtraDownload.Ribble()
Catch ex As Exception
Log(ex, "保存 CurseForge 文件失败", LogLevel.Feedback)
End Try
End Sub
Private Sub BtnIntroCf_Click(sender As Object, e As EventArgs) Handles BtnIntroCf.Click
OpenWebsite(Project.Website)
End Sub
Private Sub BtnIntroWiki_Click(sender As Object, e As EventArgs) Handles BtnIntroWiki.Click
OpenWebsite("https://www.mcmod.cn/class/" & Project.McWikiId & ".html")
End Sub
Private Sub BtnIntroMCBBS_Click(sender As Object, e As EventArgs) Handles BtnIntroMCBBS.Click
OpenWebsite("https://www.mcbbs.net/thread-" & Project.MCBBS & "-1-1.html")
End Sub
End Class
@@ -0,0 +1,31 @@
<local:MyPageRight
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:PCL" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" x:Class="PageDownloadClient"
d:DesignWidth="778.571" d:DesignHeight="90.857">
<Grid>
<local:MyScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" x:Name="PanBack">
<StackPanel Orientation="Vertical" Margin="5">
<!--<local:MyCard Margin="20,20,20,0" Grid.IsSharedSizeScope="True" Title="自动安装提示" x:Name="CardTip">
<StackPanel Margin="25,40,15,20">
<TextBlock Margin="0,0,0,2" Text="本页只提供需要在下载后手动进行安装的游戏 Jar 与 Json 下载。" TextWrapping="Wrap" />
<TextBlock Margin="0,0,0,11" Text="如果你想要进行自动安装,在游戏安装页选择游戏版本,然后直接安装即可。" TextWrapping="Wrap" />
<Grid Height="35">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
</Grid.ColumnDefinitions>
<local:MyButton x:Name="BtnWeb" Grid.Column="0" MinWidth="140" Text="打开官网" Padding="13,0" Margin="0,0,20,0" HorizontalAlignment="Left" ColorType="Highlight" />
<local:MyButton x:Name="BtnInstall" Grid.Column="1" MinWidth="140" Text="转到游戏安装页" Padding="13,0" Margin="0,0,20,0" HorizontalAlignment="Left" />
</Grid>
</StackPanel>
</local:MyCard>-->
<StackPanel Name="PanMain" Margin="20,20,20,5" Grid.IsSharedSizeScope="True" />
</StackPanel>
</local:MyScrollViewer>
<local:MyCard HorizontalAlignment="Center" VerticalAlignment="Center" Margin="40,0" SnapsToDevicePixels="True" x:Name="PanLoad" UseAnimation="False">
<local:MyLoading Text="正在获取版本列表" Margin="20,20,20,17" x:Name="Load" HorizontalAlignment="Center" VerticalAlignment="Center" />
</local:MyCard>
</Grid>
</local:MyPageRight>
@@ -0,0 +1,107 @@
Public Class PageDownloadClient
Private Sub LoaderInit() Handles Me.Initialized
PageLoaderInit(Load, PanLoad, PanBack, Nothing, DlClientListLoader, AddressOf Load_OnFinish)
End Sub
Private Sub Init() Handles Me.Loaded
PanBack.ScrollToHome()
End Sub
Private Sub Load_OnFinish()
'结果数据化
Try
'归类
Dim Dict As New Dictionary(Of String, List(Of JObject)) From {
{"正式版", New List(Of JObject)}, {"预览版", New List(Of JObject)}, {"远古版", New List(Of JObject)}, {"愚人节版", New List(Of JObject)}
}
Dim Versions As JArray = DlClientListLoader.Output.Value("versions")
For Each Version As JObject In Versions
'确定分类
Dim Type As String = Version("type")
Select Case Type
Case "release"
Type = "正式版"
Case "snapshot"
Type = "预览版"
'Mojang 误分类
If Version("id").ToString.StartsWith("1.") AndAlso
Not Version("id").ToString.ToLower.Contains("combat") AndAlso
Not Version("id").ToString.ToLower.Contains("rc") AndAlso
Not Version("id").ToString.ToLower.Contains("experimental") AndAlso
Not Version("id").ToString.ToLower.Contains("pre") Then
Type = "正式版"
Version("type") = "release"
End If
'愚人节版本
Select Case Version("id").ToString.ToLower
Case "20w14infinite", "20w14∞"
Type = "愚人节版"
Version("id") = "20w14∞"
Version("type") = "special"
Version.Add("lore", GetMcFoolName(Version("id")))
Case "3d shareware v1.34", "1.rv-pre1", "15w14a", "2.0", "22w13oneblockatatime"
Type = "愚人节版"
Version("type") = "special"
Version.Add("lore", GetMcFoolName(Version("id")))
End Select
Case "special"
'已被处理的愚人节版
Type = "愚人节版"
Case Else
Type = "远古版"
End Select
'加入辞典
Dict(Type).Add(Version)
Next
'排序
For i = 0 To Dict.Keys.Count - 1
Dict(Dict.Keys(i)) = Sort(Dict.Values(i), Function(Left As JObject, Right As JObject) As Boolean
Return Left("releaseTime").Value(Of Date) > Right("releaseTime").Value(Of Date)
End Function)
Next
'清空当前
PanMain.Children.Clear()
'添加最新版本
Dim CardInfo As New MyCard With {.Title = "最新版本", .Margin = New Thickness(0, 0, 0, 15), .SwapType = 2}
Dim TopestVersions As New List(Of JObject)
Dim Release As JObject = Dict("正式版")(0).DeepClone()
Release("lore") = "最新正式版,发布于 " & Release("releaseTime").ToString()
TopestVersions.Add(Release)
If Dict("正式版")(0)("releaseTime").Value(Of Date) < Dict("预览版")(0)("releaseTime").Value(Of Date) Then
Dim Snapshot As JObject = Dict("预览版")(0).DeepClone()
Snapshot("lore") = "最新预览版,发布于 " & Snapshot("releaseTime").ToString()
TopestVersions.Add(Snapshot)
End If
Dim PanInfo As New StackPanel With {.Margin = New Thickness(20, MyCard.SwapedHeight, 18, 0), .VerticalAlignment = VerticalAlignment.Top, .RenderTransform = New TranslateTransform(0, 0), .Tag = TopestVersions}
MyCard.StackInstall(PanInfo, 2)
CardInfo.Children.Add(PanInfo)
PanMain.Children.Add(CardInfo)
'添加其他版本
For Each Pair As KeyValuePair(Of String, List(Of JObject)) In Dict
If Pair.Value.Count = 0 Then Continue For
'增加卡片
Dim NewCard As New MyCard With {.Title = Pair.Key & " (" & Pair.Value.Count & ")", .Margin = New Thickness(0, 0, 0, 15), .SwapType = 2}
Dim NewStack As New StackPanel With {.Margin = New Thickness(20, MyCard.SwapedHeight, 18, 0), .VerticalAlignment = VerticalAlignment.Top, .RenderTransform = New TranslateTransform(0, 0), .Tag = Pair.Value}
NewCard.Children.Add(NewStack)
NewCard.SwapControl = NewStack
NewCard.IsSwaped = True
PanMain.Children.Add(NewCard)
Next
Catch ex As Exception
Log(ex, "可视化版本列表出错", LogLevel.Feedback)
End Try
End Sub
Public Sub DownloadStart(sender As MyListItem, e As Object)
McDownloadClient(NetPreDownloadBehaviour.HintWhileExists, sender.Title, sender.Tag("url").ToString)
End Sub
''介绍栏
'Private Sub BtnWeb_Click(sender As Object, e As EventArgs) Handles BtnWeb.Click
' OpenWebsite("https://www.minecraft.net/zh-hans")
'End Sub
'Private Sub BtnInstall_Click(sender As Object, e As EventArgs) Handles BtnInstall.Click
' FrmMain.PageChange(FormMain.PageType.Download, FormMain.PageSubType.DownloadInstall)
'End Sub
End Class
@@ -0,0 +1,28 @@
<local:MyPageRight
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:PCL" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" x:Class="PageDownloadFabric"
d:DesignWidth="778.571" d:DesignHeight="90.857">
<local:MyScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" x:Name="PanBack">
<StackPanel Orientation="Vertical" Margin="5">
<local:MyCard Margin="20,20,20,0" Grid.IsSharedSizeScope="True" Title="Fabric 简介" x:Name="CardTip">
<StackPanel Margin="25,40,15,20">
<TextBlock Margin="0,0,0,11" Text="Fabric Loader 是新版 Minecraft 下的轻量化 Mod 加载器,你需要先安装它才能安装各种 Fabric 模组。&#xa;本页面提供 Fabric 安装器下载,在下载后你需要手动打开安装器进行安装。" TextWrapping="Wrap" />
<Grid Height="35">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
</Grid.ColumnDefinitions>
<local:MyButton x:Name="BtnWeb" Grid.Column="0" MinWidth="140" Text="打开官网" Padding="13,0" Margin="0,0,20,0" HorizontalAlignment="Left" ColorType="Highlight" />
</Grid>
</StackPanel>
</local:MyCard>
<local:MyCard x:Name="CardVersions" Margin="20,15,20,20" Title="版本列表">
<StackPanel x:Name="PanVersions" Margin="20,40,18,20" />
</local:MyCard>
<local:MyCard HorizontalAlignment="Center" SnapsToDevicePixels="True" x:Name="PanLoad" UseAnimation="False" Margin="40,50">
<local:MyLoading Text="正在获取 Fabric 列表" Margin="20,20,20,17" x:Name="Load" HorizontalAlignment="Center" VerticalAlignment="Center" />
</local:MyCard>
</StackPanel>
</local:MyScrollViewer>
</local:MyPageRight>
@@ -0,0 +1,32 @@
Public Class PageDownloadFabric
Private Sub LoaderInit() Handles Me.Initialized
PageLoaderInit(Load, PanLoad, CardVersions, CardTip, DlFabricListLoader, AddressOf Load_OnFinish)
End Sub
Private Sub Init() Handles Me.Loaded
PanBack.ScrollToHome()
End Sub
Private Sub Load_OnFinish()
'结果数据化
Try
Dim Versions As JArray = DlFabricListLoader.Output.Value("installer")
PanVersions.Children.Clear()
For Each Version In Versions
PanVersions.Children.Add(FabricDownloadListItem(Version, AddressOf Fabric_Selected))
Next
CardVersions.Title = "版本列表 (" & Versions.Count & ")"
Catch ex As Exception
Log(ex, "可视化 Fabric 版本列表出错", LogLevel.Feedback)
End Try
End Sub
Private Sub Fabric_Selected(sender As MyListItem, e As EventArgs)
McDownloadFabricLoaderSave(sender.Tag)
End Sub
Private Sub BtnWeb_Click(sender As Object, e As EventArgs) Handles BtnWeb.Click
OpenWebsite("https://www.fabricmc.net")
End Sub
End Class
@@ -0,0 +1,26 @@
<local:MyPageRight
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:PCL" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" x:Class="PageDownloadForge"
d:DesignWidth="778.571" d:DesignHeight="90.857">
<local:MyScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" x:Name="PanBack">
<StackPanel Orientation="Vertical" Margin="5">
<local:MyCard Margin="20,20,20,0" Grid.IsSharedSizeScope="True" Title="Forge 简介" x:Name="CardTip">
<StackPanel Margin="25,40,15,20">
<TextBlock Name="LabConnect" Margin="0,0,0,11" Text="Forge 是一个 Mod 加载器,你需要先安装 Forge 才能安装各种 Forge 模组。" TextWrapping="Wrap" />
<Grid Height="35">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
</Grid.ColumnDefinitions>
<local:MyButton x:Name="BtnWeb" Grid.Column="0" MinWidth="140" Text="打开官网" Padding="13,0" Margin="0,0,20,0" HorizontalAlignment="Left" ColorType="Highlight" />
</Grid>
</StackPanel>
</local:MyCard>
<StackPanel Name="PanMain" Margin="20,15,20,5" Grid.IsSharedSizeScope="True" />
<local:MyCard HorizontalAlignment="Center" Margin="40,50" SnapsToDevicePixels="True" x:Name="PanLoad" UseAnimation="False">
<local:MyLoading Text="正在获取 Forge 列表" Margin="20,20,20,17" x:Name="Load" HorizontalAlignment="Center" VerticalAlignment="Center" />
</local:MyCard>
</StackPanel>
</local:MyScrollViewer>
</local:MyPageRight>
@@ -0,0 +1,67 @@
Public Class PageDownloadForge
Private Sub LoaderInit() Handles Me.Initialized
PageLoaderInit(Load, PanLoad, PanMain, CardTip, DlForgeListLoader, AddressOf Load_OnFinish)
End Sub
Private Sub Init() Handles Me.Loaded
PanBack.ScrollToHome()
End Sub
Private Sub Load_OnFinish()
'结果数据化
Try
'排序
Dim Versions = Sort(DlForgeListLoader.Output.Value, AddressOf VersionSortBoolean)
'清空当前
PanMain.Children.Clear()
'转化为 UI
For Each Version As String In Versions
'增加卡片
Dim NewCard As New MyCard With {.Title = Version.Replace("_p", " P"), .Margin = New Thickness(0, 0, 0, 15), .SwapType = 5}
Dim NewStack As New StackPanel With {.Margin = New Thickness(20, MyCard.SwapedHeight, 18, 0), .VerticalAlignment = VerticalAlignment.Top, .RenderTransform = New TranslateTransform(0, 0), .Tag = Version}
NewCard.Children.Add(NewStack)
NewCard.SwapControl = NewStack
NewCard.IsSwaped = True
PanMain.Children.Add(NewCard)
Next
''非官方源警示
'If Setup.Get("ToolDownloadOutOfDate") AndAlso Not DlForgeListLoader.Output.IsOfficial Then
' Dim CardWarn As New MyCard With {.Title = "过期提示", .Margin = New Thickness(0, 0, 0, 15)}
' CardWarn.Children.Add(New TextBlock With {
' .Margin = New Thickness(25, MyCard.SwapedHeight, 15, 15), .VerticalAlignment = VerticalAlignment.Top, .HorizontalAlignment = HorizontalAlignment.Left, .TextTrimming = TextTrimming.None, .TextWrapping = TextWrapping.Wrap,
' .Text = "获取官方源失败,正在使用 " & DlForgeListLoader.Output.SourceName & " 镜像源,版本列表可能并非最新。" & vbCrLf & "官方源错误原因:" & If(DlForgeListLoader.Output.OfficialError, New Exception("连接服务器超时")).Message})
' PanMain.Children.Insert(0, CardWarn)
'End If
Catch ex As Exception
Log(ex, "可视化版本列表出错", LogLevel.Feedback)
End Try
End Sub
'Forge 版本列表加载
Public Sub Forge_Click(sender As MyLoading, e As MouseButtonEventArgs)
If sender.State.LoadingState = MyLoading.MyLoadingState.Error Then
CType(sender.State, LoaderTask(Of String, List(Of DlForgeVersionEntry))).Start(IsForceRestart:=True)
End If
End Sub
Public Sub Forge_StateChanged(sender As MyLoading, newState As MyLoading.MyLoadingState, oldState As MyLoading.MyLoadingState)
If newState <> MyLoading.MyLoadingState.Stop Then Exit Sub
Dim Card As MyCard = CType(sender.Parent, FrameworkElement).Parent
Dim Loader As LoaderTask(Of String, List(Of DlForgeVersionEntry)) = sender.State
'载入列表
Card.SwapControl.Children.Clear()
Card.SwapControl.Tag = Loader.Output
Card.SwapType = 6
Card.StackInstall()
End Sub
Public Sub DownloadStart(sender As MyListItem, e As Object)
McDownloadForge(sender.Tag)
End Sub
'介绍栏
Private Sub BtnWeb_Click(sender As Object, e As EventArgs) Handles BtnWeb.Click
OpenWebsite("https://files.minecraftforge.net")
End Sub
End Class
@@ -0,0 +1,180 @@
<local:MyPageRight
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:PCL" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" x:Class="PageDownloadInstall"
d:DesignWidth="778.571" d:DesignHeight="90.857">
<Grid>
<local:MyScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" x:Name="PanBack">
<Grid Margin="25,10,25,25">
<VirtualizingStackPanel Grid.Row="1" VirtualizingStackPanel.IsVirtualizing="True" VirtualizingStackPanel.VirtualizationMode="Recycling" Name="PanMinecraft" Grid.IsSharedSizeScope="True">
<VirtualizingStackPanel.RenderTransform>
<TranslateTransform />
</VirtualizingStackPanel.RenderTransform>
</VirtualizingStackPanel>
<StackPanel Grid.Row="1" x:Name="PanSelect" Visibility="Collapsed" Opacity="0" IsHitTestVisible="False">
<StackPanel.RenderTransform>
<TranslateTransform X="40" />
</StackPanel.RenderTransform>
<local:MyCard Title="安装预览" Margin="0,15,0,0" UseAnimation="False">
<StackPanel Margin="25,37,25,15">
<local:MyHint Text="你尚未选择安装 Fabric API,这会导致大多数 Mod 无法使用!" Margin="0,1,0,7" x:Name="HintFabricAPI" />
<local:MyHint Text="你尚未选择安装 OptiFabric,这会导致 OptiFine 无法使用!" Margin="0,1,0,7" x:Name="HintOptiFabric" />
<Grid Margin="0,0,0,11">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<local:MyListItem Grid.Column="0" x:Name="ItemSelect" IsHitTestVisible="False" Margin="-7,0,0,0" Height="42" PaddingRight="15" SnapsToDevicePixels="True" Type="None" />
<local:MyButton Grid.Column="1" HorizontalAlignment="Right" ColorType="Highlight" Text="开始安装" Margin="0,2,0,0" x:Name="BtnSelectStart" MinWidth="140" Padding="13,0" Height="35" VerticalAlignment="Center" />
</Grid>
<Grid Margin="0,0,0,5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Name" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock VerticalAlignment="Top" HorizontalAlignment="Left" Text="版本名称" Margin="0,5,25,0" />
<local:MyTextBox Grid.Column="1" x:Name="TextSelectName" MinHeight="28" />
</Grid>
</StackPanel>
</local:MyCard>
<local:MyCard Title="Minecraft" Height="40" Margin="0,15,0,0" x:Name="CardMinecraft" IsSwaped="True" CanSwap="True" SwapLogoRight="True">
<FrameworkElement Tag="用于折叠" />
<Grid x:Name="PanMinecraftInfo" Height="18" Margin="175,11,15,0" VerticalAlignment="Top">
<Grid.RenderTransform>
<TranslateTransform />
</Grid.RenderTransform>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Image x:Name="ImgMinecraft" Margin="0,0,7,0" SnapsToDevicePixels="True" Height="18" RenderOptions.BitmapScalingMode="Linear" />
<TextBlock x:Name="LabMinecraft" VerticalAlignment="Center" TextTrimming="CharacterEllipsis" Grid.Column="1" />
</Grid>
</local:MyCard>
<local:MyCard Title="OptiFine" Height="40" Margin="0,15,0,0" x:Name="CardOptiFine" IsSwaped="True" CanSwap="True" SwapLogoRight="True">
<StackPanel Margin="20,40,18,15" VerticalAlignment="Top">
<StackPanel Name="PanOptiFine" />
</StackPanel>
<Grid x:Name="PanOptiFineInfo" Height="18" Margin="175,11,15,0" VerticalAlignment="Top" Tag="True">
<Grid.RenderTransform>
<TranslateTransform />
</Grid.RenderTransform>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Image x:Name="ImgOptiFine" Margin="0,0,7,0" SnapsToDevicePixels="True" Height="18" RenderOptions.BitmapScalingMode="Linear" Source="pack://application:,,,/images/Blocks/GrassPath.png" />
<TextBlock x:Name="LabOptiFine" VerticalAlignment="Center" TextTrimming="CharacterEllipsis" Grid.Column="1" />
</Grid>
<Grid x:Name="BtnOptiFineClear" Height="30" Width="30" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,5,32,0" Background="{StaticResource ColorBrushSemiTransparent}">
<Path x:Name="BtnOptiFineClearInner" Height="10" Width="10" Stretch="Uniform" Fill="{StaticResource ColorBrushGray1}" HorizontalAlignment="Center" VerticalAlignment="Center"
Data="F1 M2,0 L0,2 8,10 0,18 2,20 10,12 18,20 20,18 12,10 20,2 18,0 10,8 2,0Z" />
</Grid>
</local:MyCard>
<local:MyCard Title="Forge" Height="40" Margin="0,15,0,0" x:Name="CardForge" IsSwaped="True" CanSwap="True" SwapLogoRight="True">
<StackPanel Margin="20,40,18,15" VerticalAlignment="Top" Name="PanForge" />
<Grid x:Name="PanForgeInfo" Height="18" Margin="175,11,15,0" VerticalAlignment="Top" Tag="True">
<Grid.RenderTransform>
<TranslateTransform />
</Grid.RenderTransform>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Image x:Name="ImgForge" Margin="0,0,7,0" SnapsToDevicePixels="True" Height="18" RenderOptions.BitmapScalingMode="Linear" Source="pack://application:,,,/images/Blocks/Anvil.png" />
<TextBlock x:Name="LabForge" VerticalAlignment="Center" TextTrimming="CharacterEllipsis" Grid.Column="1" />
</Grid>
<Grid x:Name="BtnForgeClear" Height="30" Width="30" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,5,32,0" Background="{StaticResource ColorBrushSemiTransparent}">
<Path x:Name="BtnForgeClearInner" Height="10" Width="10" Stretch="Uniform" Fill="{StaticResource ColorBrushGray1}" HorizontalAlignment="Center" VerticalAlignment="Center"
Data="F1 M2,0 L0,2 8,10 0,18 2,20 10,12 18,20 20,18 12,10 20,2 18,0 10,8 2,0Z" />
</Grid>
</local:MyCard>
<local:MyCard Title="Fabric" Height="40" Margin="0,15,0,0" x:Name="CardFabric" IsSwaped="True" CanSwap="True" SwapLogoRight="True">
<StackPanel Margin="20,40,18,15" VerticalAlignment="Top">
<StackPanel Name="PanFabric" />
</StackPanel>
<Grid x:Name="PanFabricInfo" Height="18" Margin="175,11,15,0" VerticalAlignment="Top" Tag="True">
<Grid.RenderTransform>
<TranslateTransform />
</Grid.RenderTransform>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Image x:Name="ImgFabric" Margin="0,0,7,0" SnapsToDevicePixels="True" Height="18" RenderOptions.BitmapScalingMode="Linear" Source="pack://application:,,,/images/Blocks/Fabric.png" />
<TextBlock x:Name="LabFabric" VerticalAlignment="Center" TextTrimming="CharacterEllipsis" Grid.Column="1" />
</Grid>
<Grid x:Name="BtnFabricClear" Height="30" Width="30" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,5,32,0" Background="{StaticResource ColorBrushSemiTransparent}">
<Path x:Name="BtnFabricClearInner" Height="10" Width="10" Stretch="Uniform" Fill="{StaticResource ColorBrushGray1}" HorizontalAlignment="Center" VerticalAlignment="Center"
Data="F1 M2,0 L0,2 8,10 0,18 2,20 10,12 18,20 20,18 12,10 20,2 18,0 10,8 2,0Z" />
</Grid>
</local:MyCard>
<local:MyCard Title="Fabric API" Height="40" Margin="0,15,0,0" x:Name="CardFabricApi" IsSwaped="True" CanSwap="True" SwapLogoRight="True">
<StackPanel Margin="20,40,18,15" VerticalAlignment="Top" Name="PanFabricApi" />
<Grid x:Name="PanFabricApiInfo" Height="18" Margin="175,11,15,0" VerticalAlignment="Top" Tag="True">
<Grid.RenderTransform>
<TranslateTransform />
</Grid.RenderTransform>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Image x:Name="ImgFabricApi" Margin="0,0,7,0" SnapsToDevicePixels="True" Height="18" RenderOptions.BitmapScalingMode="Linear" Source="pack://application:,,,/images/Blocks/Fabric.png" />
<TextBlock x:Name="LabFabricApi" VerticalAlignment="Center" TextTrimming="CharacterEllipsis" Grid.Column="1" />
</Grid>
<Grid x:Name="BtnFabricApiClear" Height="30" Width="30" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,5,32,0" Background="{StaticResource ColorBrushSemiTransparent}">
<Path x:Name="BtnFabricApiClearInner" Height="10" Width="10" Stretch="Uniform" Fill="{StaticResource ColorBrushGray1}" HorizontalAlignment="Center" VerticalAlignment="Center"
Data="F1 M2,0 L0,2 8,10 0,18 2,20 10,12 18,20 20,18 12,10 20,2 18,0 10,8 2,0Z" />
</Grid>
</local:MyCard>
<local:MyCard Title="OptiFabric" Height="40" Margin="0,15,0,0" x:Name="CardOptiFabric" IsSwaped="True" CanSwap="True" SwapLogoRight="True">
<StackPanel Margin="20,40,18,15" VerticalAlignment="Top" Name="PanOptiFabric" />
<Grid x:Name="PanOptiFabricInfo" Height="18" Margin="175,11,15,0" VerticalAlignment="Top" Tag="True">
<Grid.RenderTransform>
<TranslateTransform />
</Grid.RenderTransform>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Image x:Name="ImgOptiFabric" Margin="0,0,7,0" SnapsToDevicePixels="True" Height="18" RenderOptions.BitmapScalingMode="HighQuality" Source="pack://application:,,,/images/Blocks/OptiFabric.png" />
<TextBlock x:Name="LabOptiFabric" VerticalAlignment="Center" TextTrimming="CharacterEllipsis" Grid.Column="1" />
</Grid>
<Grid x:Name="BtnOptiFabricClear" Height="30" Width="30" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,5,32,0" Background="{StaticResource ColorBrushSemiTransparent}">
<Path x:Name="BtnOptiFabricClearInner" Height="10" Width="10" Stretch="Uniform" Fill="{StaticResource ColorBrushGray1}" HorizontalAlignment="Center" VerticalAlignment="Center"
Data="F1 M2,0 L0,2 8,10 0,18 2,20 10,12 18,20 20,18 12,10 20,2 18,0 10,8 2,0Z" />
</Grid>
</local:MyCard>
<local:MyCard Title="LiteLoader" Height="40" Margin="0,15,0,0" x:Name="CardLiteLoader" IsSwaped="True" CanSwap="True" SwapLogoRight="True">
<StackPanel Margin="20,40,18,15" VerticalAlignment="Top" Name="PanLiteLoader" />
<Grid x:Name="PanLiteLoaderInfo" Height="18" Margin="175,11,15,0" VerticalAlignment="Top" Tag="True">
<Grid.RenderTransform>
<TranslateTransform />
</Grid.RenderTransform>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Image x:Name="ImgLiteLoader" Margin="-1,0,6,0" SnapsToDevicePixels="True" Height="20" RenderOptions.BitmapScalingMode="Linear" Source="pack://application:,,,/images/Blocks/Egg.png" />
<TextBlock x:Name="LabLiteLoader" VerticalAlignment="Center" TextTrimming="CharacterEllipsis" Grid.Column="1" />
</Grid>
<Grid x:Name="BtnLiteLoaderClear" Height="30" Width="30" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,5,32,0" Background="{StaticResource ColorBrushSemiTransparent}">
<Path x:Name="BtnLiteLoaderClearInner" Height="10" Width="10" Stretch="Uniform" Fill="{StaticResource ColorBrushGray1}" HorizontalAlignment="Center" VerticalAlignment="Center"
Data="F1 M2,0 L0,2 8,10 0,18 2,20 10,12 18,20 20,18 12,10 20,2 18,0 10,8 2,0Z" />
</Grid>
</local:MyCard>
</StackPanel>
</Grid>
</local:MyScrollViewer>
<local:MyCard HorizontalAlignment="Center" VerticalAlignment="Center" Margin="40,0" SnapsToDevicePixels="True" x:Name="PanLoad" UseAnimation="False">
<local:MyLoading Text="正在获取版本列表" Margin="20,20,20,17" x:Name="LoadMinecraft" HorizontalAlignment="Center" VerticalAlignment="Center" />
<local:MyLoading Visibility="Collapsed" x:Name="LoadOptiFine" HasAnimation="False" />
<local:MyLoading Visibility="Collapsed" x:Name="LoadForge" HasAnimation="False" />
<local:MyLoading Visibility="Collapsed" x:Name="LoadLiteLoader" HasAnimation="False" />
<local:MyLoading Visibility="Collapsed" x:Name="LoadFabric" HasAnimation="False" />
<local:MyLoading Visibility="Collapsed" x:Name="LoadFabricApi" HasAnimation="False" />
<local:MyLoading Visibility="Collapsed" x:Name="LoadOptiFabric" HasAnimation="False" />
</local:MyCard>
</Grid>
</local:MyPageRight>
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,81 @@
<local:MyPageLeft x:Class="PageDownloadLeft"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:PCL" AnimatedControl="{Binding ElementName=PanItem, Mode=OneWay}">
<StackPanel Margin="0,12,0,0" Name="PanItem">
<TextBlock x:Name="LabGame" Text="游戏组件" Margin="13,6,5,4" Opacity="0.6" FontSize="12" />
<local:MyListItem x:Name="ItemInstall" Checked="True" IsScaleAnimationEnabled="False" Type="RadioBox" Tag="1" PaddingRight="35" Height="36" VerticalAlignment="Top" Title="自动安装"
LogoScale="0.87" Logo="M1091.291429 0H78.935771C35.34848 0.035109 0.029257 35.354331 0 78.935771v863.331475c0 43.534629 35.401143 78.994286 78.935771 78.994285H1091.291429c43.534629 0 78.994286-35.401143 78.994285-78.994285V78.871406C1170.156983 35.319223 1134.849463 0.064366 1091.291429 0z m-8.835658 87.771429v78.754377H87.771429v-78.760229h994.684342zM87.771429 933.425737V254.232869h994.684342v679.140205H87.771429v0.058515zM724.95104 340.00896l-206.19264 547.605943a43.903269 43.903269 0 0 1-82.154057-31.012572l206.139977-547.547428a43.944229 43.944229 0 0 1 82.20672 30.954057zM369.558674 545.909029l-85.489371 85.489371 85.489371 85.542034a43.885714 43.885714 0 0 1-62.025143 62.083657l-116.554605-116.560457a43.8272 43.8272 0 0 1 0-62.025143l116.560457-116.49024a43.885714 43.885714 0 0 1 62.019291 61.966629z m610.567315-37.566172a43.885714 43.885714 0 0 1 0 62.083657l-116.560458 116.560457a43.768686 43.768686 0 0 1-62.019291 0 43.885714 43.885714 0 0 1 0-62.083657l85.547886-85.547885-85.547886-85.542035a43.897417 43.897417 0 0 1 62.083657-62.083657l116.496092 116.618972z">
<local:MyListItem.Buttons>
<x:Array Type="{x:Type local:MyIconButton}">
<local:MyIconButton Tag="1" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.ShowDuration="2333333" ToolTipService.InitialShowDelay="200" LogoScale="0.85" Click="Refresh" Logo="M875.52 148.48C783.36 56.32 655.36 0 512 0 291.84 0 107.52 138.24 30.72 332.8l122.88 46.08C204.8 230.4 348.16 128 512 128c107.52 0 199.68 40.96 271.36 112.64L640 384h384V0L875.52 148.48zM512 896c-107.52 0-199.68-40.96-271.36-112.64L384 640H0v384l148.48-148.48C240.64 967.68 368.64 1024 512 1024c220.16 0 404.48-138.24 481.28-332.8L870.4 645.12C819.2 793.6 675.84 896 512 896z" />
</x:Array>
</local:MyListItem.Buttons>
</local:MyListItem>
<local:MyListItem x:Name="ItemHand" IsScaleAnimationEnabled="False" Type="RadioBox" PaddingRight="35" Height="36" VerticalAlignment="Top" Title="手动安装包"
LogoScale="1.02" Logo="M292.693 787.627c0 30.72-24.746 55.466-55.466 55.466s-55.467-24.746-55.467-55.466 24.747-55.467 55.467-55.467c30.72-0.853 55.466 24.747 55.466 55.467z M1000.96 241.493c-2.56-5.973-4.267-11.946-6.827-17.92-0.853-6.826-4.266-12.8-8.533-17.92-7.68-9.386-18.773-15.36-31.573-15.36-6.827 0-13.654 1.707-19.627 5.12l-15.36 15.36-17.067 17.067-21.333 21.333L749.227 381.44c-14.507 14.507-38.4 14.507-52.907 0l-54.613-54.613c-14.507-14.507-14.507-38.4 0-52.907l132.266-132.267 14.507-14.506 20.48-20.48 16.213-16.214c3.414-5.973 5.12-11.946 5.12-19.626 0-12.8-5.973-24.747-16.213-32.427-5.973-4.267-11.947-6.827-18.773-7.68-5.12-2.56-10.24-4.267-16.214-5.973-36.693-12.8-76.8-19.627-117.76-19.627-7.68 0-14.506 0-22.186 0.853-188.587 11.947-337.92 168.107-337.92 360.96 0 16.214 0.853 32.427 3.413 48.64L56.32 663.04c-73.387 74.24-73.387 193.707 0 267.093l33.28 33.28c73.387 73.387 193.707 73.387 267.093 0l240.64-241.493c21.334 4.267 42.667 5.973 64 5.973 190.294 0 346.454-146.773 360.107-333.653 0.853-8.533 0.853-17.92 0.853-27.307 0.854-44.373-6.826-86.186-21.333-125.44zM658.773 639.147c-28.16 0-54.613-4.267-79.36-11.094-4.266 7.68-10.24 14.507-16.213 21.334l-258.56 258.56c-43.52 43.52-115.2 43.52-158.72 0l-29.013-29.014c-43.52-44.373-43.52-115.2 0-158.72l212.48-212.48 46.08-46.08c5.973-5.973 12.8-11.093 19.626-15.36-8.533-26.453-12.8-54.613-12.8-83.626v-1.707c0-152.747 123.734-275.627 276.48-275.627 18.774 0 37.547 1.707 55.467 5.974L597.333 207.36c-52.053 52.053-52.053 137.387 0 189.44l29.867 29.867c52.053 52.053 137.387 52.053 189.44 0L930.987 312.32c2.56 16.213 4.266 33.28 4.266 50.347 0 152.746-123.733 276.48-276.48 276.48z" />
<TextBlock x:Name="LabHand" Visibility="Collapsed" Text="手动安装包" Margin="13,18,5,4" Opacity="0.6" FontSize="12" />
<local:MyListItem x:Name="ItemClient" Visibility="Collapsed" IsScaleAnimationEnabled="False" Type="RadioBox" Tag="4" PaddingRight="35" Height="36" VerticalAlignment="Top" Title="Minecraft"
LogoScale="0.98" Logo="M989.7 510.8l-202.3-101c-10.8-5.4-17.7-16.5-17.7-28.6V172.7c0-26.7-16.6-50.6-41.6-59.9L550.5 46.3c-24.2-9-50.8-9-74.9 0.1l-176.9 66.8c-24.9 9.4-41.4 33.2-41.4 59.9v207.1c0 12.1-6.9 23.2-17.7 28.6l-204 101.9C13.9 521.6 0.1 543.8 0.2 568.1l0.5 226c0 23.2 12.6 44.5 32.9 55.8l223.8 124.6 1.2 0.7c18.9 10.5 41.9 10.4 60.8-0.2l2-1.1L497 873.2c9.9-5.7 22.1-5.6 32 0.1l176.7 102.5c18.9 10.7 42 10.8 61 0.3l3-1.7L992.4 851c20.4-11.3 33-32.8 33-56l-0.3-226.9c0-24.3-13.7-46.5-35.4-57.3zM321 192l115.3 46.1c27 10.8 44.7 36.9 44.7 66v163c0 5.9-6.2 9.8-11.6 7.2L339 409.5c-10.9-5.4-17.7-16.5-17.8-28.6L321 192z m-63.7 703.4L82.5 809.6c-10.9-5.4-17.9-16.5-17.9-28.7l-0.4-189.5L217.9 668c24.1 12 39.4 36.7 39.4 63.6v163.8z m64-274.3c-20.1 10.1-43.7 10-63.8 0l-0.2-0.1-149.1-75 149.1-74.4 16.8-8.4c9.2-4.6 20-4.5 29.1 0.3l18.1 9.4 129.8 64.3c5.8 2.9 6 11.1 0.2 14.2l-130 69.7z m141.9 203.8l-141.8 70.6-0.8-163.6c-0.1-27 15.1-51.8 39.2-63.9l108.8-54.5c5.3-2.7 11.6 1.2 11.6 7.1l0.8 175.6c0 12.1-6.9 23.2-17.8 28.7zM385 144l128-48 128 48-103 38.6c-16.1 6-33.8 6-49.9 0L385 144z m320 48l0.6 187.8c0 12.2-6.8 23.3-17.7 28.7l-131.4 65.7c-5.3 2.7-11.6-1.2-11.6-7.2V304.1c0-29.1 17.7-55.2 44.7-66L705 192z m0.7 710.3l-143.8-77.2c-10.4-5.6-16.9-16.4-16.9-28.2v-176c0-5.9 6.3-9.8 11.6-7.2l109.3 54.6c24 12 39.2 36.5 39.3 63.4l0.5 170.6z m-2-280.5l-129.2-70.5c-5.7-3.1-5.5-11.3 0.3-14.2l131-65.3 16.1-8.5c9.1-4.8 19.9-4.9 29.1-0.3l18.7 9.3L916.9 546l-146.2 76.4c-21.1 11-46.2 10.8-67-0.6z m66 279.4l-0.6-169.1c-0.1-27 15.1-51.7 39.3-63.8L961 592v188.7c0 11.9-6.6 22.7-17 28.3l-174.3 92.2z">
<!--Logo="M469.333333 213.333333V128a42.666667 42.666667 0 1 1 85.333334 0v85.333333h127.829333C847.722667 213.333333 981.333333 347.029333 981.333333 512.149333v319.936A106.496 106.496 0 0 1 874.730667 938.666667h-85.461334c-48.661333 0-107.221333-29.290667-136.469333-68.266667l-64-85.333333c-6.144-8.170667-23.957333-17.066667-34.24-17.066667h-85.12c-10.282667 0-28.096 8.896-34.24 17.066667l-64 85.333333c-29.226667 38.976-87.808 68.266667-136.469333 68.266667H149.269333A106.496 106.496 0 0 1 42.666667 832.085333V512.149333C42.666667 347.029333 176.277333 213.333333 341.504 213.333333H469.333333z m213.162667 85.333334H341.504A213.333333 213.333333 0 0 0 128 512.149333v319.936c0 11.818667 9.450667 21.248 21.269333 21.248h85.461334c21.802667 0 55.082667-16.64 68.202666-34.133333l64-85.333333c22.272-29.696 65.408-51.2 102.506667-51.2h85.12c37.098667 0 80.213333 21.504 102.506667 51.2l64 85.333333c13.12 17.493333 46.4 34.133333 68.202666 34.133333h85.461334a21.162667 21.162667 0 0 0 21.269333-21.248V512.149333A213.333333 213.333333 0 0 0 682.496 298.666667zM362.666667 469.333333h42.666666a42.666667 42.666667 0 1 1 0 85.333334h-42.666666v42.666666a42.666667 42.666667 0 1 1-85.333334 0v-42.666666h-42.666666a42.666667 42.666667 0 1 1 0-85.333334h42.666666v-42.666666a42.666667 42.666667 0 1 1 85.333334 0v42.666666z m341.333333-21.333333a42.666667 42.666667 0 1 1 0-85.333333 42.666667 42.666667 0 0 1 0 85.333333z m0 213.333333a42.666667 42.666667 0 1 1 0-85.333333 42.666667 42.666667 0 0 1 0 85.333333z m-106.666667-106.666666a42.666667 42.666667 0 1 1 0-85.333334 42.666667 42.666667 0 0 1 0 85.333334z m213.333334 0a42.666667 42.666667 0 1 1 0-85.333334 42.666667 42.666667 0 0 1 0 85.333334z">-->
<local:MyListItem.Buttons>
<x:Array Type="{x:Type local:MyIconButton}">
<local:MyIconButton Tag="4" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.ShowDuration="2333333" ToolTipService.InitialShowDelay="200" LogoScale="0.85" Click="Refresh" Logo="M875.52 148.48C783.36 56.32 655.36 0 512 0 291.84 0 107.52 138.24 30.72 332.8l122.88 46.08C204.8 230.4 348.16 128 512 128c107.52 0 199.68 40.96 271.36 112.64L640 384h384V0L875.52 148.48zM512 896c-107.52 0-199.68-40.96-271.36-112.64L384 640H0v384l148.48-148.48C240.64 967.68 368.64 1024 512 1024c220.16 0 404.48-138.24 481.28-332.8L870.4 645.12C819.2 793.6 675.84 896 512 896z" />
</x:Array>
</local:MyListItem.Buttons>
</local:MyListItem>
<local:MyListItem x:Name="ItemOptiFine" Visibility="Collapsed" Type="RadioBox" IsScaleAnimationEnabled="False" Tag="5" PaddingRight="35" Height="36" VerticalAlignment="Top" Title="OptiFine"
LogoScale="1.00" Logo="M439.667 538.133l-323.311-174.763c-6.554-3.641-13.836-5.098-20.389-5.098-23.301 0-45.147 20.389-45.147 48.788v341.516c0 35.681 18.205 67.721 48.060 83.741l323.311 174.763c6.554 3.641 13.836 5.825 20.389 5.825 23.301 0 45.147-21.117 45.147-49.516v-341.516c0-34.953-18.205-67.721-48.060-83.741zM414.909 920.427l-281.805-152.189c-4.369-2.913-9.467-9.467-9.467-19.661v-298.553l281.805 152.189c5.825 3.641 9.467 11.651 9.467 19.661v298.553zM952.304 358.274c-6.554 0-13.836 1.456-20.389 5.098l-323.311 175.491c-29.855 16.020-48.060 48.788-48.060 84.468v340.059c0 28.399 21.845 49.516 45.147 49.516 6.554 0 13.836-1.456 20.389-5.098l323.311-175.491c29.127-16.020 48.060-48.060 48.060-83.741v-341.516c0-28.399-21.845-48.788-45.147-48.788zM924.634 747.849c0 10.194-5.098 17.476-9.467 19.661l-281.805 152.917v-297.097c0-10.194 5.098-17.476 9.467-19.661l281.805-153.646v297.825zM902.060 283.272c15.292-8.010 22.574-21.845 21.117-34.953 1.456-13.836-5.825-26.943-21.117-34.953l-329.136-171.85c-14.563-8.010-31.312-11.651-48.788-11.651 0 0 0 0 0 0 0 0 0 0 0 0s-34.224 3.641-49.516 11.651l-329.865 171.122c-15.292 8.010-21.845 21.845-21.117 35.681-0.729 13.107 5.825 26.943 21.117 34.953l329.136 171.122c14.563 8.010 32.039 11.651 49.516 11.651 0 0 0 0 0.729 0 0 0 0 0 0.729 0s34.224-3.641 49.516-11.651l327.68-171.122zM523.407 393.227c-5.825 0-11.651-1.456-16.020-3.641l-272.338-141.266 272.338-141.995c4.369-2.185 10.194-3.641 16.748-3.641 5.825 0 11.651 1.456 16.020 3.641l272.338 141.995-273.067 141.266c-3.641 2.185-9.467 3.641-16.020 3.641z">
<!--Logo="M12 0l-11 6v12.131l11 5.869 11-5.869v-12.066l-11-6.065zm-1 21.2l-6.664-3.555 4.201-2.801c1.08-.719-.066-2.359-1.243-1.575l-4.294 2.862v-7.901l8 4.363v8.607zm-6.867-14.63l6.867-3.746v4.426c0 1.323 2 1.324 2 0v-4.415l6.91 3.811-7.905 4.218-7.872-4.294zm8.867 6.03l8-4.269v7.8l-4.263-2.842c-1.181-.785-2.323.855-1.245 1.574l4.172 2.781-6.664 3.556v-8.6z">-->
<local:MyListItem.Buttons>
<x:Array Type="{x:Type local:MyIconButton}">
<local:MyIconButton Tag="5" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.ShowDuration="2333333" ToolTipService.InitialShowDelay="200" LogoScale="0.85" Click="Refresh" Logo="M875.52 148.48C783.36 56.32 655.36 0 512 0 291.84 0 107.52 138.24 30.72 332.8l122.88 46.08C204.8 230.4 348.16 128 512 128c107.52 0 199.68 40.96 271.36 112.64L640 384h384V0L875.52 148.48zM512 896c-107.52 0-199.68-40.96-271.36-112.64L384 640H0v384l148.48-148.48C240.64 967.68 368.64 1024 512 1024c220.16 0 404.48-138.24 481.28-332.8L870.4 645.12C819.2 793.6 675.84 896 512 896z" />
</x:Array>
</local:MyListItem.Buttons>
</local:MyListItem>
<local:MyListItem x:Name="ItemForge" Visibility="Collapsed" Type="RadioBox" IsScaleAnimationEnabled="False" Tag="6" PaddingRight="35" Height="36" VerticalAlignment="Top" Title="Forge"
LogoScale="1.00" Logo="M402.807089 481.189274c-12.040221-6.991228-27.412326-2.797719-34.397415 9.242502l-8.387018 14.512529c-6.987135 12.035104-2.793626 27.40721 9.246595 34.392298 12.040221 6.985088 27.408233 2.797719 34.393321-9.242502l8.387018-14.511505C418.930301 503.437997 414.842193 488.063845 402.807089 481.189274L402.807089 481.189274zM495.028467 919.955342 59.056024 919.955342c-18.485003 0-33.532721 15.046694-33.532721 33.536814 0 18.485003 15.046694 33.532721 33.532721 33.532721l435.972443 0c18.49012 0 33.537837-15.046694 33.537837-33.532721C528.566304 935.002037 513.518586 919.955342 495.028467 919.955342L495.028467 919.955342zM997.431901 660.155295 590.482469 446.039729l90.935082-157.474544c18.485003-32.031531 7.520277-73.090669-24.51023-91.581812L395.496589 46.070268c-32.031531-18.485003-73.094762-7.520277-91.579765 24.51023L18.74697 564.277644c-18.485003 32.031531-7.521301 73.089645 24.51023 91.579765l261.408685 150.907988c32.031531 18.491143 73.095785 7.526417 91.581812-24.505114l91.364871-158.330028 392.332527 239.48128c16.016789 9.247618 36.544311 3.76372 45.792952-12.249999l83.838454-145.219429C1019.033895 689.930435 1013.444597 669.39882 997.431901 660.155295L997.431901 660.155295zM355.078041 719.704552c-9.242502 16.012695-29.774117 21.497617-45.787836 12.251022L105.923448 614.57826c-16.016789-9.242502-21.497617-29.774117-12.255115-45.787836l251.522524-435.653171c9.246595-16.012695 29.774117-21.497617 45.792952-12.249999l203.25624 117.376291c16.018835 9.242502 21.497617 29.774117 12.255115 45.786813L355.078041 719.704552 355.078041 719.704552zM884.568391 788.601712 522.115382 564.492538l33.537837-58.048067L934.875147 701.539844 884.568391 788.601712 884.568391 788.601712zM520.184403 277.8174c-12.040221-6.987135-27.41335-2.792603-34.399461 9.246595l-75.456552 130.702807c-6.985088 12.040221-2.791579 27.412326 9.242502 34.397415 12.040221 6.987135 27.412326 2.791579 34.397415-9.242502l75.458599-130.706901C536.307615 300.174594 532.219507 284.807604 520.184403 277.8174L520.184403 277.8174zM520.184403 277.8174">
<!--Logo="M789.504 912.896h-195.072a35.328 35.328 0 0 1-34.816-35.328v-77.312a39.936 39.936 0 0 0-40.448-39.936H481.28a40.448 40.448 0 0 0-40.448 39.936v77.312a34.816 34.816 0 0 1-34.816 35.328H204.8a41.984 41.984 0 0 1-40.448-42.496v-200.192a35.328 35.328 0 0 1 35.328-35.328h72.704a39.936 39.936 0 0 0 39.936-39.936v-37.888a39.936 39.936 0 0 0-39.936-40.448H199.68a35.328 35.328 0 0 1-35.328-35.328V287.744A41.984 41.984 0 0 1 204.8 245.76h176.64v-32.768a102.4 102.4 0 0 1 102.4-102.4h33.792a102.4 102.4 0 0 1 102.4 102.4v32.768h170.496a41.984 41.984 0 0 1 41.984 41.984V460.8h28.672a102.4 102.4 0 0 1 102.4 102.4v33.792a102.4 102.4 0 0 1-102.4 102.4h-28.672V870.4a41.984 41.984 0 0 1-43.008 42.496z m-159.744-70.144h131.584V665.6a34.304 34.304 0 0 1 34.816-34.816h64a31.744 31.744 0 0 0 31.744-31.744V563.2a31.744 31.744 0 0 0-31.744-31.744h-64a34.816 34.816 0 0 1-34.816-35.328V316.416h-177.152a35.328 35.328 0 0 1-35.328-35.328V212.992a31.744 31.744 0 0 0-31.744-31.744h-33.792a31.744 31.744 0 0 0-31.744 31.744v68.096a35.328 35.328 0 0 1-34.816 35.328H234.496v130.048h37.888a110.592 110.592 0 0 1 110.08 110.592v37.888a110.592 110.592 0 0 1-110.08 110.592h-37.888v137.216h136.192v-42.496a110.592 110.592 0 0 1 110.592-110.08h37.888a110.592 110.592 0 0 1 110.592 110.08z">-->
<local:MyListItem.Buttons>
<x:Array Type="{x:Type local:MyIconButton}">
<local:MyIconButton Tag="6" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.ShowDuration="2333333" ToolTipService.InitialShowDelay="200" LogoScale="0.85" Click="Refresh" Logo="M875.52 148.48C783.36 56.32 655.36 0 512 0 291.84 0 107.52 138.24 30.72 332.8l122.88 46.08C204.8 230.4 348.16 128 512 128c107.52 0 199.68 40.96 271.36 112.64L640 384h384V0L875.52 148.48zM512 896c-107.52 0-199.68-40.96-271.36-112.64L384 640H0v384l148.48-148.48C240.64 967.68 368.64 1024 512 1024c220.16 0 404.48-138.24 481.28-332.8L870.4 645.12C819.2 793.6 675.84 896 512 896z" />
</x:Array>
</local:MyListItem.Buttons>
</local:MyListItem>
<local:MyListItem x:Name="ItemFabric" Visibility="Collapsed" Type="RadioBox" IsScaleAnimationEnabled="False" Tag="7" PaddingRight="35" Height="36" VerticalAlignment="Top" Title="Fabric"
LogoScale="1.02" Logo="M826.453333 170.666667c-100.266667-93.866667-248.96-76.373333-256-75.52a31.786667 31.786667 0 0 0-26.666666 22.613333c-1.066667 3.2-101.546667 330.666667-426.666667 445.013333a29.013333 29.013333 0 0 0-7.893333 4.48l-1.493334 1.066667a29.44 29.44 0 0 0-5.973333 6.613333 31.786667 31.786667 0 0 0-3.626667 7.68 5.333333 5.333333 0 0 1 0 1.493334 30.506667 30.506667 0 0 0 0 8.96c7.466667 116.266667 45.013333 204.586667 112 262.826666a303.36 303.36 0 0 0 194.773334 71.466667h11.52a32.426667 32.426667 0 0 0 27.093333-19.626667 694.186667 694.186667 0 0 1 159.36-234.666666l-7.68 55.466666A31.786667 31.786667 0 0 0 621.44 768h4.48a32.213333 32.213333 0 0 0 31.786667-27.733333l15.573333-112.426667 112.426667 8.32a32 32 0 1 0 4.693333-64l-56.96-4.266667c36.48-25.813333 74.026667-50.56 112-75.52l51.626667-34.133333a31.573333 31.573333 0 0 0 14.08-24.746667c6.186667-115.2-21.76-203.306667-84.693334-262.826666zM620.8 573.013333l-1.706667 1.493334a219.093333 219.093333 0 0 0-87.466666-116.693334 222.933333 222.933333 0 0 0-95.146667-33.28c18.986667-21.333333 36.266667-42.666667 51.626667-64a198.613333 198.613333 0 0 1 202.453333 158.08c-20.053333 14.506667-39.893333 29.44-59.52 45.226667a29.866667 29.866667 0 0 0-10.24 9.173333z m-228.693333 292.266667a238.72 238.72 0 0 1-141.44-55.893333 213.333333 213.333333 0 0 1-34.986667-39.466667 123.946667 123.946667 0 0 0 44.373333 8.106667 168.533333 168.533333 0 0 0 69.12-16.213334 29.44 29.44 0 0 0 7.04-4.266666l106.666667-85.333334a32 32 0 1 0-39.893333-49.92L298.666667 704a78.293333 78.293333 0 0 1-69.546667 1.706667c-32.426667-17.066667-52.693333-61.653333-62.506667-93.44a709.333333 709.333333 0 0 0 202.453334-123.733334 187.52 187.52 0 0 1 128 21.333334 171.946667 171.946667 0 0 1 68.906666 109.653333 756.48 756.48 0 0 0-173.866666 245.76zM810.666667 438.4l-64 42.666667A256 256 0 0 0 529.706667 298.666667a810.666667 810.666667 0 0 0 69.12-140.8c37.973333-1.066667 123.946667 4.053333 183.68 59.946666 45.866667 42.666667 67.84 108.8 65.493333 195.84z">
<local:MyListItem.Buttons>
<x:Array Type="{x:Type local:MyIconButton}">
<local:MyIconButton Tag="7" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.ShowDuration="2333333" ToolTipService.InitialShowDelay="200" LogoScale="0.85" Click="Refresh" Logo="M875.52 148.48C783.36 56.32 655.36 0 512 0 291.84 0 107.52 138.24 30.72 332.8l122.88 46.08C204.8 230.4 348.16 128 512 128c107.52 0 199.68 40.96 271.36 112.64L640 384h384V0L875.52 148.48zM512 896c-107.52 0-199.68-40.96-271.36-112.64L384 640H0v384l148.48-148.48C240.64 967.68 368.64 1024 512 1024c220.16 0 404.48-138.24 481.28-332.8L870.4 645.12C819.2 793.6 675.84 896 512 896z" />
</x:Array>
</local:MyListItem.Buttons>
</local:MyListItem>
<local:MyListItem x:Name="ItemLiteLoader" Visibility="Collapsed" Type="RadioBox" IsScaleAnimationEnabled="False" Tag="8" PaddingRight="35" Height="36" VerticalAlignment="Top" Title="LiteLoader"
LogoScale="1.06" Logo="M517.41 186.99l22.45 83.78h-55.04l-18.76-70.02c-2.85-10.63-13.78-16.95-24.42-14.1-10.63 2.85-16.95 13.78-14.1 24.42l16 59.71H388.5l-12.31-45.95c-10.45-38.99 12.69-79.08 51.69-89.52s79.08 12.68 89.53 51.68z M538.58 98c40.37 0 73.1 32.73 73.1 73.1v79.74h-53.16V171.1c0-11.01-8.93-19.94-19.94-19.94-11.01 0-19.94 8.93-19.94 19.94v79.74h-53.16V171.1c0-40.37 32.73-73.1 73.1-73.1z M512 224.26c191.58 0 346.88 155.3 346.88 346.88v61.8c0 28.85 3.33 59.94 9.98 93.27l1.29 6.28c12.43 59.1-21.15 118.2-78.28 137.78C691.18 904.75 597.9 922 512 922c-83.94 0-174.95-16.47-273.01-49.41l-6.85-2.32c-56.4-19.32-89.85-77.16-78.74-135.5l0.46-2.27c7.51-35.71 11.27-68.89 11.27-99.55v-61.8c0-189.66 152.21-343.77 341.14-346.83l5.73-0.06z m-4.64 66.49c-151.21 2.45-273.32 124.58-275.75 275.8l-0.04 4.59v61.8l-0.04 5.93c-0.45 33.74-4.7 69.49-12.65 107.3-5.53 26.27 9.4 52.53 34.79 61.23 94.08 32.23 180.19 48.15 258.32 48.15s164.25-15.92 258.32-48.15c25.39-8.7 40.32-34.97 34.79-61.23-7.95-37.81-12.2-73.56-12.65-107.3l-0.04-5.93v-61.8c0-153.33-123.05-277.91-275.79-280.39l-4.64-0.04-4.62 0.04z M500.66 717.38l-53.28-87.19c-3.83-6.26-1.85-14.44 4.41-18.27 0.76-0.46 1.56-0.85 2.39-1.15L512 589.74l57.82 21.03c6.9 2.51 10.46 10.13 7.95 17.03-0.3 0.83-0.69 1.63-1.15 2.39l-53.28 87.19c-3.83 6.26-12.01 8.24-18.27 4.41-1.8-1.1-3.31-2.61-4.41-4.41z M684.77 689.42m-46.52 0a46.52 46.52 0 1 0 93.04 0 46.52 46.52 0 1 0-93.04 0Z M339.23 689.42m-46.52 0a46.52 46.52 0 1 0 93.04 0 46.52 46.52 0 1 0-93.04 0Z">
<local:MyListItem.Buttons>
<x:Array Type="{x:Type local:MyIconButton}">
<local:MyIconButton Tag="8" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.ShowDuration="2333333" ToolTipService.InitialShowDelay="200" LogoScale="0.85" Click="Refresh" Logo="M875.52 148.48C783.36 56.32 655.36 0 512 0 291.84 0 107.52 138.24 30.72 332.8l122.88 46.08C204.8 230.4 348.16 128 512 128c107.52 0 199.68 40.96 271.36 112.64L640 384h384V0L875.52 148.48zM512 896c-107.52 0-199.68-40.96-271.36-112.64L384 640H0v384l148.48-148.48C240.64 967.68 368.64 1024 512 1024c220.16 0 404.48-138.24 481.28-332.8L870.4 645.12C819.2 793.6 675.84 896 512 896z" />
</x:Array>
</local:MyListItem.Buttons>
</local:MyListItem>
<TextBlock Text="CurseForge" Margin="13,18,5,4" Opacity="0.6" FontSize="12" />
<local:MyListItem x:Name="ItemMod" Type="RadioBox" IsScaleAnimationEnabled="False" Tag="10" PaddingRight="35" Height="36" VerticalAlignment="Top" Title="Mod"
LogoScale="0.97" Logo="M789.504 912.896h-195.072a35.328 35.328 0 0 1-34.816-35.328v-77.312a39.936 39.936 0 0 0-40.448-39.936H481.28a40.448 40.448 0 0 0-40.448 39.936v77.312a34.816 34.816 0 0 1-34.816 35.328H204.8a41.984 41.984 0 0 1-40.448-42.496v-200.192a35.328 35.328 0 0 1 35.328-35.328h72.704a39.936 39.936 0 0 0 39.936-39.936v-37.888a39.936 39.936 0 0 0-39.936-40.448H199.68a35.328 35.328 0 0 1-35.328-35.328V287.744A41.984 41.984 0 0 1 204.8 245.76h176.64v-32.768a102.4 102.4 0 0 1 102.4-102.4h33.792a102.4 102.4 0 0 1 102.4 102.4v32.768h170.496a41.984 41.984 0 0 1 41.984 41.984V460.8h28.672a102.4 102.4 0 0 1 102.4 102.4v33.792a102.4 102.4 0 0 1-102.4 102.4h-28.672V870.4a41.984 41.984 0 0 1-43.008 42.496z m-159.744-70.144h131.584V665.6a34.304 34.304 0 0 1 34.816-34.816h64a31.744 31.744 0 0 0 31.744-31.744V563.2a31.744 31.744 0 0 0-31.744-31.744h-64a34.816 34.816 0 0 1-34.816-35.328V316.416h-177.152a35.328 35.328 0 0 1-35.328-35.328V212.992a31.744 31.744 0 0 0-31.744-31.744h-33.792a31.744 31.744 0 0 0-31.744 31.744v68.096a35.328 35.328 0 0 1-34.816 35.328H234.496v130.048h37.888a110.592 110.592 0 0 1 110.08 110.592v37.888a110.592 110.592 0 0 1-110.08 110.592h-37.888v137.216h136.192v-42.496a110.592 110.592 0 0 1 110.592-110.08h37.888a110.592 110.592 0 0 1 110.592 110.08z">
<local:MyListItem.Buttons>
<x:Array Type="{x:Type local:MyIconButton}">
<local:MyIconButton Tag="10" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.ShowDuration="2333333" ToolTipService.InitialShowDelay="200" LogoScale="0.85" Click="Refresh" Logo="M875.52 148.48C783.36 56.32 655.36 0 512 0 291.84 0 107.52 138.24 30.72 332.8l122.88 46.08C204.8 230.4 348.16 128 512 128c107.52 0 199.68 40.96 271.36 112.64L640 384h384V0L875.52 148.48zM512 896c-107.52 0-199.68-40.96-271.36-112.64L384 640H0v384l148.48-148.48C240.64 967.68 368.64 1024 512 1024c220.16 0 404.48-138.24 481.28-332.8L870.4 645.12C819.2 793.6 675.84 896 512 896z" />
</x:Array>
</local:MyListItem.Buttons>
</local:MyListItem>
<local:MyListItem x:Name="ItemPack" Type="RadioBox" IsScaleAnimationEnabled="False" Tag="11" PaddingRight="35" Height="36" VerticalAlignment="Top" Title="整合包"
LogoScale="0.98" Logo="M511.488 995.328a128.654222 128.654222 0 0 1-57.116444-13.112889L70.769778 791.808a126.833778 126.833778 0 0 1-70.769778-113.777778V311.608889a126.179556 126.179556 0 0 1 15.36-60.103111V248.604444c1.479111-2.901333 3.356444-5.603556 5.518222-8.021333a127.630222 127.630222 0 0 1 49.891556-42.325333L454.371556 13.368889a128.739556 128.739556 0 0 1 112.981333 0l383.601778 190.407111a126.862222 126.862222 0 0 1 72.049777 113.379556v360.874666a126.805333 126.805333 0 0 1-70.769777 115.939556L568.604444 984.32c-17.92 7.964444-37.461333 11.747556-57.116444 11.008z m42.638222-470.897778v370.204445l360.192-178.545778c14.449778-7.253333 23.552-21.987556 23.438222-38.087111v-335.928889L554.097778 524.430222zM85.248 330.666667v347.335111a42.268444 42.268444 0 0 0 23.438222 38.087111l360.192 178.545778V523.576889L85.248 330.666667zM135.537778 260.835556l375.950222 189.952 137.671111-65.564445L286.435556 188.074667 135.537778 260.864z m245.105778-118.471112l363.576888 197.973334 150.897778-71.480889-365.283555-180.224a42.922667 42.922667 0 0 0-37.518223 0l-111.672888 53.731555z">
<local:MyListItem.Buttons>
<x:Array Type="{x:Type local:MyIconButton}">
<local:MyIconButton Tag="11" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.ShowDuration="2333333" ToolTipService.InitialShowDelay="200" LogoScale="0.85" Click="Refresh" Logo="M875.52 148.48C783.36 56.32 655.36 0 512 0 291.84 0 107.52 138.24 30.72 332.8l122.88 46.08C204.8 230.4 348.16 128 512 128c107.52 0 199.68 40.96 271.36 112.64L640 384h384V0L875.52 148.48zM512 896c-107.52 0-199.68-40.96-271.36-112.64L384 640H0v384l148.48-148.48C240.64 967.68 368.64 1024 512 1024c220.16 0 404.48-138.24 481.28-332.8L870.4 645.12C819.2 793.6 675.84 896 512 896z" />
</x:Array>
</local:MyListItem.Buttons>
</local:MyListItem>
</StackPanel>
</local:MyPageLeft>
@@ -0,0 +1,168 @@
Public Class PageDownloadLeft
#Region "页面切换"
''' <summary>
''' 当前页面的编号。
''' </summary>
Public PageID As FormMain.PageSubType = FormMain.PageSubType.DownloadInstall
''' <summary>
''' 勾选事件改变页面。
''' </summary>
Private Sub PageCheck(sender As MyListItem, e As RouteEventArgs) Handles ItemInstall.Check, ItemClient.Check, ItemOptiFine.Check, ItemForge.Check, ItemLiteLoader.Check, ItemMod.Check, ItemFabric.Check, ItemPack.Check
'尚未初始化控件属性时,sender.Tag 为 Nothing,会导致切换到页面 0
'若使用 IsLoaded,则会导致模拟点击不被执行(模拟点击切换页面时,控件的 IsLoaded 为 False)
If sender.Tag IsNot Nothing Then PageChange(Val(sender.Tag))
End Sub
Public Function PageGet(Optional ID As FormMain.PageSubType = -1)
If ID = -1 Then ID = PageID
Select Case ID
Case FormMain.PageSubType.DownloadInstall
If FrmDownloadInstall Is Nothing Then FrmDownloadInstall = New PageDownloadInstall
Return FrmDownloadInstall
Case FormMain.PageSubType.DownloadClient
If FrmDownloadClient Is Nothing Then FrmDownloadClient = New PageDownloadClient
Return FrmDownloadClient
Case FormMain.PageSubType.DownloadOptiFine
If FrmDownloadOptiFine Is Nothing Then FrmDownloadOptiFine = New PageDownloadOptiFine
Return FrmDownloadOptiFine
Case FormMain.PageSubType.DownloadForge
If FrmDownloadForge Is Nothing Then FrmDownloadForge = New PageDownloadForge
Return FrmDownloadForge
Case FormMain.PageSubType.DownloadLiteLoader
If FrmDownloadLiteLoader Is Nothing Then FrmDownloadLiteLoader = New PageDownloadLiteLoader
Return FrmDownloadLiteLoader
Case FormMain.PageSubType.DownloadFabric
If FrmDownloadFabric Is Nothing Then FrmDownloadFabric = New PageDownloadFabric
Return FrmDownloadFabric
Case FormMain.PageSubType.DownloadMod
If FrmDownloadMod Is Nothing Then FrmDownloadMod = New PageDownloadMod
Return FrmDownloadMod
Case FormMain.PageSubType.DownloadPack
If FrmDownloadPack Is Nothing Then FrmDownloadPack = New PageDownloadPack
Return FrmDownloadPack
Case Else
Throw New Exception("未知的下载子页面种类:" & ID)
End Select
End Function
''' <summary>
''' 切换现有页面。
''' </summary>
Public Sub PageChange(ID As FormMain.PageSubType)
If PageID = ID Then Exit Sub
AniControlEnabled += 1
Try
PageChangeRun(PageGet(ID))
PageID = ID
Catch ex As Exception
Log(ex, "切换设置分页面失败(ID " & ID & ")", LogLevel.Feedback)
Finally
AniControlEnabled -= 1
End Try
End Sub
Private Shared Sub PageChangeRun(Target As MyPageRight)
AniStop("FrmMain PageChangeRight") '停止主页面的右页面切换动画,防止它与本动画一起触发多次 PageOnEnter
If Target.Parent IsNot Nothing Then Target.SetValue(ContentPresenter.ContentProperty, Nothing)
FrmMain.PageRight = Target
CType(FrmMain.PanMainRight.Child, MyPageRight).PageOnExit()
AniStart({
AaCode(Sub()
CType(FrmMain.PanMainRight.Child, MyPageRight).PageOnForceExit()
FrmMain.PanMainRight.Child = FrmMain.PageRight
FrmMain.PageRight.Opacity = 0
End Sub, 130),
AaCode(Sub()
'延迟触发页面通用动画,以使得在 Loaded 事件中加载的控件得以处理
FrmMain.PageRight.Opacity = 1
FrmMain.PageRight.PageOnEnter()
End Sub, 30, True)
}, "PageLeft PageChange")
End Sub
#End Region
'强制刷新
Public Sub Refresh(sender As Object, e As EventArgs) '由边栏按钮匿名调用
Select Case Val(sender.Tag)
Case FormMain.PageSubType.DownloadInstall
DlClientListLoader.Start(IsForceRestart:=True)
DlOptiFineListLoader.Start(IsForceRestart:=True)
DlForgeListLoader.Start(IsForceRestart:=True)
DlLiteLoaderListLoader.Start(IsForceRestart:=True)
DlFabricListLoader.Start(IsForceRestart:=True)
DlFabricApiLoader.Start(IsForceRestart:=True)
DlOptiFabricLoader.Start(IsForceRestart:=True)
Case FormMain.PageSubType.DownloadMod
If FrmDownloadMod IsNot Nothing Then FrmDownloadMod.PageLoaderRestart()
Case FormMain.PageSubType.DownloadPack
If FrmDownloadPack IsNot Nothing Then FrmDownloadPack.PageLoaderRestart()
Case FormMain.PageSubType.DownloadClient
DlClientListLoader.Start(IsForceRestart:=True)
Case FormMain.PageSubType.DownloadOptiFine
DlOptiFineListLoader.Start(IsForceRestart:=True)
Case FormMain.PageSubType.DownloadForge
DlForgeListLoader.Start(IsForceRestart:=True)
Case FormMain.PageSubType.DownloadLiteLoader
DlLiteLoaderListLoader.Start(IsForceRestart:=True)
Case FormMain.PageSubType.DownloadFabric
DlFabricListLoader.Start(IsForceRestart:=True)
End Select
End Sub
'点击返回
Private Sub ItemInstall_Click(sender As Object, e As MouseButtonEventArgs) Handles ItemInstall.Click
If Not ItemInstall.Checked Then Exit Sub
FrmDownloadInstall.ExitSelectPage()
End Sub
'展开手动安装
Private Sub ItemHand_Click(sender As Object, e As RouteEventArgs) Handles ItemHand.Changed
If ItemHand.Checked = False Then Exit Sub
e.Handled = True
AniControlEnabled += 1
If Not Setup.Get("HintHandInstall") Then
Setup.Set("HintHandInstall", True)
If MyMsgBox("手动安装包功能提供了 OptiFine、Forge 等组件的 .jar 安装文件下载,但无法自动安装。" & vbCrLf &
"在自动安装页面先选择 MC 版本,然后就可以选择 OptiFine、Forge 等组件,让 PCL2 自动进行安装了。", "自动安装提示", "返回自动安装", "继续下载手动安装包") = 1 Then
FrmMain.PageChange(New FormMain.PageStackData With {.Page = FormMain.PageType.Download}, FormMain.PageSubType.DownloadInstall)
AniControlEnabled -= 1
Exit Sub
End If
End If
ItemHand.Visibility = Visibility.Collapsed
LabGame.Visibility = Visibility.Collapsed
LabHand.Visibility = Visibility.Visible
ItemClient.Visibility = Visibility.Visible
ItemOptiFine.Visibility = Visibility.Visible
ItemFabric.Visibility = Visibility.Visible
ItemForge.Visibility = Visibility.Visible
ItemLiteLoader.Visibility = Visibility.Visible
RunInThread(Sub()
Thread.Sleep(20)
RunInUiWait(Sub() ItemClient.SetChecked(True, True, True))
AniControlEnabled -= 1
End Sub)
End Sub
'折叠手动安装
Private Sub LabHand_Click(sender As Object, e As MouseButtonEventArgs) Handles LabHand.MouseLeftButtonUp
e.Handled = True
AniControlEnabled += 1
ItemHand.Visibility = Visibility.Visible
LabGame.Visibility = Visibility.Visible
LabHand.Visibility = Visibility.Collapsed
ItemClient.Visibility = Visibility.Collapsed
ItemOptiFine.Visibility = Visibility.Collapsed
ItemFabric.Visibility = Visibility.Collapsed
ItemForge.Visibility = Visibility.Collapsed
ItemLiteLoader.Visibility = Visibility.Collapsed
RunInThread(Sub()
Thread.Sleep(20)
RunInUiWait(Sub() ItemInstall.SetChecked(True, True, True))
AniControlEnabled -= 1
End Sub)
End Sub
End Class
@@ -0,0 +1,26 @@
<local:MyPageRight
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:PCL" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" x:Class="PageDownloadLiteLoader"
d:DesignWidth="778.571" d:DesignHeight="90.857">
<local:MyScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" x:Name="PanBack">
<StackPanel Orientation="Vertical" Margin="5">
<local:MyCard Margin="20,20,20,0" Grid.IsSharedSizeScope="True" Title="LiteLoader 简介" x:Name="CardTip">
<StackPanel Margin="25,40,15,20">
<TextBlock Name="LabConnect" Margin="0,0,0,11" Text="与 Forge 类似,LiteLoader 可以用于加载老版本 Minecraft 中的 LiteLoader 模组。" TextWrapping="Wrap" />
<Grid Height="35">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
</Grid.ColumnDefinitions>
<local:MyButton x:Name="BtnWeb" Grid.Column="0" MinWidth="140" Text="打开官网" Padding="13,0" Margin="0,0,20,0" HorizontalAlignment="Left" ColorType="Highlight" />
</Grid>
</StackPanel>
</local:MyCard>
<StackPanel Name="PanMain" Margin="20,15,20,5" Grid.IsSharedSizeScope="True" />
<local:MyCard HorizontalAlignment="Center" Margin="40,50" SnapsToDevicePixels="True" x:Name="PanLoad" UseAnimation="False">
<local:MyLoading Text="正在获取 LiteLoader 列表" Margin="20,20,20,17" x:Name="Load" HorizontalAlignment="Center" VerticalAlignment="Center" />
</local:MyCard>
</StackPanel>
</local:MyScrollViewer>
</local:MyPageRight>
@@ -0,0 +1,52 @@
Public Class PageDownloadLiteLoader
Private Sub LoaderInit() Handles Me.Initialized
PageLoaderInit(Load, PanLoad, PanMain, CardTip, DlLiteLoaderListLoader, AddressOf Load_OnFinish)
End Sub
Private Sub Init() Handles Me.Loaded
PanBack.ScrollToHome()
End Sub
Private Sub Load_OnFinish()
'结果数据化
Try
'归类
Dim Dict As New Dictionary(Of String, List(Of DlLiteLoaderListEntry))
For VersionCode As Integer = 30 To 0 Step -1
Dict.Add("1." & VersionCode, New List(Of DlLiteLoaderListEntry))
Next
Dict.Add("未知版本", New List(Of DlLiteLoaderListEntry))
For Each Version As DlLiteLoaderListEntry In DlLiteLoaderListLoader.Output.Value
Dim MainVersion As String = "1." & Version.Inherit.Split(".")(1)
If Dict.ContainsKey(MainVersion) Then
Dict(MainVersion).Add(Version)
Else
Dict("未知版本").Add(Version)
End If
Next
'清空当前
PanMain.Children.Clear()
'转化为 UI
For Each Pair As KeyValuePair(Of String, List(Of DlLiteLoaderListEntry)) In Dict
If Pair.Value.Count = 0 Then Continue For
'增加卡片
Dim NewCard As New MyCard With {.Title = Pair.Key & " (" & Pair.Value.Count & ")", .Margin = New Thickness(0, 0, 0, 15), .SwapType = 10}
Dim NewStack As New StackPanel With {.Margin = New Thickness(20, MyCard.SwapedHeight, 18, 0), .VerticalAlignment = VerticalAlignment.Top, .RenderTransform = New TranslateTransform(0, 0), .Tag = Pair.Value}
NewCard.Children.Add(NewStack)
NewCard.SwapControl = NewStack
NewCard.IsSwaped = True
PanMain.Children.Add(NewCard)
Next
Catch ex As Exception
Log(ex, "可视化版本列表出错", LogLevel.Feedback)
End Try
End Sub
Public Sub DownloadStart(sender As MyListItem, e As Object)
McDownloadLiteLoader(sender.Tag)
End Sub
Private Sub BtnWeb_Click(sender As Object, e As EventArgs) Handles BtnWeb.Click
OpenWebsite("https://www.liteloader.com")
End Sub
End Class
@@ -0,0 +1,108 @@
<local:MyPageRight
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:PCL" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" x:Class="PageDownloadMod"
d:DesignWidth="778.571" d:DesignHeight="90.857">
<local:MyScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" x:Name="PanBack">
<StackPanel Orientation="Vertical" Margin="25">
<local:MyCard Title="搜索 Mod" Margin="0,0,0,15" x:Name="PanAlways">
<StackPanel Margin="25,40,25,15">
<Grid Margin="0,0,0,11" HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="70" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="0.9*" />
<ColumnDefinition Width="1.6*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="28" />
<RowDefinition Height="9" />
<RowDefinition Height="28" />
</Grid.RowDefinitions>
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Left" Text="名称" Margin="0,0,25,0" />
<local:MyTextBox x:Name="TextSearchName" Grid.Column="1" Grid.ColumnSpan="10" />
<TextBlock VerticalAlignment="Center" Grid.Row="2" HorizontalAlignment="Left" Text="类型" Margin="0,0,25,0" />
<local:MyComboBox x:Name="ComboSearchTag" Grid.Column="1" Grid.Row="2" MaxDropDownHeight="320">
<local:MyComboBoxItem Content="全部" Tag="0" IsSelected="True" />
<local:MyComboBoxItem Content="世界生成" Tag="406" />
<local:MyComboBoxItem Content="生物群系" Tag="407" Margin="15,0,0,0" />
<local:MyComboBoxItem Content="天然结构" Tag="409" Margin="15,0,0,0" />
<local:MyComboBoxItem Content="维度" Tag="410" Margin="15,0,0,0" />
<local:MyComboBoxItem Content="生物" Tag="411" Margin="15,0,0,0" />
<local:MyComboBoxItem Content="科技" Tag="412" />
<local:MyComboBoxItem Content="交通与移动" Tag="414" Margin="15,0,0,0" />
<local:MyComboBoxItem Content="管道与物流" Tag="415" Margin="15,0,0,0" />
<local:MyComboBoxItem Content="能源" Tag="417" Margin="15,0,0,0" />
<local:MyComboBoxItem Content="红石" Tag="4558" Margin="15,0,0,0" />
<local:MyComboBoxItem Content="仓储" Tag="420" Margin="15,0,0,0" />
<local:MyComboBoxItem Content="农业" Tag="416" />
<local:MyComboBoxItem Content="食物" Tag="436" Margin="15,0,0,0" />
<local:MyComboBoxItem Content="魔法" Tag="419" />
<local:MyComboBoxItem Content="装备与工具" Tag="434" />
<local:MyComboBoxItem Content="冒险与探索" Tag="422" />
<local:MyComboBoxItem Content="建筑与装饰" Tag="424" />
<local:MyComboBoxItem Content="信息显示" Tag="423" />
<local:MyComboBoxItem Content="支持库" Tag="421" />
<local:MyComboBoxItem Content="服务器" Tag="435" />
</local:MyComboBox>
<TextBlock VerticalAlignment="Center" Grid.Row="2" Grid.Column="3" HorizontalAlignment="Left" Text="版本" Margin="0,0,25,0" />
<local:MyComboBox x:Name="TextSearchVersion" Grid.Row="2" Grid.Column="4" Grid.ColumnSpan="2" IsEditable="True" MaxDropDownHeight="320" HintText="全部 (也可自行输入)">
<local:MyComboBoxItem Content="" IsSelected="True" />
<local:MyComboBoxItem Content="1.19.1" />
<local:MyComboBoxItem Content="1.19" />
<local:MyComboBoxItem Content="1.18.2" />
<local:MyComboBoxItem Content="1.18.1" />
<local:MyComboBoxItem Content="1.18" />
<local:MyComboBoxItem Content="1.17.1" />
<local:MyComboBoxItem Content="1.17" />
<local:MyComboBoxItem Content="1.16.5" />
<local:MyComboBoxItem Content="1.16.4" />
<local:MyComboBoxItem Content="1.16.3" />
<local:MyComboBoxItem Content="1.16.2" />
<local:MyComboBoxItem Content="1.16.1" />
<local:MyComboBoxItem Content="1.16" />
<local:MyComboBoxItem Content="1.15.2" />
<local:MyComboBoxItem Content="1.15" />
<local:MyComboBoxItem Content="1.14.4" />
<local:MyComboBoxItem Content="1.14" />
<local:MyComboBoxItem Content="1.13.2" />
<local:MyComboBoxItem Content="1.13" />
<local:MyComboBoxItem Content="1.12.2" />
<local:MyComboBoxItem Content="1.12" />
<local:MyComboBoxItem Content="1.11.2" />
<local:MyComboBoxItem Content="1.10.2" />
<local:MyComboBoxItem Content="1.9.4" />
<local:MyComboBoxItem Content="1.8.9" />
<local:MyComboBoxItem Content="1.7.10" />
<local:MyComboBoxItem Content="1.7.2" />
<local:MyComboBoxItem Content="1.6.4" />
<local:MyComboBoxItem Content="1.5.2" />
</local:MyComboBox>
<local:MyComboBox x:Name="ComboSearchLoader" Visibility="Collapsed" Grid.Row="2" Grid.Column="5" MaxDropDownHeight="320" Margin="10,0,0,0">
<local:MyComboBoxItem Content="Forge 或 Fabric" IsSelected="True" Tag="0" />
<local:MyComboBoxItem Content="Forge" Tag="1" />
<local:MyComboBoxItem Content="Fabric" Tag="4" />
</local:MyComboBox>
</Grid>
<Grid Margin="0,4,0,6" Height="35">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
</Grid.ColumnDefinitions>
<local:MyButton x:Name="BtnSearchRun" Text="搜索" MinWidth="140" Padding="13,0" Margin="0,0,20,0" ColorType="Highlight" />
<local:MyButton x:Name="BtnSearchReset" Text="重置条件" MinWidth="140" Padding="13,0" Margin="0,0,20,0" Grid.Column="1" />
</Grid>
</StackPanel>
</local:MyCard>
<local:MyCard x:Name="CardProjects" Title="热门 Mod">
<StackPanel x:Name="PanProjects" Margin="20,40,18,20" />
</local:MyCard>
<local:MyCard HorizontalAlignment="Center" VerticalAlignment="Center" SnapsToDevicePixels="True" x:Name="PanLoad" UseAnimation="False" Margin="40,50">
<local:MyLoading Text="正在获取 Mod 列表" Margin="20,20,20,17" x:Name="Load" HorizontalAlignment="Center" VerticalAlignment="Center" />
</local:MyCard>
</StackPanel>
</local:MyScrollViewer>
</local:MyPageRight>
@@ -0,0 +1,83 @@
Public Class PageDownloadMod
'初始化加载器信息
Private Sub PageDownloadMod_Inited(sender As Object, e As EventArgs) Handles Me.Initialized
PageLoaderInit(Load, PanLoad, CardProjects, PanAlways, Loader, AddressOf Load_OnFinish, AddressOf LoaderInput)
End Sub
Public Shared Loader As New LoaderTask(Of DlCfProjectRequest, DlCfProjectResult)("DlCfProject Mod", AddressOf DlCfProjectSub, AddressOf LoaderInput) With {.ReloadTimeout = 60 * 1000}
Private Shared Function LoaderInput() As DlCfProjectRequest
If FrmDownloadMod IsNot Nothing AndAlso FrmDownloadMod.IsLoaded Then
Return New DlCfProjectRequest With {
.SearchFilter = FrmDownloadMod.TextSearchName.Text,
.GameVersion = If(FrmDownloadMod.TextSearchVersion.Text.Contains("."), FrmDownloadMod.TextSearchVersion.Text, Nothing),
.CategoryId = Val(FrmDownloadMod.ComboSearchTag.SelectedItem.Tag),
.IsModPack = False,
.ModLoader = Val(FrmDownloadMod.ComboSearchLoader.SelectedItem.Tag)
} '处理列表加载失败后的点击加载器重试
Else
Return New DlCfProjectRequest With {.IsModPack = False}
End If
End Function
'结果 UI 化
Private Sub Load_OnFinish()
Try
PanProjects.Children.Clear()
If Loader.Input.SearchFilter = "" Then
CardProjects.Title = "热门 Mod"
Else
CardProjects.Title = "搜索结果 (" & Loader.Output.Projects.Count & If(Loader.Output.Projects.Count < Loader.Output.RealCount, "+", "") & ")"
End If
For Each Project In Loader.Output.Projects
PanProjects.Children.Add(Project.ToCfItem(Loader.Input.GameVersion Is Nothing, Loader.Input.ModLoader Is Nothing OrElse Loader.Input.ModLoader = 0, AddressOf ProjectClick))
Next
Catch ex As Exception
Log(ex, "可视化 Mod 列表出错", LogLevel.Feedback)
End Try
End Sub
'自动重试
Private Sub Load_State(sender As Object, state As MyLoading.MyLoadingState, oldState As MyLoading.MyLoadingState) Handles Load.StateChanged
Select Case Loader.State
Case LoadState.Failed
Dim ErrorMessage As String = ""
If DlCfFileLoader.Error IsNot Nothing Then ErrorMessage = DlCfFileLoader.Error.Message
If ErrorMessage.Contains("不是有效的 Json 文件") Then
Log("[Download] 下载的 Mod 列表 Json 文件损坏,已自动重试", LogLevel.Debug)
PageLoaderRestart()
End If
End Select
End Sub
'进入详情页面
Public Sub ProjectClick(sender As MyCfItem, e As EventArgs)
FrmMain.PageChange(New FormMain.PageStackData With {.Page = FormMain.PageType.CfDetail, .Additional = sender.Tag})
End Sub
'搜索
Private Sub TextSearchName_KeyUp(sender As Object, e As KeyEventArgs) Handles TextSearchName.KeyUp, TextSearchVersion.KeyUp
If e.Key = Key.Enter Then StartSearch()
End Sub
Private Shared Sub StartSearch() Handles BtnSearchRun.Click
Loader.Start()
End Sub
Private Sub BtnSearchReset_Click(sender As Object, e As EventArgs) Handles BtnSearchReset.Click
TextSearchName.Text = ""
TextSearchVersion.SelectedIndex = 0
TextSearchVersion.Text = ""
ComboSearchTag.SelectedIndex = 0
ComboSearchLoader.SelectedIndex = 0
Loader.LastFinishedTime = 0 '要求强制重新开始
End Sub
Private Sub TextSearchVersion_TextChanged(sender As Object, e As TextChangedEventArgs) Handles TextSearchVersion.TextChanged
If TextSearchVersion.Text = "" Then
ComboSearchLoader.Visibility = Visibility.Collapsed
Grid.SetColumnSpan(TextSearchVersion, 2)
ComboSearchLoader.SelectedIndex = 0
Else
ComboSearchLoader.Visibility = Visibility.Visible
Grid.SetColumnSpan(TextSearchVersion, 1)
End If
End Sub
End Class
@@ -0,0 +1,28 @@
<local:MyPageRight
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:PCL" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" x:Class="PageDownloadOptiFine"
d:DesignWidth="778.571" d:DesignHeight="90.857">
<local:MyScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" x:Name="PanBack">
<StackPanel Orientation="Vertical" Margin="5">
<local:MyCard Margin="20,20,20,0" Grid.IsSharedSizeScope="True" Title="OptiFine 简介" x:Name="CardTip">
<StackPanel Margin="25,40,15,20">
<TextBlock Name="LabConnect" Margin="0,0,0,11" Text="OptiFine 又名高清修复,它让你可以安装光影、使用高清材质,并且可以大幅提高游戏性能。" TextWrapping="Wrap" />
<Grid Height="35">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
</Grid.ColumnDefinitions>
<local:MyButton x:Name="BtnChina" Grid.Column="0" MinWidth="140" Text="打开中文网" Padding="13,0" Margin="0,0,20,0" HorizontalAlignment="Left" ColorType="Highlight" />
<local:MyButton x:Name="BtnWeb" Grid.Column="1" MinWidth="140" Text="打开官网" Padding="13,0" Margin="0,0,20,0" HorizontalAlignment="Left" />
</Grid>
</StackPanel>
</local:MyCard>
<StackPanel Name="PanMain" Margin="20,15,20,5" Grid.IsSharedSizeScope="True" />
<local:MyCard HorizontalAlignment="Center" VerticalAlignment="Center" SnapsToDevicePixels="True" x:Name="PanLoad" UseAnimation="False" Margin="40,50">
<local:MyLoading Text="正在获取 OptiFine 列表" Margin="20,20,20,17" x:Name="Load" HorizontalAlignment="Center" VerticalAlignment="Center" />
</local:MyCard>
</StackPanel>
</local:MyScrollViewer>
</local:MyPageRight>
@@ -0,0 +1,60 @@
Public Class PageDownloadOptiFine
Private Sub LoaderInit() Handles Me.Initialized
PageLoaderInit(Load, PanLoad, PanMain, CardTip, DlOptiFineListLoader, AddressOf Load_OnFinish)
End Sub
Private Sub Init() Handles Me.Loaded
PanBack.ScrollToHome()
End Sub
Private Sub Load_OnFinish()
'结果数据化
Try
'归类
Dim Dict As New Dictionary(Of String, List(Of DlOptiFineListEntry))
Dict.Add("快照版本", New List(Of DlOptiFineListEntry))
For VersionCode As Integer = 30 To 0 Step -1
Dict.Add("1." & VersionCode, New List(Of DlOptiFineListEntry))
Next
For Each Version As DlOptiFineListEntry In DlOptiFineListLoader.Output.Value
If Version.Inherit.StartsWith("1.") Then
Dim MainVersion As String = "1." & Version.NameDisplay.Split(".")(1).Split(" ")(0)
If Dict.ContainsKey(MainVersion) Then
Dict(MainVersion).Add(Version)
Else
Dict("快照版本").Add(Version)
End If
Else
Dict("快照版本").Add(Version)
End If
Next
'清空当前
PanMain.Children.Clear()
'转化为 UI
For Each Pair As KeyValuePair(Of String, List(Of DlOptiFineListEntry)) In Dict
If Pair.Value.Count = 0 Then Continue For
'增加卡片
Dim NewCard As New MyCard With {.Title = Pair.Key & " (" & Pair.Value.Count & ")", .Margin = New Thickness(0, 0, 0, 15), .SwapType = 3}
Dim NewStack As New StackPanel With {.Margin = New Thickness(20, MyCard.SwapedHeight, 18, 0), .VerticalAlignment = VerticalAlignment.Top, .RenderTransform = New TranslateTransform(0, 0), .Tag = Pair.Value}
NewCard.Children.Add(NewStack)
NewCard.SwapControl = NewStack
NewCard.IsSwaped = True
PanMain.Children.Add(NewCard)
Next
Catch ex As Exception
Log(ex, "可视化版本列表出错", LogLevel.Feedback)
End Try
End Sub
Public Sub DownloadStart(sender As MyListItem, e As Object)
McDownloadOptiFine(sender.Tag)
End Sub
Private Sub BtnWeb_Click(sender As Object, e As EventArgs) Handles BtnWeb.Click
OpenWebsite("https://www.optifine.net/")
End Sub
Private Sub BtnChina_Click(sender As Object, e As EventArgs) Handles BtnChina.Click
OpenWebsite("https://optifine.cn/home")
End Sub
End Class
@@ -0,0 +1,112 @@
<local:MyPageRight
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:PCL" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" x:Class="PageDownloadPack"
d:DesignWidth="778.571" d:DesignHeight="90.857">
<local:MyScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" x:Name="PanBack">
<StackPanel Orientation="Vertical" Margin="25">
<local:MyCard Title="搜索整合包" Margin="0,0,0,15" x:Name="PanAlways">
<StackPanel Margin="25,40,25,15">
<Grid Margin="0,0,0,11" HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="70" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="28" />
<RowDefinition Height="9" />
<RowDefinition Height="28" />
</Grid.RowDefinitions>
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Left" Text="名称" Margin="0,0,25,0" />
<local:MyTextBox x:Name="TextSearchName" Grid.Column="1" Grid.ColumnSpan="10" HintText="仅支持使用英文搜索" />
<TextBlock VerticalAlignment="Center" Grid.Row="2" HorizontalAlignment="Left" Text="类型" Margin="0,0,25,0" />
<local:MyComboBox x:Name="ComboSearchTag" Grid.Column="1" Grid.Row="2" MaxDropDownHeight="320">
<local:MyComboBoxItem Content="全部" Tag="0" IsSelected="True" />
<local:MyComboBoxItem IsHitTestVisible="False" Content="规格" />
<local:MyComboBoxItem Tag="4481" Content="小型整合" Margin="15,0,0,0" />
<local:MyComboBoxItem Tag="4482" Content="大型整合" Margin="15,0,0,0" />
<local:MyComboBoxItem IsHitTestVisible="False" Content="特殊" />
<local:MyComboBoxItem Tag="4487" Content="FTB" Margin="15,0,0,0" ToolTip="该整合包由 FTB 官方发布" />
<local:MyComboBoxItem Tag="4480" Content="基于地图" Margin="15,0,0,0" ToolTip="该整合包基于已有的 Minecraft 游戏地图运行" />
<local:MyComboBoxItem Tag="4479" Content="硬核" />
<local:MyComboBoxItem Tag="4471" Content="科幻" />
<local:MyComboBoxItem Tag="4483" Content="战斗" />
<local:MyComboBoxItem Tag="4478" Content="任务" />
<local:MyComboBoxItem Tag="4484" Content="多人" />
<local:MyComboBoxItem Tag="4476" Content="探索" />
<local:MyComboBoxItem Tag="4736" Content="空岛" />
<local:MyComboBoxItem Tag="4475" Content="冒险" />
<local:MyComboBoxItem Tag="4472" Content="科技" />
<local:MyComboBoxItem Tag="4473" Content="魔法" />
<local:MyComboBoxItem Tag="4477" Content="小游戏" />
</local:MyComboBox>
<TextBlock VerticalAlignment="Center" Grid.Row="2" Grid.Column="3" HorizontalAlignment="Left" Text="版本" Margin="0,0,25,0" />
<local:MyComboBox x:Name="TextSearchVersion" Grid.Row="2" Grid.Column="4" IsEditable="True" MaxDropDownHeight="320" HintText="全部 (也可自行输入)">
<local:MyComboBoxItem Content="" IsSelected="True" />
<local:MyComboBoxItem Content="1.19.1" />
<local:MyComboBoxItem Content="1.19" />
<local:MyComboBoxItem Content="1.18.2" />
<local:MyComboBoxItem Content="1.18.1" />
<local:MyComboBoxItem Content="1.18" />
<local:MyComboBoxItem Content="1.17.1" />
<local:MyComboBoxItem Content="1.17" />
<local:MyComboBoxItem Content="1.16.5" />
<local:MyComboBoxItem Content="1.16.4" />
<local:MyComboBoxItem Content="1.16.3" />
<local:MyComboBoxItem Content="1.16.2" />
<local:MyComboBoxItem Content="1.16.1" />
<local:MyComboBoxItem Content="1.16" />
<local:MyComboBoxItem Content="1.15.2" />
<local:MyComboBoxItem Content="1.15.1" />
<local:MyComboBoxItem Content="1.15" />
<local:MyComboBoxItem Content="1.14.4" />
<local:MyComboBoxItem Content="1.14.3" />
<local:MyComboBoxItem Content="1.14.2" />
<local:MyComboBoxItem Content="1.14.1" />
<local:MyComboBoxItem Content="1.14" />
<local:MyComboBoxItem Content="1.13.2" />
<local:MyComboBoxItem Content="1.13.1" />
<local:MyComboBoxItem Content="1.13" />
<local:MyComboBoxItem Content="1.12.2" />
<local:MyComboBoxItem Content="1.12.1" />
<local:MyComboBoxItem Content="1.12" />
<local:MyComboBoxItem Content="1.11.2" />
<local:MyComboBoxItem Content="1.11" />
<local:MyComboBoxItem Content="1.10.2" />
<local:MyComboBoxItem Content="1.10" />
<local:MyComboBoxItem Content="1.9.4" />
<local:MyComboBoxItem Content="1.9" />
<local:MyComboBoxItem Content="1.8.9" />
<local:MyComboBoxItem Content="1.8" />
<local:MyComboBoxItem Content="1.7.10" />
<local:MyComboBoxItem Content="1.7.2" />
<local:MyComboBoxItem Content="1.6.4" />
<local:MyComboBoxItem Content="1.5.2" />
</local:MyComboBox>
</Grid>
<Grid Margin="0,4,0,6" Height="35">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
</Grid.ColumnDefinitions>
<local:MyButton x:Name="BtnSearchRun" Text="搜索" MinWidth="140" Padding="13,0" Margin="0,0,20,0" ColorType="Highlight" />
<local:MyButton x:Name="BtnSearchReset" Text="重置条件" MinWidth="140" Padding="13,0" Margin="0,0,20,0" Grid.Column="1" />
<local:MyButton x:Name="BtnSearchInstall" Text="安装已有整合包" MinWidth="140" Padding="13,0" Margin="0,0,20,0" Grid.Column="2"
ToolTip="在当前选择的 Minecraft 文件夹下安装整合包" ToolTipService.ShowDuration="2333333" />
</Grid>
</StackPanel>
</local:MyCard>
<local:MyCard x:Name="CardProjects" Title="热门整合包">
<StackPanel x:Name="PanProjects" Margin="20,40,18,20" />
</local:MyCard>
<local:MyCard HorizontalAlignment="Center" VerticalAlignment="Center" SnapsToDevicePixels="True" x:Name="PanLoad" UseAnimation="False" Margin="40,50">
<local:MyLoading Text="正在获取整合包列表" Margin="20,20,20,17" x:Name="Load" HorizontalAlignment="Center" VerticalAlignment="Center" />
</local:MyCard>
</StackPanel>
</local:MyScrollViewer>
</local:MyPageRight>
@@ -0,0 +1,82 @@
Public Class PageDownloadPack
'初始化加载器信息
Private Sub PageDownloadMod_Inited(sender As Object, e As EventArgs) Handles Me.Initialized
PageLoaderInit(Load, PanLoad, CardProjects, PanAlways, Loader, AddressOf Load_OnFinish, AddressOf LoaderInput)
End Sub
Public Shared Loader As New LoaderTask(Of DlCfProjectRequest, DlCfProjectResult)("DlCfProject ModPack", AddressOf DlCfProjectSub, AddressOf LoaderInput) With {.ReloadTimeout = 60 * 1000}
Private Shared Function LoaderInput() As DlCfProjectRequest
If FrmDownloadPack IsNot Nothing AndAlso FrmDownloadPack.IsLoaded Then
Return New DlCfProjectRequest With {
.SearchFilter = FrmDownloadPack.TextSearchName.Text,
.GameVersion = If(FrmDownloadPack.TextSearchVersion.Text.Contains("."), FrmDownloadPack.TextSearchVersion.Text, Nothing),
.CategoryId = Val(FrmDownloadPack.ComboSearchTag.SelectedItem.Tag),
.IsModPack = True
} '处理列表加载失败后的点击加载器重试
Else
Return New DlCfProjectRequest With {.IsModPack = True}
End If
End Function
'结果 UI 化
Private Sub Load_OnFinish()
Try
PanProjects.Children.Clear()
If Loader.Input.SearchFilter = "" Then
CardProjects.Title = "热门整合包"
Else
CardProjects.Title = "搜索结果 (" & Loader.Output.Projects.Count & If(Loader.Output.Projects.Count < Loader.Output.RealCount, "+", "") & ")"
End If
For Each Project In Loader.Output.Projects
PanProjects.Children.Add(Project.ToCfItem(Loader.Input.GameVersion Is Nothing, Loader.Input.ModLoader Is Nothing OrElse Loader.Input.ModLoader = 0, AddressOf ProjectClick))
Next
Catch ex As Exception
Log(ex, "可视化整合包列表出错", LogLevel.Feedback)
End Try
End Sub
'自动重试
Private Sub Load_State(sender As Object, state As MyLoading.MyLoadingState, oldState As MyLoading.MyLoadingState) Handles Load.StateChanged
Select Case Loader.State
Case LoadState.Failed
Dim ErrorMessage As String = ""
If DlCfFileLoader.Error IsNot Nothing Then ErrorMessage = DlCfFileLoader.Error.Message
If ErrorMessage.Contains("不是有效的 Json 文件") Then
Log("[Download] 下载的整合包列表 Json 文件损坏,已自动重试", LogLevel.Debug)
PageLoaderRestart()
End If
End Select
End Sub
Private Sub Load_OnStart()
PanLoad.Visibility = Visibility.Visible
AniStart({
AaOpacity(PanLoad, 1 - PanLoad.Opacity, 150),
AaOpacity(CardProjects, -CardProjects.Opacity, 150),
AaCode(Sub()
CardProjects.Visibility = Visibility.Collapsed
PanProjects.Children.Clear()
End Sub,, True)
}, "FrmDownloadPack Load Switch")
End Sub
Public Sub ProjectClick(sender As MyCfItem, e As EventArgs)
FrmMain.PageChange(New FormMain.PageStackData With {.Page = FormMain.PageType.CfDetail, .Additional = sender.Tag})
End Sub
Private Sub TextSearchName_KeyUp(sender As Object, e As KeyEventArgs) Handles TextSearchName.KeyUp, TextSearchVersion.KeyUp
If e.Key = Key.Enter Then StartSearch()
End Sub
Private Shared Sub StartSearch() Handles BtnSearchRun.Click
Loader.Start()
End Sub
Private Sub BtnSearchReset_Click(sender As Object, e As EventArgs) Handles BtnSearchReset.Click
TextSearchName.Text = ""
TextSearchVersion.SelectedIndex = 0
TextSearchVersion.Text = "全部"
ComboSearchTag.SelectedIndex = 0
Loader.LastFinishedTime = 0 '要求强制重新开始
End Sub
Private Sub BtnSearchInstall_Click(sender As Object, e As EventArgs) Handles BtnSearchInstall.Click
ModpackInstall()
End Sub
End Class
@@ -0,0 +1,27 @@
<Window x:Class="FormLoginOAuth"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:PCL"
mc:Ignorable="d"
Height="720" Width="580" MinHeight="720" MinWidth="580" ResizeMode="CanResize" WindowStartupLocation="CenterScreen" Title="Microsoft 账户登录">
<Grid>
<Grid.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="White" Offset="0"/>
<GradientStop Color="{DynamicResource ColorObject8}" Offset="1"/>
</LinearGradientBrush>
</Grid.Background>
<StackPanel x:Name="PanLoading" Orientation="Vertical" VerticalAlignment="Center" HorizontalAlignment="Center">
<local:MyLoading x:Name="Loading" Text="正在加载登录页面" HorizontalAlignment="Center" />
<TextBlock Text="如果网络环境不佳,加载可能非常缓慢甚至一直加载不出来" Margin="0,25,0,0"
HorizontalAlignment="Center" Foreground="{DynamicResource ColorBrush1}" Opacity="0.7" />
<TextBlock Text="此时请尝试使用 VPN 或代理服务器,然后再试"
HorizontalAlignment="Center" Foreground="{DynamicResource ColorBrush1}" Opacity="0.7" />
</StackPanel>
<WebBrowser x:Name="Browser1" Visibility="Collapsed" Tag="1" />
<WebBrowser x:Name="Browser2" Visibility="Collapsed" Tag="2" />
<WebBrowser x:Name="Browser3" Visibility="Collapsed" Tag="3" />
</Grid>
</Window>
@@ -0,0 +1,78 @@
Imports System.Windows.Navigation
Public Class FormLoginOAuth
Public Event OnLoginSuccess(code As String)
Public Event OnLoginCanceled(IsForceExit As Boolean)
'跳转事件
Private IsLoginSuccessed As Boolean = False
Private IsForceExit As Boolean = False
Private Sub Browser_Navigating(sender As WebBrowser, e As NavigatingCancelEventArgs) Handles Browser1.Navigating, Browser2.Navigating, Browser3.Navigating
Dim Url As String = e.Uri.AbsoluteUri
If ModeDebug Then Log("[Login] 登录浏览器 " & sender.Tag & " 导向:" & Url)
If Url.Contains("code=") Then
Dim Code As String = RegexSeek(Url, "(?<=code\=)[^&]+")
Log("[Login] 抓取到 OAuth 返回码:" & Code)
IsLoginSuccessed = True
RaiseEvent OnLoginSuccess(Code)
ElseIf Url.Contains("github.") Then
Hint("PCL2 不支持使用 GitHub 登录微软账号!", HintType.Critical)
IsForceExit = True
Close()
End If
End Sub
'已导航事件
Private IsFirstLoaded As Boolean = False
Private IsFirstLoadedLock As New Object
Private Sub Browser_Navigated(sender As WebBrowser, e As NavigationEventArgs) Handles Browser1.Navigated, Browser2.Navigated, Browser3.Navigated
SyncLock IsFirstLoadedLock
If IsFirstLoaded Then Exit Sub
IsFirstLoaded = True
End SyncLock
RunInThread(Sub()
Thread.Sleep(1000)
RunInUi(Sub()
sender.Visibility = Visibility.Visible
PanLoading.Visibility = Visibility.Collapsed
End Sub)
End Sub)
End Sub
'窗体的进出事件
Public Shared LoginUrl1 As String = "https://login.microsoftonline.com/consumers/oauth2/v2.0/authorize?prompt=login&client_id=00000000402b5328&response_type=code&scope=service%3A%3Auser.auth.xboxlive.com%3A%3AMBI_SSL&redirect_uri=https:%2F%2Flogin.live.com%2Foauth20_desktop.srf"
Public Shared LoginUrl2 As String = "https://login.live.com/oauth20_authorize.srf?prompt=login&client_id=00000000402b5328&response_type=code&scope=service%3A%3Auser.auth.xboxlive.com%3A%3AMBI_SSL&redirect_uri=https:%2F%2Flogin.live.com%2Foauth20_desktop.srf"
Private Sub FrmLoginOAuth_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
Browser1.Navigate(LoginUrl1)
RunInThread(Sub()
'估计是由于时间戳原因,同时导航会导致误报密码失败
Thread.Sleep(2500)
RunInUi(Sub()
Try '防止在 Dispose 之后调用
If Not IsFirstLoaded Then Browser2.Navigate(LoginUrl1)
Catch
End Try
End Sub)
Thread.Sleep(2500)
RunInUi(Sub()
Try
If Not IsFirstLoaded Then Browser3.Navigate(LoginUrl2)
Catch
End Try
End Sub)
End Sub)
End Sub
Private Sub FormLoginOAuth_Closed() Handles Me.Closed
Try
Browser1.Dispose()
Browser2.Dispose()
Browser3.Dispose()
Catch ex As Exception
Log(ex, "释放微软登录浏览器失败")
End Try
If Not IsLoginSuccessed Then RaiseEvent OnLoginCanceled(IsForceExit)
FrmMain.Focus()
End Sub
End Class
@@ -0,0 +1,22 @@
<Grid x:Class="MySkin"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:PCL"
Height="64" Width="64" UseLayoutRounding="True" RenderTransformOrigin="0.5,0.5" Background="{StaticResource ColorBrushSemiTransparent}"
ToolTipService.ShowDuration="23333333" ToolTipService.Placement="Center" ToolTipService.VerticalOffset="-50" ToolTipService.HorizontalOffset="2" ToolTipService.InitialShowDelay="100">
<Grid.Effect>
<DropShadowEffect x:Name="ShadowSkin" BlurRadius="10" ShadowDepth="0" Color="{DynamicResource ColorObject2}" Opacity="0.2" />
</Grid.Effect>
<Grid.RenderTransform>
<ScaleTransform />
</Grid.RenderTransform>
<Grid.ContextMenu>
<ContextMenu>
<local:MyMenuItem x:Name="BtnSkinSave" Header="另存为" Padding="0,2" Icon="F1 M 48,39L 56,39L 56,49L 63.25,49L 52,60.25L 40.75,49L 48,49L 48,39 Z M 20,20L 50.25,20L 56,25.75L 56,38L 52,38L 52,27.25L 48.75,24L 48,24L 48,37L 28,37L 28,24L 24,24L 24,52L 42.25,52L 46.25,56L 20,56L 20,20 Z M 39,24L 39,34L 44,34L 44,24L 39,24 Z" />
<local:MyMenuItem x:Name="BtnSkinRefresh" Header="刷新" Padding="0,2" Icon="F1 M 38,20.5833C 42.9908,20.5833 47.4912,22.6825 50.6667,26.046L 50.6667,17.4167L 55.4166,22.1667L 55.4167,34.8333L 42.75,34.8333L 38,30.0833L 46.8512,30.0833C 44.6768,27.6539 41.517,26.125 38,26.125C 31.9785,26.125 27.0037,30.6068 26.2296,36.4167L 20.6543,36.4167C 21.4543,27.5397 28.9148,20.5833 38,20.5833 Z M 38,49.875C 44.0215,49.875 48.9963,45.3932 49.7703,39.5833L 55.3457,39.5833C 54.5457,48.4603 47.0852,55.4167 38,55.4167C 33.0092,55.4167 28.5088,53.3175 25.3333,49.954L 25.3333,58.5833L 20.5833,53.8333L 20.5833,41.1667L 33.25,41.1667L 38,45.9167L 29.1487,45.9167C 31.3231,48.3461 34.483,49.875 38,49.875 Z" />
<local:MyMenuItem x:Name="BtnSkinCape" Header="更换披风" Padding="0,2" Icon="M764.330761 922.841896h-496.758545c-18.741345 0-33.869901-15.128556-33.869901-33.8699V540.789416l-68.642999 29.805512c-15.805954 6.77398-34.0957 0.903197-42.676075-13.999559L22.354135 386.116869c-7.225579-12.418964-5.870783-28.224917 3.38699-39.063286 36.805292-42.901874 256.959647-176.349283 300.764718-202.767806 15.805954-9.483572 36.353693-4.515987 46.063065 11.064168 43.579272 69.320397 86.932745 74.739581 143.156781 74.739581s99.577508-5.419184 143.156781-74.739581c9.709372-15.580154 30.257111-20.54774 46.063065-11.064168 43.805072 26.418523 263.959427 159.865932 300.764719 202.767806 9.483572 11.064168 10.838368 26.644322 3.38699 39.063286l-100.029107 170.4785c-8.580375 14.676957-26.870121 20.773539-42.676075 13.999559l-68.642999-29.805512v348.18258c0.451599 18.741345-14.676957 33.869901-33.418302 33.8699z m-462.888644-67.739801h429.018743v-365.794929c0-11.515766 5.644983-22.128335 15.354355-28.224917 9.483572-6.322381 21.676736-7.225579 32.063506-2.709592l88.287541 38.385888 70.900993-120.802646c-44.25667-34.547299-153.091951-104.093495-239.798898-157.15634-57.578831 72.481588-123.286439 79.029768-181.316869 79.029768s-123.738037-6.548181-181.316868-79.029768c-86.706946 52.837045-195.768026 122.609041-239.798898 157.15634L165.510915 496.758545l88.513341-38.611687c10.38677-4.515987 22.579934-3.612789 32.063506 2.709592 9.483572 6.322381 15.354355 16.93495 15.354355 28.224917v366.020728z" />
</ContextMenu>
</Grid.ContextMenu>
<Image x:Name="ImgBack" Width="48" Height="48" Stretch="Fill" RenderOptions.BitmapScalingMode="NearestNeighbor" SnapsToDevicePixels="True" HorizontalAlignment="Center" VerticalAlignment="Center" />
<Image x:Name="ImgFore" Width="56" Height="56" Stretch="Fill" RenderOptions.BitmapScalingMode="NearestNeighbor" SnapsToDevicePixels="True" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
@@ -0,0 +1,260 @@
Public Class MySkin
'事件
Public Event Click(sender As Object, e As MouseButtonEventArgs)
'皮肤储存
Private _Address As String
Public Property Address() As String
Get
Return _Address
End Get
Set(value As String)
_Address = value
ToolTip = If(_Address = "", "加载中", "点击更换皮肤(右键查看更多选项)")
End Set
End Property
Public Loader As LoaderTask(Of EqualableList(Of String), String)
'控件动画
Private Sub PanSkin_MouseEnter(sender As Object, e As MouseEventArgs) Handles Me.MouseEnter
AniStart(AaOpacity(ShadowSkin, 0.8 - ShadowSkin.Opacity, 200, 100), "Skin Shadow")
End Sub
Private Sub PanSkin_MouseLeave(sender As Object, e As MouseEventArgs) Handles Me.MouseLeave
AniStart(AaOpacity(ShadowSkin, 0.2 - ShadowSkin.Opacity, 200), "Skin Shadow")
IsSkinMouseDown = False
AniStart(AaScaleTransform(Me, 1 - CType(Me.RenderTransform, ScaleTransform).ScaleX, 60,, New AniEaseOutFluent), "Skin Scale")
End Sub
'点击
Private IsSkinMouseDown As Boolean = False
Private Sub PanSkin_MouseLeftButtonDown(sender As Object, e As MouseButtonEventArgs) Handles Me.MouseLeftButtonDown
IsSkinMouseDown = True
AniStart(AaScaleTransform(Me, 0.9 - CType(Me.RenderTransform, ScaleTransform).ScaleX, 60,, New AniEaseOutFluent), "Skin Scale")
End Sub
Private Sub PanSkin_MouseLeftButtonUp(sender As Object, e As MouseButtonEventArgs) Handles Me.MouseLeftButtonUp
AniStart(AaScaleTransform(Me, 1 - CType(Me.RenderTransform, ScaleTransform).ScaleX, 60,, New AniEaseOutFluent), "Skin Scale")
If IsSkinMouseDown Then
IsSkinMouseDown = False
RaiseEvent Click(sender, e)
End If
End Sub
'保存皮肤
Private Sub BtnSkinSave_Click(sender As Object, e As RoutedEventArgs) Handles BtnSkinSave.Click
Save(Loader)
End Sub
Public Shared Sub Save(Loader As LoaderTask(Of EqualableList(Of String), String))
Dim Address = Loader.Output
If Not Loader.State = LoadState.Finished Then
Hint("皮肤正在获取中,请稍候!", HintType.Critical)
If Not Loader.State = LoadState.Loading Then Loader.Start()
Exit Sub
End If
Try
Dim FileAddress As String = SelectAs("选取保存皮肤的位置", GetFileNameFromPath(Address), "皮肤图片文件(*.png)|*.png")
If FileAddress.Contains("\") Then
File.Delete(FileAddress)
If Address.StartsWith(PathImage) Then
Dim Image As New MyBitmap(Address)
Image.Save(FileAddress)
Else
File.Copy(Address, FileAddress)
End If
Hint("皮肤保存成功!", HintType.Finish)
End If
Catch ex As Exception
Log(ex, "保存皮肤失败", LogLevel.Hint)
End Try
End Sub
Private Sub BtnSkinSave_Checked(sender As MyMenuItem, e As RoutedEventArgs) Handles BtnSkinSave.Checked
sender.IsEnabled = Address = ""
End Sub
''' <summary>
''' 载入皮肤。
''' </summary>
Public Sub Load()
Try
Address = Loader.Output
'检查文件存在
If Address = "" Then Throw New Exception("皮肤加载器 " & Loader.Name & " 没有输出")
If Not Address.StartsWith(PathImage) AndAlso Not File.Exists(Address) Then Throw New FileNotFoundException("皮肤文件未找到", Address)
'加载
Dim Image As New MyBitmap(Address)
ImgBack.Tag = Address
'头发层(附加层)
If Image.Pic.Width >= 64 AndAlso Image.Pic.Height >= 32 Then
'如果图片中有透明像素,或是头部颜色和透明区均不一样,则加载附加层
If (Image.Pic.GetPixel(1, 1).A = 0 OrElse Image.Pic.GetPixel(Image.Pic.Width - 1, Image.Pic.Height - 1).A = 0 OrElse Image.Pic.GetPixel(Image.Pic.Width - 2, 2).A = 0) OrElse
(Image.Pic.GetPixel(1, 1) <> Image.Pic.GetPixel(41, 9) AndAlso Image.Pic.GetPixel(Image.Pic.Width - 1, Image.Pic.Height - 1) <> Image.Pic.GetPixel(41, 9) AndAlso Image.Pic.GetPixel(Image.Pic.Width - 2, 2) <> Image.Pic.GetPixel(41, 9)) Then
ImgFore.Source = New CroppedBitmap(Image, New Int32Rect(40, 8, 8, 8))
Else
ImgFore.Source = Nothing
End If
Else
ImgFore.Source = Nothing
End If
'脸层
If Image.Pic.Width >= 32 AndAlso Image.Pic.Height >= 32 Then
ImgBack.Source = New CroppedBitmap(Image, New Int32Rect(8, 8, 8, 8))
Log("[Skin] 载入头像成功:" & Loader.Name)
Else
ImgBack.Source = Nothing
Throw New Exception("图片大小不足,长为 " & Image.Pic.Height & ",宽为 " & Image.Pic.Width)
End If
Catch ex As Exception
Log(ex, "载入头像失败(" & If(Address, "null") & "," & Loader.Name & ")", LogLevel.Hint)
End Try
End Sub
''' <summary>
''' 清空皮肤。
''' </summary>
Public Sub Clear()
Address = ""
ImgFore.Source = Nothing
ImgBack.Source = Nothing
End Sub
'刷新缓存
Private Sub RefreshClick(sender As MyMenuItem, e As EventArgs) Handles BtnSkinRefresh.Click
RefreshCache(Loader)
End Sub
''' <summary>
''' 刷新皮肤缓存。
''' </summary>
Public Shared Sub RefreshCache(Optional sender As LoaderTask(Of EqualableList(Of String), String) = Nothing)
Dim HasLoaderRunning As Boolean = False
For Each SkinLoader In PageLaunchLeft.SkinLoaders
If SkinLoader.State = LoadState.Loading Then
HasLoaderRunning = True : Exit For
End If
Next
If FrmLaunchLeft IsNot Nothing AndAlso HasLoaderRunning Then
'由于 Abort 不是实时的,暂时不会释放文件,会导致删除报错,故只能取消执行
Hint("有正在获取中的皮肤,请稍后再试!", HintType.Info)
Else
RunInThread(Sub()
Try
Hint("正在刷新皮肤……")
'清空缓存
Log("[Skin] 正在清空皮肤缓存")
If Directory.Exists(PathTemp & "Cache\Skin") Then DeleteDirectory(PathTemp & "Cache\Skin")
If Directory.Exists(PathTemp & "Cache\Uuid") Then DeleteDirectory(PathTemp & "Cache\Uuid")
IniClearCache(PathTemp & "Cache\Skin\IndexMojang.ini")
IniClearCache(PathTemp & "Cache\Skin\IndexMs.ini")
IniClearCache(PathTemp & "Cache\Skin\IndexNide.ini")
IniClearCache(PathTemp & "Cache\Skin\IndexAuth.ini")
IniClearCache(PathTemp & "Cache\Uuid\Mojang.ini")
'刷新控件
For Each SkinLoader In If(sender IsNot Nothing, {sender}, {PageLaunchLeft.SkinMojang, PageLaunchLeft.SkinLegacy, PageLaunchLeft.SkinMs})
SkinLoader.WaitForExit(IsForceRestart:=True)
Next
Hint("已刷新皮肤!", HintType.Finish)
Catch ex As Exception
Log(ex, "刷新皮肤缓存失败", LogLevel.Msgbox)
End Try
End Sub)
End If
End Sub
''' <summary>
''' 在更换正版皮肤后,刷新正版皮肤。
''' </summary>
''' <param name="SkinAddress">新的正版皮肤完整地址。</param>
Public Shared Sub ReloadCache(SkinAddress As String, IsMsLogin As Boolean)
RunInThread(Sub()
Try
'更新缓存
Dim LoginType As String = If(IsMsLogin, "Ms", "Mojang")
WriteIni(PathTemp & "Cache\Skin\Index" & LoginType & ".ini", Setup.Get("Cache" & LoginType & "Uuid"), SkinAddress)
Log(String.Format("[Skin] 已写入皮肤地址缓存 {0} -> {1}", Setup.Get("Cache" & LoginType & "Uuid"), SkinAddress))
'刷新控件
For Each SkinLoader In If(IsMsLogin, {PageLaunchLeft.SkinMs, PageLaunchLeft.SkinLegacy}, {PageLaunchLeft.SkinMojang, PageLaunchLeft.SkinLegacy})
SkinLoader.WaitForExit(IsForceRestart:=True)
Next
'完成提示
Hint("更改皮肤成功!", HintType.Finish)
Catch ex As Exception
Log(ex, "更改正版皮肤后刷新皮肤失败", LogLevel.Feedback)
End Try
End Sub)
End Sub
'披风
Public Property HasCape As Boolean
Get
Return BtnSkinCape.Visibility = Visibility.Collapsed
End Get
Set(value As Boolean)
If value Then
BtnSkinCape.Visibility = Visibility.Visible
Else
BtnSkinCape.Visibility = Visibility.Collapsed
End If
End Set
End Property
Private IsChanging As Boolean = False
Private Sub BtnSkinCape_Click(sender As Object, e As RoutedEventArgs) Handles BtnSkinCape.Click
'检查条件,获取新披风
If IsChanging Then
Hint("正在更改披风中,请稍候!")
Exit Sub
End If
If McLoginMsLoader.State = LoadState.Failed Then
Hint("登录失败,无法更改披风!", HintType.Critical)
Exit Sub
End If
Hint("正在获取披风列表,请稍候……")
IsChanging = True
'开始实际获取
RunInNewThread(Sub()
Try
Retry:
'获取登录信息
If McLoginMsLoader.State <> LoadState.Finished Then McLoginMsLoader.WaitForExit() '等待登录结束
If McLoginMsLoader.State <> LoadState.Finished Then
Hint("登录失败,无法更改披风!", HintType.Critical)
Exit Sub
End If
Dim AccessToken As String = McLoginMsLoader.Output.AccessToken
Dim Uuid As String = McLoginMsLoader.Output.Uuid
Dim SkinData As JObject = GetJson(McLoginMsLoader.Output.ProfileJson)
'获取玩家的所有披风
Dim SelId As Integer? = Nothing
RunInUiWait(Sub()
Try
Dim CapeNames As New Dictionary(Of String, String) From {
{"Migrator", "迁移者披风"}, {"MapMaker", "Realms 地图制作者披风"}, {"Moderator", "Mojira 管理员披风"}, {"Translator-Chinese", "Crowdin 中文翻译者披风"}, {"Translator", "Crowdin 翻译者披风"}
}
Dim SelectionControl As New List(Of IMyRadio) From {New MyRadioBox With {.Text = "无披风"}}
For Each Cape In SkinData("capes")
Dim CapeName As String = Cape("alias").ToString
If CapeNames.ContainsKey(CapeName) Then CapeName = CapeNames(CapeName)
SelectionControl.Add(New MyRadioBox With {.Text = CapeName})
Next
SelId = MyMsgBoxSelect(SelectionControl, "选择披风", "确定", "取消")
Catch ex As Exception
Log(ex, "获取玩家皮肤列表失败", LogLevel.Feedback)
End Try
End Sub)
If SelId Is Nothing Then Exit Sub
'发送请求
Dim Result As String = NetRequestRetry("https://api.minecraftservices.com/minecraft/profile/capes/active",
If(SelId = 0, "DELETE", "PUT"),
If(SelId = 0, "", "{""capeId"": """ & SkinData("capes")(SelId - 1)("id").ToString & """}"),
"application/json", Headers:=New Dictionary(Of String, String) From {{"Authorization", "Bearer " & AccessToken}})
If Result.Contains("""errorMessage""") Then
Hint("更改披风失败:" & GetJson(Result)("errorMessage"), HintType.Critical)
Exit Sub
Else
Hint("更改披风成功!", HintType.Finish)
End If
Catch ex As Exception
Log(ex, "更改披风失败", LogLevel.Hint)
Finally
IsChanging = False
End Try
End Sub, "Cape Change")
End Sub
End Class
@@ -0,0 +1,158 @@
<local:MyPageLeft x:Class="PageLaunchLeft"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:PCL"
mc:Ignorable="d" x:Name="PanBack"
d:DesignHeight="417.2" Width="300">
<Grid Name="PanInput" RenderTransformOrigin="0.5,0.5">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="20" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="20" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="10" />
</Grid.ColumnDefinitions>
<Grid.RenderTransform>
<ScaleTransform />
</Grid.RenderTransform>
<local:MyButton Grid.Row="3" Grid.Column="2" x:Name="BtnVersion" Height="35" Margin="0,10,10,0" Text="版本选择" IsEnabled="False" />
<local:MyButton Grid.Row="3" Grid.Column="3" x:Name="BtnMore" Visibility="Collapsed" Height="35" Margin="0,10,10,0" TextPadding="36" Text="版本设置" />
<Grid Grid.ColumnSpan="5" Grid.Row="1" Margin="20,0" VerticalAlignment="Center" x:Name="PanLogin" />
<Grid Grid.ColumnSpan="5" Margin="20,24,20,-4" Name="PanTypeOne">
<Border HorizontalAlignment="Center" VerticalAlignment="Center" Background="{StaticResource ColorBrushSemiTransparent}" CornerRadius="13" MinHeight="27" MaxHeight="27">
<StackPanel Orientation="Horizontal">
<Path Name="PathTypeOne" HorizontalAlignment="Left" RenderTransformOrigin="0.5,0.5" Margin="12,0,0,0" Stretch="Uniform" Fill="{DynamicResource ColorBrush3}" MaxHeight="16" MaxWidth="16" VerticalAlignment="Center"
Data="">
<Path.RenderTransform>
<ScaleTransform ScaleX="1.4" ScaleY="1.4" />
</Path.RenderTransform>
</Path>
<TextBlock Name="LabTypeOne" Text="" FontSize="14" VerticalAlignment="Center" Grid.Column="1" Foreground="{DynamicResource ColorBrush3}" Margin="15,0,12,0" Grid.ColumnSpan="2" SnapsToDevicePixels="False" UseLayoutRounding="False" />
</StackPanel>
</Border>
</Grid>
<Grid Grid.ColumnSpan="5" Margin="20,22,20,0" Name="PanType" Visibility="Collapsed">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<local:MyRadioButton x:Name="RadioLoginType1" Tag="LoginType/1" Grid.Column="1" Grid.ColumnSpan="1" ColorType="Highlight" Text="Mojang" Margin="4,0"
LogoScale="1.1" Logo="M9.183,18.967c-0.109-2.239,1.336-5.119,3.92-4.96c3.657-0.027,7.319-0.044,10.977,0.005 c3.712,0.214,6.596,2.759,9.652,4.533c0.181-1.697-0.197-3.717,1.237-4.982c1.899,2.091,3.143,4.894,5.677,6.334 c1.577,0.805,2.973-0.668,4.221-1.44c1.55,2.305,2.108,5.075,2.622,7.752c0.657,3.438,0.947,6.925,1.111,10.413 c-1.734-0.733-3.355-1.708-4.971-2.671c-1.396-4.933-5.349-8.656-9.723-11.059c-3.46-1.817-7.752-2.185-11.338-0.52 c-3.761,1.593-6.285,5.666-5.891,9.75c0.121,4.577,3.17,8.765,7.391,10.456c7.746,3.285,16.407,2.234,24.521,1.243 c0.454,2.315-1.511,4.527-3.695,4.889c-10.577,0.038-21.148-0.011-31.725,0.022c-2.217,0.279-4.079-1.879-3.964-4.008 C9.167,36.141,9.216,27.556,9.183,18.967z M40.114,8.09c0.294-0.801,0.872-1.417,1.542-1.924c1.379,2.589,2.742,5.482,2.311,8.491 c-0.332,2.54-4.42,2.507-5.052,0.163C38.349,12.527,39.209,10.178,40.114,8.09z M0,53 l0.1,0 z" Checked="True" />
<local:MyRadioButton x:Name="RadioLoginType5" Tag="LoginType/5" Grid.Column="2" Grid.ColumnSpan="1" ColorType="Highlight" Text="微软" Margin="4,0"
LogoScale="0.9" Logo="M481.882353 826.428235V527.661176l402.371765 2.409412v356.592941l-402.371765-60.235294z m0-628.85647l402.371765-60.235294v330.089411H481.882353V197.571765zM137.336471 525.251765h289.129411v293.948235l-289.129411-45.778824V525.251765z m0-55.416471V248.169412l289.129411-45.778824v265.035294h-289.129411z" />
<local:MyRadioButton x:Name="RadioLoginType0" Tag="LoginType/0" Grid.Column="3" Grid.ColumnSpan="1" ColorType="Highlight" Text="离线" Margin="4,0"
LogoScale="0.95" Logo="M660.338 528.065c63.61-46.825 105.131-121.964 105.131-206.83 0-141.7-115.29-256.987-256.997-256.987-141.706 0-256.998 115.288-256.998 256.987 0 85.901 42.52 161.887 107.456 208.562-152.1 59.92-260.185 207.961-260.185 381.077 0 21.276 17.253 38.53 38.53 38.53 21.278 0 38.53-17.254 38.53-38.53 0-183.426 149.232-332.671 332.667-332.671 1.589 0 3.113-0.207 4.694-0.244 0.8 0.056 1.553 0.244 2.362 0.244 183.434 0 332.664 149.245 332.664 332.671 0 21.276 17.255 38.53 38.533 38.53 21.277 0 38.53-17.254 38.53-38.53 0-174.885-110.354-324.13-264.917-382.809z m-331.803-206.83c0-99.22 80.72-179.927 179.935-179.927s179.937 80.708 179.937 179.927c0 99.203-80.721 179.91-179.937 179.91s-179.935-80.708-179.935-179.91z" />
<!--<local:MyRadioButton x:Name="RadioLoginType2" Tag="LoginType/2" Grid.Column="4" ColorType="Highlight" Text="统一通行证" Visibility="Collapsed"
LogoScale="1.1" Logo="M834.5 684.1c-31.2-70.4-98.9-120.9-179.1-127.3 63.5-8.5 112.6-63 112.6-128.8 0-71.8-58.2-130-130-130s-130 58.2-130 130c0 65.9 49 120.3 112.6 128.8-80.2 6.4-148 57-179.1 127.3-8.7 19.7 6 42 27.6 42 12.1 0 22.7-7.5 27.7-18.5 24.3-53.9 78.5-91.5 141.3-91.5s117 37.6 141.3 91.5c5 11.1 15.6 18.5 27.7 18.5 21.4 0 36.1-22.3 27.4-42zM567.9 427.9c0-38.6 31.4-70 70-70s70 31.4 70 70-31.4 70-70 70-70-31.4-70-70zM460.3 347.9H216.9c-16.6 0-30 13.4-30 30s13.4 30 30 30h243.3c16.6 0 30-13.4 30-30 0.1-16.5-13.4-30-29.9-30zM367.4 459.6H216.9c-16.6 0-30 13.4-30 30s13.4 30 30 30h150.4c16.6 0 30-13.4 30-30 0.1-16.6-13.4-30-29.9-30zM297.4 571.2H217c-16.6 0-30 13.4-30 30s13.4 30 30 30h80.4c16.6 0 30-13.4 30-30 0-16.5-13.5-30-30-30zM900 236v552H124V236h776m0-60H124c-33.1 0-60 26.9-60 60v552c0 33.1 26.9 60 60 60h776c33.1 0 60-26.9 60-60V236c0-33.1-26.9-60-60-60z" />-->
</Grid>
<Grid Grid.ColumnSpan="5" Grid.Row="2" RenderTransformOrigin="0.5,0.5">
<Grid.RenderTransform>
<TransformGroup>
<ScaleTransform x:Name="AprilScaleTrans" />
<TranslateTransform x:Name="AprilPosTrans" />
</TransformGroup>
</Grid.RenderTransform>
<local:MyButton x:Name="BtnLaunch" Height="54" Margin="20,0" Text="正在加载" ColorType="Highlight" Padding="30,0,30,15" IsEnabled="False" />
<TextBlock x:Name="LabVersion" Text="正在加载版本列表,请稍候" Margin="35,0,35,10" IsHitTestVisible="False" VerticalAlignment="Bottom" HorizontalAlignment="Center" TextTrimming="CharacterEllipsis" FontSize="11" Foreground="{DynamicResource ColorBrushGray3}" RenderTransformOrigin="0.5,-0.2">
<TextBlock.RenderTransform>
<ScaleTransform ScaleX="{Binding RealRenderTransform.ScaleX, ElementName=BtnLaunch, Mode=OneWay}" ScaleY="{Binding RealRenderTransform.ScaleY, ElementName=BtnLaunch, Mode=OneWay}" />
</TextBlock.RenderTransform>
</TextBlock>
</Grid>
</Grid>
<Grid Name="PanLaunching" RenderTransformOrigin="0.5,0.5" Visibility="Collapsed" Opacity="0">
<Grid.RenderTransform>
<ScaleTransform ScaleX="0.8" ScaleY="0.8" />
</Grid.RenderTransform>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="1" RenderTransformOrigin="0.5,0.5" Margin="0,-7,0,0">
<StackPanel.BitmapEffect>
<DropShadowBitmapEffect Color="{StaticResource ColorObjectGray2}" ShadowDepth="1.5" Direction="270" Opacity="0.15" Softness="0.15" />
</StackPanel.BitmapEffect>
<local:MyLoading x:Name="LoadLaunching" AutoRun="False" Height="50" Margin="0,10,0,5" />
<TextBlock Name="LabLaunchingTitle" Margin="15,10,15,0" Text="正在启动游戏" HorizontalAlignment="Center" FontSize="20" Foreground="{DynamicResource ColorBrush3}">
<TextBlock.RenderTransform>
<SkewTransform AngleX="-3"/>
</TextBlock.RenderTransform>
</TextBlock>
<TextBlock Name="LabLaunchingName" Margin="40,5,40,0" FontSize="13.5" Text="Forge 1.12.2-15.8.0.1560" HorizontalAlignment="Center" Foreground="{DynamicResource ColorBrush3}" RenderTransformOrigin="0.5,0.5">
<TextBlock.RenderTransform>
<SkewTransform AngleX="-3"/>
</TextBlock.RenderTransform>
</TextBlock>
<Grid Height="4" Margin="30,12,30,27" SnapsToDevicePixels="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Name="ProgressLaunchingFinished" Width="69.28*"/>
<ColumnDefinition Name="ProgressLaunchingUnfinished" Width="30.72*"/>
</Grid.ColumnDefinitions>
<Rectangle Grid.Column="0" >
<Rectangle.Fill>
<LinearGradientBrush EndPoint="1,0" StartPoint="0,0">
<GradientStop Color="{DynamicResource ColorObject4}" Offset="0"/>
<GradientStop Color="{DynamicResource ColorObject3}" Offset="0.6"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Rectangle Grid.Column="1" Fill="{DynamicResource ColorBrush6}" Opacity="0.6" />
</Grid>
<Grid HorizontalAlignment="Center" Name="PanLaunchingInfo">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="15" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock FontSize="12.5" Margin="0,0,0,5" Text="当前步骤" Grid.Row="0" Grid.Column="1" HorizontalAlignment="Right" Opacity="0.5" />
<TextBlock FontSize="12.5" Margin="0,0,0,5" Text="下载支持" Grid.Row="0" Grid.Column="3" HorizontalAlignment="Left" Name="LabLaunchingStage" />
<TextBlock FontSize="12.5" Margin="0,0,0,5" Text="登录方式" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Right" Opacity="0.5" />
<TextBlock FontSize="12.5" Margin="0,0,0,5" Text="正版登录" Grid.Row="1" Grid.Column="3" HorizontalAlignment="Left" Name="LabLaunchingMethod" />
<TextBlock FontSize="12.5" Margin="0,0,0,5" Text="启动进度" Grid.Row="2" Grid.Column="1" HorizontalAlignment="Right" Opacity="0.5" Name="LabLaunchingProgressLeft" />
<TextBlock FontSize="12.5" Margin="0,0,0,5" Text="69.28 %" Grid.Row="2" Grid.Column="3" HorizontalAlignment="Left" Name="LabLaunchingProgress" />
<TextBlock FontSize="12.5" Margin="0,0,0,5" Text="下载速度" Grid.Row="3" Grid.Column="1" HorizontalAlignment="Right" Opacity="0" Name="LabLaunchingDownloadLeft" Visibility="Collapsed" />
<TextBlock FontSize="12.5" Margin="0,0,0,5" Text="5.2 M/s" Grid.Row="3" Grid.Column="3" HorizontalAlignment="Left" Name="LabLaunchingDownload" Opacity="0" Visibility="Collapsed" />
<Grid x:Name="PanLaunchingHint" HorizontalAlignment="Center" Grid.Row="2" Grid.ColumnSpan="5" Grid.RowSpan="2" Width="260" Margin="0,16,0,2" Visibility="Collapsed" Opacity="0">
<Border Margin="0,8,0,0" BorderThickness="1" CornerRadius="3" BorderBrush="{StaticResource ColorBrushGray1}" Opacity="0.5">
<Border.Clip>
<CombinedGeometry GeometryCombineMode="Exclude">
<CombinedGeometry.Geometry1>
<RectangleGeometry Rect="0,0,1000,1000" />
</CombinedGeometry.Geometry1>
<CombinedGeometry.Geometry2>
<RectangleGeometry Rect="94,0,72,10" />
</CombinedGeometry.Geometry2>
</CombinedGeometry>
</Border.Clip>
</Border>
<TextBlock FontSize="12.5" Text="你知道吗" HorizontalAlignment="Center" VerticalAlignment="Top" Foreground="{StaticResource ColorBrushGray1}" Opacity="0.5" />
<TextBlock x:Name="LabLaunchingHint" FontSize="12.5" Text="这是一段测试用的小提示文本,它应该足够长以让它有两行。" Margin="11,21,11,10" TextWrapping="Wrap" HorizontalAlignment="Center" />
</Grid>
</Grid>
</StackPanel>
<local:MyButton Grid.Row="4" x:Name="BtnCancel" Height="35" Margin="20,0,20,20" VerticalAlignment="Bottom" Text="取消" />
</Grid>
</local:MyPageLeft>
@@ -0,0 +1,877 @@
Public Class PageLaunchLeft
'加载当前版本
Private IsLoad As Boolean = False
Private IsLoadFinished As Boolean = False
Public Sub PageLaunchLeft_Loaded() Handles Me.Loaded
If IsLoad Then RefreshPage(True, False)
AprilPosTrans.X = 0
AprilPosTrans.Y = 0
If IsLoad Then Exit Sub
IsLoad = True
AniControlEnabled += 1
'开始按钮
AddHandler McVersionListLoader.LoadingStateChanged, AddressOf RefreshButtonsUI
AddHandler McFolderListLoader.LoadingStateChanged, AddressOf RefreshButtonsUI
RefreshButtonsUI()
'加载版本
RunInNewThread(Sub()
'确认 Minecraft 文件夹存在
PathMcFolder = Setup.Get("LaunchFolderSelect").ToString.Replace("$", Path)
If PathMcFolder = "" OrElse Not Directory.Exists(PathMcFolder) Then
'无效的文件夹
If PathMcFolder = "" Then
Log("[Launch] 没有已储存的 Minecraft 文件夹")
Else
Log("[Launch] Minecraft 文件夹无效,该文件夹已不存在:" & PathMcFolder, LogLevel.Debug)
End If
McFolderListLoader.WaitForExit(IsForceRestart:=True)
Setup.Set("LaunchFolderSelect", McFolderList(0).Path.Replace(Path, "$"))
End If
Log("[Launch] Minecraft 文件夹:" & PathMcFolder)
If Setup.Get("SystemDebugDelay") Then Thread.Sleep(RandomInteger(500, 3000))
'确认 Minecraft 版本存在
Dim Selection As String = Setup.Get("LaunchVersionSelect")
Dim Version As McVersion
If Selection = "" Then
Version = Nothing
Else
Version = New McVersion(Selection)
End If
If IsNothing(Version) OrElse Not (Version.Path.StartsWith(PathMcFolder) AndAlso Version.Check) Then
'无效的版本
Log("[Launch] Minecraft 版本无效" & If(IsNothing(Version), ",没有有效版本", ":" & Version.Path), If(IsNothing(Version), LogLevel.Normal, LogLevel.Debug))
If Not McVersionListLoader.State = LoadState.Finished Then LoaderFolderRun(McVersionListLoader, PathMcFolder, LoaderFolderRunType.ForceRun, MaxDepth:=1, ExtraPath:="versions\", WaitForExit:=True)
If McVersionList.Count = 0 OrElse McVersionList.First.Value(0).Logo.Contains("RedstoneBlock") Then
Version = Nothing
Setup.Set("LaunchVersionSelect", "")
Log("[Launch] 无可用 Minecraft 版本")
Else
Version = McVersionList.First.Value(0)
Setup.Set("LaunchVersionSelect", Version.Name)
Log("[Launch] 自动选择 Minecraft 版本:" & Version.Path)
End If
End If
RunInUi(Sub()
McVersionCurrent = Version '绕这一圈是为了避免 McVersionCheck 触发第二次版本改变
IsLoadFinished = True
RefreshButtonsUI()
RefreshPage(False, False) '有可能选择的版本变化了,需要重新刷新
If McLoginAble() = "" Then McLoginLoader.Start() '自动登录
End Sub)
End Sub, "Version Check", ThreadPriority.AboveNormal)
'改变页面
Dim LoginType As McLoginType = Setup.Get("LoginType")
If LoginType = McLoginType.Legacy OrElse LoginType = McLoginType.Mojang OrElse LoginType = McLoginType.Ms Then CType(FindName("RadioLoginType" & LoginType), MyRadioButton).Checked = True
RefreshPage(False, False)
AniControlEnabled -= 1
End Sub
#Region "切换大页面"
''' <summary>
''' 切换至启动中页面。
''' </summary>
Public Sub PageChangeToLaunching()
LaunchingPreload()
PanInput.IsHitTestVisible = False
PanLaunching.IsHitTestVisible = False
LoadLaunching.State.LoadingState = MyLoading.MyLoadingState.Run
PanLaunching.Visibility = Visibility.Visible
AniStart({
AaOpacity(PanInput, 0, 50), '略作延迟,这样如果预检测失败,不会出现奇怪的弹一下的动画
AaOpacity(PanInput, -PanInput.Opacity, 110, , New AniEaseInFluent, True),
AaScaleTransform(PanInput, 1.2 - CType(PanInput.RenderTransform, ScaleTransform).ScaleX, 160),
AaOpacity(PanLaunching, 1 - PanLaunching.Opacity, 150, 100),
AaScaleTransform(PanLaunching, 1 - CType(PanLaunching.RenderTransform, ScaleTransform).ScaleX, 500, 100, New AniEaseOutBack(AniEasePower.Weak)),
AaCode(Sub() PanLaunching.IsHitTestVisible = True, 150)
}, "Launch State Page")
End Sub
''' <summary>
''' 切换至登录页面。
''' </summary>
Public Sub PageChangeToLogin()
PageGet(PageCurrent).Reload(KeepInput:=False)
PanInput.IsHitTestVisible = False
PanLaunching.IsHitTestVisible = False
LoadLaunching.State.LoadingState = MyLoading.MyLoadingState.Stop
PanInput.Visibility = Visibility.Visible
AniStart({
AaOpacity(PanLaunching, -PanLaunching.Opacity, 150),
AaScaleTransform(PanLaunching, 0.8 - CType(PanLaunching.RenderTransform, ScaleTransform).ScaleX, 150,, New AniEaseOutFluent(AniEasePower.Weak)),
AaOpacity(PanInput, 1 - PanInput.Opacity, 250, 50),
AaScaleTransform(PanInput, 1 - CType(PanInput.RenderTransform, ScaleTransform).ScaleX, 300, 50, New AniEaseOutBack(AniEasePower.Weak)),
AaCode(Sub() PanInput.IsHitTestVisible = True, 200)
}, "Launch State Page", True)
End Sub
#End Region
#Region "切换登录页面"
Private Enum PageType
None
Mojang
MojangSkin
Legacy
Nide
NideSkin
Auth
AuthSkin
Ms
MsSkin
End Enum
''' <summary>
''' 当前页面的种类。
''' </summary>
Private PageCurrent As PageType = PageType.None
Private Function PageGet(Type As PageType)
Select Case Type
Case PageType.Mojang
If IsNothing(FrmLoginMojang) Then FrmLoginMojang = New PageLoginMojang
Return FrmLoginMojang
Case PageType.MojangSkin
If IsNothing(FrmLoginMojangSkin) Then FrmLoginMojangSkin = New PageLoginMojangSkin
Return FrmLoginMojangSkin
Case PageType.Legacy
If IsNothing(FrmLoginLegacy) Then FrmLoginLegacy = New PageLoginLegacy
Return FrmLoginLegacy
Case PageType.Nide
If IsNothing(FrmLoginNide) Then FrmLoginNide = New PageLoginNide
Return FrmLoginNide
Case PageType.NideSkin
If IsNothing(FrmLoginNideSkin) Then FrmLoginNideSkin = New PageLoginNideSkin
Return FrmLoginNideSkin
Case PageType.Auth
If IsNothing(FrmLoginAuth) Then FrmLoginAuth = New PageLoginAuth
Return FrmLoginAuth
Case PageType.AuthSkin
If IsNothing(FrmLoginAuthSkin) Then FrmLoginAuthSkin = New PageLoginAuthSkin
Return FrmLoginAuthSkin
Case PageType.Ms
If IsNothing(FrmLoginMs) Then FrmLoginMs = New PageLoginMs
Return FrmLoginMs
Case PageType.MsSkin
If IsNothing(FrmLoginMsSkin) Then FrmLoginMsSkin = New PageLoginMsSkin
Return FrmLoginMsSkin
Case Else
Throw New ArgumentOutOfRangeException("Type", "即将切换的登录分页编号越界")
End Select
End Function
''' <summary>
''' 切换现有登录页面种类,返回新页面的实例。
''' </summary>
''' <param name="Type">新页面的种类。</param>
''' <param name="Anim">是否显示动画。</param>
Private Function PageChange(Type As PageType, Anim As Boolean)
Dim PageNew As Object = FrmLoginMojang '初始化一个东西,避免在执行时出现异常导致雪崩
Try
#Region "确定更改的页面实例并实例化"
If PageCurrent = Type Then Return PageNew
PageNew = PageGet(Type)
#End Region
#Region "切换页面"
AniStop("FrmLogin PageChange")
'清除页面关联性
If Not IsNothing(PageNew) AndAlso Not IsNothing(PageNew.Parent) Then PageNew.SetValue(ContentPresenter.ContentProperty, Nothing)
If Anim Then
'动画
Dispatcher.Invoke(Sub()
'执行动画
AniStart({
AaOpacity(PanLogin, -PanLogin.Opacity, 100,, New AniEaseOutFluent),
AaCode(Sub()
AniControlEnabled += 1
PanLogin.Children.Clear()
PanLogin.Children.Add(PageNew)
AniControlEnabled -= 1
End Sub, 100),
AaOpacity(PanLogin, 1, 100, 120, New AniEaseInFluent)
}, "FrmLogin PageChange")
End Sub, Threading.DispatcherPriority.Render)
Else
'无动画
AniControlEnabled += 1
PanLogin.Children.Clear()
PanLogin.Children.Add(PageNew)
AniControlEnabled -= 1
End If
#End Region
PageCurrent = Type
Return PageNew
Catch ex As Exception
Log(ex, "切换登录分页失败(" & GetStringFromEnum(CType(Type, [Enum])) & ")", LogLevel.Feedback)
Return PageNew
End Try
End Function
''' <summary>
''' 确认当前显示的子页面正确,并刷新该页面。
''' </summary>
Public Sub RefreshPage(KeepInput As Boolean, Anim As Boolean)
'获取页面的可用种类并回写缓存
Dim Type As PageType
Dim LoginPageType As Integer
If McVersionCurrent IsNot Nothing Then
LoginPageType = Setup.Get("VersionServerLogin", Version:=McVersionCurrent)
'缓存当前版本的页面种类,下一次打开 McVersionCurrent 为空时才能加载出正确的页面
Setup.Set("LoginPageType", LoginPageType)
Else
LoginPageType = Setup.Get("LoginPageType")
End If
Select Case LoginPageType
Case 0 '正版或离线
UnknownType:
If RadioLoginType1.Checked Then
If Setup.Get("CacheMojangAccess") = "" Then
Type = PageType.Mojang
Else
Type = PageType.MojangSkin
End If
Setup.Set("LoginType", McLoginType.Mojang)
ElseIf RadioLoginType5.Checked Then
If Setup.Get("CacheMsAccess") = "" Then
Type = PageType.Ms
Else
Type = PageType.MsSkin
End If
Setup.Set("LoginType", McLoginType.Ms)
Else
Type = PageType.Legacy
Setup.Set("LoginType", McLoginType.Legacy)
End If
PanType.Visibility = Visibility.Visible
PanTypeOne.Visibility = Visibility.Collapsed
RadioLoginType1.Visibility = Visibility.Visible
RadioLoginType5.Visibility = Visibility.Visible
RadioLoginType0.Visibility = Visibility.Visible
Case 1 '仅正版
If RadioLoginType5.Checked Then
If Setup.Get("CacheMsAccess") = "" Then
Type = PageType.Ms
Else
Type = PageType.MsSkin
End If
Setup.Set("LoginType", McLoginType.Ms)
Else
If Setup.Get("CacheMojangAccess") = "" Then
Type = PageType.Mojang
Else
Type = PageType.MojangSkin
End If
Setup.Set("LoginType", McLoginType.Mojang)
End If
PanType.Visibility = Visibility.Visible
PanTypeOne.Visibility = Visibility.Collapsed
RadioLoginType1.Visibility = Visibility.Visible
RadioLoginType5.Visibility = Visibility.Visible
RadioLoginType0.Visibility = Visibility.Collapsed
Case 2 '仅离线
Type = PageType.Legacy
Setup.Set("LoginType", McLoginType.Legacy)
PanType.Visibility = Visibility.Collapsed
PanTypeOne.Visibility = Visibility.Visible
PathTypeOne.Data = (New GeometryConverter).ConvertFromString(Logo.IconButtonUser)
LabTypeOne.Text = "离线登录"
Case 3 '统一通行证
If Setup.Get("CacheNideAccess") = "" Then
Type = PageType.Nide
Else
Type = PageType.NideSkin
End If
Setup.Set("LoginType", McLoginType.Nide)
PanType.Visibility = Visibility.Collapsed
PanTypeOne.Visibility = Visibility.Visible
PathTypeOne.Data = (New GeometryConverter).ConvertFromString(Logo.IconButtonCard)
LabTypeOne.Text = "统一通行证登录"
Case 4 'Authlib-Injector
If Setup.Get("CacheAuthAccess") = "" Then
Type = PageType.Auth
Else
Type = PageType.AuthSkin
End If
Setup.Set("LoginType", McLoginType.Auth)
PanType.Visibility = Visibility.Collapsed
PanTypeOne.Visibility = Visibility.Visible
PathTypeOne.Data = (New GeometryConverter).ConvertFromString(Logo.IconButtonCard)
LabTypeOne.Text = If(McVersionCurrent Is Nothing, Setup.Get("CacheAuthServerName"), Setup.Get("VersionServerAuthName", Version:=McVersionCurrent))
If LabTypeOne.Text = "" Then LabTypeOne.Text = "第三方登录"
Case Else
Log("[Control] 未知的登录页面:" & LoginPageType, LogLevel.Hint)
GoTo UnknownType
End Select
'刷新页面
If PageCurrent = Type Then Exit Sub
PageChange(Type, Anim).Reload(KeepInput)
Dim Control As MyRadioButton = FindName("RadioLoginType" & Setup.Get("LoginType"))
If Control IsNot Nothing Then Control.Checked = True
End Sub
Private Sub RadioLoginType_Change(sender As Object, raiseByMouse As Boolean) Handles RadioLoginType0.Check, RadioLoginType1.Check, RadioLoginType5.Check
If raiseByMouse Then RefreshPage(True, True)
End Sub
#End Region
#Region "皮肤"
'Mojang 正版皮肤
Public Shared SkinMojang As New LoaderTask(Of EqualableList(Of String), String)("Loader Skin Mojang", AddressOf SkinMojangLoad, AddressOf SkinMojangInput, ThreadPriority.AboveNormal)
Private Shared Function SkinMojangInput() As EqualableList(Of String)
'获取名称
Return New EqualableList(Of String) From {Setup.Get("CacheMojangName"), Setup.Get("CacheMojangUuid")}
End Function
Private Shared Sub SkinMojangLoad(Data As LoaderTask(Of EqualableList(Of String), String))
'清空已有皮肤
'如果在输入时清空皮肤,若输入内容一样则不会执行 Load 方法,导致皮肤不被加载
RunInUi(Sub() If FrmLoginMojangSkin IsNot Nothing AndAlso FrmLoginMojangSkin.Skin IsNot Nothing Then FrmLoginMojangSkin.Skin.Clear())
'获取 Url
Dim UserName As String = Data.Input(0)
Dim Uuid As String = Data.Input(1)
If UserName = "" Then
Data.Output = PathImage & "Skins/" & McSkinSex(McLoginLegacyUuid(UserName)) & ".png"
Log("[Minecraft] 获取正版皮肤失败,ID 为空")
GoTo Finish
End If
Try
Dim Result As String = McSkinGetAddress(Uuid, "Mojang")
If Data.IsAborted Then Throw New ThreadInterruptedException("当前任务已取消:" & UserName)
Result = McSkinDownload(Result)
If Data.IsAborted Then Throw New ThreadInterruptedException("当前任务已取消:" & UserName)
Data.Output = Result
Catch ex As Exception
If ex.GetType.Name = "ThreadInterruptedException" Then
Data.Output = ""
Exit Sub
ElseIf GetString(ex).Contains("429") Then
Data.Output = PathImage & "Skins/" & McSkinSex(McLoginLegacyUuid(UserName)) & ".png"
Log("[Minecraft] 获取正版皮肤失败(" & UserName & "):获取皮肤太过频繁,请 5 分钟后再试!", LogLevel.Hint)
ElseIf GetString(ex).Contains("未设置自定义皮肤") Then
Data.Output = PathImage & "Skins/" & McSkinSex(McLoginLegacyUuid(UserName)) & ".png"
Log("[Minecraft] 用户未设置自定义皮肤,跳过皮肤加载")
Else
Data.Output = PathImage & "Skins/" & McSkinSex(McLoginLegacyUuid(UserName)) & ".png"
Log(ex, "获取正版皮肤失败(" & UserName & ")", LogLevel.Hint)
End If
End Try
Finish:
'刷新显示
If FrmLoginMojangSkin IsNot Nothing Then
RunInUi(AddressOf FrmLoginMojangSkin.Skin.Load)
ElseIf Not Data.IsAborted Then '如果已经中断,Input 也被清空,就不会再次刷新
Data.Input = Nothing '清空输入,因为皮肤实际上没有被渲染,如果不清空切换到页面的 Start 会由于输入相同而不渲染
End If
End Sub
'微软正版皮肤
Public Shared SkinMs As New LoaderTask(Of EqualableList(Of String), String)("Loader Skin Ms", AddressOf SkinMsLoad, AddressOf SkinMsInput, ThreadPriority.AboveNormal)
Private Shared Function SkinMsInput() As EqualableList(Of String)
'获取名称
Return New EqualableList(Of String) From {Setup.Get("CacheMsName"), Setup.Get("CacheMsUuid")}
End Function
Private Shared Sub SkinMsLoad(Data As LoaderTask(Of EqualableList(Of String), String))
'清空已有皮肤
'如果在输入时清空皮肤,若输入内容一样则不会执行 Load 方法,导致皮肤不被加载
RunInUi(Sub() If FrmLoginMsSkin IsNot Nothing AndAlso FrmLoginMsSkin.Skin IsNot Nothing Then FrmLoginMsSkin.Skin.Clear())
'获取 Url
Dim UserName As String = Data.Input(0)
Dim Uuid As String = Data.Input(1)
If UserName = "" Then
Data.Output = PathImage & "Skins/" & McSkinSex(McLoginLegacyUuid(UserName)) & ".png"
Log("[Minecraft] 获取微软正版皮肤失败,ID 为空")
GoTo Finish
End If
Try
Dim Result As String = McSkinGetAddress(Uuid, "Ms")
If Data.IsAborted Then Throw New ThreadInterruptedException("当前任务已取消:" & UserName)
Result = McSkinDownload(Result)
If Data.IsAborted Then Throw New ThreadInterruptedException("当前任务已取消:" & UserName)
Data.Output = Result
Catch ex As Exception
If ex.GetType.Name = "ThreadInterruptedException" Then
Data.Output = ""
Exit Sub
ElseIf GetString(ex).Contains("429") Then
Data.Output = PathImage & "Skins/" & McSkinSex(McLoginLegacyUuid(UserName)) & ".png"
Log("[Minecraft] 获取正版皮肤失败(" & UserName & "):获取皮肤太过频繁,请 5 分钟后再试!", LogLevel.Hint)
ElseIf GetString(ex).Contains("未设置自定义皮肤") Then
Data.Output = PathImage & "Skins/" & McSkinSex(McLoginLegacyUuid(UserName)) & ".png"
Log("[Minecraft] 用户未设置自定义皮肤,跳过皮肤加载")
Else
Data.Output = PathImage & "Skins/" & McSkinSex(McLoginLegacyUuid(UserName)) & ".png"
Log(ex, "获取微软正版皮肤失败(" & UserName & ")", LogLevel.Hint)
End If
End Try
Finish:
'刷新显示
If FrmLoginMsSkin IsNot Nothing Then
RunInUi(AddressOf FrmLoginMsSkin.Skin.Load)
ElseIf Not Data.IsAborted Then '如果已经中断,Input 也被清空,就不会再次刷新
Data.Input = Nothing '清空输入,因为皮肤实际上没有被渲染,如果不清空切换到页面的 Start 会由于输入相同而不渲染
End If
End Sub
'离线皮肤
Public Shared SkinLegacy As New LoaderTask(Of EqualableList(Of String), String)("Loader Skin Legacy", AddressOf SkinLegacyLoad, AddressOf SkinLegacyInput, ThreadPriority.AboveNormal)
Private Shared Function SkinLegacyInput() As EqualableList(Of String)
'根据类型判断输入
Dim Type As Integer = Setup.Get("LaunchSkinType")
Select Case Type
Case 0
If FrmLoginLegacy IsNot Nothing AndAlso FrmLoginLegacy.IsReloaded Then
Return New EqualableList(Of String) From {0, If(FrmLoginLegacy.ComboName.Text, "")}
ElseIf Setup.Get("LoginLegacyName") = "" Then
Return New EqualableList(Of String) From {0, ""}
Else
Return New EqualableList(Of String) From {0, If(Setup.Get("LoginLegacyName").ToString.Split("¨")(0), "")}
End If
Case 3
Return New EqualableList(Of String) From {3, Setup.Get("LaunchSkinID")}
Case Else
Return New EqualableList(Of String) From {Type}
End Select
End Function
Private Shared Sub SkinLegacyLoad(Data As LoaderTask(Of EqualableList(Of String), String))
'清空已有皮肤
RunInUi(Sub() If FrmLoginLegacy IsNot Nothing AndAlso FrmLoginLegacy.Skin IsNot Nothing Then FrmLoginLegacy.Skin.Clear())
'获取 Url
Select Case Data.Input(0)
Case 0 '默认
Data.Output = PathImage & "Skins/" & McSkinSex(McLoginLegacyUuid(Data.Input(1))) & ".png"
Case 1 'Steve
UseDefault:
Data.Output = PathImage & "Skins/Steve.png"
Case 2 'Alex
Data.Output = PathImage & "Skins/Alex.png"
Case 3 '正版
Dim ID As String = Data.Input(1)
Try
If ID.Count < 2 Then
Data.Output = PathImage & "Skins/Steve.png"
Else
Dim Result As String = McLoginMojangUuid(ID, True)
If Data.IsAborted Then Throw New ThreadInterruptedException("当前任务已取消:" & ID)
Result = McSkinGetAddress(Result, "Mojang")
If Data.IsAborted Then Throw New ThreadInterruptedException("当前任务已取消:" & ID)
Result = McSkinDownload(Result)
If Data.IsAborted Then Throw New ThreadInterruptedException("当前任务已取消:" & ID)
Data.Output = Result
End If
Catch ex As Exception
If ex.GetType.Name = "ThreadInterruptedException" Then
Data.Output = ""
Exit Sub
ElseIf GetString(ex).Contains("429") Then
Data.Output = PathImage & "Skins/" & McSkinSex(McLoginLegacyUuid(ID)) & ".png"
Log("获取离线登录使用的正版皮肤失败(" & ID & "):获取皮肤太过频繁,请 5 分钟后再试!")
Else
Data.Output = PathImage & "Skins/" & McSkinSex(McLoginLegacyUuid(ID)) & ".png"
Log(ex, "获取离线登录使用的正版皮肤失败(" & ID & ")")
End If
End Try
Case 4 '自定义
If Not File.Exists(PathTemp & "CustomSkin.png") Then
Hint("未找到离线皮肤自定义文件,可能它已被删除。PCL2 将使用默认的 Steve 皮肤!")
Setup.Set("LaunchSkinType", 1)
GoTo UseDefault
End If
Data.Output = PathTemp & "CustomSkin.png"
End Select
'刷新显示
If FrmLoginLegacy IsNot Nothing Then
RunInUi(AddressOf FrmLoginLegacy.Skin.Load)
ElseIf Not Data.IsAborted Then '如果已经中断,Input 也被清空,就不会再次刷新
Data.Input = Nothing '清空输入,因为皮肤实际上没有被渲染,如果不清空切换到页面的 Start 会由于输入相同而不渲染
End If
End Sub
'统一通行证皮肤
Public Shared SkinNide As New LoaderTask(Of EqualableList(Of String), String)("Loader Skin Nide", AddressOf SkinNideLoad, AddressOf SkinNideInput, ThreadPriority.AboveNormal)
Private Shared Function SkinNideInput() As EqualableList(Of String)
'获取名称
Return New EqualableList(Of String) From {Setup.Get("CacheNideName"), Setup.Get("CacheNideUuid")}
End Function
Private Shared Sub SkinNideLoad(Data As LoaderTask(Of EqualableList(Of String), String))
'清空已有皮肤
'如果在输入时清空皮肤,若输入内容一样则不会执行 Load 方法,导致皮肤不被加载
RunInUi(Sub() If FrmLoginNideSkin IsNot Nothing AndAlso FrmLoginNideSkin.Skin IsNot Nothing Then FrmLoginNideSkin.Skin.Clear())
'获取 Url
Dim UserName As String = Data.Input(0)
Dim Uuid As String = Data.Input(1)
If UserName = "" Then
Data.Output = PathImage & "Skins/" & McSkinSex(McLoginLegacyUuid(UserName)) & ".png"
Log("[Minecraft] 获取统一通行证皮肤失败,ID 为空")
GoTo Finish
End If
Try
Dim Result As String = McSkinGetAddress(Uuid, "Nide")
If Data.IsAborted Then Throw New ThreadInterruptedException("当前任务已取消:" & UserName)
Result = McSkinDownload(Result)
If Data.IsAborted Then Throw New ThreadInterruptedException("当前任务已取消:" & UserName)
Data.Output = Result
Catch ex As Exception
If ex.GetType.Name = "ThreadInterruptedException" Then
Data.Output = ""
Exit Sub
ElseIf GetString(ex).Contains("429") Then
Data.Output = PathImage & "Skins/Steve.png"
Log("[Minecraft] 获取统一通行证皮肤失败(" & UserName & "):获取皮肤太过频繁,请 5 分钟后再试!", LogLevel.Hint)
ElseIf GetString(ex).Contains("未设置自定义皮肤") Then
Data.Output = PathImage & "Skins/Steve.png"
Log("[Minecraft] 用户未设置自定义皮肤,跳过皮肤加载")
Else
Data.Output = PathImage & "Skins/Steve.png"
Log(ex, "获取统一通行证皮肤失败(" & UserName & ")", LogLevel.Hint)
End If
End Try
Finish:
'刷新显示
If FrmLoginNideSkin IsNot Nothing Then
RunInUi(AddressOf FrmLoginNideSkin.Skin.Load)
ElseIf Not Data.IsAborted Then '如果已经中断,Input 也被清空,就不会再次刷新
Data.Input = Nothing '清空输入,因为皮肤实际上没有被渲染,如果不清空切换到页面的 Start 会由于输入相同而不渲染
End If
End Sub
'Authlib-Injector 皮肤
Public Shared SkinAuth As New LoaderTask(Of EqualableList(Of String), String)("Loader Skin Auth", AddressOf SkinAuthLoad, AddressOf SkinAuthInput, ThreadPriority.AboveNormal)
Private Shared Function SkinAuthInput() As EqualableList(Of String)
'获取名称
Return New EqualableList(Of String) From {Setup.Get("CacheAuthName"), Setup.Get("CacheAuthUuid")}
End Function
Private Shared Sub SkinAuthLoad(Data As LoaderTask(Of EqualableList(Of String), String))
'清空已有皮肤
'如果在输入时清空皮肤,若输入内容一样则不会执行 Load 方法,导致皮肤不被加载
RunInUi(Sub() If FrmLoginAuthSkin IsNot Nothing AndAlso FrmLoginAuthSkin.Skin IsNot Nothing Then FrmLoginAuthSkin.Skin.Clear())
'获取 Url
Dim UserName As String = Data.Input(0)
Dim Uuid As String = Data.Input(1)
If UserName = "" Then
Data.Output = PathImage & "Skins/Steve.png"
Log("[Minecraft] 获取 Authlib-Injector 皮肤失败,ID 为空")
GoTo Finish
End If
Try
Dim Result As String = McSkinGetAddress(Uuid, "Auth")
If Data.IsAborted Then Throw New ThreadInterruptedException("当前任务已取消:" & UserName)
Result = McSkinDownload(Result)
If Data.IsAborted Then Throw New ThreadInterruptedException("当前任务已取消:" & UserName)
Data.Output = Result
Catch ex As Exception
If ex.GetType.Name = "ThreadInterruptedException" Then
Data.Output = ""
Exit Sub
ElseIf GetString(ex).Contains("429") Then
Data.Output = PathImage & "Skins/Steve.png"
Log("[Minecraft] 获取 Authlib-Injector 皮肤失败(" & UserName & "):获取皮肤太过频繁,请 5 分钟后再试!", LogLevel.Hint)
ElseIf GetString(ex).Contains("未设置自定义皮肤") Then
Data.Output = PathImage & "Skins/Steve.png"
Log("[Minecraft] 用户未设置自定义皮肤,跳过皮肤加载")
Else
Data.Output = PathImage & "Skins/Steve.png"
Log(ex, "获取 Authlib-Injector 皮肤失败(" & UserName & ")", LogLevel.Hint)
End If
End Try
Finish:
'刷新显示
If FrmLoginAuthSkin IsNot Nothing Then
RunInUi(AddressOf FrmLoginAuthSkin.Skin.Load)
ElseIf Not Data.IsAborted Then '如果已经中断,Input 也被清空,就不会再次刷新
Data.Input = Nothing '清空输入,因为皮肤实际上没有被渲染,如果不清空切换到页面的 Start 会由于输入相同而不渲染
End If
End Sub
'全部皮肤加载器
'需要放在其中元素的后面,否则会因为它提前被加载而莫名其妙变成 Nothing
Public Shared SkinLoaders As New List(Of LoaderTask(Of EqualableList(Of String), String)) From {SkinMojang, SkinMs, SkinLegacy, SkinNide, SkinAuth}
#End Region
'版本选择按钮
Private Sub BtnVersion_Click(sender As Object, e As EventArgs) Handles BtnVersion.Click
FrmMain.PageChange(FormMain.PageType.VersionSelect)
End Sub
'启动按钮
Private Sub BtnLaunch_Click() Handles BtnLaunch.Click
LaunchButtonClick()
End Sub
Public Sub LaunchButtonClick(Optional ServerIp As String = "")
If BtnLaunch.IsEnabled AndAlso BtnLaunch.Visibility = Visibility.Visible AndAlso BtnLaunch.IsHitTestVisible Then
If BtnLaunch.Text = "启动游戏" Then
McLaunchLoader.Start(ServerIp)
ElseIf BtnLaunch.Text = "下载游戏" Then
FrmMain.PageChange(FormMain.PageType.Download, FormMain.PageSubType.DownloadInstall)
End If
'愚人节处理
If IsAprilEnabled AndAlso Not IsAprilGiveup Then
ThemeUnlock(12, False, "隐藏主题 滑稽彩 已解锁!")
IsAprilGiveup = True
FrmLaunchLeft.AprilScaleTrans.ScaleX = 1
FrmLaunchLeft.AprilScaleTrans.ScaleY = 1
FrmLaunchLeft.AprilPosTrans.X = 0
FrmLaunchLeft.AprilPosTrans.Y = 0
FrmMain.BtnExtraApril.ShowRefresh()
End If
End If
End Sub
Private BtnLaunchState As Integer = 0
Private BtnLaunchVersion As McVersion = Nothing
Public Sub RefreshButtonsUI() Handles BtnLaunch.Loaded
If Not BtnLaunch.IsLoaded Then Exit Sub
'获取当前状态
Dim CurrentState As Integer
If (Not IsLoadFinished) OrElse McVersionListLoader.State = LoadState.Loading OrElse McFolderListLoader.State = LoadState.Loading Then
CurrentState = 0
Else
If McVersionCurrent Is Nothing Then
If Setup.Get("UiHiddenPageDownload") AndAlso Not PageSetupUI.HiddenForceShow Then
CurrentState = 1
Else
CurrentState = 2
End If
Else
CurrentState = 3
End If
End If
'更新状态
If CurrentState = BtnLaunchState AndAlso
If(McVersionCurrent Is Nothing, "", McVersionCurrent.Path) = If(BtnLaunchVersion Is Nothing, "", BtnLaunchVersion.Path) Then GoTo ExitRefresh
BtnLaunchVersion = McVersionCurrent
BtnLaunchState = CurrentState
Select Case CurrentState
Case 0
Log("[Minecraft] 启动按钮:正在加载 Minecraft 版本")
FrmLaunchLeft.BtnLaunch.Text = "正在加载"
FrmLaunchLeft.BtnLaunch.IsEnabled = False
FrmLaunchLeft.LabVersion.Text = "正在加载版本列表,请稍候"
FrmLaunchLeft.BtnVersion.IsEnabled = False
FrmLaunchLeft.BtnMore.Visibility = Visibility.Collapsed
Case 1
Log("[Minecraft] 启动按钮:无 Minecraft 版本,下载已禁用")
FrmLaunchLeft.BtnLaunch.Text = "启动游戏"
FrmLaunchLeft.BtnLaunch.IsEnabled = False
FrmLaunchLeft.LabVersion.Text = "未找到可用的游戏版本"
FrmLaunchLeft.BtnVersion.IsEnabled = True
FrmLaunchLeft.BtnMore.Visibility = Visibility.Collapsed
Case 2
Log("[Minecraft] 启动按钮:无 Minecraft 版本,要求下载")
FrmLaunchLeft.BtnLaunch.Text = "下载游戏"
FrmLaunchLeft.BtnLaunch.IsEnabled = True
FrmLaunchLeft.LabVersion.Text = "未找到可用的游戏版本"
FrmLaunchLeft.BtnVersion.IsEnabled = True
FrmLaunchLeft.BtnMore.Visibility = Visibility.Collapsed
Case 3
Log("[Minecraft] 启动按钮:Minecraft 版本:" & McVersionCurrent.Path)
FrmLaunchLeft.BtnLaunch.Text = "启动游戏"
FrmLaunchLeft.BtnVersion.IsEnabled = True
FrmLaunchLeft.BtnLaunch.IsEnabled = True
FrmLaunchLeft.LabVersion.Text = McVersionCurrent.Name
'FrmLaunchLeft.BtnMore.Visibility = Visibility.Visible '由功能隐藏设置修改
End Select
ExitRefresh:
'功能隐藏
FrmLaunchLeft.BtnVersion.Visibility = If(Not PageSetupUI.HiddenForceShow AndAlso Setup.Get("UiHiddenFunctionSelect"), Visibility.Collapsed, Visibility.Visible)
If CurrentState = 3 Then
FrmLaunchLeft.BtnMore.Visibility = FrmLaunchLeft.BtnVersion.Visibility
End If
End Sub
'取消按钮
Private Sub BtnCancel_Click() Handles BtnCancel.Click
If McLaunchLoaderReal IsNot Nothing Then
McLaunchLoaderReal.Abort()
McLaunchLog("已取消启动")
Try
If McLaunchWatcher IsNot Nothing Then
McLaunchWatcher.Kill()
ElseIf McLaunchProcess IsNot Nothing Then
If Not McLaunchProcess.HasExited Then McLaunchProcess.Kill()
End If
Catch ex As Exception
Log(ex, "取消启动结束进程失败", LogLevel.Hint)
End Try
End If
End Sub
'更多按钮
Private Sub BtnMore_Click(sender As Object, e As EventArgs) Handles BtnMore.Click
McVersionCurrent.Load()
PageVersionLeft.Version = McVersionCurrent
FrmMain.PageChange(FormMain.PageType.VersionSetup, 0)
End Sub
'刷新 UI
Public Sub LaunchingPreload()
'修改登陆方式
Select Case Setup.Get("LoginType")
Case McLoginType.Legacy
LabLaunchingMethod.Text = "离线登录"
Case McLoginType.Mojang
LabLaunchingMethod.Text = "Mojang 正版登录"
Case McLoginType.Ms
LabLaunchingMethod.Text = "微软正版登录"
Case McLoginType.Nide
LabLaunchingMethod.Text = "统一通行证"
Case McLoginType.Auth
LabLaunchingMethod.Text = "Authlib-Injector"
End Select
'初始化页面
LabLaunchingName.Text = McVersionCurrent.Name
LabLaunchingStage.Text = "初始化"
LabLaunchingTitle.Text = "正在启动游戏"
LabLaunchingProgress.Text = "0.00 %"
LabLaunchingProgress.Opacity = 1
LabLaunchingDownload.Visibility = Visibility.Visible
LabLaunchingProgressLeft.Opacity = 0.6
LabLaunchingDownload.Visibility = Visibility.Visible
LabLaunchingDownload.Text = "0 B/s"
LabLaunchingDownload.Opacity = 0
LabLaunchingDownload.Visibility = Visibility.Collapsed
LabLaunchingDownloadLeft.Opacity = 0
LabLaunchingDownloadLeft.Visibility = Visibility.Collapsed
ProgressLaunchingFinished.Width = New GridLength(0, GridUnitType.Star)
ProgressLaunchingUnfinished.Width = New GridLength(1, GridUnitType.Star)
PanLaunchingHint.Opacity = 0
PanLaunchingHint.Visibility = Visibility.Collapsed
PanLaunchingInfo.Width = Double.NaN '重置宽度改变动画
McLaunchProcess = Nothing
McLaunchWatcher = Nothing
'获取 “你知道吗” 提示
Dim Hint As String = PageOtherTest.GetRandomHint()
Try
Dim RawHints = Array.FindAll(
ReadFile(Path & "PCL\hints.txt").Replace(vbLf, "").Split(vbCr),
Function(Input As String) As Boolean
Return Not String.IsNullOrWhiteSpace(Input)
End Function)
If RawHints.Count > 0 Then Hint = RandomOne(RawHints)
Catch ex As Exception
Log(ex, "获取自定义 你知道吗 提示失败", LogLevel.Hint)
End Try
LabLaunchingHint.Text = Hint
End Sub
Private ShowProgress As Double = 0
''' <summary>
''' 每 0.2s 执行一次,刷新启动的数据 UI 显示。
''' </summary>
Public Sub LaunchingRefresh()
Try
If McLaunchLoaderReal.State = LoadState.Aborted Then Exit Sub
'阶段状态获取
Dim IsLaunched As Boolean = False '是否已经启动游戏,只是在等待窗口
Try
For Each Loader In McLaunchLoaderReal.GetLoaderList(False)
If Loader.State = LoadState.Loading OrElse Loader.State = LoadState.Waiting Then
LabLaunchingStage.Text = Loader.Name
IsLaunched = Loader.Name = "等待游戏窗口出现" OrElse Loader.Name = "结束处理"
Exit Try
End If
Next
LabLaunchingStage.Text = "已完成"
Catch ex As Exception
Log(ex, "获取是否启动完成失败,可能是由于启动状态改变导致集合已修改")
Exit Sub
End Try
If AniIsRun("Launch State Page") Then IsLaunched = False '等待页面切换动画完成
'计算应显示的进度
Dim ActualProgress = McLaunchLoaderReal.Progress
If ActualProgress >= ShowProgress Then ShowProgress += (ActualProgress - ShowProgress) * 0.2 + 0.005 '向实际进度靠一点
If ActualProgress <= ShowProgress Then ShowProgress = ActualProgress '原来或处理后变得比实际进度高,直接回退
If IsLaunched Then ShowProgress = 1 '如果已经完成了,就不卖关子了
'文本
LabLaunchingTitle.Text = If(IsLaunched, "已启动游戏", "正在启动游戏")
LabLaunchingProgress.Text = StrFillNum(ShowProgress * 100, 2) & " %"
Dim HasLaunchDownloader As Boolean = False
Try
For Each Loader In NetManager.Tasks
If Loader.RealParent IsNot Nothing AndAlso Loader.RealParent.Name = "Minecraft 启动" AndAlso Loader.State = LoadState.Loading Then HasLaunchDownloader = True
Next
Catch ex As Exception
Log(ex, "获取 Minecraft 启动下载器失败,可能是因为启动被取消")
HasLaunchDownloader = False
End Try
LabLaunchingDownload.Text = GetString(NetManager.Speed) & "/s"
'进度改变动画
Dim AnimList As New List(Of AniData) From {
AaGridLengthWidth(ProgressLaunchingFinished, ShowProgress - ProgressLaunchingFinished.Width.Value, 260,, New AniEaseOutFluent),
AaGridLengthWidth(ProgressLaunchingUnfinished, 1 - ShowProgress - ProgressLaunchingUnfinished.Width.Value, 260,, New AniEaseOutFluent)
}
Dim IsDownloadStateChanged As Boolean = HasLaunchDownloader = (LabLaunchingDownload.Visibility = Visibility.Collapsed)
If IsDownloadStateChanged Then
LabLaunchingDownload.Visibility = Visibility.Visible
LabLaunchingDownloadLeft.Visibility = Visibility.Visible
AnimList.AddRange({
AaOpacity(LabLaunchingDownload, If(HasLaunchDownloader, 1, 0) - LabLaunchingDownload.Opacity, 100),
AaOpacity(LabLaunchingDownloadLeft, If(HasLaunchDownloader, 0.5, 0) - LabLaunchingDownloadLeft.Opacity, 100),
AaCode(Sub()
If Not HasLaunchDownloader Then
LabLaunchingDownload.Visibility = Visibility.Collapsed
LabLaunchingDownloadLeft.Visibility = Visibility.Collapsed
End If
End Sub, 110)
})
End If
Dim IsProgressStateChanged As Boolean = (Not IsLaunched) = (LabLaunchingProgress.Visibility = Visibility.Collapsed)
If IsProgressStateChanged Then
LabLaunchingProgress.Visibility = Visibility.Visible
LabLaunchingProgressLeft.Visibility = Visibility.Visible
If IsLaunched Then
'IsWidthAnimating = True
PanLaunchingHint.Visibility = Visibility.Visible
'AniStop("Launching Info Width")
'PanLaunchingInfo.Width = 260
'ActualUsedWidth = 260
'IsWidthAnimating = False
End If
AnimList.AddRange({
AaOpacity(LabLaunchingProgress, If(Not IsLaunched, 1, 0) - LabLaunchingProgress.Opacity, 100),
AaOpacity(LabLaunchingProgressLeft, If(Not IsLaunched, 0.5, 0) - LabLaunchingProgressLeft.Opacity, 100),
AaOpacity(PanLaunchingHint, If(IsLaunched, 1, 0) - PanLaunchingHint.Opacity, 100)
})
End If
AniStart(AnimList, "Launching Progress")
Catch ex As Exception
Log(ex, "刷新启动信息失败", LogLevel.Feedback)
End Try
End Sub
'尺寸改变动画
Private IsWidthAnimating As Boolean = False
Private ActualUsedWidth As Double
Private Sub PanLaunchingInfo_SizeChangedW(sender As Object, e As SizeChangedEventArgs) Handles PanLaunchingInfo.SizeChanged
Dim DeltaWidth As Double = e.NewSize.Width - e.PreviousSize.Width
If e.PreviousSize.Width = 0 OrElse IsWidthAnimating OrElse Math.Abs(DeltaWidth) < 1 OrElse PanLaunchingInfo.ActualWidth = 0 Then Exit Sub
AniStart({
AaWidth(PanLaunchingInfo, DeltaWidth, 180,, New AniEaseOutFluent),
AaCode(Sub()
IsWidthAnimating = False
PanLaunchingInfo.Width = ActualUsedWidth
End Sub,, True)
}, "Launching Info Width")
IsWidthAnimating = True
ActualUsedWidth = PanLaunchingInfo.Width
PanLaunchingInfo.Width = e.PreviousSize.Width
End Sub
Private IsHeightAnimating As Boolean = False
Private ActualUsedHeight As Double
Private Sub PanLaunchingInfo_SizeChangedH(sender As Object, e As SizeChangedEventArgs) Handles PanLaunchingInfo.SizeChanged
Dim DeltaHeight As Double = e.NewSize.Height - e.PreviousSize.Height
If e.PreviousSize.Height = 0 OrElse IsHeightAnimating OrElse Math.Abs(DeltaHeight) < 1 OrElse PanLaunchingInfo.ActualHeight = 0 Then Exit Sub
AniStart({
AaHeight(PanLaunchingInfo, DeltaHeight, 180,, New AniEaseOutFluent),
AaCode(Sub()
IsHeightAnimating = False
PanLaunchingInfo.Height = ActualUsedHeight
End Sub,, True)
}, "Launching Info Height")
IsHeightAnimating = True
ActualUsedHeight = PanLaunchingInfo.Height
PanLaunchingInfo.Height = e.PreviousSize.Height
End Sub
End Class
@@ -0,0 +1,37 @@
<local:MyPageRight x:Class="PageLaunchRight"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:PCL"
mc:Ignorable="d">
<local:MyScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" x:Name="PanBack">
<StackPanel Name="PanMain" Margin="25,25,25,10" Grid.IsSharedSizeScope="True">
<StackPanel x:Name="PanCustom">
</StackPanel>
<local:MyCard Margin="0,0,0,15" Title="请立即迁移到微软账号!" x:Name="PanMs" Visibility="Collapsed" CanSwap="True" IsSwaped="True">
<StackPanel Margin="25,37,20,14">
<TextBlock TextWrapping="Wrap" Text="为了提高账户安全性,你必须将 Mojang 账号迁移到微软账号上,否则将无法进入正版服务器!" Margin="0,0,0,2" />
<TextBlock TextWrapping="Wrap" Text="在完成迁移后,你需要将左侧的登录方式从 Mojang 改为 微软,才能继续登录。此外,你还会获得一件披风作为奖励!" Margin="0,0,0,2" />
<Grid Height="35" Margin="0,10,0,4">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
</Grid.ColumnDefinitions>
<local:MyButton x:Name="BtnMsStart" Grid.Column="0" MinWidth="140" Text="开始迁移" Padding="13,0" Margin="0,0,20,0" HorizontalAlignment="Left" ColorType="Highlight" />
<local:MyButton x:Name="BtnMsFaq" Grid.Column="1" MinWidth="140" Text="迁移常见问题" Padding="13,0" HorizontalAlignment="Left" />
</Grid>
</StackPanel>
</local:MyCard>
<local:MyCard Margin="0,0,0,15" Title="快照版提示" x:Name="PanHint">
<StackPanel Margin="25,40,23,12">
<TextBlock x:Name="LabHint1" TextWrapping="Wrap" Margin="0,0,0,2" />
<TextBlock x:Name="LabHint2" TextWrapping="Wrap" Margin="0,0,0,2" />
</StackPanel>
</local:MyCard>
<local:MyCard Margin="0,0,0,15" Title="启动日志" x:Name="PanLog">
<TextBlock x:Name="LabLog" Margin="20,38,20,18" TextTrimming="None" TextWrapping="Wrap" />
</local:MyCard>
</StackPanel>
</local:MyScrollViewer>
</local:MyPageRight>
@@ -0,0 +1,110 @@
Public Class PageLaunchRight
Private Sub Init() Handles Me.Loaded
PanBack.ScrollToHome()
PanLog.Visibility = If(ModeDebug, Visibility.Visible, Visibility.Collapsed)
'刷新主页
If ShouldRefresh Then
ShouldRefresh = False
RefreshCustom()
End If
'快照版提示
#If BETA Then
PanHint.Visibility = Visibility.Collapsed
#Else
PanHint.Title = "快照版提示"
PanHint.Visibility = If(ThemeCheckGold(), Visibility.Collapsed, Visibility.Visible)
LabHint1.Text = "快照版包含尚未在正式版发布的测试性功能,仅用于赞助者本人尝鲜。所以请不要发给其他人或者用于制作整合包哦!如果发现了 Bug,可以在 更多 → 反馈 中提交!"
LabHint2.Text = "你可以通过赞助¥23.33 档位换取解锁码来隐藏这个提示。"
#End If
End Sub
Private LatestFileContent As String = ""
Private LatestFileLink As String = Nothing
Private IsRefreshing As Boolean = False
Public ShouldRefresh As Boolean = True
''' <summary>
''' 刷新自定义的主页。返回是否成功。
''' </summary>
Private Sub RefreshCustom()
If IsRefreshing Then
ShouldRefresh = True
Exit Sub
End If
Try
IsRefreshing = True
PanCustom.Children.Clear()
RunInNewThread(Sub()
Dim FileContent As String = ""
Select Case Setup.Get("UiCustomType")
Case 0
'啥也不干
Case 1
'加载本地文件
FileContent = ReadFile(Path & "PCL\Custom.xaml") 'ReadFile 会进行存在检测
Log("[System] 尝试从本地文件读取主页自定义数据(" & FileContent.Length & ")")
Case 2
'加载联网文件
Try
Dim Link As String = Setup.Get("UiCustomNet")
If Link = LatestFileLink Then
FileContent = LatestFileContent
Log("[System] 尝试缓存加载主页自定义数据(" & FileContent.Length & ")")
ElseIf Not String.IsNullOrWhiteSpace(Link) Then
Log("[System] 开始从网络读取主页自定义数据(" & Link & ")")
FileContent = NetGetCodeByRequestRetry(Link)
Log("[System] 尝试从网络读取主页自定义数据(" & FileContent.Length & ")")
End If
LatestFileLink = Link
LatestFileContent = FileContent
Catch ex As Exception
Log(ex, "获取 PCL2 主页自定义信息失败", LogLevel.Msgbox)
LatestFileLink = ""
End Try
End Select
If FileContent = "" Then
IsRefreshing = False
Exit Sub
End If
FileContent = "<StackPanel xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"" xmlns:local=""clr-namespace:PCL;assembly=Plain Craft Launcher 2"">" & FileContent & "</StackPanel>"
FileContent = FileContent.Replace("{path}", Path)
RunInUi(Sub()
Try
Log("[System] 加载主页自定义数据")
PanCustom.Children.Add(GetObjectFromXML(FileContent))
IsRefreshing = False
Catch ex As Exception
IsRefreshing = False
Log("[System] 自定义信息内容:" & vbCrLf & FileContent)
If MyMsgBox(ex.Message, "加载自定义主页失败", "重试", "取消") = 1 Then
LatestFileLink = Nothing
LatestFileContent = ""
RefreshCustom()
End If
End Try
End Sub)
End Sub, "主页自定义刷新")
Catch ex As Exception
Log(ex, "加载 PCL2 主页自定义信息失败", LogLevel.Msgbox)
IsRefreshing = False
End Try
End Sub
Public Sub ForceRefresh(Optional ShowHint As Boolean = True)
ShouldRefresh = True
LatestFileContent = ""
LatestFileLink = Nothing
If ShowHint Then Hint("已刷新主页!", HintType.Finish)
FrmMain.PageChange(FormMain.PageType.Launch)
Init()
End Sub
Private Sub BtnMsStart_Click() Handles BtnMsStart.Click
MyMsgBox("在迁移过程中,你可能需要设置你的档案信息。" & vbCrLf & "在输入年龄或生日时,请注意让你的年龄大于 18 岁,否则可能导致无法登录!", "迁移提示", "继续", ForceWait:=True)
OpenWebsite("https://www.minecraft.net/zh-hans/account-security")
End Sub
Private Sub BtnMsFaq_Click() Handles BtnMsFaq.Click
OpenWebsite("https://www.mcbbs.net/thread-1252431-1-1.html")
End Sub
End Class
@@ -0,0 +1,24 @@
<Grid x:Class="PageLoginAuth" Tag="False"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:PCL"
mc:Ignorable="d" d:DesignWidth="317.6" Margin="0,0,0,-2">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="10" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="224" />
</Grid.ColumnDefinitions>
<local:MyComboBox Grid.Row="0" Grid.Column="1" IsEditable="True" Height="28" x:Name="ComboName" />
<TextBlock Text="邮箱" Grid.Row="0" VerticalAlignment="Center" />
<PasswordBox Grid.Row="2" Grid.Column="1" x:Name="TextPass" />
<TextBlock Text="密码" Grid.Row="2" VerticalAlignment="Center" />
<local:MyCheckBox x:Name="CheckRemember" Tag="LoginRemember" Height="20" Margin="-1,12,80,0" Text="记住密码" Grid.Row="3" Grid.Column="1" Grid.ColumnSpan="2" />
<local:MyTextButton Margin="0,12,2,0" x:Name="BtnLink" Content="注册账号" Grid.Row="3" HorizontalAlignment="Right" Grid.Column="1" Padding="20,0,0,0" HorizontalContentAlignment="Right" FontSize="13" VerticalContentAlignment="Center" />
</Grid>
@@ -0,0 +1,86 @@
Public Class PageLoginAuth
Private IsFirstLoad As Boolean = True
''' <summary>
''' 刷新页面显示的所有信息。
''' </summary>
Public Sub Reload(KeepInput As Boolean)
'记住密码
CheckRemember.Checked = Setup.Get("LoginRemember")
If KeepInput AndAlso Not IsFirstLoad Then '避免第一次就以 KeepInput 的方式加载,导致文本框里没东西
'保留输入,只刷新下拉框列表
Dim Input As String = ComboName.Text
ComboName.ItemsSource = If(Setup.Get("LoginAuthEmail") = "", Nothing, Setup.Get("LoginAuthEmail").ToString.Split("¨"))
ComboName.Text = Input
Else
'不保留输入,刷新列表后自动选择第一项
If Setup.Get("LoginAuthEmail") = "" Then
ComboName.ItemsSource = Nothing
Else
ComboName.ItemsSource = Setup.Get("LoginAuthEmail").ToString.Split("¨")
ComboName.Text = Setup.Get("LoginAuthEmail").ToString.Split("¨")(0)
If Setup.Get("LoginRemember") Then TextPass.Password = Setup.Get("LoginAuthPass").ToString.Split("¨")(0).Trim
End If
End If
IsFirstLoad = False
End Sub
''' <summary>
''' 获取当前页面的登录信息。
''' </summary>
Public Shared Function GetLoginData() As McLoginServer
Dim Server As String = If(IsNothing(McVersionCurrent), Setup.Get("CacheAuthServerServer"), Setup.Get("VersionServerAuthServer", Version:=McVersionCurrent)) & "/authserver"
If FrmLoginAuth Is Nothing Then
Return New McLoginServer(McLoginType.Auth) With {.Token = "Auth", .BaseUrl = Server, .UserName = "", .Password = "", .Description = "Authlib-Injector", .Type = McLoginType.Auth}
Else
Return New McLoginServer(McLoginType.Auth) With {.Token = "Auth", .BaseUrl = Server, .UserName = FrmLoginAuth.ComboName.Text.Replace("¨", "").Trim, .Password = FrmLoginAuth.TextPass.Password.Replace("¨", "").Trim, .Description = "Authlib-Injector", .Type = McLoginType.Auth}
End If
End Function
''' <summary>
''' 当前页面的登录信息是否有效。
''' </summary>
Public Shared Function IsVaild(LoginData As McLoginServer) As String
If LoginData.UserName = "" Then Return "账号不能为空!"
If LoginData.Password = "" Then Return "密码不能为空!"
Return ""
End Function
Public Function IsVaild() As String
Return IsVaild(GetLoginData())
End Function
'保存输入信息
Private Sub ComboName_TextChanged(sender As Object, e As TextChangedEventArgs) Handles ComboName.TextChanged
If sender.Text = "" Then TextPass.Password = ""
If AniControlEnabled = 0 Then Setup.Set("CacheAuthAccess", "") '迫使其不进行 Validate
End Sub
Private Sub TextPass_PasswordChanged(sender As Object, e As RoutedEventArgs) Handles TextPass.PasswordChanged
If AniControlEnabled = 0 Then Setup.Set("CacheAuthAccess", "")
End Sub
Private Sub ComboName_SelectionChanged(sender As MyComboBox, e As SelectionChangedEventArgs) Handles ComboName.SelectionChanged
If sender.SelectedIndex = -1 OrElse Not Setup.Get("LoginRemember") Then
TextPass.Password = ""
Else
TextPass.Password = Setup.Get("LoginAuthPass").ToString.Split("¨")(sender.SelectedIndex).Trim
End If
End Sub
Private Sub CheckBoxChange(sender As MyCheckBox, e As Object) Handles CheckRemember.Change
If AniControlEnabled = 0 Then Setup.Set(sender.Tag, sender.Checked)
End Sub
'链接处理
Private Sub ComboName_TextChanged() Handles ComboName.TextChanged
BtnLink.Content = If(ComboName.Text = "", "注册账号", "找回密码")
End Sub
Private Sub Btn_Click(sender As Object, e As EventArgs) Handles BtnLink.Click
If BtnLink.Content = "注册账号" Then
OpenWebsite(If(McVersionCurrent Is Nothing, Setup.Get("VersionServerAuthRegister", Version:=McVersionCurrent), Setup.Get("CacheAuthServerRegister")))
Else
Dim Website As String = If(McVersionCurrent Is Nothing, Setup.Get("VersionServerAuthRegister", Version:=McVersionCurrent), Setup.Get("CacheAuthServerRegister"))
OpenWebsite(Website.Replace("/auth/register", "/auth/forgot"))
End If
End Sub
'切换注册按钮可见性
Private Sub ReloadRegisterButton() Handles Me.Loaded
Dim Address As String = If(McVersionCurrent IsNot Nothing, Setup.Get("VersionServerAuthRegister", Version:=McVersionCurrent), Setup.Get("CacheAuthServerRegister"))
BtnLink.Visibility = If(String.IsNullOrEmpty(New ValidateHttp().Validate(Address)), Visibility.Visible, Visibility.Collapsed)
End Sub
End Class
@@ -0,0 +1,27 @@
<Grid x:Class="PageLoginAuthSkin" Tag="True"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:PCL"
mc:Ignorable="d" d:DesignWidth="297.6" Margin="0,19,0,5">
<Grid Margin="0,56,0,0" Background="{StaticResource ColorBrushSemiTransparent}" Name="PanData">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="34" />
<ColumnDefinition />
<ColumnDefinition Width="34" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="19" />
<RowDefinition Height="Auto" MinHeight="30" />
<RowDefinition Height="19" />
</Grid.RowDefinitions>
<StackPanel Grid.Column="1" Grid.Row="1" VerticalAlignment="Center">
<TextBlock Name="TextName" Text="加载中" Margin="8,0" FontSize="14" HorizontalAlignment="Center" TextTrimming="CharacterEllipsis" />
<TextBlock Name="TextEmail" Text="加载中" Margin="8,4,8,0" FontSize="12" HorizontalAlignment="Center" TextTrimming="CharacterEllipsis" Foreground="{DynamicResource ColorBrushGray3}" />
</StackPanel>
<local:MyIconButton ToolTip="更换角色" Grid.Row="1" Height="14" Opacity="0" x:Name="BtnEdit" ToolTipService.Placement="Center" ToolTipService.VerticalOffset="32" ToolTipService.InitialShowDelay="50" ToolTipService.ShowDuration="1000000" Grid.Column="0" HorizontalAlignment="Center" Logo="F1 M 53.2929,21.2929L 54.7071,22.7071C 56.4645,24.4645 56.4645,27.3137 54.7071,29.0711L 52.2323,31.5459L 44.4541,23.7677L 46.9289,21.2929C 48.6863,19.5355 51.5355,19.5355 53.2929,21.2929 Z M 31.7262,52.052L 23.948,44.2738L 43.0399,25.182L 50.818,32.9601L 31.7262,52.052 Z M 23.2409,47.1023L 28.8977,52.7591L 21.0463,54.9537L 23.2409,47.1023 Z" Margin="8,0,0,0" VerticalAlignment="Center" />
<local:MyIconButton ToolTip="退出登录" Grid.Row="1" Height="14" Opacity="0" x:Name="BtnExit" ToolTipService.Placement="Center" ToolTipService.VerticalOffset="32" ToolTipService.InitialShowDelay="50" ToolTipService.ShowDuration="1000000" Grid.Column="2" HorizontalAlignment="Center" Logo="F1 M 51.0071,19.0027L 51.0071,27.0038L 48.0067,27.0038L 48.0067,22.0031L 25.0035,22.0031L 25.0035,54.0075L 48.0067,54.0075L 48.0067,49.0068L 51.0071,49.0068L 51.0071,57.008L 22.1698,57.008L 22.0031,19.0027L 51.0071,19.0027 Z M 30.0042,35.0049L 45.2563,35.0049L 37.005,28.0039L 47.0066,28.0039L 58.5082,38.0053L 47.0066,48.0067L 37.005,48.0067L 45.2563,41.0057L 30.0042,41.0057L 30.0042,35.0049 Z" Margin="0,0,8,0" VerticalAlignment="Center" />
</Grid>
<local:MySkin HorizontalAlignment="Center" VerticalAlignment="Top" x:Name="Skin" HasCape="False" />
</Grid>
@@ -0,0 +1,82 @@
Public Class PageLoginAuthSkin
Public Sub New()
InitializeComponent()
Skin.Loader = PageLaunchLeft.SkinAuth
End Sub
Private Sub PageLoginLegacy_Loaded() Handles Me.Loaded
Skin.Loader.Start()
End Sub
''' <summary>
''' 刷新页面显示的所有信息。
''' </summary>
Public Sub Reload(KeepInput As Boolean)
TextName.Text = Setup.Get("CacheAuthName")
TextEmail.Text = Setup.Get("CacheAuthUsername")
TextEmail.Visibility = If(Setup.Get("UiLauncherEmail"), Visibility.Collapsed, Visibility.Visible)
PageLoginLegacy_Loaded()
End Sub
''' <summary>
''' 获取当前页面的登录信息。
''' </summary>
Public Shared Function GetLoginData() As McLoginServer
Dim Server As String = If(IsNothing(McVersionCurrent), Setup.Get("CacheAuthServerServer"), Setup.Get("VersionServerAuthServer", Version:=McVersionCurrent)) & "/authserver"
Return New McLoginServer(McLoginType.Auth) With {.Token = "Auth", .BaseUrl = Server, .UserName = Setup.Get("CacheAuthUsername"), .Password = Setup.Get("CacheAuthPass"), .Description = "Authlib-Injector", .Type = McLoginType.Auth}
End Function
Private Sub PageLoginAuthSkin_MouseEnter(sender As Object, e As MouseEventArgs) Handles PanData.MouseEnter
AniStart({
AaOpacity(BtnEdit, 1 - BtnEdit.Opacity, 80),
AaHeight(BtnEdit, 25.5 - BtnEdit.Height, 140,, New AniEaseOutFluent),
AaHeight(BtnEdit, -1.5, 50, 140, New AniEaseInFluent),
AaOpacity(BtnExit, 1 - BtnExit.Opacity, 80),
AaHeight(BtnExit, 25.5 - BtnExit.Height, 140,, New AniEaseOutFluent),
AaHeight(BtnExit, -1.5, 50, 140, New AniEaseInFluent)
}, "PageLoginAuthSkin Button")
End Sub
Private Sub PageLoginAuthSkin_MouseLeave(sender As Object, e As MouseEventArgs) Handles PanData.MouseLeave
AniStart({
AaOpacity(BtnEdit, -BtnEdit.Opacity, 120,, New AniEaseOutFluent),
AaHeight(BtnEdit, 14 - BtnEdit.Height, 120,, New AniEaseInFluent),
AaOpacity(BtnExit, -BtnExit.Opacity, 120,, New AniEaseOutFluent),
AaHeight(BtnExit, 14 - BtnExit.Height, 120,, New AniEaseInFluent)
}, "PageLoginAuthSkin Button")
End Sub
Private Sub BtnEdit_Click(sender As Object, e As EventArgs) Handles BtnEdit.Click
If McLoginLoader.State = LoadState.Loading Then
Log("[Launch] 要求更换角色,但登录加载器繁忙", LogLevel.Debug)
If CType(McLoginLoader.Input, McLoginServer).ForceReselectProfile Then
Hint("正在尝试更换,请稍候!")
Exit Sub
Else
Hint("正在登录中,请稍后再更换角色!", HintType.Critical)
Exit Sub
End If
End If
Hint("正在尝试更换,请稍候!")
Setup.Set("CacheAuthUuid", "") '清空选择缓存
Setup.Set("CacheAuthName", "")
RunInThread(Sub()
Try
Dim Data As McLoginServer = GetLoginData()
Data.ForceReselectProfile = True
McLoginLoader.WaitForExit(Data, IsForceRestart:=True)
RunInUi(Sub() Reload(True))
Catch ex As Exception
Log(ex, "更换角色失败", LogLevel.Hint)
End Try
End Sub)
End Sub
Private Sub BtnExit_Click() Handles BtnExit.Click
Setup.Set("CacheAuthAccess", "")
FrmLaunchLeft.RefreshPage(False, True)
End Sub
Private Sub Skin_Click(sender As Object, e As MouseButtonEventArgs) Handles Skin.Click
Dim Address As String = If(McVersionCurrent IsNot Nothing, Setup.Get("VersionServerAuthRegister", Version:=McVersionCurrent), Setup.Get("CacheAuthServerRegister"))
If String.IsNullOrEmpty(New ValidateHttp().Validate(Address)) Then OpenWebsite(Address.Replace("/auth/register", "/user/closet"))
End Sub
End Class
@@ -0,0 +1,10 @@
<Grid x:Class="PageLoginLegacy" Tag="True"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:PCL"
mc:Ignorable="d" d:DesignWidth="297.6" Margin="0,0,0,5">
<local:MyComboBox Margin="0,84,0,0" IsEditable="True" x:Name="ComboName" Height="28" IsTextSearchEnabled="False" HintText="游戏用户名" />
<local:MySkin HorizontalAlignment="Center" VerticalAlignment="Top" x:Name="Skin" HasCape="False" />
</Grid>
@@ -0,0 +1,67 @@
Public Class PageLoginLegacy
Public Sub New()
InitializeComponent()
Skin.Loader = PageLaunchLeft.SkinLegacy
End Sub
Private Sub PageLoginLegacy_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
Skin.Loader.Start()
End Sub
Public IsReloaded As Boolean = False
''' <summary>
''' 刷新页面显示的所有信息。
''' </summary>
Public Sub Reload(KeepInput As Boolean)
If KeepInput AndAlso IsReloaded Then '避免第一次就以 KeepInput 的方式加载,导致文本框里没东西
'保留输入,只刷新下拉框列表
Dim Input As String = ComboName.Text
ComboName.ItemsSource = If(Setup.Get("LoginLegacyName") = "", Nothing, Setup.Get("LoginLegacyName").ToString.Split("¨"))
ComboName.Text = Input
Else
'不保留输入,刷新列表后自动选择第一项
If Setup.Get("LoginLegacyName") = "" Then
ComboName.ItemsSource = Nothing
Else
ComboName.ItemsSource = Setup.Get("LoginLegacyName").ToString.Split("¨")
ComboName.Text = Setup.Get("LoginLegacyName").ToString.Split("¨")(0)
End If
End If
IsReloaded = True
End Sub
''' <summary>
''' 获取当前页面的登录信息。
''' </summary>
Public Shared Function GetLoginData() As McLoginLegacy
If FrmLoginLegacy Is Nothing Then
Return New McLoginLegacy With {.UserName = "", .SkinType = Setup.Get("LaunchSkinType"), .SkinName = Setup.Get("LaunchSkinID")}
Else
Return New McLoginLegacy With {.UserName = FrmLoginLegacy.ComboName.Text.Replace("¨", "").Trim, .SkinType = Setup.Get("LaunchSkinType"), .SkinName = Setup.Get("LaunchSkinID")}
End If
End Function
''' <summary>
''' 当前页面的登录信息是否有效。
''' </summary>
Public Shared Function IsVaild(LoginData As McLoginLegacy) As String
If LoginData.UserName.Trim = "" Then Return "玩家名不能为空!"
If LoginData.UserName.Contains("""") Then Return "玩家名不能包含英文引号!"
Return ""
End Function
Public Function IsVaild() As String
Return IsVaild(GetLoginData())
End Function
Private Sub ComboLegacy_TextChanged(sender As Object, e As TextChangedEventArgs) Handles ComboName.TextChanged
If Setup.Get("LaunchSkinType") = 0 Then
PageLaunchLeft.SkinLegacy.Start(IsForceRestart:=True)
End If
End Sub
Private Sub Skin_Click() Handles Skin.Click
If (Setup.Get("UiHiddenPageSetup") OrElse Setup.Get("UiHiddenSetupLaunch")) AndAlso Not PageSetupUI.HiddenForceShow Then
Hint("启动设置已被禁用!", HintType.Critical)
Else
FrmMain.PageChange(FormMain.PageType.Setup, FormMain.PageSubType.SetupLaunch) '切换到皮肤设置页面
End If
End Sub
End Class
@@ -0,0 +1,24 @@
<Grid x:Class="PageLoginMojang" Tag="False"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:PCL"
mc:Ignorable="d" d:DesignWidth="302.4" Margin="0,0,0,-2">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="10" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="224" />
</Grid.ColumnDefinitions>
<local:MyComboBox Grid.Row="0" Grid.Column="1" IsEditable="True" Height="28" x:Name="ComboName" />
<TextBlock Text="邮箱" VerticalAlignment="Center" />
<PasswordBox Grid.Row="2" Grid.Column="1" x:Name="TextPass" />
<TextBlock Text="密码" Grid.Row="2" VerticalAlignment="Center" />
<local:MyCheckBox x:Name="CheckRemember" Tag="LoginRemember" Height="20" Margin="-1,12,80,0" Text="记住密码" Grid.Row="3" Grid.Column="1" Grid.ColumnSpan="2" />
<local:MyTextButton Margin="0,12,2,0" x:Name="BtnLink" Content="购买正版" Grid.Row="3" HorizontalAlignment="Right" Grid.Column="1" Padding="20,0,0,0" HorizontalContentAlignment="Right" VerticalContentAlignment="Center" FontSize="13" />
</Grid>
@@ -0,0 +1,81 @@
Public Class PageLoginMojang
Private IsFirstLoad As Boolean = True
''' <summary>
''' 刷新页面显示的所有信息。
''' </summary>
Public Sub Reload(KeepInput As Boolean)
'记住密码
CheckRemember.Checked = Setup.Get("LoginRemember")
If KeepInput AndAlso Not IsFirstLoad Then '避免第一次就以 KeepInput 的方式加载,导致文本框里没东西
'保留输入,只刷新下拉框列表
Dim Input As String = ComboName.Text
ComboName.ItemsSource = If(Setup.Get("LoginMojangEmail") = "", Nothing, Setup.Get("LoginMojangEmail").ToString.Split("¨"))
ComboName.Text = Input
Else
'不保留输入,刷新列表后自动选择第一项
If Setup.Get("LoginMojangEmail") = "" Then
ComboName.ItemsSource = Nothing
Else
ComboName.ItemsSource = Setup.Get("LoginMojangEmail").ToString.Split("¨")
ComboName.Text = Setup.Get("LoginMojangEmail").ToString.Split("¨")(0)
If Setup.Get("LoginRemember") Then TextPass.Password = Setup.Get("LoginMojangPass").ToString.Split("¨")(0).Trim
End If
End If
IsFirstLoad = False
End Sub
''' <summary>
''' 获取当前页面的登录信息。
''' </summary>
Public Shared Function GetLoginData() As McLoginServer
If FrmLoginMojang Is Nothing Then
Return New McLoginServer(McLoginType.Mojang) With {.BaseUrl = "https://authserver.mojang.com", .Token = "Mojang", .UserName = "", .Password = "", .Type = McLoginType.Mojang, .Description = "Mojang 正版"}
Else
Return New McLoginServer(McLoginType.Mojang) With {.BaseUrl = "https://authserver.mojang.com", .Token = "Mojang", .UserName = If(FrmLoginMojang.ComboName.Text, "").Replace("¨", "").Trim(), .Password = If(FrmLoginMojang.TextPass.Password, "").Replace("¨", "").Trim(), .Type = McLoginType.Mojang, .Description = "Mojang 正版"}
End If
End Function
''' <summary>
''' 当前页面的登录信息是否有效。
''' </summary>
Public Shared Function IsVaild(LoginData As McLoginServer) As String
If LoginData.UserName = "" Then Return "邮箱不能为空!"
If Not LoginData.UserName.Contains("@") Then Return "邮箱格式错误!"
If LoginData.Password = "" Then Return "密码不能为空!"
Return ""
End Function
Public Function IsVaild() As String
Return IsVaild(GetLoginData())
End Function
'保存输入信息
Private Sub ComboMojangName_TextChanged(sender As Object, e As TextChangedEventArgs) Handles ComboName.TextChanged
If sender.Text = "" Then TextPass.Password = ""
If AniControlEnabled = 0 Then Setup.Set("CacheMojangAccess", "") '迫使其不进行 Validate
End Sub
Private Sub TextMojangPass_PasswordChanged(sender As Object, e As RoutedEventArgs) Handles TextPass.PasswordChanged
If AniControlEnabled = 0 Then Setup.Set("CacheMojangAccess", "")
End Sub
Private Sub ComboMojangName_SelectionChanged(sender As MyComboBox, e As SelectionChangedEventArgs) Handles ComboName.SelectionChanged
If sender.SelectedIndex = -1 OrElse Not Setup.Get("LoginRemember") Then
TextPass.Password = ""
Else
TextPass.Password = Setup.Get("LoginMojangPass").ToString.Split("¨")(sender.SelectedIndex).Trim
End If
End Sub
Private Sub CheckRememberChange(sender As MyCheckBox, e As Object) Handles CheckRemember.Change
If AniControlEnabled = 0 Then Setup.Set(sender.Tag, sender.Checked)
End Sub
'链接处理
Private Sub InputChanged() Handles ComboName.TextChanged, TextPass.PasswordChanged
BtnLink.Content = If(ComboName.Text = "" AndAlso TextPass.Password = "", "购买正版", "找回密码")
End Sub
Private Sub BtnMojang_Click(sender As Object, e As EventArgs) Handles BtnLink.Click
If BtnLink.Content = "购买正版" Then
OpenWebsite("https://www.minecraft.net/store/minecraft-java-edition/buy")
Else
OpenWebsite("https://account.mojang.com/password")
End If
End Sub
End Class
@@ -0,0 +1,27 @@
<Grid x:Class="PageLoginMojangSkin" Tag="True"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:PCL"
mc:Ignorable="d" d:DesignWidth="297.6" Margin="0,19,0,5">
<Grid Margin="0,56,0,0" Background="{StaticResource ColorBrushSemiTransparent}" Name="PanData">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="34" />
<ColumnDefinition />
<ColumnDefinition Width="34" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="19" />
<RowDefinition Height="Auto" MinHeight="30" />
<RowDefinition Height="19" />
</Grid.RowDefinitions>
<StackPanel Grid.Column="1" Grid.Row="1" VerticalAlignment="Center">
<TextBlock Name="TextName" Text="加载中" Margin="8,0" FontSize="14" HorizontalAlignment="Center" TextTrimming="CharacterEllipsis" />
<TextBlock Name="TextEmail" Text="加载中" Margin="8,4,8,0" FontSize="12" HorizontalAlignment="Center" TextTrimming="CharacterEllipsis" Foreground="{DynamicResource ColorBrushGray3}" />
</StackPanel>
<local:MyIconButton ToolTip="更改密码" Grid.Row="1" Height="14" Opacity="0" x:Name="BtnEdit" ToolTipService.Placement="Center" ToolTipService.VerticalOffset="32" ToolTipService.InitialShowDelay="50" ToolTipService.ShowDuration="1000000" Grid.Column="0" HorizontalAlignment="Center" Logo="F1 M 53.2929,21.2929L 54.7071,22.7071C 56.4645,24.4645 56.4645,27.3137 54.7071,29.0711L 52.2323,31.5459L 44.4541,23.7677L 46.9289,21.2929C 48.6863,19.5355 51.5355,19.5355 53.2929,21.2929 Z M 31.7262,52.052L 23.948,44.2738L 43.0399,25.182L 50.818,32.9601L 31.7262,52.052 Z M 23.2409,47.1023L 28.8977,52.7591L 21.0463,54.9537L 23.2409,47.1023 Z" Margin="8,0,0,0" VerticalAlignment="Center" />
<local:MyIconButton ToolTip="退出登录" Grid.Row="1" Height="14" Opacity="0" x:Name="BtnExit" ToolTipService.Placement="Center" ToolTipService.VerticalOffset="32" ToolTipService.InitialShowDelay="50" ToolTipService.ShowDuration="1000000" Grid.Column="2" HorizontalAlignment="Center" Logo="F1 M 51.0071,19.0027L 51.0071,27.0038L 48.0067,27.0038L 48.0067,22.0031L 25.0035,22.0031L 25.0035,54.0075L 48.0067,54.0075L 48.0067,49.0068L 51.0071,49.0068L 51.0071,57.008L 22.1698,57.008L 22.0031,19.0027L 51.0071,19.0027 Z M 30.0042,35.0049L 45.2563,35.0049L 37.005,28.0039L 47.0066,28.0039L 58.5082,38.0053L 47.0066,48.0067L 37.005,48.0067L 45.2563,41.0057L 30.0042,41.0057L 30.0042,35.0049 Z" Margin="0,0,8,0" VerticalAlignment="Center" />
</Grid>
<local:MySkin HorizontalAlignment="Center" VerticalAlignment="Top" x:Name="Skin" HasCape="False" />
</Grid>
@@ -0,0 +1,114 @@
Public Class PageLoginMojangSkin
Public Sub New()
InitializeComponent()
Skin.Loader = PageLaunchLeft.SkinMojang
End Sub
Private Sub PageLoginLegacy_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
Skin.Loader.Start()
End Sub
''' <summary>
''' 刷新页面显示的所有信息。
''' </summary>
Public Sub Reload(KeepInput As Boolean)
TextName.Text = Setup.Get("CacheMojangName")
TextEmail.Text = Setup.Get("CacheMojangUsername")
TextEmail.Visibility = If(Setup.Get("UiLauncherEmail"), Visibility.Collapsed, Visibility.Visible)
'皮肤在 Loaded 加载
End Sub
''' <summary>
''' 获取当前页面的登录信息。
''' </summary>
Public Shared Function GetLoginData() As McLoginServer
Return New McLoginServer(McLoginType.Mojang) With {.BaseUrl = "https://authserver.mojang.com", .Token = "Mojang", .UserName = Setup.Get("CacheMojangUsername"), .Password = Setup.Get("CacheMojangPass"), .Description = "Mojang 正版", .Type = McLoginType.Mojang}
End Function
Private Sub PageLoginMojangSkin_MouseEnter(sender As Object, e As MouseEventArgs) Handles PanData.MouseEnter
AniStart({
AaOpacity(BtnEdit, 1 - BtnEdit.Opacity, 80),
AaHeight(BtnEdit, 25.5 - BtnEdit.Height, 140,, New AniEaseOutFluent),
AaHeight(BtnEdit, -1.5, 50, 140, New AniEaseInFluent),
AaOpacity(BtnExit, 1 - BtnExit.Opacity, 80),
AaHeight(BtnExit, 25.5 - BtnExit.Height, 140,, New AniEaseOutFluent),
AaHeight(BtnExit, -1.5, 50, 140, New AniEaseInFluent)
}, "PageLoginMojangSkin Button")
End Sub
Private Sub PageLoginMojangSkin_MouseLeave(sender As Object, e As MouseEventArgs) Handles PanData.MouseLeave
AniStart({
AaOpacity(BtnEdit, -BtnEdit.Opacity, 120,, New AniEaseOutFluent),
AaHeight(BtnEdit, 14 - BtnEdit.Height, 120,, New AniEaseInFluent),
AaOpacity(BtnExit, -BtnExit.Opacity, 120,, New AniEaseOutFluent),
AaHeight(BtnExit, 14 - BtnExit.Height, 120,, New AniEaseInFluent)
}, "PageLoginMojangSkin Button")
End Sub
Private Sub BtnEdit_Click(sender As Object, e As EventArgs) Handles BtnEdit.Click
Select Case MyMsgBox("你希望通过哪种途径更改密码?" & vbCrLf & "首次通过个人档案修改密码可能需要验证你的密保问题。", "更改密码", "个人档案", "密保邮箱", "取消")
Case 1
'个人档案
OpenWebsite("https://www.minecraft.net/zh-hans/profile/")
Case 2
'密保邮箱
OpenWebsite("https://account.mojang.com/password")
Case 3
'取消
End Select
End Sub
Private Sub BtnExit_Click() Handles BtnExit.Click
Setup.Set("CacheMojangAccess", "")
FrmLaunchLeft.RefreshPage(False, True)
End Sub
Private Sub Skin_Click(sender As Object, e As MouseButtonEventArgs) Handles Skin.Click
If McLoginLoader.State = LoadState.Failed Then
Hint("登录失败,无法更改皮肤!", HintType.Critical)
Exit Sub
End If
Dim SkinInfo As McSkinInfo = McSkinSelect(False)
If Not SkinInfo.IsVaild Then Exit Sub
Hint("正在更改皮肤……")
RunInNewThread(Async Sub()
Try
If McLoginLoader.State = LoadState.Loading Then McLoginLoader.WaitForExit() '等待登录结束
Dim AccessToken As String = Setup.Get("CacheMojangAccess")
Dim Uuid As String = Setup.Get("CacheMojangUuid")
Dim Client As New Net.Http.HttpClient With {.Timeout = New TimeSpan(0, 0, 10)}
Client.DefaultRequestHeaders.Authorization = New Net.Http.Headers.AuthenticationHeaderValue("Bearer", AccessToken)
Client.DefaultRequestHeaders.Accept.Add(New Net.Http.Headers.MediaTypeWithQualityHeaderValue("*/*"))
Client.DefaultRequestHeaders.UserAgent.Add(New Net.Http.Headers.ProductInfoHeaderValue("MojangSharp", "0.1"))
Dim Contents As New Net.Http.MultipartFormDataContent From {
{New Net.Http.StringContent(If(SkinInfo.IsSlim, "slim", "")), "model"},
{New Net.Http.ByteArrayContent(File.ReadAllBytes(SkinInfo.LocalFile)), "file", GetFileNameFromPath(SkinInfo.LocalFile)}
}
Dim Result As String = Await (Await Client.PutAsync(New Uri("https://api.mojang.com/user/profile/" & Uuid & "/skin"), Contents)).Content.ReadAsStringAsync
If RegexCheck(Result, "^[0-9a-f]{59,64}$") Then
MySkin.ReloadCache("http://textures.minecraft.net/texture/" & Result, False)
ElseIf Result.ToLower.Contains("ip not secured") Then
If MyMsgBox("首次操作需要在官网验证密保问题。" & vbCrLf & "验证完成后,你即可使用 PCL 更改皮肤,且无需再次验证。", "验证密保问题", "开始验证", "取消") = 1 Then
OpenWebsite("https://www.minecraft.net/zh-hans/profile/skin")
End If
ElseIf Result.Contains("request requires user authentication") Then
Hint("正在重新登录,请稍后再次尝试更改皮肤!")
RunInUi(Sub()
BtnExit_Click()
If String.IsNullOrEmpty(McLoginAble()) Then McLoginLoader.Start()
End Sub)
ElseIf Result.Contains("""errorMessage""") Then
Hint("更改皮肤失败:" & GetJson(Result)("errorMessage"), HintType.Critical)
Else
Throw New Exception("未知错误(" & Result & ")")
End If
Catch ex As Exception
If ex.GetType.Equals(GetType(Tasks.TaskCanceledException)) Then
Hint("更改皮肤失败:与 Mojang 皮肤服务器的连接超时,请检查你的网络是否通畅!", HintType.Critical)
Else
Log(ex, "更改皮肤失败", LogLevel.Hint)
End If
End Try
End Sub, "Mojang Skin Upload")
End Sub
End Class
@@ -0,0 +1,16 @@
<StackPanel x:Class="PageLoginMs" Tag="False" Orientation="Vertical"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:PCL"
mc:Ignorable="d" d:DesignWidth="302.4" Margin="0,0,0,-2">
<StackPanel x:Name="PanEmpty">
<Path Data="M535.94 571.76l291.060 0.36v286.020l-291.060-39.24v-247.14M499.94 535.76v314.64l363.060 48.96v-363.060l-363.060-0.54zM197 571.4l218.52 0.36v226.98l-218.52-30.42v-196.92M161 535.4v264.42l290.52 40.32v-304.2l-290.52-0.54zM827 166.76v285.12l-291.060-0.36v-239.76l291.060-45M863 124.64l-363.060 56.16v306.54l363.060 0.54v-363.24zM415.52 231.2v219.96l-218.52-0.18v-189.36l218.52-30.42M451.52 189.8l-290.52 40.5v256.68l290.52 0.36v-297.54z"
Fill="{DynamicResource ColorBrush1}" Opacity="0.7"
Width="40" Stretch="Uniform"/>
<TextBlock Text="    无账号信息&#xa;点击 添加账号 按钮以登录" HorizontalAlignment="Center" Margin="0,15,0,25"
Foreground="{DynamicResource ColorBrush1}" Opacity="0.7" />
<local:MyButton Text="添加账号" x:Name="BtnLogin" ColorType="Highlight" Height="35" HorizontalAlignment="Center" Width="150" />
</StackPanel>
</StackPanel>
@@ -0,0 +1,65 @@
Public Class PageLoginMs
''' <summary>
''' 刷新页面显示的所有信息。
''' </summary>
Public Sub Reload(KeepInput As Boolean)
End Sub
''' <summary>
''' 获取当前页面的登录信息。
''' </summary>
Public Shared Function GetLoginData() As McLoginMs
Return New McLoginMs With {.OAuthRefreshToken = Setup.Get("CacheMsOAuthRefresh"), .UserName = Setup.Get("CacheMsName")}
End Function
''' <summary>
''' 当前页面的登录信息是否有效。
''' </summary>
Public Shared Function IsVaild(LoginData As McLoginMs) As String
If LoginData.OAuthRefreshToken = "" Then
Return "请在登录账号后再继续!"
Else
Return ""
End If
End Function
Public Function IsVaild() As String
Return IsVaild(GetLoginData())
End Function
Private Sub BtnLogin_Click(sender As Object, e As EventArgs) Handles BtnLogin.Click
BtnLogin.IsEnabled = False
BtnLogin.Text = "登录中 0%"
RunInNewThread(Sub()
Try
McLoginMsLoader.Start(GetLoginData(), IsForceRestart:=True)
Do While McLoginMsLoader.State = LoadState.Loading
RunInUi(Sub() BtnLogin.Text = "登录中 " & Math.Round(McLoginMsLoader.Progress * 100) & "%")
Thread.Sleep(50)
Loop
If McLoginMsLoader.State = LoadState.Finished Then
RunInUi(Sub() FrmLaunchLeft.RefreshPage(False, True))
ElseIf McLoginMsLoader.State = LoadState.Aborted Then
Throw New ThreadInterruptedException
ElseIf McLoginMsLoader.Error Is Nothing Then
Throw New Exception("未知错误!")
Else
Throw New Exception(McLoginMsLoader.Error.Message, McLoginMsLoader.Error)
End If
Catch ex As ThreadInterruptedException
Hint("登录已取消!")
Catch ex As Exception
If ex.Message = "$$" Then
ElseIf ex.Message.StartsWith("$") Then
Hint(ex.Message.TrimStart("$"), HintType.Critical)
Else
Log(ex, "微软登录尝试失败", LogLevel.Msgbox)
End If
Finally
RunInUi(Sub()
BtnLogin.IsEnabled = True
BtnLogin.Text = "添加账号"
End Sub)
End Try
End Sub, "Ms Login")
End Sub
End Class
@@ -0,0 +1,24 @@
<Grid x:Class="PageLoginMsSkin" Tag="True"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:PCL"
mc:Ignorable="d" d:DesignWidth="297.6" Margin="0,19,0,5">
<Grid Margin="0,56,0,0" Background="{StaticResource ColorBrushSemiTransparent}" Name="PanData">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="34" />
<ColumnDefinition />
<ColumnDefinition Width="34" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="19" />
<RowDefinition Height="Auto" MinHeight="30" />
<RowDefinition Height="19" />
</Grid.RowDefinitions>
<TextBlock Grid.Column="1" Grid.Row="1" VerticalAlignment="Center" Name="TextName" Text="加载中" Margin="8,0" FontSize="14" HorizontalAlignment="Center" TextTrimming="CharacterEllipsis" />
<local:MyIconButton ToolTip="更改密码" Grid.Row="1" Height="14" Opacity="0" x:Name="BtnEdit" ToolTipService.Placement="Center" ToolTipService.VerticalOffset="32" ToolTipService.InitialShowDelay="50" ToolTipService.ShowDuration="1000000" Grid.Column="0" HorizontalAlignment="Center" Logo="F1 M 53.2929,21.2929L 54.7071,22.7071C 56.4645,24.4645 56.4645,27.3137 54.7071,29.0711L 52.2323,31.5459L 44.4541,23.7677L 46.9289,21.2929C 48.6863,19.5355 51.5355,19.5355 53.2929,21.2929 Z M 31.7262,52.052L 23.948,44.2738L 43.0399,25.182L 50.818,32.9601L 31.7262,52.052 Z M 23.2409,47.1023L 28.8977,52.7591L 21.0463,54.9537L 23.2409,47.1023 Z" Margin="8,0,0,0" VerticalAlignment="Center" />
<local:MyIconButton ToolTip="退出登录" Grid.Row="1" Height="14" Opacity="0" x:Name="BtnExit" ToolTipService.Placement="Center" ToolTipService.VerticalOffset="32" ToolTipService.InitialShowDelay="50" ToolTipService.ShowDuration="1000000" Grid.Column="2" HorizontalAlignment="Center" Logo="F1 M 51.0071,19.0027L 51.0071,27.0038L 48.0067,27.0038L 48.0067,22.0031L 25.0035,22.0031L 25.0035,54.0075L 48.0067,54.0075L 48.0067,49.0068L 51.0071,49.0068L 51.0071,57.008L 22.1698,57.008L 22.0031,19.0027L 51.0071,19.0027 Z M 30.0042,35.0049L 45.2563,35.0049L 37.005,28.0039L 47.0066,28.0039L 58.5082,38.0053L 47.0066,48.0067L 37.005,48.0067L 45.2563,41.0057L 30.0042,41.0057L 30.0042,35.0049 Z" Margin="0,0,8,0" VerticalAlignment="Center" />
</Grid>
<local:MySkin HorizontalAlignment="Center" VerticalAlignment="Top" x:Name="Skin" HasCape="True" />
</Grid>
@@ -0,0 +1,122 @@
Public Class PageLoginMsSkin
Public Sub New()
InitializeComponent()
Skin.Loader = PageLaunchLeft.SkinMs
End Sub
Private Sub PageLoginLegacy_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
Skin.Loader.Start()
End Sub
''' <summary>
''' 刷新页面显示的所有信息。
''' </summary>
Public Sub Reload(KeepInput As Boolean)
TextName.Text = Setup.Get("CacheMsName")
'皮肤在 Loaded 加载
End Sub
''' <summary>
''' 获取当前页面的登录信息。
''' </summary>
Public Shared Function GetLoginData() As McLoginMs
If McLoginMsLoader.State = LoadState.Finished Then
Return New McLoginMs With {.OAuthRefreshToken = Setup.Get("CacheMsOAuthRefresh"), .UserName = Setup.Get("CacheMsName"), .AccessToken = Setup.Get("CacheMsAccess"), .Uuid = Setup.Get("CacheMsUuid")}
Else
Return New McLoginMs With {.OAuthRefreshToken = Setup.Get("CacheMsOAuthRefresh"), .UserName = Setup.Get("CacheMsName")}
End If
End Function
Private Sub PageLoginMsSkin_MouseEnter(sender As Object, e As MouseEventArgs) Handles PanData.MouseEnter
AniStart({
AaOpacity(BtnEdit, 1 - BtnEdit.Opacity, 80),
AaHeight(BtnEdit, 25.5 - BtnEdit.Height, 140,, New AniEaseOutFluent),
AaHeight(BtnEdit, -1.5, 50, 140, New AniEaseInFluent),
AaOpacity(BtnExit, 1 - BtnExit.Opacity, 80),
AaHeight(BtnExit, 25.5 - BtnExit.Height, 140,, New AniEaseOutFluent),
AaHeight(BtnExit, -1.5, 50, 140, New AniEaseInFluent)
}, "PageLoginMsSkin Button")
End Sub
Private Sub PageLoginMsSkin_MouseLeave(sender As Object, e As MouseEventArgs) Handles PanData.MouseLeave
AniStart({
AaOpacity(BtnEdit, -BtnEdit.Opacity, 120,, New AniEaseOutFluent),
AaHeight(BtnEdit, 14 - BtnEdit.Height, 120,, New AniEaseInFluent),
AaOpacity(BtnExit, -BtnExit.Opacity, 120,, New AniEaseOutFluent),
AaHeight(BtnExit, 14 - BtnExit.Height, 120,, New AniEaseInFluent)
}, "PageLoginMsSkin Button")
End Sub
Private Sub BtnEdit_Click(sender As Object, e As EventArgs) Handles BtnEdit.Click
OpenWebsite("https://account.microsoft.com/security")
End Sub
Private Sub BtnExit_Click() Handles BtnExit.Click
Setup.Set("CacheMsOAuthRefresh", "")
Setup.Set("CacheMsAccess", "")
Setup.Set("CacheMsUuid", "")
Setup.Set("CacheMsName", "")
McLoginMsLoader.Abort()
FrmLaunchLeft.RefreshPage(False, True)
End Sub
Private IsChanging As Boolean = False
Private Sub Skin_Click(sender As Object, e As MouseButtonEventArgs) Handles Skin.Click
'检查条件,获取新皮肤
If IsChanging Then
Hint("正在更改皮肤中,请稍候!")
Exit Sub
End If
If McLoginLoader.State = LoadState.Failed Then
Hint("登录失败,无法更改皮肤!", HintType.Critical)
Exit Sub
End If
Dim SkinInfo As McSkinInfo = McSkinSelect(False)
If Not SkinInfo.IsVaild Then Exit Sub
Hint("正在更改皮肤……")
IsChanging = True
'开始实际获取
RunInNewThread(Async Sub()
Try
Retry:
If McLoginMsLoader.State = LoadState.Loading Then McLoginMsLoader.WaitForExit() '等待登录结束
Dim AccessToken As String = Setup.Get("CacheMsAccess")
Dim Uuid As String = Setup.Get("CacheMsUuid")
Dim Client As New Net.Http.HttpClient With {.Timeout = New TimeSpan(0, 0, 30)}
Client.DefaultRequestHeaders.Authorization = New Net.Http.Headers.AuthenticationHeaderValue("Bearer", AccessToken)
Client.DefaultRequestHeaders.Accept.Add(New Net.Http.Headers.MediaTypeWithQualityHeaderValue("*/*"))
Client.DefaultRequestHeaders.UserAgent.Add(New Net.Http.Headers.ProductInfoHeaderValue("MojangSharp", "0.1"))
Dim Contents As New Net.Http.MultipartFormDataContent From {
{New Net.Http.StringContent(If(SkinInfo.IsSlim, "slim", "classic")), "variant"},
{New Net.Http.ByteArrayContent(File.ReadAllBytes(SkinInfo.LocalFile)), "file", GetFileNameFromPath(SkinInfo.LocalFile)}
}
Dim Result As String = Await (Await Client.PostAsync(New Uri("https://api.minecraftservices.com/minecraft/profile/skins"), Contents)).Content.ReadAsStringAsync
If Result.Contains("request requires user authentication") Then
Hint("正在登录,将在登录完成后继续更改皮肤……")
McLoginMsLoader.Start(GetLoginData(), IsForceRestart:=True)
GoTo Retry
ElseIf Result.Contains("""error""") Then
Hint("更改皮肤失败:" & GetJson(Result)("error"), HintType.Critical)
Exit Sub
End If
'获取新皮肤地址
Log("[Skin] 皮肤修改返回值:" & vbCrLf & Result)
Dim ResultJson As JObject = GetJson(Result)
For Each Skin As JObject In ResultJson("skins")
If Skin("state").ToString = "ACTIVE" Then
MySkin.ReloadCache(Skin("url"), True)
Exit Sub
End If
Next
Throw New Exception("未知错误(" & Result & ")")
Catch ex As Exception
If ex.GetType.Equals(GetType(Tasks.TaskCanceledException)) Then
Hint("更改皮肤失败:与 Mojang 皮肤服务器的连接超时,请检查你的网络是否通畅!", HintType.Critical)
Else
Log(ex, "更改皮肤失败", LogLevel.Hint)
End If
Finally
IsChanging = False
End Try
End Sub, "Ms Skin Upload")
End Sub
End Class
@@ -0,0 +1,24 @@
<Grid x:Class="PageLoginNide" Tag="False"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:PCL"
mc:Ignorable="d" d:DesignWidth="317.6" Margin="0,0,0,-2">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="10" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="224" />
</Grid.ColumnDefinitions>
<local:MyComboBox Grid.Row="0" Grid.Column="1" IsEditable="True" Height="28" x:Name="ComboName" />
<TextBlock Text="账号" Grid.Row="0" VerticalAlignment="Center" />
<PasswordBox Grid.Row="2" Grid.Column="1" x:Name="TextPass" />
<TextBlock Text="密码" Grid.Row="2" VerticalAlignment="Center" />
<local:MyCheckBox x:Name="CheckRemember" Tag="LoginRemember" Height="20" Margin="-1,12,80,0" Text="记住密码" Grid.Row="3" Grid.Column="1" Grid.ColumnSpan="2" />
<local:MyTextButton Margin="0,12,2,0" x:Name="BtnLink" Content="注册账号" Grid.Row="3" HorizontalAlignment="Right" Grid.Column="1" Padding="20,0,0,0" HorizontalContentAlignment="Right" FontSize="13" VerticalContentAlignment="Center" />
</Grid>
@@ -0,0 +1,80 @@
Public Class PageLoginNide
Private IsFirstLoad As Boolean = True
''' <summary>
''' 刷新页面显示的所有信息。
''' </summary>
Public Sub Reload(KeepInput As Boolean)
'记住密码
CheckRemember.Checked = Setup.Get("LoginRemember")
If KeepInput AndAlso Not IsFirstLoad Then '避免第一次就以 KeepInput 的方式加载,导致文本框里没东西
'保留输入,只刷新下拉框列表
Dim Input As String = ComboName.Text
ComboName.ItemsSource = If(Setup.Get("LoginNideEmail") = "", Nothing, Setup.Get("LoginNideEmail").ToString.Split("¨"))
ComboName.Text = Input
Else
'不保留输入,刷新列表后自动选择第一项
If Setup.Get("LoginNideEmail") = "" Then
ComboName.ItemsSource = Nothing
Else
ComboName.ItemsSource = Setup.Get("LoginNideEmail").ToString.Split("¨")
ComboName.Text = Setup.Get("LoginNideEmail").ToString.Split("¨")(0)
If Setup.Get("LoginRemember") Then TextPass.Password = Setup.Get("LoginNidePass").ToString.Split("¨")(0).Trim
End If
End If
IsFirstLoad = False
End Sub
''' <summary>
''' 获取当前页面的登录信息。
''' </summary>
Public Shared Function GetLoginData() As McLoginServer
Dim Server As String = If(IsNothing(McVersionCurrent), Setup.Get("CacheNideServer"), Setup.Get("VersionServerNide", Version:=McVersionCurrent))
If FrmLoginNide Is Nothing Then
Return New McLoginServer(McLoginType.Nide) With {.Token = "Nide", .UserName = "", .Password = "", .Description = "统一通行证", .Type = McLoginType.Nide, .BaseUrl = "https://auth.mc-user.com:233/" & Server & "/authserver"}
Else
Return New McLoginServer(McLoginType.Nide) With {.Token = "Nide", .UserName = FrmLoginNide.ComboName.Text.Replace("¨", "").Trim, .Password = FrmLoginNide.TextPass.Password.Replace("¨", "").Trim, .Description = "统一通行证", .Type = McLoginType.Nide, .BaseUrl = "https://auth.mc-user.com:233/" & Server & "/authserver"}
End If
End Function
''' <summary>
''' 当前页面的登录信息是否有效。
''' </summary>
Public Shared Function IsVaild(LoginData As McLoginServer) As String
If LoginData.UserName = "" Then Return "账号不能为空!"
If LoginData.Password = "" Then Return "密码不能为空!"
Return ""
End Function
Public Function IsVaild() As String
Return IsVaild(GetLoginData())
End Function
'保存输入信息
Private Sub ComboName_TextChanged(sender As Object, e As TextChangedEventArgs) Handles ComboName.TextChanged
If sender.Text = "" Then TextPass.Password = ""
If AniControlEnabled = 0 Then Setup.Set("CacheNideAccess", "") '迫使其不进行 Validate
End Sub
Private Sub TextPass_PasswordChanged(sender As Object, e As RoutedEventArgs) Handles TextPass.PasswordChanged
If AniControlEnabled = 0 Then Setup.Set("CacheNideAccess", "")
End Sub
Private Sub ComboName_SelectionChanged(sender As MyComboBox, e As SelectionChangedEventArgs) Handles ComboName.SelectionChanged
If sender.SelectedIndex = -1 OrElse Not Setup.Get("LoginRemember") Then
TextPass.Password = ""
Else
TextPass.Password = Setup.Get("LoginNidePass").ToString.Split("¨")(sender.SelectedIndex).Trim
End If
End Sub
Private Sub CheckBoxChange(sender As MyCheckBox, e As Object) Handles CheckRemember.Change
If AniControlEnabled = 0 Then Setup.Set(sender.Tag, sender.Checked)
End Sub
'链接处理
Private Sub ComboName_TextChanged() Handles ComboName.TextChanged
BtnLink.Content = If(ComboName.Text = "", "注册账号", "找回密码")
End Sub
Private Sub Btn_Click(sender As Object, e As EventArgs) Handles BtnLink.Click
If BtnLink.Content = "注册账号" Then
OpenWebsite("https://login.mc-user.com:233/" & Setup.Get("VersionServerNide", Version:=McVersionCurrent) & "/register")
Else
OpenWebsite("https://login.mc-user.com:233/account/login")
End If
End Sub
End Class
@@ -0,0 +1,27 @@
<Grid x:Class="PageLoginNideSkin" Tag="True"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:PCL"
mc:Ignorable="d" d:DesignWidth="297.6" Margin="0,19,0,5">
<Grid Margin="0,56,0,0" Background="{StaticResource ColorBrushSemiTransparent}" Name="PanData">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="34" />
<ColumnDefinition />
<ColumnDefinition Width="34" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="19" />
<RowDefinition Height="Auto" MinHeight="30" />
<RowDefinition Height="19" />
</Grid.RowDefinitions>
<StackPanel Grid.Column="1" Grid.Row="1" VerticalAlignment="Center">
<TextBlock Name="TextName" Text="加载中" Margin="8,0" FontSize="14" HorizontalAlignment="Center" TextTrimming="CharacterEllipsis" />
<TextBlock Name="TextEmail" Text="加载中" Margin="8,4,8,0" FontSize="12" HorizontalAlignment="Center" TextTrimming="CharacterEllipsis" Foreground="{DynamicResource ColorBrushGray3}" />
</StackPanel>
<local:MyIconButton ToolTip="更改密码" Grid.Row="1" Height="14" Opacity="0" x:Name="BtnEdit" ToolTipService.Placement="Center" ToolTipService.VerticalOffset="32" ToolTipService.InitialShowDelay="50" ToolTipService.ShowDuration="1000000" Grid.Column="0" HorizontalAlignment="Center" Logo="F1 M 53.2929,21.2929L 54.7071,22.7071C 56.4645,24.4645 56.4645,27.3137 54.7071,29.0711L 52.2323,31.5459L 44.4541,23.7677L 46.9289,21.2929C 48.6863,19.5355 51.5355,19.5355 53.2929,21.2929 Z M 31.7262,52.052L 23.948,44.2738L 43.0399,25.182L 50.818,32.9601L 31.7262,52.052 Z M 23.2409,47.1023L 28.8977,52.7591L 21.0463,54.9537L 23.2409,47.1023 Z" Margin="8,0,0,0" VerticalAlignment="Center" />
<local:MyIconButton ToolTip="退出登录" Grid.Row="1" Height="14" Opacity="0" x:Name="BtnExit" ToolTipService.Placement="Center" ToolTipService.VerticalOffset="32" ToolTipService.InitialShowDelay="50" ToolTipService.ShowDuration="1000000" Grid.Column="2" HorizontalAlignment="Center" Logo="F1 M 51.0071,19.0027L 51.0071,27.0038L 48.0067,27.0038L 48.0067,22.0031L 25.0035,22.0031L 25.0035,54.0075L 48.0067,54.0075L 48.0067,49.0068L 51.0071,49.0068L 51.0071,57.008L 22.1698,57.008L 22.0031,19.0027L 51.0071,19.0027 Z M 30.0042,35.0049L 45.2563,35.0049L 37.005,28.0039L 47.0066,28.0039L 58.5082,38.0053L 47.0066,48.0067L 37.005,48.0067L 45.2563,41.0057L 30.0042,41.0057L 30.0042,35.0049 Z" Margin="0,0,8,0" VerticalAlignment="Center" />
</Grid>
<local:MySkin HorizontalAlignment="Center" VerticalAlignment="Top" x:Name="Skin" HasCape="False" />
</Grid>
@@ -0,0 +1,59 @@
Public Class PageLoginNideSkin
Public Sub New()
InitializeComponent()
Skin.Loader = PageLaunchLeft.SkinNide
End Sub
Private Sub PageLoginLegacy_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
Skin.Loader.Start()
End Sub
''' <summary>
''' 刷新页面显示的所有信息。
''' </summary>
Public Sub Reload(KeepInput As Boolean)
TextName.Text = Setup.Get("CacheNideName")
TextEmail.Text = Setup.Get("CacheNideUsername")
TextEmail.Visibility = If(Setup.Get("UiLauncherEmail"), Visibility.Collapsed, Visibility.Visible)
'皮肤在 Loaded 加载
End Sub
''' <summary>
''' 获取当前页面的登录信息。
''' </summary>
Public Shared Function GetLoginData() As McLoginServer
Dim Server As String = If(IsNothing(McVersionCurrent), Setup.Get("CacheNideServer"), Setup.Get("VersionServerNide", Version:=McVersionCurrent))
Return New McLoginServer(McLoginType.Nide) With {.Token = "Nide", .UserName = Setup.Get("CacheNideUsername"), .Password = Setup.Get("CacheNidePass"), .Description = "统一通行证", .Type = McLoginType.Nide, .BaseUrl = "https://auth.mc-user.com:233/" & Server & "/authserver"}
End Function
Private Sub PageLoginNideSkin_MouseEnter(sender As Object, e As MouseEventArgs) Handles PanData.MouseEnter
AniStart({
AaOpacity(BtnEdit, 1 - BtnEdit.Opacity, 80),
AaHeight(BtnEdit, 25.5 - BtnEdit.Height, 140,, New AniEaseOutFluent),
AaHeight(BtnEdit, -1.5, 50, 140, New AniEaseInFluent),
AaOpacity(BtnExit, 1 - BtnExit.Opacity, 80),
AaHeight(BtnExit, 25.5 - BtnExit.Height, 140,, New AniEaseOutFluent),
AaHeight(BtnExit, -1.5, 50, 140, New AniEaseInFluent)
}, "PageLoginNideSkin Button")
End Sub
Private Sub PageLoginNideSkin_MouseLeave(sender As Object, e As MouseEventArgs) Handles PanData.MouseLeave
AniStart({
AaOpacity(BtnEdit, -BtnEdit.Opacity, 120,, New AniEaseOutFluent),
AaHeight(BtnEdit, 14 - BtnEdit.Height, 120,, New AniEaseInFluent),
AaOpacity(BtnExit, -BtnExit.Opacity, 120,, New AniEaseOutFluent),
AaHeight(BtnExit, 14 - BtnExit.Height, 120,, New AniEaseInFluent)
}, "PageLoginNideSkin Button")
End Sub
Private Sub BtnEdit_Click(sender As Object, e As EventArgs) Handles BtnEdit.Click
OpenWebsite("https://login.mc-user.com:233/account/changepw")
End Sub
Private Sub BtnExit_Click() Handles BtnExit.Click
Setup.Set("CacheNideAccess", "")
FrmLaunchLeft.RefreshPage(False, True)
End Sub
Private Sub Skin_Click(sender As Object, e As MouseButtonEventArgs) Handles Skin.Click
OpenWebsite("https://login.mc-user.com:233/" & If(IsNothing(McVersionCurrent), Setup.Get("CacheNideServer"), Setup.Get("VersionServerNide", Version:=McVersionCurrent)) & "/skin")
End Sub
End Class
@@ -0,0 +1,23 @@
<local:MyPageRight
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:PCL" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" x:Class="PageOtherHelp"
d:DesignWidth="800" d:DesignHeight="800">
<Grid>
<local:MyScrollViewer Visibility="Collapsed" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" x:Name="PanBack">
<StackPanel x:Name="PanMain" Margin="25,25,25,10" Grid.IsSharedSizeScope="True">
<local:MySearchBox Margin="0,0,0,15" HintText="搜索帮助" x:Name="SearchBox" />
<Grid>
<local:MyCard x:Name="PanSearch" Visibility="Collapsed" VerticalAlignment="Top" Opacity="0" Margin="0,0,0,15" Title=" " MinHeight="40">
<StackPanel Margin="20,40,18,18" Name="PanSearchList" VerticalAlignment="Top" />
</local:MyCard>
<StackPanel Name="PanList" />
</Grid>
</StackPanel>
</local:MyScrollViewer>
<local:MyCard Visibility="Collapsed" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="40,0" SnapsToDevicePixels="True" x:Name="PanLoad" UseAnimation="False">
<local:MyLoading Text="正在加载帮助列表" Margin="20,20,20,17" x:Name="Load" HorizontalAlignment="Center" VerticalAlignment="Center" />
</local:MyCard>
</Grid>
</local:MyPageRight>
@@ -0,0 +1,177 @@
Public Class PageOtherHelp
#Region "初始化"
'滚动条
Private Sub PageOther_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
PanBack.ScrollToHome()
End Sub
'初始化加载器信息
Private Sub PageOther_Inited(sender As Object, e As EventArgs) Handles Me.Initialized
PageLoaderInit(Load, PanLoad, PanBack, Nothing, HelpLoader, AddressOf HelpListLoad)
End Sub
#End Region
''' <summary>
''' 将帮助列表对象实例化为主页 UI。
''' </summary>
Private Sub HelpListLoad(Loader As LoaderTask(Of Integer, List(Of HelpEntry)))
Try
'初始化
PanList.Children.Clear()
PanBack.ScrollToHome()
Dim HelpItems = Loader.Output
'获取全部分类
Dim Types As New List(Of String)
For Each Item As HelpEntry In HelpItems
If Val(VersionBranchCode) = 50 AndAlso Not Item.ShowInPublic Then Continue For
If Val(VersionBranchCode) <> 50 AndAlso Not Item.ShowInSnapshot Then Continue For
For Each Type In Item.Types
If Not Types.Contains(Type) Then Types.Add(Type)
Next
Next
'将指南页面置顶
If Types.Contains("指南") Then
Types.Remove("指南")
Types.Insert(0, "指南")
End If
'转化为 UI
For Each Type As String In Types
'确认所属该分类的项目
Dim TypeItems As New List(Of HelpEntry)
For Each Item In HelpItems
If Val(VersionBranchCode) = 50 AndAlso Not Item.ShowInPublic Then Continue For
If Val(VersionBranchCode) <> 50 AndAlso Not Item.ShowInSnapshot Then Continue For
If Item.Types.Contains(Type) Then TypeItems.Add(Item)
Next
'增加卡片
Dim NewCard As New MyCard With {.Title = Type, .Margin = New Thickness(0, 0, 0, 15), .SwapType = 11}
Dim NewStack As New StackPanel With {.Margin = New Thickness(20, MyCard.SwapedHeight, 18, 0), .VerticalAlignment = VerticalAlignment.Top, .RenderTransform = New TranslateTransform(0, 0), .Tag = TypeItems}
NewCard.Children.Add(NewStack)
NewCard.SwapControl = NewStack
If Type = "指南" Then
MyCard.StackInstall(NewStack, 11, "指南")
Else
NewCard.IsSwaped = True
End If
PanList.Children.Add(NewCard)
Next
Catch ex As Exception
Log(ex, "加载帮助列表 UI 失败", LogLevel.Feedback)
End Try
End Sub
''' <summary>
''' 帮助项目的点击事件。
''' </summary>
Public Shared Sub OnItemClick(Entry As HelpEntry)
Try
If Entry.IsEvent Then
ModEvent.TryStartEvent(Entry.EventType, Entry.EventData)
Else
EnterHelpPage(Entry)
End If
Catch ex As Exception
Log(ex, "处理帮助项目点击时发生意外错误", LogLevel.Feedback)
End Try
End Sub
Public Shared Sub EnterHelpPage(Location As String)
RunInThread(Sub()
If Not HelpLoader.State = LoadState.Finished Then HelpLoader.WaitForExit(GetUuid)
Dim Entry As New HelpEntry(Location)
RunInUi(Sub()
Dim FrmHelpDetail As New PageOtherHelpDetail
If FrmHelpDetail.Init(Entry) Then
FrmMain.PageChange(New FormMain.PageStackData With {.Page = FormMain.PageType.HelpDetail, .Additional = {Entry, FrmHelpDetail}})
Else
Log("[Help] 已取消进入帮助项目,这一般是由于 xaml 初始化失败,且用户在弹窗中手动放弃", LogLevel.Debug)
End If
End Sub)
End Sub)
End Sub
Public Shared Sub EnterHelpPage(Entry As HelpEntry)
RunInThread(Sub()
If Not HelpLoader.State = LoadState.Finished Then HelpLoader.WaitForExit(GetUuid)
RunInUi(Sub()
Dim FrmHelpDetail As New PageOtherHelpDetail
If FrmHelpDetail.Init(Entry) Then
FrmMain.PageChange(New FormMain.PageStackData With {.Page = FormMain.PageType.HelpDetail, .Additional = {Entry, FrmHelpDetail}})
Else
Log("[Help] 已取消进入帮助项目,这一般是由于 xaml 初始化失败,且用户在弹窗中手动放弃", LogLevel.Debug)
End If
End Sub)
End Sub)
End Sub
Public Shared Function GetHelpPage(Location As String) As PageOtherHelpDetail
If Not HelpLoader.State = LoadState.Finished Then HelpLoader.WaitForExit(GetUuid)
Dim FrmHelpDetail As New PageOtherHelpDetail
If FrmHelpDetail.Init(New HelpEntry(Location)) Then
Return FrmHelpDetail
Else
Throw New Exception("已取消进入帮助项目,这一般是由于 xaml 初始化失败,且用户在弹窗中手动放弃")
End If
End Function
''' <summary>
''' 搜索帮助。
''' </summary>
Public Sub SearchRun() Handles SearchBox.TextChanged
If String.IsNullOrWhiteSpace(SearchBox.Text) Then
'隐藏
AniStart({
AaOpacity(PanSearch, -PanSearch.Opacity, 100),
AaCode(Sub()
PanSearch.Height = 0
PanSearch.Visibility = Visibility.Collapsed
PanList.Visibility = Visibility.Visible
End Sub,, True),
AaOpacity(PanList, 1 - PanList.Opacity, 150, 30)
}, "FrmOtherHelp Search Switch")
Else
'构造请求
Dim QueryList As New List(Of SearchEntry(Of HelpEntry))
For Each Entry As HelpEntry In HelpLoader.Output
If Not Entry.ShowInSearch OrElse (Val(VersionBranchCode) = 50 AndAlso Not Entry.ShowInPublic) Then Continue For
If Not Entry.ShowInSearch OrElse (Val(VersionBranchCode) <> 50 AndAlso Not Entry.ShowInSnapshot) Then Continue For
QueryList.Add(New SearchEntry(Of HelpEntry) With {
.Item = Entry,
.SearchSource = New List(Of KeyValuePair(Of String, Double)) From {
New KeyValuePair(Of String, Double)(Entry.Title, 1),
New KeyValuePair(Of String, Double)(Entry.Desc, 0.5),
New KeyValuePair(Of String, Double)(Entry.Search, 1.5)
}
})
'New KeyValuePair(Of String, Double)(If(Entry.IsEvent, If(Entry.EventData, ""), Entry.XamlContent), 0.2)
Next
'进行搜索,构造列表
Dim SearchResult = Search(QueryList, SearchBox.Text, MaxBlurCount:=5, MinBlurSimilarity:=0.08)
PanSearchList.Children.Clear()
If SearchResult.Count = 0 Then
PanSearch.Title = "无搜索结果"
PanSearchList.Visibility = Visibility.Collapsed
Else
PanSearch.Title = "搜索结果"
For Each Result In SearchResult
Dim Item = Result.Item.ToListItem
If ModeDebug Then Item.Info = If(Result.AbsoluteRight, "完全匹配,", "") & "相似度:" & Math.Round(Result.Similarity, 3) & "," & Item.Info
PanSearchList.Children.Add(Item)
Next
PanSearchList.Visibility = Visibility.Visible
End If
'显示
AniStart({
AaOpacity(PanList, -PanList.Opacity, 100),
AaCode(Sub()
PanList.Visibility = Visibility.Collapsed
PanSearch.Visibility = Visibility.Visible
PanSearch.TriggerForceResize()
End Sub,, True),
AaOpacity(PanSearch, 1 - PanSearch.Opacity, 150, 30)
}, "FrmOtherHelp Search Switch")
End If
End Sub
End Class
@@ -0,0 +1,24 @@
<local:MyPageRight x:Class="PageOtherHelpDetail"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:PCL"
mc:Ignorable="d">
<local:MyScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" x:Name="PanBack">
<StackPanel x:Name="PanCustom" Margin="25,25,25,10">
<StackPanel.Resources>
<Style TargetType="TextBlock" BasedOn="{StaticResource BasedOnTextBlock}">
<Setter Property="TextWrapping" Value="Wrap"/>
</Style>
<Style TargetType="local:MyCard">
<Setter Property="Margin" Value="0,0,0,15"/>
</Style>
<Style TargetType="Image">
<Setter Property="RenderOptions.BitmapScalingMode" Value="HighQuality"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
</Style>
</StackPanel.Resources>
</StackPanel>
</local:MyScrollViewer>
</local:MyPageRight>
@@ -0,0 +1,27 @@
Public Class PageOtherHelpDetail
Public Entry As HelpEntry
Private Sub PageOtherHelpDetail_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
PanBack.ScrollToTop()
End Sub
''' <summary>
''' 根据特定帮助项初始化页面 UI,返回是否成功加载。
''' </summary>
Public Function Init(Entry As HelpEntry) As Boolean
Dim FileContent = "<StackPanel xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"" xmlns:local=""clr-namespace:PCL;assembly=Plain Craft Launcher 2"">" & If(Entry.XamlContent, "") & "</StackPanel>"
Try
If String.IsNullOrEmpty(Entry.XamlContent) Then Throw New Exception("帮助 xaml 文件为空")
Me.Entry = Entry
PanCustom.Children.Clear()
FileContent = FileContent.Replace("{path}", Path)
PanCustom.Children.Add(GetObjectFromXML(FileContent))
Return True
Catch ex As Exception
Log("[System] 自定义信息内容:" & vbCrLf & FileContent)
Log(ex, "加载帮助 xaml 文件失败", LogLevel.Msgbox)
Return False
End Try
End Function
End Class
@@ -0,0 +1,27 @@
<local:MyPageLeft x:Class="PageOtherLeft"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:PCL" AnimatedControl="{Binding ElementName=PanItem, Mode=OneWay}">
<StackPanel Margin="0,12,0,0" Name="PanItem">
<local:MyListItem x:Name="ItemHelp" IsScaleAnimationEnabled="False" Checked="True" Type="RadioBox" Tag="0" PaddingRight="35" Height="36" VerticalAlignment="Top" Title="帮助"
LogoScale="0.97" Logo="M520.6 620.3c-11.3-0.6-20.1-4-26.9-10.5-6.6-6.3-8.1-11-10.1-20.8-1.9-9.5-1.5-16.7-1-24.9l0.3-5.3c0.5-9.9 3.5-19.6 8.8-28.1 5.7-9 12.5-17.2 20.8-25.1 8.6-8 17.7-15.7 27-22.9 9.4-7.2 18.7-14.8 27.7-22.7 9-7.9 16.2-15.8 22.1-24.3 6.2-9 9.3-18.8 9.3-29.4 1.2-20.3-6.5-37.7-22.8-51.3-16-13.3-37.4-20-63.5-20-13.7 0-26.3 3.3-37.4 10-10.9 6.5-20.2 14.5-27.7 23.8-7.5 9.2-13.5 19-17.9 29.2-4.5 10.6-6.7 19.4-6.7 26.8 0 9.2-3.3 16-10.1 20.8-6.9 4.8-14.6 7.3-22.8 7.3h-1.3c-9-0.3-17-3.3-24.6-9.2-7.3-5.6-11.1-14.6-11.6-27.5-0.6-11.5 1.9-26.1 7.2-43.5 5.4-17.4 14.8-34.4 28.1-50.5 13.4-16.3 31.2-30.4 52.8-41.8 21.6-11.4 49.2-17.2 81.9-17.2 26.4 0 49.6 3.9 69.1 11.7 19.4 7.7 35.4 18.2 47.5 31.1l1.6 1.7c11.8 12.6 20.3 21.7 29.4 44.4 11.6 28.9 7.1 52.1 5.5 58.5-5.8 22.6-12.6 37.7-22.7 50.4-11.7 14.6-24.9 28.2-39.2 40.4-14 11.7-39.2 33.3-39.2 33.3-13.3 11.4-19.4 22.1-18.6 32.9V587c0.5 8.7-2.4 16.1-8.8 22.8-6.2 6.4-14.8 10-26.2 10.5zM519 766.1c-13 0-23.6-4.2-32.2-12.9-8.7-8.7-13-19-13-31.4 0-12.9 4.2-23.5 12.9-32.2 8.7-8.7 19.2-12.9 32.2-12.9 13 0 23.5 4.2 32.2 12.9s12.9 19.2 12.9 32.2c0 12.4-4.2 22.7-12.9 31.4-8.6 8.6-19.2 12.9-32.1 12.9z M515 928.3c-228.1 0-413.7-185.6-413.7-413.7S286.9 100.9 515 100.9s413.7 185.6 413.7 413.7c0.1 228.1-185.5 413.7-413.7 413.7z m0-747.4c-184 0-333.7 149.7-333.7 333.7S331 848.3 515 848.3s333.7-149.7 333.7-333.7S699 180.9 515 180.9z">
<local:MyListItem.Buttons>
<x:Array Type="{x:Type local:MyIconButton}">
<local:MyIconButton Tag="0" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.ShowDuration="2333333" ToolTipService.InitialShowDelay="200" Click="Refresh" LogoScale="0.85" Logo="M875.52 148.48C783.36 56.32 655.36 0 512 0 291.84 0 107.52 138.24 30.72 332.8l122.88 46.08C204.8 230.4 348.16 128 512 128c107.52 0 199.68 40.96 271.36 112.64L640 384h384V0L875.52 148.48zM512 896c-107.52 0-199.68-40.96-271.36-112.64L384 640H0v384l148.48-148.48C240.64 967.68 368.64 1024 512 1024c220.16 0 404.48-138.24 481.28-332.8L870.4 645.12C819.2 793.6 675.84 896 512 896z" />
</x:Array>
</local:MyListItem.Buttons>
</local:MyListItem>
<local:MyListItem x:Name="ItemAbout" IsScaleAnimationEnabled="False" Type="RadioBox" Tag="1" PaddingRight="28" Height="36" VerticalAlignment="Top" Title="关于与鸣谢"
LogoScale="0.98" Logo="M149.883623 873.911618c47.094581 47.094581 101.765247 83.95121 162.783444 109.75085 63.065787 26.618676 130.226755 40.337532 199.230553 40.337532 69.003799 0 136.164767-13.514097 199.230554-40.337532 61.018196-25.79964 115.688862-62.656269 162.783444-109.75085s83.95121-101.765247 109.75085-162.783444c26.618676-63.065787 40.337532-130.226755 40.337532-199.230554 0-69.003799-13.514097-136.164767-40.337532-199.230553-25.79964-61.018196-62.656269-115.688862-109.75085-162.783444-46.889822-46.889822-101.765247-83.95121-162.783444-109.75085C648.062388 13.514097 580.90142 0 511.89762 0s-136.164767 13.514097-199.230553 40.337532c-61.018196 25.79964-115.688862 62.656269-162.783444 109.75085s-83.95121 101.765247-109.75085 162.783444C13.514097 375.732853 0 442.893821 0 511.89762s13.514097 136.164767 40.337532 199.230554c25.594881 61.018196 62.656269 115.688862 109.546091 162.783444zM97.670066 511.89762c0-228.511098 185.921216-414.227554 414.227554-414.227554 228.511098 0 414.227554 185.921216 414.227555 414.227554S740.408718 926.125175 511.89762 926.125175c-228.511098 0-414.227554-185.716457-414.227554-414.227555z M539.130574 244.277544c-8.190362-4.709458-17.609278-7.371326-27.232954-7.371325-9.623675 0-19.042591 2.457109-27.232953 7.371325-16.790242 9.623675-27.232953 27.847231-27.232953 47.299341 0 30.09958 24.366327 54.465907 54.465906 54.465906 30.09958 0 54.465907-24.366327 54.465907-54.465906 0-19.45211-10.442711-37.470906-27.232953-47.299341zM566.363527 732.218356v-284.615077c0-30.09958-24.366327-54.465907-54.465907-54.465906-30.09958 0-54.465907 24.366327-54.465906 54.465906v284.615077c0 30.09958 24.366327 54.465907 54.465906 54.465907 30.09958 0 54.465907-24.366327 54.465907-54.465907z" />
<local:MyListItem x:Name="ItemTest" IsScaleAnimationEnabled="False" Tag="2" PaddingRight="35" Type="RadioBox" Height="36" VerticalAlignment="Top" Title="百宝箱"
LogoScale="0.97" Logo="M511.488 995.328a128.654222 128.654222 0 0 1-57.116444-13.112889L70.769778 791.808a126.833778 126.833778 0 0 1-70.769778-113.777778V311.608889a126.179556 126.179556 0 0 1 15.36-60.103111V248.604444c1.479111-2.901333 3.356444-5.603556 5.518222-8.021333a127.630222 127.630222 0 0 1 49.891556-42.325333L454.371556 13.368889a128.739556 128.739556 0 0 1 112.981333 0l383.601778 190.407111a126.862222 126.862222 0 0 1 72.049777 113.379556v360.874666a126.805333 126.805333 0 0 1-70.769777 115.939556L568.604444 984.32c-17.92 7.964444-37.461333 11.747556-57.116444 11.008z m42.638222-470.897778v370.204445l360.192-178.545778c14.449778-7.253333 23.552-21.987556 23.438222-38.087111v-335.928889L554.097778 524.430222zM85.248 330.666667v347.335111a42.268444 42.268444 0 0 0 23.438222 38.087111l360.192 178.545778V523.576889L85.248 330.666667zM135.537778 260.835556l375.950222 189.952 137.671111-65.564445L286.435556 188.074667 135.537778 260.864z m245.105778-118.471112l363.576888 197.973334 150.897778-71.480889-365.283555-180.224a42.922667 42.922667 0 0 0-37.518223 0l-111.672888 53.731555z" />
<local:MyListItem x:Name="ItemFeedback" IsScaleAnimationEnabled="False" Type="RadioBox" Tag="3" PaddingRight="35" Height="36" VerticalAlignment="Top" Title="反馈"
LogoScale="0.9" Logo="M613.717333 64.426667l3.413334 3.242666 331.861333 331.861334a85.333333 85.333333 0 0 1 3.2 117.269333l-3.2 3.413333L573.162667 896H960a21.333333 21.333333 0 0 1 21.333333 21.333333v42.666667a21.333333 21.333333 0 0 1-21.333333 21.333333H64a21.333333 21.333333 0 0 1-21.333333-21.333333v-42.666667a21.333333 21.333333 0 0 1 21.333333-21.333333h295.338667L74.069333 610.709333a85.333333 85.333333 0 0 1-3.221333-117.269333l3.2-3.413333 422.4-422.357334a85.333333 85.333333 0 0 1 117.269333-3.221333z m-20.629333 99.882666l-21.418667 321.493334a85.333333 85.333333 0 0 1-74.944 79.04l-4.522666 0.426666-321.493334 21.44 295.552 295.530667 422.4-422.378667L593.066667 164.309333z m-86.442667 13.824L184.533333 500.266667l301.994667-20.117334 20.117333-301.994666z">
<local:MyListItem.Buttons>
<x:Array Type="{x:Type local:MyIconButton}">
<local:MyIconButton Tag="3" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.ShowDuration="2333333" ToolTipService.InitialShowDelay="200" Click="Refresh" LogoScale="0.85" Logo="M875.52 148.48C783.36 56.32 655.36 0 512 0 291.84 0 107.52 138.24 30.72 332.8l122.88 46.08C204.8 230.4 348.16 128 512 128c107.52 0 199.68 40.96 271.36 112.64L640 384h384V0L875.52 148.48zM512 896c-107.52 0-199.68-40.96-271.36-112.64L384 640H0v384l148.48-148.48C240.64 967.68 368.64 1024 512 1024c220.16 0 404.48-138.24 481.28-332.8L870.4 645.12C819.2 793.6 675.84 896 512 896z" />
</x:Array>
</local:MyListItem.Buttons>
</local:MyListItem>
</StackPanel>
</local:MyPageLeft>
@@ -0,0 +1,140 @@
Public Class PageOtherLeft
Private IsLoad As Boolean = False
Private IsPageSwitched As Boolean = False '如果在 Loaded 前切换到其他页面,会导致触发 Loaded 时再次切换一次
Private Sub PageOtherLeft_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
'是否处于隐藏的子页面
Dim IsHiddenPage As Boolean = False
If ItemHelp.Checked AndAlso Setup.Get("UiHiddenOtherHelp") Then IsHiddenPage = True
If ItemFeedback.Checked AndAlso Setup.Get("UiHiddenOtherFeedback") Then IsHiddenPage = True
If ItemAbout.Checked AndAlso Setup.Get("UiHiddenOtherAbout") Then IsHiddenPage = True
If ItemTest.Checked AndAlso Setup.Get("UiHiddenOtherTest") Then IsHiddenPage = True
If PageSetupUI.HiddenForceShow Then IsHiddenPage = False
'若页面错误,或尚未加载,则继续
If IsLoad AndAlso Not IsHiddenPage Then Exit Sub
IsLoad = True
'刷新子页面隐藏情况
PageSetupUI.HiddenRefresh()
'选择第一个未被禁用的子页面
If IsPageSwitched Then Exit Sub
If Not Setup.Get("UiHiddenOtherHelp") Then
ItemHelp.SetChecked(True, False, False)
ElseIf Not Setup.Get("UiHiddenOtherAbout") Then
ItemAbout.SetChecked(True, False, False)
ElseIf Not Setup.Get("UiHiddenOtherTest") Then
ItemTest.SetChecked(True, False, False)
Else
ItemFeedback.SetChecked(True, False, False)
End If
End Sub
Private Sub PageOtherLeft_Unloaded(sender As Object, e As RoutedEventArgs) Handles Me.Unloaded
IsPageSwitched = False
End Sub
#Region "页面切换"
''' <summary>
''' 当前页面的编号。从 0 开始计算。
''' </summary>
Public PageID As FormMain.PageSubType
Public Sub New()
InitializeComponent()
'选择第一个未被禁用的子页面
If Not Setup.Get("UiHiddenOtherHelp") Then
PageID = FormMain.PageSubType.OtherHelp
ElseIf Not Setup.Get("UiHiddenOtherAbout") Then
PageID = FormMain.PageSubType.OtherAbout
ElseIf Not Setup.Get("UiHiddenOtherTest") Then
PageID = FormMain.PageSubType.OtherTest
Else
PageID = FormMain.PageSubType.OtherFeedback
End If
End Sub
''' <summary>
''' 勾选事件改变页面。
''' </summary>
Private Sub PageCheck(sender As MyListItem, e As RouteEventArgs) Handles ItemAbout.Check, ItemHelp.Check, ItemFeedback.Check, ItemTest.Check
'尚未初始化控件属性时,sender.Tag 为 Nothing,会导致切换到页面 0
'若使用 IsLoaded,则会导致模拟点击不被执行(模拟点击切换页面时,控件的 IsLoaded 为 False)
If sender.Tag IsNot Nothing Then PageChange(Val(sender.Tag))
End Sub
Public Function PageGet(Optional ID As FormMain.PageSubType = -1)
If ID = -1 Then ID = PageID
Select Case ID
Case FormMain.PageSubType.OtherHelp
If FrmOtherHelp Is Nothing Then FrmOtherHelp = New PageOtherHelp
Return FrmOtherHelp
Case FormMain.PageSubType.OtherFeedback
If FrmOtherFeedback Is Nothing Then FrmOtherFeedback = New PageOtherFeedback
Return FrmOtherFeedback
Case FormMain.PageSubType.OtherAbout
If FrmOtherAbout Is Nothing Then FrmOtherAbout = New PageOtherAbout
Return FrmOtherAbout
Case FormMain.PageSubType.OtherTest
If FrmOtherTest Is Nothing Then FrmOtherTest = New PageOtherTest
Return FrmOtherTest
Case Else
Throw New Exception("未知的更多子页面种类:" & ID)
End Select
End Function
''' <summary>
''' 切换现有页面。
''' </summary>
Public Sub PageChange(ID As FormMain.PageSubType)
If PageID = ID Then Exit Sub
AniControlEnabled += 1
IsPageSwitched = True
Try
PageChangeRun(PageGet(ID))
PageID = ID
Catch ex As Exception
Log(ex, "切换设置分页面失败(ID " & ID & ")", LogLevel.Feedback)
Finally
AniControlEnabled -= 1
End Try
End Sub
Private Shared Sub PageChangeRun(Target As MyPageRight)
AniStop("FrmMain PageChangeRight") '停止主页面的右页面切换动画,防止它与本动画一起触发多次 PageOnEnter
If Target.Parent IsNot Nothing Then Target.SetValue(ContentPresenter.ContentProperty, Nothing)
FrmMain.PageRight = Target
CType(FrmMain.PanMainRight.Child, MyPageRight).PageOnExit()
AniStart({
AaCode(Sub()
CType(FrmMain.PanMainRight.Child, MyPageRight).PageOnForceExit()
FrmMain.PanMainRight.Child = FrmMain.PageRight
FrmMain.PageRight.Opacity = 0
End Sub, 130),
AaCode(Sub()
'延迟触发页面通用动画,以使得在 Loaded 事件中加载的控件得以处理
FrmMain.PageRight.Opacity = 1
FrmMain.PageRight.PageOnEnter()
End Sub, 30, True)
}, "PageLeft PageChange")
End Sub
#End Region
'强制刷新
Public Sub Refresh(sender As Object, e As EventArgs) '由边栏按钮匿名调用
Select Case Val(sender.Tag)
Case FormMain.PageSubType.OtherHelp
RefreshHelp()
Case FormMain.PageSubType.OtherFeedback
If FrmOtherFeedback IsNot Nothing Then
FrmOtherFeedback.PageLoaderRestart()
FrmOtherFeedback.SearchBox.Text = ""
Else
FeedbackLoader.Start()
End If
End Select
End Sub
Public Shared Sub RefreshHelp()
Setup.Set("SystemHelpVersion", 0) '强制重新解压文件
FrmOtherHelp.PageLoaderRestart()
FrmOtherHelp.SearchBox.Text = ""
End Sub
End Class
@@ -0,0 +1,17 @@
<local:MyPageLeft
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:PCL;assembly=" x:Class="PageSelectLeft"
AnimatedControl="{Binding ElementName=PanList, Mode=OneWay}">
<AdornerDecorator>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
<RowDefinition Height="5" />
</Grid.RowDefinitions>
<local:MyScrollViewer DeltaMuity="0.7" Grid.Row="1" MaxWidth="300" MinWidth="250" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" Style="{StaticResource ScrollViewerFullMargin}">
<StackPanel x:Name="PanList" />
</local:MyScrollViewer>
</Grid>
</AdornerDecorator>
</local:MyPageLeft>
@@ -0,0 +1,404 @@
Public Class PageSelectLeft
Private Sub PageSelectLeft_Initialized(sender As Object, e As EventArgs) Handles Me.Initialized
AddHandler McFolderListLoader.PreviewFinish, Sub() If FrmSelectLeft IsNot Nothing Then RunInUiWait(AddressOf McFolderListUI)
End Sub
Private IsFirstLoad As Boolean = True
Private Sub PageSelectLeft_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
If IsFirstLoad Then McFolderListUI() '若已经执行完成,触发首次加载
IsFirstLoad = False
End Sub
Private Sub McFolderListUI()
Try
'确认数据有变化
If McFolderListLast IsNot Nothing AndAlso McFolderListLast.SequenceEqual(McFolderList) Then
Dim IsEqual As Boolean = True
For i = 0 To McFolderListLast.Count - 1
If Not McFolderListLast(i).Equals(McFolderList(i)) Then
IsEqual = False
Exit For
End If
Next
If IsEqual Then Exit Sub
End If
McFolderListLast = McFolderList
'创建 UI
FrmSelectLeft.PanList.Children.Clear()
'文件夹列表
FrmSelectLeft.PanList.Children.Add(New TextBlock With {.Text = "文件夹列表", .Margin = New Thickness(13, 18, 5, 4), .Opacity = 0.6, .FontSize = 12})
For Each Folder As McFolder In McFolderList.ToArray
'添加控件
Dim ContMenu As ContextMenu = Nothing
Select Case Folder.Type
Case McFolderType.Original
ContMenu = GetObjectFromXML(
<ContextMenu xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:PCL;assembly=Plain Craft Launcher 2">
<local:MyMenuItem x:Name="Rename" Header="重命名" Padding="0,2,0,0" Icon="F1 M 53.2929,21.2929L 54.7071,22.7071C 56.4645,24.4645 56.4645,27.3137 54.7071,29.0711L 52.2323,31.5459L 44.4541,23.7677L 46.9289,21.2929C 48.6863,19.5355 51.5355,19.5355 53.2929,21.2929 Z M 31.7262,52.052L 23.948,44.2738L 43.0399,25.182L 50.818,32.9601L 31.7262,52.052 Z M 23.2409,47.1023L 28.8977,52.7591L 21.0463,54.9537L 23.2409,47.1023 Z"/>
<local:MyMenuItem x:Name="Open" Header="打开" Icon="F1 M 19,50L 28,34L 63,34L 54,50L 19,50 Z M 19,28.0001L 35,28C 36,25 37.4999,24.0001 37.4999,24.0001L 48.75,24C 49.3023,24 50,24.6977 50,25.25L 50,28L 54,28.0001L 54,32L 27,32L 19,46.4L 19,28.0001 Z"/>
<local:MyMenuItem x:Name="Refresh" Header="刷新" Icon="F1 M 38,20.5833C 42.9908,20.5833 47.4912,22.6825 50.6667,26.046L 50.6667,17.4167L 55.4166,22.1667L 55.4167,34.8333L 42.75,34.8333L 38,30.0833L 46.8512,30.0833C 44.6768,27.6539 41.517,26.125 38,26.125C 31.9785,26.125 27.0037,30.6068 26.2296,36.4167L 20.6543,36.4167C 21.4543,27.5397 28.9148,20.5833 38,20.5833 Z M 38,49.875C 44.0215,49.875 48.9963,45.3932 49.7703,39.5833L 55.3457,39.5833C 54.5457,48.4603 47.0852,55.4167 38,55.4167C 33.0092,55.4167 28.5088,53.3175 25.3333,49.954L 25.3333,58.5833L 20.5833,53.8333L 20.5833,41.1667L 33.25,41.1667L 38,45.9167L 29.1487,45.9167C 31.3231,48.3461 34.483,49.875 38,49.875 Z"/>
<local:MyMenuItem x:Name="Delete" Header="删除" Padding="0,0,0,2" Icon="F1 M 26.9166,22.1667L 37.9999,33.25L 49.0832,22.1668L 53.8332,26.9168L 42.7499,38L 53.8332,49.0834L 49.0833,53.8334L 37.9999,42.75L 26.9166,53.8334L 22.1666,49.0833L 33.25,38L 22.1667,26.9167L 26.9166,22.1667 Z "/>
</ContextMenu>
)
Case McFolderType.RenamedOriginal
ContMenu = GetObjectFromXML(
<ContextMenu xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:PCL;assembly=Plain Craft Launcher 2">
<local:MyMenuItem x:Name="Remove" Header="复原名称" Padding="0,2,0,0" Icon="F1 M 53.2929,21.2929L 54.7071,22.7071C 56.4645,24.4645 56.4645,27.3137 54.7071,29.0711L 52.2323,31.5459L 44.4541,23.7677L 46.9289,21.2929C 48.6863,19.5355 51.5355,19.5355 53.2929,21.2929 Z M 31.7262,52.052L 23.948,44.2738L 43.0399,25.182L 50.818,32.9601L 31.7262,52.052 Z M 23.2409,47.1023L 28.8977,52.7591L 21.0463,54.9537L 23.2409,47.1023 Z"/>
<local:MyMenuItem x:Name="Rename" Header="重命名" Icon="F1 M 53.2929,21.2929L 54.7071,22.7071C 56.4645,24.4645 56.4645,27.3137 54.7071,29.0711L 52.2323,31.5459L 44.4541,23.7677L 46.9289,21.2929C 48.6863,19.5355 51.5355,19.5355 53.2929,21.2929 Z M 31.7262,52.052L 23.948,44.2738L 43.0399,25.182L 50.818,32.9601L 31.7262,52.052 Z M 23.2409,47.1023L 28.8977,52.7591L 21.0463,54.9537L 23.2409,47.1023 Z"/>
<local:MyMenuItem x:Name="Open" Header="打开" Icon="F1 M 19,50L 28,34L 63,34L 54,50L 19,50 Z M 19,28.0001L 35,28C 36,25 37.4999,24.0001 37.4999,24.0001L 48.75,24C 49.3023,24 50,24.6977 50,25.25L 50,28L 54,28.0001L 54,32L 27,32L 19,46.4L 19,28.0001 Z"/>
<local:MyMenuItem x:Name="Refresh" Header="刷新" Icon="F1 M 38,20.5833C 42.9908,20.5833 47.4912,22.6825 50.6667,26.046L 50.6667,17.4167L 55.4166,22.1667L 55.4167,34.8333L 42.75,34.8333L 38,30.0833L 46.8512,30.0833C 44.6768,27.6539 41.517,26.125 38,26.125C 31.9785,26.125 27.0037,30.6068 26.2296,36.4167L 20.6543,36.4167C 21.4543,27.5397 28.9148,20.5833 38,20.5833 Z M 38,49.875C 44.0215,49.875 48.9963,45.3932 49.7703,39.5833L 55.3457,39.5833C 54.5457,48.4603 47.0852,55.4167 38,55.4167C 33.0092,55.4167 28.5088,53.3175 25.3333,49.954L 25.3333,58.5833L 20.5833,53.8333L 20.5833,41.1667L 33.25,41.1667L 38,45.9167L 29.1487,45.9167C 31.3231,48.3461 34.483,49.875 38,49.875 Z"/>
<local:MyMenuItem x:Name="Delete" Header="删除" Padding="0,0,0,2" Icon="F1 M 26.9166,22.1667L 37.9999,33.25L 49.0832,22.1668L 53.8332,26.9168L 42.7499,38L 53.8332,49.0834L 49.0833,53.8334L 37.9999,42.75L 26.9166,53.8334L 22.1666,49.0833L 33.25,38L 22.1667,26.9167L 26.9166,22.1667 Z "/>
</ContextMenu>
)
Case McFolderType.Custom
ContMenu = GetObjectFromXML(
<ContextMenu xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:PCL;assembly=Plain Craft Launcher 2">
<local:MyMenuItem x:Name="Rename" Header="重命名" Padding="0,2,0,0" Icon="F1 M 53.2929,21.2929L 54.7071,22.7071C 56.4645,24.4645 56.4645,27.3137 54.7071,29.0711L 52.2323,31.5459L 44.4541,23.7677L 46.9289,21.2929C 48.6863,19.5355 51.5355,19.5355 53.2929,21.2929 Z M 31.7262,52.052L 23.948,44.2738L 43.0399,25.182L 50.818,32.9601L 31.7262,52.052 Z M 23.2409,47.1023L 28.8977,52.7591L 21.0463,54.9537L 23.2409,47.1023 Z"/>
<local:MyMenuItem x:Name="Open" Header="打开" Icon="F1 M 19,50L 28,34L 63,34L 54,50L 19,50 Z M 19,28.0001L 35,28C 36,25 37.4999,24.0001 37.4999,24.0001L 48.75,24C 49.3023,24 50,24.6977 50,25.25L 50,28L 54,28.0001L 54,32L 27,32L 19,46.4L 19,28.0001 Z"/>
<local:MyMenuItem x:Name="Refresh" Header="刷新" Icon="F1 M 38,20.5833C 42.9908,20.5833 47.4912,22.6825 50.6667,26.046L 50.6667,17.4167L 55.4166,22.1667L 55.4167,34.8333L 42.75,34.8333L 38,30.0833L 46.8512,30.0833C 44.6768,27.6539 41.517,26.125 38,26.125C 31.9785,26.125 27.0037,30.6068 26.2296,36.4167L 20.6543,36.4167C 21.4543,27.5397 28.9148,20.5833 38,20.5833 Z M 38,49.875C 44.0215,49.875 48.9963,45.3932 49.7703,39.5833L 55.3457,39.5833C 54.5457,48.4603 47.0852,55.4167 38,55.4167C 33.0092,55.4167 28.5088,53.3175 25.3333,49.954L 25.3333,58.5833L 20.5833,53.8333L 20.5833,41.1667L 33.25,41.1667L 38,45.9167L 29.1487,45.9167C 31.3231,48.3461 34.483,49.875 38,49.875 Z"/>
<local:MyMenuItem x:Name="Remove" Header="移出列表" Icon="F1 M 23.3428,25.205L 23.3805,25.4461C 23.9229,27.177 30.261,29.0992 38,29.0992C 45.7386,29.0992 52.0765,27.1771 52.6194,25.4463L 52.6571,25.205C 52.6571,23.3616 46.0949,21.3109 38,21.3109C 29.9051,21.3109 23.3428,23.3616 23.3428,25.205 Z M 23.3428,53.0204L 19.1571,26.2111C 19.0534,25.8817 19,25.5459 19,25.205C 19,20.9036 27.5066,17.4167 38,17.4167C 48.4934,17.4167 57,20.9036 57,25.205C 57,25.5459 56.9466,25.8818 56.8429,26.2112L 52.6571,53.0204L 52.5974,53.0204C 51.9241,56.1393 45.6457,58.5833 38,58.5833C 30.3543,58.5833 24.076,56.1393 23.4026,53.0204L 23.3428,53.0204 Z M 51.8228,30.5485C 48.3585,32.0537 43.4469,32.9933 38,32.9933C 32.5531,32.9933 27.6415,32.0537 24.1771,30.5484L 27.5988,52.464L 27.6857,52.464C 27.6857,53.3857 32.3036,54.6892 38,54.6892C 43.6964,54.6892 48.3143,53.3857 48.3143,52.464L 48.4011,52.464L 51.8228,30.5485 Z "/>
<local:MyMenuItem x:Name="Delete" Header="删除" Padding="0,0,0,2" Icon="F1 M 26.9166,22.1667L 37.9999,33.25L 49.0832,22.1668L 53.8332,26.9168L 42.7499,38L 53.8332,49.0834L 49.0833,53.8334L 37.9999,42.75L 26.9166,53.8334L 22.1666,49.0833L 33.25,38L 22.1667,26.9167L 26.9166,22.1667 Z "/>
</ContextMenu>
)
End Select
If (Folder.Type = McFolderType.Original OrElse Folder.Type = McFolderType.RenamedOriginal) AndAlso Folder.Path = Path & ".minecraft\" AndAlso McFolderList.Count = 1 Then CType(ContMenu.FindName("Delete"), MyMenuItem).Header = "清空"
'注册事件
If Not Folder.Type = McFolderType.Original Then CType(ContMenu.FindName("Remove"), MyMenuItem).AddHandler(MyMenuItem.ClickEvent, New RoutedEventHandler(AddressOf FrmSelectLeft.Remove_Click))
CType(ContMenu.FindName("Open"), MyMenuItem).AddHandler(MyMenuItem.ClickEvent, New RoutedEventHandler(AddressOf FrmSelectLeft.Open_Click))
CType(ContMenu.FindName("Delete"), MyMenuItem).AddHandler(MyMenuItem.ClickEvent, New RoutedEventHandler(AddressOf FrmSelectLeft.Delete_Click))
CType(ContMenu.FindName("Rename"), MyMenuItem).AddHandler(MyMenuItem.ClickEvent, New RoutedEventHandler(AddressOf FrmSelectLeft.Rename_Click))
CType(ContMenu.FindName("Refresh"), MyMenuItem).AddHandler(MyMenuItem.ClickEvent, New RoutedEventHandler(AddressOf FrmSelectLeft.Refresh_Click))
'构建框架与图表按钮
Dim NewItem As New MyListItem With {.IsScaleAnimationEnabled = False, .Type = MyListItem.CheckType.RadioBox, .PaddingRight = 30, .Title = Folder.Name, .Info = Folder.Path, .Height = 40, .ContextMenu = ContMenu, .Tag = Folder}
AddHandler NewItem.Changed, AddressOf FrmSelectLeft.Folder_Change
Dim NewIconButton As New MyIconButton With {.Logo = Logo.IconButtonSetup, .LogoScale = 1.1}
AddHandler NewIconButton.Click, Sub(sender, e)
ContMenu.PlacementTarget = NewItem
ContMenu.IsOpen = True
End Sub
NewItem.Buttons = {NewIconButton}
FrmSelectLeft.PanList.Children.Add(NewItem)
Log("[Minecraft] 有效的 Minecraft 文件夹:" & Folder.Name & " > " & Folder.Path)
Next
'标题文本
FrmSelectLeft.PanList.Children.Add(New TextBlock With {.Text = "添加或导入", .Margin = New Thickness(13, 18, 5, 4), .Opacity = 0.6, .FontSize = 12})
'确认创建按钮状态
If Not Directory.Exists(Path & ".minecraft\") Then
Dim ItemCreate As New MyListItem With {.IsScaleAnimationEnabled = False, .Type = MyListItem.CheckType.Clickable, .Title = "新建 .minecraft 文件夹", .Height = 34,
.ToolTip = "在 PCL 当前所在文件夹下创建新的 .minecraft 文件夹",
.LogoScale = 0.9,
.Logo = "M103.331925 384.978025l25.805736 0L129.137661 161.847132c0-18.313088 14.905478-33.718963 33.718963-33.718963l0.969071 0 253.006318 0c10.82044 0 20.218484 4.797259 26.500561 12.257162l117.579929 126.753869 297.819966 0c18.297738 0 33.736359 15.179724 33.736359 33.977859l0 0.952698 0 82.909292 25.547863 0c18.538215 0 34.187637 15.179724 34.187637 33.977859 0 2.163269-0.469698 3.617387-0.469698 5.539156l-54.437843 432.971086c-1.210571 10.382465-7.007601 19.056008-14.968923 24.352641-6.249331 5.765307-14.680351 9.624195-23.595394 9.624195l-0.969071 0-694.906773 0c-9.155521 0-17.344017-3.858888-23.626094-9.155521-8.67252-5.765307-14.453177-14.939247-15.389502-25.758664L69.597613 423.040922c-2.165316-18.313088 10.868535-35.414581 29.665647-38.062897L103.331925 384.978025 103.331925 384.978025zM196.576609 384.978025 196.576609 384.978025l627.938546 0 0-49.625234L546.461371 335.352791l0 0c-9.400091 0-18.329461-4.117784-25.048489-11.110035L402.363486 196.067514 196.576609 196.067514 196.576609 384.978025 196.576609 384.978025zM879.469767 452.916347 879.469767 452.916347l-20.267603 0-0.469698 0-0.969071 0-694.906773 0-0.984421 0-20.218484 0 45.781696 366.728382 646.218888 0L879.469767 452.916347 879.469767 452.916347z"}
ToolTipService.SetPlacement(ItemCreate, Primitives.PlacementMode.Right)
ToolTipService.SetHorizontalOffset(ItemCreate, -50)
ToolTipService.SetVerticalOffset(ItemCreate, 2.5)
ToolTipService.SetShowDuration(ItemCreate, 2333333)
FrmSelectLeft.PanList.Children.Add(ItemCreate)
AddHandler ItemCreate.Click, AddressOf FrmSelectLeft.Create_Click
End If
'添加按钮
Dim ItemAdd As New MyListItem With {.IsScaleAnimationEnabled = False, .Type = MyListItem.CheckType.Clickable, .Title = "添加已有文件夹", .Height = 34,
.ToolTip = "将一个已有的 Minecraft 文件夹添加到列表",
.Logo = "M512.277 954.412c-118.89 0-230.659-46.078-314.73-129.73S67.12 629.666 67.12 511.222s46.327-229.744 130.398-313.427 195.82-129.73 314.73-129.73 230.659 46.078 314.72 129.73S957.397 392.81 957.397 511.183 911.078 740.96 826.97 824.642s-195.8 129.77-314.692 129.77z m0-822.784c-101.972 0-197.809 39.494-269.865 111.222s-111.7 166.997-111.7 268.373 39.653 196.695 111.67 268.335S410.246 890.78 512.248 890.78s197.809-39.484 269.865-111.222 111.7-166.998 111.67-268.374c-0.03-101.375-39.654-196.665-111.67-268.303S614.22 131.628 512.277 131.628z m222.585 347.8H544.073V288.64c-0.76-17.561-15.613-31.18-33.173-30.419-16.495 0.714-29.704 13.924-30.419 30.419v190.787H289.703c-17.56 0.761-31.179 15.614-30.419 33.174 0.715 16.494 13.924 29.703 30.42 30.418H480.48v190.788c0.761 17.56 15.614 31.179 33.174 30.419 16.494-0.715 29.703-13.925 30.418-30.42V543.02h190.788c17.56 0.762 32.413-12.857 33.173-30.418 0.762-17.561-12.858-32.414-30.419-33.174a31.683 31.683 0 0 0-2.753 0z"}
ToolTipService.SetPlacement(ItemAdd, Primitives.PlacementMode.Right)
ToolTipService.SetHorizontalOffset(ItemAdd, -50)
ToolTipService.SetVerticalOffset(ItemAdd, 2.5)
ToolTipService.SetShowDuration(ItemAdd, 2333333)
FrmSelectLeft.PanList.Children.Add(ItemAdd)
AddHandler ItemAdd.Click, AddressOf FrmSelectLeft.Add_Click
'安装按钮
Dim ItemInstall As New MyListItem With {.IsScaleAnimationEnabled = False, .Type = MyListItem.CheckType.Clickable, .Title = "导入整合包", .Height = 34,
.ToolTip = "在当前选择的 Minecraft 文件夹下安装整合包",
.Logo = "M512 40.96C249.344 40.96 35.84 252.416 35.84 512s213.504 471.04 476.16 471.04c103.424 0 202.752-33.28 286.72-96.256l1.536-1.536c5.12-5.632 7.68-12.8 7.68-19.968 0-16.896-13.824-30.208-30.72-30.208-7.68 0-15.36 2.56-20.992 7.68h-0.512c-71.68 52.224-155.648 79.36-243.712 79.36-227.328 0-412.16-182.784-412.16-407.552 0-224.768 184.832-407.552 412.16-407.552s412.16 182.784 412.16 407.552c0 68.608-15.872 132.608-46.592 190.464-0.512 1.024-1.024 2.048-1.024 3.072-0.512 2.048-1.536 4.608-1.536 8.192 0 16.896 13.824 30.208 30.72 30.208 12.288 0 23.04-7.168 28.16-18.432 35.84-68.608 53.76-141.312 53.76-216.064 0.512-259.584-212.992-471.04-475.648-471.04z M812.032 483.328c-31.744-20.992-71.68 1.536-78.848 6.144-1.024 0.512-104.448 61.44-128 74.752-8.192 4.608-22.528-0.512-27.136-4.096-31.232-36.352-54.272-70.656-68.608-102.4-13.312-29.184 0.512-41.472 3.072-43.52 7.168-4.608 114.688-68.608 143.36-83.456 24.064-12.288 40.96-25.088 46.08-45.056 3.072-13.312 0-27.136-9.216-39.936-22.016-31.744-172.544-84.992-311.296-3.584-157.184 91.648-152.064 242.688-150.528 292.352v9.216c0 18.944-12.8 37.376-14.848 40.448l-20.992 21.504c-6.144 6.144-9.216 13.824-9.216 22.528 0 8.704 3.584 16.384 9.728 22.528 12.8 12.288 32.768 11.776 45.056-0.512l22.528-23.552 0.512-0.512c3.072-3.584 30.208-38.4 30.208-81.92l-0.512-11.264c-1.536-44.544-5.632-162.816 119.296-235.52 88.064-51.2 173.056-32.256 208.896-19.968-36.864 19.456-143.36 83.456-144.896 84.48-22.016 14.336-55.808 58.88-26.112 122.88 17.408 37.376 43.52 76.8 80.896 120.32 14.336 17.408 62.976 37.376 103.424 15.36 24.576-13.312 125.44-73.216 130.048-75.776 2.048-1.024 4.608-2.56 7.68-3.584 0 2.56-0.512 6.144-1.024 10.752-5.632 35.84-35.328 155.136-191.488 181.76-49.664 8.704-89.6 3.584-121.856-0.512h-0.512c-37.888-4.608-73.216-9.216-101.888 14.336-31.232 26.112-40.96 34.304-35.84 54.272 3.584 14.336 16.384 24.064 30.72 24.064 2.56 0 5.12-0.512 7.68-1.024 6.656-1.536 12.8-5.632 16.896-10.752 2.048-2.048 7.68-6.656 20.992-18.432 6.656-5.632 25.088-3.584 52.736 0 34.816 4.608 81.92 10.24 141.312 0.512 157.184-26.624 228.864-138.752 243.2-234.496 7.68-38.912 0-64.512-21.504-78.336z"}
ToolTipService.SetPlacement(ItemInstall, Primitives.PlacementMode.Right)
ToolTipService.SetHorizontalOffset(ItemInstall, -50)
ToolTipService.SetVerticalOffset(ItemInstall, 2.5)
ToolTipService.SetShowDuration(ItemInstall, 2333333)
FrmSelectLeft.PanList.Children.Add(ItemInstall)
AddHandler ItemInstall.Click, AddressOf ModpackInstall
'边距
FrmSelectLeft.PanList.Children.Add(New FrameworkElement With {.Height = 10, .IsHitTestVisible = False})
'确认勾选状态
For i = 0 To McFolderList.Count - 1
If McFolderList(i).Path = PathMcFolder Then
CType(FrmSelectLeft.PanList.Children(i + 1), MyListItem).Checked = True '去掉第一个标题
Exit Sub
End If
Next
If McFolderList.Count = 0 Then
Throw New ArgumentNullException("没有可用的 Minecraft 文件夹")
Else
Setup.Set("LaunchFolderSelect", McFolderList(0).Path.Replace(Path, "$"))
CType(FrmSelectLeft.PanList.Children(1), MyListItem).Checked = True
End If
Catch ex As Exception
Log(ex, "构建 Minecraft 文件夹列表 UI 出错", LogLevel.Feedback)
Finally
LoaderFolderRun(McVersionListLoader, PathMcFolder, LoaderFolderRunType.RunOnUpdated, MaxDepth:=1, ExtraPath:="versions\") '刷新版本列表
End Try
End Sub
Private McFolderListLast As List(Of McFolder)
'添加文件夹
Public Sub Add_Click()
Dim NewFolder As String = ""
'检查是否有下载任务
If HasDownloadingTask() Then
Hint("请不要在下载过程中添加游戏文件夹!", HintType.Critical)
Exit Sub
End If
Try
'获取输入
NewFolder = SelectFolder()
If NewFolder = "" Then Exit Sub
If NewFolder.Contains("!") OrElse NewFolder.Contains(";") Then Hint("Minecraft 文件夹路径中不能含有感叹号或分号!", HintType.Critical) : Exit Sub
'要求输入显示名称
Dim SplitedNames As String() = NewFolder.TrimEnd("\").Split("\")
Dim NewName As String = MyMsgBoxInput(If(SplitedNames.Last = ".minecraft", If(SplitedNames.Count >= 3, SplitedNames(SplitedNames.Count - 2), ""), SplitedNames.Last), New ObjectModel.Collection(Of Validate) From {
New ValidateNullOrWhiteSpace, New ValidateLength(1, 30), New ValidateExcept({">", "|"})
},, "输入显示名称",, "取消")
If String.IsNullOrWhiteSpace(NewName) Then Exit Sub
'添加文件夹
AddFolder(NewFolder, NewName, True)
Catch ex As Exception
Log(ex, "添加文件夹失败(" & NewFolder & ")", LogLevel.Feedback)
End Try
End Sub
Public Shared Sub AddFolder(FolderPath As String, DisplayName As String, ShowHint As Boolean)
RunInThread(
Sub()
Try
If Not FolderPath.EndsWith("\") Then FolderPath &= "\" '加上斜杠……
'检查文件夹权限
If Not CheckPermission(FolderPath) Then
If ShowHint Then
Hint("添加文件夹失败:PCL 没有访问该文件夹的权限!", HintType.Critical)
Exit Sub
Else
Throw New Exception("PCL 没有访问文件夹的权限:" & FolderPath)
End If
End If
'检查实际的 Minecraft 文件夹位置(没有问题,或是在子文件夹中)
If Not CheckPermission(FolderPath & "versions\") Then
For Each Folder As DirectoryInfo In New DirectoryInfo(FolderPath).GetDirectories
If CheckPermission(Folder.FullName & "\versions\") Then
FolderPath = Folder.FullName & "\"
Exit For
End If
Next
End If
'判断是否已经添加过,若添加过则直接修改自定义名
Dim Folders As New List(Of String)(Setup.Get("LaunchFolders").ToString.Split("|"))
Dim IsAdded As Boolean = False
Dim IsReplace As Boolean = False
For i = 0 To Folders.Count - 1
Dim Folder As String = Folders(i)
If Folder = "" Then Continue For
If Folder.Split(">")(1) = FolderPath Then
IsAdded = True
If Folder.Split(">")(0) = DisplayName Then
If ShowHint Then Hint("此文件夹已在列表中!", HintType.Info)
Exit Sub
Else
Folders(i) = DisplayName & ">" & FolderPath
IsReplace = True
If ShowHint Then Hint("文件夹名称已更新为 " & DisplayName & " !", HintType.Finish)
End If
Exit For
End If
Next
'如果没有添加过,则添加进去
If Not IsAdded Then Folders.Add(DisplayName & ">" & FolderPath)
'保存
Setup.Set("LaunchFolders", Join(Folders.ToArray, "|"))
'切换选择并更新列表
Setup.Set("LaunchFolderSelect", FolderPath.Replace(Path, "$"))
McFolderListLoader.Start(IsForceRestart:=True)
'提示
If IsReplace Then Exit Sub
If ShowHint Then Hint("文件夹 " & DisplayName & " 已添加!", HintType.Finish)
'自动关闭版本隔离
'1. 根目录中存在数个 Mod
Dim ModFolder As New DirectoryInfo(FolderPath & "mods\")
If Not (ModFolder.Exists AndAlso ModFolder.EnumerateFiles.Count >= 3) Then Exit Sub
'2. 版本数较少,可能为整合包
Dim VersionFolder As New DirectoryInfo(FolderPath & "versions\")
If Not (VersionFolder.Exists AndAlso VersionFolder.EnumerateDirectories.Count <= 3) Then Exit Sub
'3. 能够找到可安装 Mod 的版本
For Each VersionPath In VersionFolder.EnumerateDirectories
Dim Version As New McVersion(VersionPath.FullName)
Version.Load()
If Not Version.Version.Modable Then Continue For
'4. 该版本的隔离文件夹下不存在 mods
Dim ModIndieFolder As New DirectoryInfo(Version.Path & "mods\")
If ModIndieFolder.Exists AndAlso ModIndieFolder.EnumerateFiles.Count > 0 Then Exit Sub
'满足以上全部条件则视为根目录整合包
Setup.Set("VersionArgumentIndie", 2, Version:=Version)
Log("[Setup] 已自动关闭单版本隔离:" & Version.Name, LogLevel.Debug)
Next
Catch ex As Exception
Log(ex, "向文件夹列表中添加新文件夹失败", LogLevel.Feedback)
End Try
End Sub)
End Sub
'创建文件夹
Public Sub Create_Click()
'检查是否有下载任务
If HasDownloadingTask() Then
Hint("请不要在下载过程中创建游戏文件夹!", HintType.Critical)
Exit Sub
End If
If Not Directory.Exists(Path & ".minecraft\") Then
Directory.CreateDirectory(Path & ".minecraft\")
Directory.CreateDirectory(Path & ".minecraft\versions\")
Setup.Set("LaunchFolderSelect", "$.minecraft\")
Hint("新建 .minecraft 文件夹成功!", HintType.Finish)
End If
McFolderListLoader.Start(IsForceRestart:=True)
End Sub
'右键菜单
Public Sub Remove_Click(sender As Object, e As RoutedEventArgs)
Try
Dim Folder As McFolder = CType(CType(CType(sender.Parent, ContextMenu).Parent, Primitives.Popup).PlacementTarget, MyListItem).Tag
'若为 “移除”,则提醒是否删除 PCL 的配置文件
If Folder.Type = McFolderType.Custom Then
Select Case MyMsgBox("是否需要清理 PCL 在该文件夹中的配置文件?" & vbCrLf & "这包括各个版本的独立设置(如自定义图标、第三方登录配置)等,对游戏本身没有影响。", "配置文件清理", "删除", "保留", "取消")
Case 1
'删除配置文件
If File.Exists(Folder.Path & "PCL.ini") Then File.Delete(Folder.Path & "PCL.ini")
If Directory.Exists(Folder.Path & "versions\") Then
For Each Version In New DirectoryInfo(Folder.Path & "versions\").EnumerateDirectories
If Directory.Exists(Version.FullName & "\PCL\") Then Directory.Delete(Version.FullName & "\PCL\", True)
Next
End If
Case 2
'不删除
Case 3
'取消
Exit Sub
End Select
End If
'若修改了本部分代码,应对应修改 Delete_Click 中的代码
'获取并删除列表项
Dim Folders As New List(Of String)(Setup.Get("LaunchFolders").ToString.Split("|"))
Dim Name As String = ""
For i = 0 To Folders.Count - 1
If Folders(i) = "" Then Exit For
If Folders(i).ToString.EndsWith(Folder.Path) Then
Name = Folders(i).ToString.Split(">")(0)
Folders.RemoveAt(i)
Exit For
End If
Next
'保存
Setup.Set("LaunchFolders", If(Folders.Count = 0, "", Join(Folders.ToArray, "|")))
Hint(If(Folder.Type = McFolderType.Custom, "文件夹 " & Name & " 已从列表中移除!", "文件夹名称已复原!"), HintType.Finish)
McFolderListLoader.Start(IsForceRestart:=True)
Catch ex As Exception
Log(ex, "从列表中移除游戏文件夹失败", LogLevel.Feedback)
End Try
End Sub
Public Sub Delete_Click(sender As Object, e As RoutedEventArgs)
Dim Folder As McFolder = CType(CType(CType(sender.Parent, ContextMenu).Parent, Primitives.Popup).PlacementTarget, MyListItem).Tag
Dim DeleteText As String = If((Folder.Type = McFolderType.Original OrElse Folder.Type = McFolderType.RenamedOriginal) AndAlso Folder.Path = Path & ".minecraft\" AndAlso McFolderList.Count = 1, "清空", "删除")
If MyMsgBox("你确定要" & DeleteText & "这个文件夹吗?" & vbCrLf & "这会导致该文件夹中的所有存档与其他文件永久消失,且不可恢复!", "删除警告", "取消", "继续") = 1 Then Exit Sub
If MyMsgBox(DeleteText & "这个文件夹会导致该文件夹中的所有文件永久消失,且不可恢复!" & vbCrLf & "这是最后一次警告!", "删除警告", DeleteText, "取消",, True) = 2 Then Exit Sub
'移出列表
If Folder.Type = McFolderType.Custom Then
Dim Folders As New List(Of String)(Setup.Get("LaunchFolders").ToString.Split("|"))
For i = 0 To Folders.Count - 1
If Folders(i) = "" Then Exit For
If Folders(i).ToString.EndsWith(Folder.Path) Then
'Name = Folders(i).ToString.Split(">")(0)
Folders.RemoveAt(i)
Exit For
End If
Next
Setup.Set("LaunchFolders", If(Folders.Count = 0, "", Join(Folders.ToArray, "|")))
End If
RunInNewThread(Sub()
'删除文件夹
Try
Hint("正在" & DeleteText & "文件夹 " & Folder.Name & "!", HintType.Info)
DeleteDirectory(Folder.Path)
If DeleteText = "清空" Then Directory.CreateDirectory(Folder.Path)
Hint("已" & DeleteText & "文件夹 " & Folder.Name & "!", HintType.Finish)
Catch ex As Exception
Log(ex, DeleteText & "文件夹 " & Folder.Name & " 失败", LogLevel.Hint)
Finally
'刷新列表
McFolderListLoader.Start(IsForceRestart:=True)
End Try
End Sub, "Folder Delete " & GetUuid(), ThreadPriority.BelowNormal)
End Sub
Public Sub Open_Click(sender As Object, e As RoutedEventArgs)
OpenExplorer("""" & CType(CType(CType(sender.Parent, ContextMenu).Parent, Primitives.Popup).PlacementTarget, MyListItem).Info & """")
End Sub
Public Sub Refresh_Click(sender As Object, e As RoutedEventArgs)
Dim Data As McFolder = CType(CType(CType(sender.Parent, ContextMenu).Parent, Primitives.Popup).PlacementTarget, MyListItem).Tag
WriteIni(Data.Path & "PCL.ini", "VersionCache", "") '删除缓存以强制要求下一次加载时更新列表
If Data.Path = PathMcFolder Then LoaderFolderRun(McVersionListLoader, PathMcFolder, LoaderFolderRunType.ForceRun, MaxDepth:=1, ExtraPath:="versions\")
End Sub
Public Sub Rename_Click(sender As Object, e As RoutedEventArgs)
Dim Folder As McFolder = CType(CType(CType(sender.Parent, ContextMenu).Parent, Primitives.Popup).PlacementTarget, MyListItem).Tag
Try
'获取输入
Dim NewName As String = MyMsgBoxInput(Folder.Name, New ObjectModel.Collection(Of Validate) From {New ValidateNullOrWhiteSpace, New ValidateLength(1, 30), New ValidateExcept({">", "|"})},
, "输入新名称",, "取消")
If String.IsNullOrWhiteSpace(NewName) Then Exit Sub
'修改自定义名
Dim Folders As New List(Of String)(Setup.Get("LaunchFolders").ToString.Split("|"))
Dim IsAdded As Boolean = False
For i = 0 To Folders.Count - 1
Dim FolderCurrent As String = Folders(i)
If FolderCurrent = "" Then Continue For
If FolderCurrent.Split(">")(1) = Folder.Path Then
IsAdded = True
If FolderCurrent.Split(">")(0) = NewName Then
'名称未修改
Exit Sub
Else
Folders(i) = NewName & ">" & Folder.Path
End If
Exit For
End If
Next
'如果没有添加过,则添加进去(因为修改了默认项的名称)
If Not IsAdded Then Folders.Add(NewName & ">" & Folder.Path)
Hint("文件夹名称已更新为 " & NewName & " !", HintType.Finish)
'保存
Setup.Set("LaunchFolders", Join(Folders.ToArray, "|"))
McFolderListLoader.Start(IsForceRestart:=True)
Catch ex As Exception
Log(ex, "重命名文件夹失败", LogLevel.Feedback)
End Try
End Sub
'点击选项
Public Sub Folder_Change(sender As MyListItem, e As RouteEventArgs)
If Not e.RaiseByMouse OrElse Not sender.Checked Then Exit Sub
'检查是否有下载任务
If HasDownloadingTask(True) Then
Hint("请不要在下载过程中切换游戏文件夹!", HintType.Critical)
e.Handled = True
Exit Sub
End If
'更换
Setup.Set("LaunchFolderSelect", CType(sender.Tag, McFolder).Path.Replace(Path, "$"))
McFolderListLoader.Start(IsForceRestart:=True)
LoaderFolderRun(McVersionListLoader, PathMcFolder, LoaderFolderRunType.RunOnUpdated, MaxDepth:=1, ExtraPath:="versions\") '刷新版本列表
End Sub
End Class
@@ -0,0 +1,25 @@
<local:MyPageRight
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:PCL" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" x:Class="PageSelectRight"
d:DesignWidth="800" d:DesignHeight="800">
<Grid>
<Grid x:Name="PanAllBack">
<local:MyScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" x:Name="PanBack">
<VirtualizingStackPanel VirtualizingStackPanel.IsVirtualizing="True" VirtualizingStackPanel.VirtualizationMode="Recycling" Name="PanMain" Margin="25,25,25,10" Grid.IsSharedSizeScope="True" />
</local:MyScrollViewer>
<local:MyCard HorizontalAlignment="Center" VerticalAlignment="Center" Margin="40" x:Name="PanEmpty" UseAnimation="False">
<StackPanel Margin="20,17">
<TextBlock Name="LabEmptyTitle" Margin="0,0,0,9" HorizontalAlignment="Center" Text="无可用版本" FontSize="19" UseLayoutRounding="True" SnapsToDevicePixels="True" Foreground="{DynamicResource ColorBrush3}" />
<Rectangle HorizontalAlignment="Stretch" Height="2" Fill="{DynamicResource ColorBrush3}" />
<TextBlock Name="LabEmptyContent" Margin="10,15,10,5" Text="未找到任何版本的游戏,请先下载任意版本的游戏。&#xA;若有已存在的游戏,请在左边的列表中选择“添加文件夹”,选择 .minecraft 文件夹将其导入。" TextWrapping="Wrap" />
<local:MyButton Height="35" HorizontalAlignment="Center" x:Name="BtnEmptyDownload" MinWidth="140" Text="下载游戏" Margin="0,10,0,0" Padding="13,0" ColorType="Highlight" />
</StackPanel>
</local:MyCard>
</Grid>
<local:MyCard HorizontalAlignment="Center" VerticalAlignment="Center" SnapsToDevicePixels="True" x:Name="PanLoad" Margin="40">
<local:MyLoading Text="正在获取版本列表" Margin="20,20,20,17" x:Name="Load" HorizontalAlignment="Center" VerticalAlignment="Center" IsHitTestVisible="False" AutoRun="False" />
</local:MyCard>
</Grid>
</local:MyPageRight>
@@ -0,0 +1,266 @@
Public Class PageSelectRight
'窗口基础
Private Sub PageSelectRight_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
LoaderFolderRun(McVersionListLoader, PathMcFolder, LoaderFolderRunType.RunOnUpdated, MaxDepth:=1, ExtraPath:="versions\")
PanBack.ScrollToHome()
End Sub
Private Sub LoaderInit() Handles Me.Initialized
PageLoaderInit(Load, PanLoad, PanAllBack, Nothing, McVersionListLoader, AddressOf McVersionListUI, AutoRun:=False)
End Sub
Private Sub Load_Click(sender As Object, e As MouseButtonEventArgs) Handles Load.Click
If McModLoader.State = LoadState.Failed Then
LoaderFolderRun(McVersionListLoader, PathMcFolder, LoaderFolderRunType.ForceRun, MaxDepth:=1, ExtraPath:="versions\")
End If
End Sub
'窗口属性
''' <summary>
''' 是否显示隐藏的 Minecraft 版本。
''' </summary>
Public ShowHidden As Boolean = False
#Region "结果 UI 化"
Private Sub McVersionListUI(Loader As LoaderTask(Of String, Integer))
Try
Dim Path As String = Loader.Input
'加载 UI
PanMain.Children.Clear()
For Each Card As KeyValuePair(Of McVersionCardType, List(Of McVersion)) In McVersionList.ToArray
'确认是否为隐藏版本显示状态
If Card.Key = McVersionCardType.Hidden Xor ShowHidden Then Continue For
#Region "确认卡片名称"
Dim CardName As String = ""
Select Case Card.Key
Case McVersionCardType.OriginalLike
CardName = "常规版本"
Case McVersionCardType.API
Dim IsForgeExists As Boolean = False
Dim IsFabricExists As Boolean = False
Dim IsLiteExists As Boolean = False
For Each Version As McVersion In Card.Value
If Version.Version.HasFabric Then IsFabricExists = True
If Version.Version.HasLiteLoader Then IsLiteExists = True
If Version.Version.HasForge Then IsForgeExists = True
Next
If If(IsLiteExists, 1, 0) + If(IsForgeExists, 1, 0) + If(IsFabricExists, 1, 0) > 1 Then
CardName = "可安装 Mod"
ElseIf IsForgeExists Then
CardName = "Forge 版本"
ElseIf IsLiteExists Then
CardName = "LiteLoader 版本"
Else
CardName = "Fabric 版本"
End If
Case McVersionCardType.Error
CardName = "错误的版本"
Case McVersionCardType.Hidden
CardName = "隐藏的版本"
Case McVersionCardType.Rubbish
CardName = "不常用版本"
Case McVersionCardType.Star
CardName = "收藏夹"
Case McVersionCardType.Fool
CardName = "愚人节版本"
Case Else
Throw New ArgumentException("未知的卡片种类(" & Card.Key & ")")
End Select
#End Region
'建立控件
Dim CardTitle As String = CardName & If(CardName = "收藏夹", "", " (" & Card.Value.Count & ")")
Dim NewCard As New MyCard With {.Title = CardTitle, .Margin = New Thickness(0, 0, 0, 15), .SwapType = 0}
Dim NewStack As New StackPanel With {.Margin = New Thickness(20, MyCard.SwapedHeight, 18, 0), .VerticalAlignment = VerticalAlignment.Top, .RenderTransform = New TranslateTransform(0, 0), .Tag = Card.Value}
NewCard.Children.Add(NewStack)
NewCard.SwapControl = NewStack
PanMain.Children.Add(NewCard)
'确定卡片是否展开
If Card.Key = McVersionCardType.Rubbish OrElse Card.Key = McVersionCardType.Error OrElse Card.Key = McVersionCardType.Fool Then
NewCard.IsSwaped = True
Else
MyCard.StackInstall(NewStack, 0, CardTitle)
End If
Next
'若只有一个卡片,则强制展开
If PanMain.Children.Count = 1 AndAlso CType(PanMain.Children(0), MyCard).IsSwaped Then
CType(PanMain.Children(0), MyCard).IsSwaped = False
End If
'判断应该显示哪一个页面
If PanMain.Children.Count = 0 Then
PanEmpty.Visibility = Visibility.Visible
PanBack.Visibility = Visibility.Collapsed
If ShowHidden Then
LabEmptyTitle.Text = "无隐藏版本"
LabEmptyContent.Text = "没有版本被隐藏,你可以在版本设置的版本分类选项中隐藏版本。" & vbCrLf & "再次按下 F11 即可退出隐藏版本查看模式。"
BtnEmptyDownload.Visibility = Visibility.Collapsed
Else
LabEmptyTitle.Text = "无可用版本"
LabEmptyContent.Text = "未找到任何版本的游戏,请先下载任意版本的游戏。" & vbCrLf & "若有已存在的游戏,请在左边的列表中选择添加文件夹,选择 .minecraft 文件夹将其导入。"
BtnEmptyDownload.Visibility = If(Setup.Get("UiHiddenPageDownload") AndAlso Not PageSetupUI.HiddenForceShow, Visibility.Collapsed, Visibility.Visible)
End If
Else
PanBack.Visibility = Visibility.Visible
PanEmpty.Visibility = Visibility.Collapsed
End If
Catch ex As Exception
Log(ex, "将版本列表转换显示时失败", LogLevel.Feedback)
End Try
End Sub
Public Shared Function McVersionListItem(Version As McVersion) As MyListItem
Dim NewItem As New MyListItem With {.Title = Version.Name, .Info = Version.Info, .Height = 42, .Tag = Version, .PaddingRight = 78, .SnapsToDevicePixels = True, .Type = MyListItem.CheckType.Clickable}
Try
If Version.Logo.EndsWith("PCL\Logo.png") Then
NewItem.Logo = Version.Path & "PCL\Logo.png" '修复老版本中,存储的自定义 Logo 使用完整路径,导致移动后无法加载的 Bug
Else
NewItem.Logo = Version.Logo
End If
Catch ex As Exception
Log(ex, "加载版本图标失败", LogLevel.Hint)
NewItem.Logo = "pack://application:,,,/images/Blocks/RedstoneBlock.png"
End Try
NewItem.ContentHandler = AddressOf McVersionListContent
Return NewItem
End Function
Private Shared Sub McVersionListContent(sender As MyListItem, e As EventArgs)
Dim Version As McVersion = sender.Tag
'注册点击事件
AddHandler sender.Click, AddressOf Item_Click
'图标按钮
Dim BtnStar As New MyIconButton
If Version.IsStar Then
BtnStar.ToolTip = "取消收藏"
ToolTipService.SetPlacement(BtnStar, Primitives.PlacementMode.Center)
ToolTipService.SetVerticalOffset(BtnStar, 30)
ToolTipService.SetHorizontalOffset(BtnStar, 2)
BtnStar.LogoScale = 1.1
BtnStar.Logo = Logo.IconButtonLikeFill
Else
BtnStar.ToolTip = "收藏"
ToolTipService.SetPlacement(BtnStar, Primitives.PlacementMode.Center)
ToolTipService.SetVerticalOffset(BtnStar, 30)
ToolTipService.SetHorizontalOffset(BtnStar, 2)
BtnStar.LogoScale = 1.1
BtnStar.Logo = Logo.IconButtonLikeLine
End If
AddHandler BtnStar.Click, Sub()
WriteIni(Version.Path & "PCL\Setup.ini", "IsStar", Not Version.IsStar)
McVersionListForceRefresh = True
LoaderFolderRun(McVersionListLoader, PathMcFolder, LoaderFolderRunType.ForceRun, MaxDepth:=1, ExtraPath:="versions\")
End Sub
Dim BtnDel As New MyIconButton With {.LogoScale = 1.1, .Logo = Logo.IconButtonDelete}
BtnDel.ToolTip = "删除"
ToolTipService.SetPlacement(BtnDel, Primitives.PlacementMode.Center)
ToolTipService.SetVerticalOffset(BtnDel, 30)
ToolTipService.SetHorizontalOffset(BtnDel, 2)
AddHandler BtnDel.Click, Sub() DeleteVersion(sender, Version)
If Version.State <> McVersionState.Error Then
Dim BtnCont As New MyIconButton With {.LogoScale = 1.1, .Logo = Logo.IconButtonSetup}
BtnCont.ToolTip = "设置"
ToolTipService.SetPlacement(BtnCont, Primitives.PlacementMode.Center)
ToolTipService.SetVerticalOffset(BtnCont, 30)
ToolTipService.SetHorizontalOffset(BtnCont, 2)
AddHandler BtnCont.Click, Sub()
PageVersionLeft.Version = Version
FrmMain.PageChange(FormMain.PageType.VersionSetup, 0)
End Sub
AddHandler sender.MouseRightButtonUp, Sub()
PageVersionLeft.Version = Version
FrmMain.PageChange(FormMain.PageType.VersionSetup, 0)
End Sub
sender.Buttons = {BtnStar, BtnDel, BtnCont}
Else
Dim BtnCont As New MyIconButton With {.LogoScale = 1.15, .Logo = Logo.IconButtonOpen}
BtnCont.ToolTip = "打开文件夹"
ToolTipService.SetPlacement(BtnCont, Primitives.PlacementMode.Center)
ToolTipService.SetVerticalOffset(BtnCont, 30)
ToolTipService.SetHorizontalOffset(BtnCont, 2)
AddHandler BtnCont.Click, Sub()
PageVersionOverall.OpenVersionFolder(Version)
End Sub
AddHandler sender.MouseRightButtonUp, Sub()
PageVersionOverall.OpenVersionFolder(Version)
End Sub
sender.Buttons = {BtnStar, BtnDel, BtnCont}
End If
End Sub
#End Region
#Region "页面事件"
'点击选项
Public Shared Sub Item_Click(sender As MyListItem, e As EventArgs)
Dim Version As McVersion = sender.Tag
If New McVersion(Version.Path).Check Then
'正常版本
McVersionCurrent = Version
Setup.Set("LaunchVersionSelect", McVersionCurrent.Name)
FrmMain.PageBack()
Else
'错误版本
PageVersionOverall.OpenVersionFolder(Version)
End If
End Sub
Private Sub BtnDownload_Click(sender As Object, e As EventArgs) Handles BtnEmptyDownload.Click
FrmMain.PageChange(FormMain.PageType.Download, FormMain.PageSubType.DownloadInstall)
End Sub
Public Shared Sub DeleteVersion(Item As MyListItem, Version As McVersion)
'修改此代码时,同时修改 PageVersionOverall 中的代码
Try
Dim IsHintIndie As Boolean = Version.State <> McVersionState.Error AndAlso Version.PathIndie <> PathMcFolder
Select Case MyMsgBox("你确定要删除版本 " & Version.Name & " 吗?" &
If(IsHintIndie, vbCrLf & "由于该版本开启了版本隔离,删除版本时该版本对应的存档、资源包、Mod 等文件也将被一并删除!", ""),
"版本删除确认", , "取消",, True)
Case 1
FileIO.FileSystem.DeleteDirectory(Version.Path, FileIO.UIOption.AllDialogs, FileIO.RecycleOption.SendToRecycleBin)
Hint("版本 " & Version.Name & " 已删除到回收站!", HintType.Finish)
Case 2
' DeleteDirectory(Version.Path)
' Hint("版本 " & Version.Name & " 已永久删除!", HintType.Finish)
'Case 3
Exit Sub
End Select
'从 UI 中移除
If Version.DisplayType = McVersionCardType.Hidden OrElse Not Version.IsStar Then
'仅出现在当前卡片
Dim Parent As StackPanel = Item.Parent
If Parent.Children.Count > 2 Then '当前的项目与一个占位符
'删除后还有剩
Dim Card As MyCard = Parent.Parent
Card.Title = Card.Title.Replace(Parent.Children.Count - 1, Parent.Children.Count - 2) '有一个占位符
Parent.Children.Remove(Item)
If McVersionCurrent IsNot Nothing AndAlso Version.Path = McVersionCurrent.Path Then
'删除当前版本就更改选择
McVersionCurrent = CType(Parent.Children(0), MyListItem).Tag
End If
LoaderFolderRun(McVersionListLoader, PathMcFolder, LoaderFolderRunType.UpdateOnly, MaxDepth:=1, ExtraPath:="versions\")
Else
'删除后没剩了
LoaderFolderRun(McVersionListLoader, PathMcFolder, LoaderFolderRunType.ForceRun, MaxDepth:=1, ExtraPath:="versions\")
End If
Else
'同时出现在当前卡片与收藏夹
LoaderFolderRun(McVersionListLoader, PathMcFolder, LoaderFolderRunType.ForceRun, MaxDepth:=1, ExtraPath:="versions\")
End If
Catch ex As Exception
Log(ex, "删除版本 " & Version.Name & " 失败", LogLevel.Msgbox)
End Try
End Sub
Public Sub BtnEmptyDownload_Loaded() Handles BtnEmptyDownload.Loaded
Dim NewVisibility = If((Setup.Get("UiHiddenPageDownload") AndAlso Not PageSetupUI.HiddenForceShow) OrElse ShowHidden, Visibility.Collapsed, Visibility.Visible)
If BtnEmptyDownload.Visibility <> NewVisibility Then
BtnEmptyDownload.Visibility = NewVisibility
PanLoad.TriggerForceResize()
End If
End Sub
#End Region
End Class
@@ -0,0 +1,235 @@
<local:MyPageRight
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:PCL" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:System="clr-namespace:System;assembly=mscorlib"
mc:Ignorable="d" x:Class="PageSetupLaunch"
d:DesignWidth="800" d:DesignHeight="800">
<local:MyScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" x:Name="PanBack">
<StackPanel x:Name="PanMain" Margin="25,10">
<local:MyCard x:Name="CardSkin" Margin="0,15" Title="离线皮肤">
<StackPanel Margin="25,40,25,15">
<Grid Margin="-1,0,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<local:MyRadioBox Text="随机" x:Name="RadioSkinType0" Height="22" Tag="LaunchSkinType/0" Grid.Column="0" ToolTipService.ShowDuration="2333333" ToolTipService.Placement="Bottom" ToolTip="在 Steve 和 Alex 中随机选择一个皮肤" />
<local:MyRadioBox Text="Steve" x:Name="RadioSkinType1" Height="22" Tag="LaunchSkinType/1" Grid.Column="1" />
<local:MyRadioBox Text="Alex" x:Name="RadioSkinType2" Height="22" Tag="LaunchSkinType/2" Grid.Column="2" />
<local:MyRadioBox Text="正版皮肤" x:Name="RadioSkinType3" Height="22" Tag="LaunchSkinType/3" Grid.Column="3" ToolTipService.ShowDuration="2333333" ToolTipService.Placement="Bottom" ToolTip="使用某个正版玩家的皮肤" />
<local:MyRadioBox Text="自定义" x:Name="RadioSkinType4" Height="22" Tag="LaunchSkinType/4" Grid.Column="4" ToolTipService.ShowDuration="2333333" ToolTipService.Placement="Bottom" ToolTip="以资源包的形式加载自定义皮肤。&#xA;使用此方式更换的皮肤在多人游戏中仅自己可见,且会替换游戏中所有的角色。" />
</Grid>
<Grid x:Name="PanSkinID" Margin="0,14,0,2" Visibility="Collapsed">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Name" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Left" Text="正版玩家名" Margin="0,0,25,0" />
<local:MyTextBox x:Name="TextSkinID" Tag="LaunchSkinID" Grid.Column="1" MaxLength="50" />
<Grid Height="35" Grid.Row="1" Grid.ColumnSpan="2" Margin="0,14,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
</Grid.ColumnDefinitions>
<local:MyButton x:Name="BtnSkinSave" Text="保存皮肤" MinWidth="140" Padding="13,0" Margin="0,0,20,0" Grid.Row="1" />
<local:MyButton x:Name="BtnSkinCache" Text="刷新缓存" MinWidth="140" Padding="13,0" Margin="0,0,20,0" ToolTip="刷新并重新下载 PCL 当前显示的皮肤" ToolTipService.ShowDuration="2333333" Grid.Row="1" Grid.Column="1" />
</Grid>
</Grid>
<Grid x:Name="PanSkinChange" Margin="0,14,0,2" Height="35" Visibility="Collapsed">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
</Grid.ColumnDefinitions>
<local:MyButton x:Name="BtnSkinChange" Text="更改皮肤" MinWidth="140" Padding="13,0" Margin="0,0,20,0" />
<local:MyButton x:Name="BtnSkinDelete" Text="重置皮肤" MinWidth="140" Padding="13,0" Margin="0,0,20,0" ColorType="Red" Grid.Column="1" />
</Grid>
</StackPanel>
</local:MyCard>
<local:MyCard x:Name="CardArgument" Margin="0,0,0,15" Title="启动选项">
<StackPanel Margin="25,40,25,15">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Name" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="60" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="28" />
<RowDefinition Height="9" />
<RowDefinition Height="28" />
<RowDefinition Height="9" />
<RowDefinition Height="28" />
<RowDefinition Height="9" />
<RowDefinition Height="28" />
<RowDefinition Height="9" />
<RowDefinition Height="28" />
<RowDefinition Height="9" />
<RowDefinition Height="28" />
<RowDefinition Height="9" />
<RowDefinition Height="28" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" VerticalAlignment="Center" HorizontalAlignment="Left" Text="游戏窗口标题" Margin="0,0,25,0" />
<local:MyTextBox x:Name="TextArgumentTitle" Grid.Row="0" Grid.ColumnSpan="2" Tag="LaunchArgumentTitle" Grid.Column="1" ToolTip="自定义游戏窗口的标题,若留空则不进行更改。&#x0a;支持以下替换标记:&#x0a; - {user}:玩家名字&#x0a; - {login}:玩家的登录方式&#x0a; - {name}:游戏版本名&#x0a; - {time}:当前的系统时间&#x0a; - {version}:游戏对应的原版版本号&#x0a; - {path}:PCL 可执行文件所在路径,以 \ 结尾" ToolTipService.ShowDuration="2333333" HintText="默认" MaxLength="100" />
<TextBlock Grid.Row="2" VerticalAlignment="Center" HorizontalAlignment="Left" Text="自定义信息" Margin="0,0,25,0" />
<local:MyTextBox x:Name="TextArgumentInfo" Grid.Row="2" Grid.ColumnSpan="2" Tag="LaunchArgumentInfo" Text="Plain Craft Launcher 2" Grid.Column="1" ToolTip="该信息会显示在游戏主界面的左下角,与 F3 调试页面的左上角" ToolTipService.ShowDuration="2333333">
<local:MyTextBox.ValidateRules>
<local:ValidateExcept>
<local:ValidateExcept.Excepts>
<System:String>"</System:String>
<System:String>“</System:String>
<System:String>”</System:String>
</local:ValidateExcept.Excepts>
</local:ValidateExcept>
</local:MyTextBox.ValidateRules>
</local:MyTextBox>
<TextBlock Grid.Row="4" VerticalAlignment="Center" HorizontalAlignment="Left" Text="版本隔离" Margin="0,0,25,0" />
<local:MyComboBox x:Name="ComboArgumentIndie" Grid.Row="4" Grid.ColumnSpan="2" Tag="LaunchArgumentIndie" Grid.Column="1">
<local:MyComboBoxItem Content="关闭" ToolTip="所有版本均使用同一档案,存档、Mod、资源包等均为公用。&#xA;若存在不同版本的 Forge,可能会由于 Mod 与版本冲突导致未知问题。" />
<local:MyComboBoxItem Content="仅隔离可安装 Mod 的版本" IsSelected="True" ToolTip="每个 LiteLoader、Forge、Fabric 版本均互相独立以避免 Mod 冲突,未安装 Mod API 的其他版本则不会被隔离。" />
<local:MyComboBoxItem Content="仅隔离非正式版" ToolTip="将 Minecraft 快照、预发布版、远古版本、愚人节版本与其他版本进行隔离。" />
<local:MyComboBoxItem Content="隔离非正式版与可安装 Mod 的版本" />
<local:MyComboBoxItem Content="隔离所有版本" ToolTip="不同版本之间的存档、Mod、资源包等均不互通。" />
</local:MyComboBox>
<TextBlock VerticalAlignment="Center" Grid.Row="6" HorizontalAlignment="Left" Text="启动器可见性" Margin="0,0,25,0" />
<local:MyComboBox x:Name="ComboArgumentVisibie" Grid.Row="6" Grid.ColumnSpan="2" Tag="LaunchArgumentVisible" Grid.Column="1">
<local:MyComboBoxItem Content="游戏启动后立即关闭" />
<local:MyComboBoxItem Content="" IsEnabled="False" Visibility="Collapsed" />
<local:MyComboBoxItem Content="游戏启动后隐藏,游戏退出后自动关闭" />
<local:MyComboBoxItem Content="游戏启动后隐藏,游戏退出后重新打开" />
<local:MyComboBoxItem Content="游戏启动后最小化" />
<local:MyComboBoxItem Content="游戏启动后仍保持不变" IsSelected="True" />
</local:MyComboBox>
<TextBlock VerticalAlignment="Center" Grid.Row="8" HorizontalAlignment="Left" Text="进程优先级" Margin="0,0,25,0" />
<local:MyComboBox x:Name="ComboArgumentPriority" Grid.Row="8" Grid.ColumnSpan="2" Tag="LaunchArgumentPriority" Grid.Column="1">
<local:MyComboBoxItem Content="高(优先保证游戏运行,游戏性能更佳,但可能造成其他程序卡顿)" />
<local:MyComboBoxItem Content="中(平衡)" IsSelected="True" />
<local:MyComboBoxItem Content="低(优先保证其他程序运行,但可能让游戏卡顿,适合挂机时使用)" />
</local:MyComboBox>
<TextBlock VerticalAlignment="Center" Grid.Row="10" HorizontalAlignment="Left" Text="游戏窗口" Margin="0,0,25,0" />
<Grid x:Name="PanArgumentWindow" Grid.Row="10" Grid.ColumnSpan="2" Grid.Column="1">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<local:MyComboBox x:Name="ComboArgumentWindowType" Tag="LaunchArgumentWindowType">
<local:MyComboBoxItem Content="全屏" />
<local:MyComboBoxItem Content="默认大小" IsSelected="True" ToolTip="以 854×480 的默认窗口大小启动 Minecraft" ToolTipService.Placement="Right" ToolTipService.HorizontalOffset="5" ToolTipService.ShowDuration="2333333" />
<local:MyComboBoxItem Content="与启动器窗口大小一致" />
<local:MyComboBoxItem Content="自定义大小" ToolTip="请注意 1.12.2 及更老的部分 Forge 存在 Bug,会导致高度设定无效" ToolTipService.Placement="Right" ToolTipService.HorizontalOffset="5" ToolTipService.ShowDuration="2333333" />
<local:MyComboBoxItem Content="最大化" />
<local:MyComboBoxItem Content="保持游戏默认" />
</local:MyComboBox>
<local:MyTextBox Padding="0,0,5,0" Visibility="Collapsed" Grid.Column="1" Margin="50,0,0,0" x:Name="TextArgumentWindowWidth" Tag="LaunchArgumentWindowWidth" Width="60" HorizontalContentAlignment="Center" Text="854">
<local:MyTextBox.ValidateRules>
<local:ValidateInteger Min="1" Max="9999" />
</local:MyTextBox.ValidateRules>
</local:MyTextBox>
<TextBlock x:Name="LabArgumentWindowMiddle" Visibility="Collapsed" Grid.Column="2" Text=" × " VerticalAlignment="Center" FontSize="18" />
<local:MyTextBox Padding="0,0,5,0" Visibility="Collapsed" Grid.Column="3" Width="60" HorizontalContentAlignment="Center" x:Name="TextArgumentWindowHeight" Tag="LaunchArgumentWindowHeight" Text="480"
ToolTip="请注意 Forge 1.12.2 存在 Bug,会导致高度设定无效,其他版本无此问题" ToolTipService.Placement="Right" ToolTipService.HorizontalOffset="5" ToolTipService.ShowDuration="2333333">
<local:MyTextBox.ValidateRules>
<local:ValidateInteger Min="1" Max="9999" />
</local:MyTextBox.ValidateRules>
</local:MyTextBox>
</Grid>
<TextBlock VerticalAlignment="Center" Grid.Row="12" HorizontalAlignment="Left" Text="游戏 Java" Margin="0,0,25,0" />
<local:MyComboBox x:Name="ComboArgumentJava" Grid.ColumnSpan="2" Grid.Row="12" Grid.Column="1" ToolTip="若将 Java 放在游戏文件夹或 PCL 文件夹,在进行自动选择时 PCL2 会尽量优先选择它" ToolTipService.ShowDuration="2333333">
<ComboBoxItem Content="加载中……" IsSelected="True" />
<!--<local:MyComboBoxItem Content="Java 8 (1.8.0_171),64 位:C:\Program Files (x86)\Common Files\Oracle\Java\javapath\javaw.exe" ToolTipService.Placement="Right" ToolTipService.HorizontalOffset="5" IsSelected="True" ToolTip="C:\Program Files (x86)\Common Files\Oracle\Java\javapath\javaw.exe" />-->
</local:MyComboBox>
<Grid Grid.Row="13" Grid.Column="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Path Height="16" HorizontalAlignment="Left" Stretch="Uniform" Margin="6,10.5,0,0" Data="F1 M 20,17L 43.25,17L 56,29.75L 56,40L 52,37.5L 52,34L 39,34L 39,21L 24,21L 24,55L 36,55L 32,59L 20,59L 20,17 Z M 43,22.25L 43,30L 50.75,30L 43,22.25 Z M 48,38C 53.5228,38 58,42.4772 58,48C 58,53.5229 53.5228,58 48,58C 46.1455,58 44.4089,57.4952 42.9201,56.6155L 36.1213,63.4142C 35.3403,64.1953 34.0739,64.1953 33.2929,63.4142L 32.5858,62.7071C 31.8047,61.9261 31.8047,60.6597 32.5858,59.8787L 39.3845,53.0799C 38.5048,51.5911 38,49.8545 38,48C 38,42.4772 42.4771,38 48,38 Z M 48,42C 44.6863,42 42,44.6863 42,48C 42,51.3137 44.6863,54 48,54C 51.3137,54 54,51.3137 54,48C 54,44.6863 51.3137,42 48,42 Z" VerticalAlignment="Top" Fill="{Binding Foreground, ElementName=BtnArgumentJavaSearch}" />
<local:MyTextButton HorizontalAlignment="Left" x:Name="BtnArgumentJavaSearch" Text="自动搜索" Padding="25,10,5,5" Grid.Row="5" VerticalContentAlignment="Top" />
<Path Height="16" VerticalAlignment="Top" HorizontalAlignment="Left" Stretch="Uniform" Margin="22,10.5,0,0" Grid.Column="1" StrokeThickness="0.5" Data="M827.4 589.1l-30.7-50.7V151.3c0-29.9-25.2-54.3-56.1-54.3h-527c-9.9 0-24.8 6.3-24.8 24.8v700.5c0 20.2 12.1 37 31.7 43.8l169.1 58.6c4.4 1.5 9.1 2.3 13.8 2.3 10.2 0 20.7-3.4 29.9-10 12.9-9.2 20.3-22.4 20.3-36.2l-0.1-16.6h325.7c30.9 0 56.1-24.3 56.1-54.3v-193c0-9.8-2.7-19.4-7.9-27.8z m-423.5 288l-165.6-54.8V153.8l201.5 51.4v439.2c-0.1 0.5-0.8 2.6-3.2 5.3l-20.9 23.4c-7.6 8.4-11.7 18.7-11.7 28.9v175.1zM785.7 810c0 2.2-2.6 4.6-6.4 4.6h-326l-0.6-108.4 20.9-23.4c10.2-11.4 15.9-25 15.9-38.2V205.2c0-21.6-14-39.3-35.7-45.1l-50.4-13.4h337.3c3.8 0 6.4 2.4 6.4 4.6v387.1c0 9.7 2.7 19.4 8 27.9l30.7 50.7v193z" Stroke="{Binding Foreground, ElementName=BtnArgumentJavaSelect}" Fill="{Binding Foreground, ElementName=BtnArgumentJavaSelect}" />
<local:MyTextButton x:Name="BtnArgumentJavaSelect" Margin="17,0,0,0" Padding="24.5,10,5,5" Text="手动导入" Grid.Row="5" Grid.Column="1" VerticalContentAlignment="Top" HorizontalAlignment="Left" />
</Grid>
</Grid>
</StackPanel>
</local:MyCard>
<local:MyCard Margin="0,0,0,15" Title="游戏内存">
<StackPanel Margin="25,40,25,15">
<local:MyHint x:Name="LabRamWarn" CanClose="False" Text="32 位 Java 最多只能分配 1 GB 内存,建议安装 64 位 Java!" IsWarn="True" Margin="0,0,0,12" />
<Grid Margin="0,0,0,3">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="9" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<local:MyRadioBox Text="自动配置" Width="110" Checked="True" x:Name="RadioRamType0" Tag="LaunchRamType/0" Margin="0,0,20,0" ToolTip="根据安装的 Mod 量与电脑剩余内存动态调整为游戏分配的内存。" />
<local:MyRadioBox Grid.Row="2" Text="自定义" x:Name="RadioRamType1" Tag="LaunchRamType/1" Margin="0,0,20,0" />
<local:MySlider Grid.Row="2" Grid.Column="1" IsEnabled="False" x:Name="SliderRamCustom" Tag="LaunchRamCustom" MaxValue="49" Value="13" />
<!--<local:MyTextBox Grid.Row="2" Grid.Column="3" Width="100" VerticalAlignment="Center" Margin="30,0,0,0" Text="2048 MB" />-->
</Grid>
<Grid x:Name="PanRamDisplay" Margin="0,11,2,0" SnapsToDevicePixels="True" Grid.Row="1" Grid.ColumnSpan="2" Grid.Column="1">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="ColumnRamUsed" Width="4.7*"/>
<ColumnDefinition x:Name="ColumnRamGame" Width="2.5*"/>
<ColumnDefinition x:Name="ColumnRamEmpty" Width="0.7*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="4" />
<RowDefinition />
</Grid.RowDefinitions>
<Rectangle x:Name="RectRamUsed" Grid.Row="1" StrokeThickness="0" >
<Rectangle.Fill>
<LinearGradientBrush EndPoint="1,0.5" StartPoint="0,0.5">
<GradientStop Color="{DynamicResource ColorObject3}" Offset="0"/>
<GradientStop Color="{DynamicResource ColorObject2}" Offset="0.5"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Rectangle Grid.Row="1" StrokeThickness="0" Grid.Column="1" Fill="{DynamicResource ColorBrush3}" Opacity="0.5" x:Name="RectRamGame" />
<Rectangle x:Name="RectRamEmpty" Grid.Row="1" StrokeThickness="0" Grid.Column="2" Fill="{DynamicResource ColorBrush6}" Opacity="0.7" />
<TextBlock x:Name="LabRamUsedTitle" Text="已使用内存" Grid.ColumnSpan="3" Opacity="0.7" TextTrimming="None" Margin="2,0,0,5" FontSize="11" HorizontalAlignment="Left" />
<TextBlock x:Name="LabRamGameTitle" Text="游戏分配" Opacity="0.7" Grid.ColumnSpan="3" TextTrimming="None" Margin="2,0,0,5" FontSize="11" HorizontalAlignment="Left" />
<StackPanel Grid.Row="2" Orientation="Horizontal" Grid.ColumnSpan="3" Margin="2,3,0,0" HorizontalAlignment="Left">
<TextBlock x:Name="LabRamUsed" Text="4.7 GB" FontSize="16" Foreground="Black" TextTrimming="None" />
<TextBlock x:Name="LabRamTotal" Text=" / 7.9 GB" FontSize="16" Foreground="Black" TextTrimming="None" />
</StackPanel>
<TextBlock Grid.Row="2" x:Name="LabRamGame" Text="2.5 GB" Grid.ColumnSpan="3" TextTrimming="None" Margin="2,3,0,0" FontSize="16" Foreground="Black" HorizontalAlignment="Left" />
</Grid>
</StackPanel>
</local:MyCard>
<local:MyCard Margin="0,0,0,15" Title="高级设置" IsSwaped="True" CanSwap="True">
<StackPanel Margin="25,40,25,15">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Name" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="28" />
<RowDefinition Height="9" />
<RowDefinition Height="28" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" VerticalAlignment="Center" HorizontalAlignment="Left" Text="JVM 参数" Margin="0,0,25,0" />
<local:MyTextBox x:Name="TextAdvanceJvm" Grid.Row="0" Grid.ColumnSpan="2" Tag="LaunchAdvanceJvm" Grid.Column="1" ToolTip="启动 Minecraft 时使用的额外 JVM 参数,在没有确定把握的情况下请不要尝试修改。&#xA;你可以通过点击左侧选项卡的初始化按钮来恢复到默认设置。" ToolTipService.ShowDuration="2333333" Text="-XX:+UseG1GC -XX:-UseAdaptiveSizePolicy -XX:-OmitStackTraceInFastThrow -Dfml.ignoreInvalidMinecraftCertificates=True -Dfml.ignorePatchDiscrepancies=True -Dlog4j2.formatMsgNoLookups=true -Djava.net.preferIPv4Stack=true" />
<TextBlock Grid.Row="2" VerticalAlignment="Center" HorizontalAlignment="Left" Text="额外参数" Margin="0,0,25,0" />
<local:MyTextBox x:Name="TextAdvanceGame" Grid.Row="2" Grid.ColumnSpan="2" Tag="LaunchAdvanceGame" Grid.Column="1" ToolTip="文本框中的内容将会被直接拼合在启动参数的末尾。&#xA;例如输入 --demo 则会以试玩模式启动游戏。" ToolTipService.ShowDuration="2333333" />
</Grid>
<local:MyCheckBox Margin="0,10,0,4" Text="关闭文件校验" x:Name="CheckAdvanceAssets" Tag="LaunchAdvanceAssets" Grid.Column="1" ToolTip="在启动 Minecraft 时,不校验 libraries 文件夹、第三方登录库与版本主 jar 文件,不更改 assets 文件夹。&#xA;如果你没有修改相关文件,请勿勾选此项。&#xA;更推荐在版本设置中关闭特定版本的校验,而不是在这里关闭所有版本的校验。" ToolTipService.ShowDuration="2333333" />
</StackPanel>
</local:MyCard>
</StackPanel>
</local:MyScrollViewer>
</local:MyPageRight>
@@ -0,0 +1,551 @@
Public Class PageSetupLaunch
Private IsLoad As Boolean = False
Private Sub PageSetupLaunch_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
'重复加载部分
PanBack.ScrollToHome()
RefreshRam(False)
'非重复加载部分
If IsLoad Then Exit Sub
IsLoad = True
AniControlEnabled += 1
Reload()
AniControlEnabled -= 1
'内存自动刷新
Dim timer As New Threading.DispatcherTimer With {.Interval = New TimeSpan(0, 0, 0, 1)}
AddHandler timer.Tick, AddressOf RefreshRam
timer.Start()
End Sub
Public Sub Reload()
Try
'离线皮肤
CType(FindName("RadioSkinType" & Setup.Load("LaunchSkinType")), MyRadioBox).Checked = True
TextSkinID.Text = Setup.Get("LaunchSkinID")
'启动参数
TextArgumentTitle.Text = Setup.Get("LaunchArgumentTitle")
TextArgumentInfo.Text = Setup.Get("LaunchArgumentInfo")
ComboArgumentIndie.SelectedIndex = Setup.Get("LaunchArgumentIndie")
ComboArgumentVisibie.SelectedIndex = Setup.Get("LaunchArgumentVisible")
ComboArgumentPriority.SelectedIndex = Setup.Get("LaunchArgumentPriority")
ComboArgumentWindowType.SelectedIndex = Setup.Get("LaunchArgumentWindowType")
TextArgumentWindowWidth.Text = Setup.Get("LaunchArgumentWindowWidth")
TextArgumentWindowHeight.Text = Setup.Get("LaunchArgumentWindowHeight")
RefreshJavaComboBox()
'游戏内存
CType(FindName("RadioRamType" & Setup.Load("LaunchRamType")), MyRadioBox).Checked = True
SliderRamCustom.Value = Setup.Get("LaunchRamCustom")
'高级设置
TextAdvanceJvm.Text = Setup.Get("LaunchAdvanceJvm")
TextAdvanceGame.Text = Setup.Get("LaunchAdvanceGame")
CheckAdvanceAssets.Checked = Setup.Get("LaunchAdvanceAssets")
Catch ex As NullReferenceException
Log(ex, "启动设置项存在异常,已被自动重置", LogLevel.Msgbox)
Reset()
Catch ex As Exception
Log(ex, "重载启动设置时出错", LogLevel.Feedback)
End Try
End Sub
'初始化
Public Sub Reset()
Try
Setup.Reset("LaunchArgumentTitle")
Setup.Reset("LaunchArgumentInfo")
Setup.Reset("LaunchArgumentIndie")
Setup.Reset("LaunchArgumentVisible")
Setup.Reset("LaunchArgumentWindowType")
Setup.Reset("LaunchArgumentWindowWidth")
Setup.Reset("LaunchArgumentWindowHeight")
Setup.Reset("LaunchArgumentPriority")
Setup.Reset("LaunchRamType")
Setup.Reset("LaunchRamCustom")
Setup.Reset("LaunchSkinType")
Setup.Reset("LaunchSkinID")
Setup.Reset("LaunchAdvanceJvm")
Setup.Reset("LaunchAdvanceGame")
Setup.Reset("LaunchAdvanceAssets")
Setup.Reset("LaunchArgumentJavaAll")
Setup.Reset("LaunchArgumentJavaSelect")
JavaSearchLoader.Start(IsForceRestart:=True)
Log("[Setup] 已初始化启动设置")
Hint("已初始化启动设置!", HintType.Finish, False)
Catch ex As Exception
Log(ex, "初始化启动设置失败", LogLevel.Msgbox)
End Try
Reload()
End Sub
'将控件改变路由到设置改变
Private Shared Sub RadioBoxChange(sender As MyRadioBox, e As Object) Handles RadioSkinType0.Check, RadioSkinType1.Check, RadioSkinType2.Check, RadioSkinType3.Check, RadioSkinType4.Check, RadioRamType0.Check, RadioRamType1.Check
If AniControlEnabled = 0 Then Setup.Set(sender.Tag.ToString.Split("/")(0), Val(sender.Tag.ToString.Split("/")(1)))
End Sub
Private Shared Sub TextBoxChange(sender As MyTextBox, e As Object) Handles TextSkinID.ValidatedTextChanged, TextArgumentWindowHeight.ValidatedTextChanged, TextArgumentWindowWidth.ValidatedTextChanged, TextArgumentInfo.ValidatedTextChanged, TextAdvanceGame.ValidatedTextChanged, TextAdvanceJvm.ValidatedTextChanged, TextArgumentTitle.ValidatedTextChanged
If AniControlEnabled = 0 Then Setup.Set(sender.Tag, sender.Text)
End Sub
Private Shared Sub SliderChange(sender As MySlider, e As Object) Handles SliderRamCustom.Change
If AniControlEnabled = 0 Then Setup.Set(sender.Tag, sender.Value)
End Sub
Private Shared Sub ComboChange(sender As MyComboBox, e As Object) Handles ComboArgumentIndie.SelectionChanged, ComboArgumentVisibie.SelectionChanged, ComboArgumentWindowType.SelectionChanged, ComboArgumentPriority.SelectionChanged
If AniControlEnabled = 0 Then Setup.Set(sender.Tag, sender.SelectedIndex)
End Sub
Private Shared Sub CheckBoxChange(sender As MyCheckBox, e As Object) Handles CheckAdvanceAssets.Change
If AniControlEnabled = 0 Then Setup.Set(sender.Tag, sender.Checked)
End Sub
#Region "离线皮肤"
Private Sub BtnSkinChange_Click(sender As Object, e As EventArgs) Handles BtnSkinChange.Click
Dim SkinInfo As McSkinInfo = McSkinSelect(True)
If Not SkinInfo.IsVaild Then Exit Sub
'设置文件
Try
'拷贝文件
File.Delete(PathTemp & "CustomSkin.png")
File.Copy(SkinInfo.LocalFile, PathTemp & "CustomSkin.png")
'更新设置
Setup.Set("LaunchSkinSlim", SkinInfo.IsSlim)
Catch ex As Exception
Log(ex, "设置离线皮肤失败", LogLevel.Msgbox)
Finally
'设置当前显示
PageLaunchLeft.SkinLegacy.Start(IsForceRestart:=True)
End Try
End Sub
Private Sub RadioSkinType3_Check(sender As Object, e As RouteEventArgs) Handles RadioSkinType4.PreviewCheck
If Not (AniControlEnabled = 0 AndAlso e.RaiseByMouse) Then Exit Sub
Try
'已有图片则不再选择
If File.Exists(PathTemp & "CustomSkin.png") Then Exit Sub
'没有图片则要求选择
Dim SkinInfo As McSkinInfo = McSkinSelect(True)
If Not SkinInfo.IsVaild Then
e.Handled = True
Exit Sub
End If
'拷贝文件
File.Delete(PathTemp & "CustomSkin.png")
File.Copy(SkinInfo.LocalFile, PathTemp & "CustomSkin.png")
'更新设置
Setup.Set("LaunchSkinSlim", SkinInfo.IsSlim)
Catch ex As Exception
Log(ex, "设置离线皮肤失败", LogLevel.Msgbox)
e.Handled = True
Finally
'设置当前显示
PageLaunchLeft.SkinLegacy.Start(IsForceRestart:=True)
End Try
End Sub
Private Sub BtnSkinDelete_Click(sender As Object, e As EventArgs) Handles BtnSkinDelete.Click
Try
File.Delete(PathTemp & "CustomSkin.png")
RadioSkinType0.SetChecked(True, True, True)
Hint("离线皮肤已清空!", HintType.Finish)
Catch ex As Exception
Log(ex, "清空离线皮肤失败", LogLevel.Msgbox)
End Try
End Sub
Private Sub BtnSkinSave_Click(sender As Object, e As EventArgs) Handles BtnSkinSave.Click
MySkin.Save(PageLaunchLeft.SkinLegacy)
End Sub
Private Sub BtnSkinCache_Click(sender As Object, e As EventArgs) Handles BtnSkinCache.Click
MySkin.RefreshCache(Nothing)
End Sub
#End Region
#Region "游戏内存"
Public Sub RamType(Type As Integer)
If SliderRamCustom Is Nothing Then Exit Sub
SliderRamCustom.IsEnabled = (Type = 1)
End Sub
''' <summary>
''' 刷新 UI 上的 RAM 显示。
''' </summary>
Public Sub RefreshRam(ShowAnim As Boolean)
If LabRamGame Is Nothing OrElse LabRamUsed Is Nothing OrElse FrmMain.PageCurrent <> FormMain.PageType.Setup OrElse FrmSetupLeft.PageID <> FormMain.PageSubType.SetupLaunch Then Exit Sub
'获取内存情况
Dim RamGame As Double = GetRam(McVersionCurrent, False)
Dim RamTotal As Double = Math.Round(My.Computer.Info.TotalPhysicalMemory / 1024 / 1024 / 1024 * 10) / 10
Dim RamAvailable As Double = Math.Round(My.Computer.Info.AvailablePhysicalMemory / 1024 / 1024 / 1024 * 10) / 10
Dim RamGameActual As Double = Math.Min(RamGame, RamAvailable)
Dim RamUsed As Double = RamTotal - RamAvailable
Dim RamEmpty As Double = Math.Round(MathRange(RamTotal - RamUsed - RamGame, 0, 1000) * 10) / 10
'设置最大可用内存
If RamTotal <= 1.5 Then
SliderRamCustom.MaxValue = Math.Max(Math.Floor((RamTotal - 0.3) / 0.1), 1)
ElseIf RamTotal <= 8 Then
SliderRamCustom.MaxValue = Math.Floor((RamTotal - 1.5) / 0.5) + 12
ElseIf RamTotal <= 16 Then
SliderRamCustom.MaxValue = Math.Floor((RamTotal - 8) / 1) + 25
ElseIf RamTotal <= 32 Then
SliderRamCustom.MaxValue = Math.Floor((RamTotal - 16) / 2) + 33
Else
SliderRamCustom.MaxValue = Math.Min(Math.Floor((RamTotal - 32) / 4) + 41, 49)
End If
'设置文本
LabRamGame.Text = If(RamGame = Math.Floor(RamGame), RamGame & ".0", RamGame) & " GB" &
If(RamGame <> RamGameActual, " (可用 " & If(RamGameActual = Math.Floor(RamGameActual), RamGameActual & ".0", RamGameActual) & " GB)", "")
LabRamUsed.Text = If(RamUsed = Math.Floor(RamUsed), RamUsed & ".0", RamUsed) & " GB"
LabRamTotal.Text = " / " & If(RamTotal = Math.Floor(RamTotal), RamTotal & ".0", RamTotal) & " GB"
LabRamWarn.Visibility = If(RamGame = 1 AndAlso Not JavaUse64Bit() AndAlso Not Is32BitSystem, Visibility.Visible, Visibility.Collapsed)
If ShowAnim Then
'宽度动画
AniStart({
AaGridLengthWidth(ColumnRamUsed, RamUsed - ColumnRamUsed.Width.Value, 800,, New AniEaseOutFluent(AniEasePower.Strong)),
AaGridLengthWidth(ColumnRamGame, RamGameActual - ColumnRamGame.Width.Value, 800,, New AniEaseOutFluent(AniEasePower.Strong)),
AaGridLengthWidth(ColumnRamEmpty, RamEmpty - ColumnRamEmpty.Width.Value, 800,, New AniEaseOutFluent(AniEasePower.Strong))
}, "SetupLaunch Ram Grid")
Else
'宽度设置
ColumnRamUsed.Width = New GridLength(RamUsed, GridUnitType.Star)
ColumnRamGame.Width = New GridLength(RamGameActual, GridUnitType.Star)
ColumnRamEmpty.Width = New GridLength(RamEmpty, GridUnitType.Star)
End If
End Sub
Private Sub RefreshRam() Handles SliderRamCustom.Change, RadioRamType0.Check, RadioRamType1.Check
RefreshRam(True)
End Sub
Private RamTextLeft As Integer = 2, RamTextRight As Integer = 1
''' <summary>
''' 刷新 UI 上的文本位置。
''' </summary>
Private Sub RefreshRamText() Handles RectRamGame.SizeChanged, RectRamEmpty.SizeChanged, LabRamGame.SizeChanged
'获取宽度信息
Dim RectUsedWidth = RectRamUsed.ActualWidth
Dim TotalWidth = PanRamDisplay.ActualWidth
Dim LabGameWidth = LabRamGame.ActualWidth, LabUsedWidth = LabRamUsed.ActualWidth, LabTotalWidth = LabRamTotal.ActualWidth
Dim LabGameTitleWidth = LabRamGameTitle.ActualWidth, LabUsedTitleWidth = LabRamUsedTitle.ActualWidth
'左侧
Dim Left As Integer
If RectUsedWidth - 30 < LabUsedWidth OrElse RectUsedWidth - 30 < LabUsedTitleWidth Then
'全写不下了
Left = 0
ElseIf RectUsedWidth - 25 < (LabUsedWidth + LabTotalWidth) Then
'显示不下完整数据
Left = 1
Else
'正常
Left = 2
End If
If RamTextLeft <> Left Then
RamTextLeft = Left
'If AniControlEnabled = 0 Then
Select Case Left
Case 0
AniStart({
AaOpacity(LabRamUsed, -LabRamUsed.Opacity, 100),
AaOpacity(LabRamTotal, -LabRamTotal.Opacity, 100),
AaOpacity(LabRamUsedTitle, -LabRamUsedTitle.Opacity, 100)
}, "SetupLaunch Ram TextLeft")
Case 1
AniStart({
AaOpacity(LabRamUsed, 1 - LabRamUsed.Opacity, 100),
AaOpacity(LabRamTotal, -LabRamTotal.Opacity, 100),
AaOpacity(LabRamUsedTitle, 0.7 - LabRamUsedTitle.Opacity, 100)
}, "SetupLaunch Ram TextLeft")
Case 2
AniStart({
AaOpacity(LabRamUsed, 1 - LabRamUsed.Opacity, 100),
AaOpacity(LabRamTotal, 1 - LabRamTotal.Opacity, 100),
AaOpacity(LabRamUsedTitle, 0.7 - LabRamUsedTitle.Opacity, 100)
}, "SetupLaunch Ram TextLeft")
End Select
'Else
' Select Case Left
' Case 0
' LabRamUsed.Opacity = 0
' LabRamTotal.Opacity = 0
' LabRamUsedTitle.Opacity = 0
' Case 1
' LabRamUsed.Opacity = 1
' LabRamTotal.Opacity = 0
' LabRamUsedTitle.Opacity = 0.7
' Case 2
' LabRamUsed.Opacity = 1
' LabRamTotal.Opacity = 1
' LabRamUsedTitle.Opacity = 0.7
' End Select
'End If
End If
'右侧
Dim Right As Integer
If TotalWidth < LabGameWidth + 2 + RectUsedWidth OrElse TotalWidth < LabGameTitleWidth + 2 + RectUsedWidth Then
'挤到最右边
Right = 0
Else
'正常情况
Right = 1
End If
If Right = 0 Then
If AniControlEnabled = 0 AndAlso (RamTextRight <> Right OrElse AniIsRun("SetupLaunch Ram TextRight")) Then
'需要动画
AniStart({
AaX(LabRamGame, TotalWidth - LabGameWidth - LabRamGame.Margin.Left, 100,, New AniEaseOutFluent(AniEasePower.Weak)),
AaX(LabRamGameTitle, TotalWidth - LabGameTitleWidth - LabRamGameTitle.Margin.Left, 100,, New AniEaseOutFluent(AniEasePower.Weak))
}, "SetupLaunch Ram TextRight")
Else
'不需要动画
LabRamGame.Margin = New Thickness(TotalWidth - LabGameWidth, 3, 0, 0)
LabRamGameTitle.Margin = New Thickness(TotalWidth - LabGameTitleWidth, 0, 0, 5)
End If
Else
If AniControlEnabled = 0 AndAlso (RamTextRight <> Right OrElse AniIsRun("SetupLaunch Ram TextRight")) Then
'需要动画
AniStart({
AaX(LabRamGame, 2 + RectUsedWidth - LabRamGame.Margin.Left, 100,, New AniEaseOutFluent(AniEasePower.Weak)),
AaX(LabRamGameTitle, 2 + RectUsedWidth - LabRamGameTitle.Margin.Left, 100,, New AniEaseOutFluent(AniEasePower.Weak))
}, "SetupLaunch Ram TextRight")
Else
'不需要动画
LabRamGame.Margin = New Thickness(2 + RectUsedWidth, 3, 0, 0)
LabRamGameTitle.Margin = New Thickness(2 + RectUsedWidth, 0, 0, 5)
End If
End If
RamTextRight = Right
End Sub
''' <summary>
''' 获取当前设置的 RAM 值。单位为 GB。
''' </summary>
Public Shared Function GetRam(Version As McVersion, UseVersionJavaSetup As Boolean) As Double
Dim RamGive As Double
If Setup.Get("LaunchRamType") = 0 Then
'自动配置
Dim RamAvailable As Double = Math.Round(My.Computer.Info.AvailablePhysicalMemory / 1024 / 1024 / 1024 * 10) / 10
'确定需求的内存值
Dim RamMininum As Double '无论如何也需要保证的最低限度内存
Dim RamTarget1 As Double '估计能勉强带动了的内存
Dim RamTarget2 As Double '估计没啥问题了的内存
Dim RamTarget3 As Double '放一百万个材质和 Mod 和光影需要的内存
If Version IsNot Nothing AndAlso Not Version.IsLoaded Then Version.Load()
If Version IsNot Nothing AndAlso Version.Version.Modable Then
'可安装 Mod 的版本
Dim ModDir As New DirectoryInfo(Version.PathIndie & "mods\")
Dim ModCount As Integer = If(ModDir.Exists, ModDir.GetFiles.Length, 0)
RamMininum = 0.4 + ModCount / 150
RamTarget1 = 1.5 + ModCount / 100
RamTarget2 = 3 + ModCount / 60
RamTarget3 = 6 + ModCount / 30
ElseIf Version IsNot Nothing AndAlso Version.Version.HasOptiFine Then
'OptiFine 版本
RamMininum = 0.3
RamTarget1 = 1.5
RamTarget2 = 3
RamTarget3 = 6
Else
'普通版本
RamMininum = 0.3
RamTarget1 = 1.5
RamTarget2 = 2.5
RamTarget3 = 4
End If
Dim RamDelta As Double
'预分配内存,阶段一,0 ~ T1,100%
RamDelta = RamTarget1
RamAvailable = Math.Max(0, RamAvailable - 0.1)
RamGive += Math.Min(RamAvailable * 1, RamDelta)
RamAvailable -= RamDelta / 1 + 0.1
If RamAvailable < 0.1 Then GoTo PreFin
'预分配内存,阶段二,T1 ~ T2,80%
RamDelta = RamTarget2 - RamTarget1
RamAvailable = Math.Max(0, RamAvailable - 0.1)
RamGive += Math.Min(RamAvailable * 0.8, RamDelta)
RamAvailable -= RamDelta / 0.8 + 0.1
If RamAvailable < 0.1 Then GoTo PreFin
'预分配内存,阶段三,T2 ~ T3,60%
RamDelta = RamTarget3 - RamTarget2
RamAvailable = Math.Max(0, RamAvailable - 0.2)
RamGive += Math.Min(RamAvailable * 0.6, RamDelta)
RamAvailable -= RamDelta / 0.6 + 0.2
If RamAvailable < 0.1 Then GoTo PreFin
'预分配内存,阶段四,T3 ~ T3 * 2,40%
RamDelta = RamTarget3
RamAvailable = Math.Max(0, RamAvailable - 0.3)
RamGive += Math.Min(RamAvailable * 0.4, RamDelta)
RamAvailable -= RamDelta / 0.4 + 0.3
If RamAvailable < 0.1 Then GoTo PreFin
PreFin:
'不低于最低值
RamGive = Math.Round(Math.Max(RamGive, RamMininum), 1)
Else
'手动配置
Dim Value As Integer = Setup.Get("LaunchRamCustom")
If Value <= 12 Then
RamGive = Value * 0.1 + 0.3
ElseIf Value <= 25 Then
RamGive = (Value - 12) * 0.5 + 1.5
ElseIf Value <= 33 Then
RamGive = (Value - 25) * 1 + 8
ElseIf Value <= 41 Then
RamGive = (Value - 33) * 2 + 16
Else
RamGive = (Value - 41) * 4 + 32
End If
End If
'若使用 32 位 Java,则限制为 1G
If Not JavaUse64Bit(If(UseVersionJavaSetup, Version, Nothing)) Then RamGive = Math.Min(1, RamGive)
Return RamGive
End Function
#End Region
#Region "Java 选择"
'刷新 Java 下拉框显示
Public Sub RefreshJavaComboBox()
If ComboArgumentJava Is Nothing Then Exit Sub
'初始化列表
ComboArgumentJava.Items.Clear()
ComboArgumentJava.Items.Add(New MyComboBoxItem With {.Content = "自动选择适合所选游戏版本的 Java", .Tag = "自动选择"})
'更新列表
Dim SelectedItem As MyComboBoxItem = Nothing
Dim SelectedBySetup As String = Setup.Get("LaunchArgumentJavaSelect")
Try
For Each Java In JavaList
Dim ListItem = New MyComboBoxItem With {.Content = Java.ToString, .ToolTip = Java.PathFolder, .Tag = Java}
ToolTipService.SetPlacement(ListItem, Primitives.PlacementMode.Right)
ToolTipService.SetHorizontalOffset(ListItem, 5)
ComboArgumentJava.Items.Add(ListItem)
'判断人为选中
If SelectedBySetup = "" Then Continue For
If JavaEntry.FromJson(GetJson(SelectedBySetup)).PathFolder = Java.PathFolder Then SelectedItem = ListItem
Next
Catch ex As Exception
Setup.Set("LaunchArgumentJavaSelect", "")
Log(ex, "更新设置 Java 下拉框失败", LogLevel.Feedback)
End Try
'更新选择项
If SelectedItem Is Nothing AndAlso JavaList.Count > 0 Then SelectedItem = ComboArgumentJava.Items(0) '选中 “自动选择”
ComboArgumentJava.SelectedItem = SelectedItem
'结束处理
If SelectedItem Is Nothing Then
ComboArgumentJava.Items.Clear()
ComboArgumentJava.Items.Add(New ComboBoxItem With {.Content = "未找到可用的 Java", .IsSelected = True})
End If
RefreshRam(True)
End Sub
'阻止在特定情况下展开下拉框
Private Sub ComboArgumentJava_DropDownOpened(sender As Object, e As EventArgs) Handles ComboArgumentJava.DropDownOpened
If ComboArgumentJava.SelectedItem Is Nothing OrElse ComboArgumentJava.Items(0).Content = "未找到可用的 Java" OrElse ComboArgumentJava.Items(0).Content = "加载中……" Then
ComboArgumentJava.IsDropDownOpen = False
End If
End Sub
'下拉框选择更改
Private Sub JavaSelectionUpdate() Handles ComboArgumentJava.SelectionChanged
If AniControlEnabled <> 0 Then Exit Sub
'Java 不可用时也不清空,会导致刷新时找不到对象
If ComboArgumentJava.SelectedItem Is Nothing OrElse ComboArgumentJava.SelectedItem.Tag Is Nothing Then Exit Sub
'设置新的 Java
Dim SelectedJava = ComboArgumentJava.SelectedItem.Tag
If "自动选择".Equals(SelectedJava) Then
'选择 “自动”
Setup.Set("LaunchArgumentJavaSelect", "")
Log("[Java] 修改 Java 选择设置:自动选择")
Else
'选择指定项
Setup.Set("LaunchArgumentJavaSelect", CType(SelectedJava.ToJson(), JObject).ToString(Newtonsoft.Json.Formatting.None))
Log("[Java] 修改 Java 选择设置:" & SelectedJava.ToString)
End If
RefreshRam(True)
End Sub
'手动选择
Private Sub BtnArgumentJavaSelect_Click(sender As Object, e As EventArgs) Handles BtnArgumentJavaSelect.Click
If JavaSearchLoader.State = LoadState.Loading Then
Hint("正在搜索 Java,请稍候!", HintType.Critical)
Exit Sub
End If
'选择 Java
Dim JavaSelected As String = SelectFile("javaw.exe|javaw.exe", "选择 javaw.exe 文件")
If JavaSelected = "" Then Exit Sub
If Not JavaSelected.ToLower.EndsWith("javaw.exe") Then
Hint("请选择 bin 文件夹中的 javaw.exe 文件!", HintType.Critical)
Exit Sub
End If
JavaSelected = GetPathFromFullPath(JavaSelected)
Try
'验证 Java 可用
Dim NewEntry As New JavaEntry(JavaSelected, True)
NewEntry.Check()
'加入列表并改变选择
Dim JavaNewList As New JArray From {NewEntry.ToJson}
For Each JsonEntry In GetJson(Setup.Get("LaunchArgumentJavaAll"))
Dim Entry = JavaEntry.FromJson(JsonEntry)
If Entry.PathFolder = NewEntry.PathFolder Then Continue For
JavaNewList.Add(JsonEntry)
Next
Setup.Set("LaunchArgumentJavaAll", JavaNewList.ToString(Newtonsoft.Json.Formatting.None))
Setup.Set("LaunchArgumentJavaSelect", NewEntry.ToJson.ToString(Newtonsoft.Json.Formatting.None)) '加载器会优先选择设置中的 Java
'重新加载列表
JavaSearchLoader.Start(IsForceRestart:=True)
Catch ex As Exception
Log(ex, "该 Java 存在异常,无法使用", LogLevel.Msgbox, "异常的 Java")
Exit Sub
End Try
End Sub
'自动查找
Private Sub BtnArgumentJavaSearch_Click(sender As Object, e As EventArgs) Handles BtnArgumentJavaSearch.Click
If JavaSearchLoader.State = LoadState.Loading Then
Hint("正在搜索 Java,请稍候!", HintType.Critical)
Exit Sub
End If
RunInThread(Sub()
Hint("正在搜索 Java!")
JavaSearchLoader.WaitForExit(GetUuid)
If JavaList.Count = 0 Then
Hint("未找到可用的 Java!", HintType.Critical)
Else
Hint("已找到 " & JavaList.Count & " 个 Java,请检查下拉框查看列表!", HintType.Finish)
End If
End Sub)
End Sub
#End Region
#Region "启动参数"
Private Sub WindowTypeUIRefresh() Handles ComboArgumentWindowType.SelectionChanged
If ComboArgumentWindowType Is Nothing Then Exit Sub
If ComboArgumentWindowType.SelectedIndex = 3 AndAlso LabArgumentWindowMiddle IsNot Nothing AndAlso LabArgumentWindowMiddle.Visibility = Visibility.Collapsed Then
LabArgumentWindowMiddle.Visibility = Visibility.Visible
TextArgumentWindowHeight.Visibility = Visibility.Visible
TextArgumentWindowWidth.Visibility = Visibility.Visible
ElseIf ComboArgumentWindowType.SelectedIndex <> 3 AndAlso LabArgumentWindowMiddle IsNot Nothing AndAlso LabArgumentWindowMiddle.Visibility = Visibility.Visible Then
LabArgumentWindowMiddle.Visibility = Visibility.Collapsed
TextArgumentWindowHeight.Visibility = Visibility.Collapsed
TextArgumentWindowWidth.Visibility = Visibility.Collapsed
End If
End Sub
'可见性选择直接关闭的警告
Private Sub ComboArgumentVisibie_SizeChanged(sender As Object, e As SelectionChangedEventArgs) Handles ComboArgumentVisibie.SelectionChanged
If AniControlEnabled <> 0 Then Exit Sub
If ComboArgumentVisibie.SelectedIndex = 0 Then
If MyMsgBox("若在游戏启动后立即关闭启动器,崩溃检测、更改游戏标题等功能将失效。" & vbCrLf &
"如果想保留这些功能,可以选择让启动器在游戏启动后隐藏,游戏退出后自动关闭。", "提示", "继续", "取消") = 2 Then
ComboArgumentVisibie.SelectedItem = e.RemovedItems(0)
End If
End If
End Sub
#End Region
End Class
@@ -0,0 +1,39 @@
<local:MyPageLeft
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:PCL" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" x:Class="PageSetupLeft"
d:DesignWidth="152" AnimatedControl="{Binding ElementName=PanItem, Mode=OneWay}">
<StackPanel Margin="0,12,0,0" x:Name="PanItem">
<local:MyListItem x:Name="ItemLaunch" IsScaleAnimationEnabled="False" Checked="True" Tag="0" PaddingRight="35" Height="36" VerticalAlignment="Top" Title="游戏" Type="RadioBox"
LogoScale="1" Logo="M924.009688 527.92367C875.975633 601.905321 808.729835 663.317138 733.564477 712.920073 726.302532 832.878385 665.670459 944.569541 567.084624 1015.075229 558.826862 1020.965578 549.065982 1024 539.239339 1024 533.048367 1024 526.829211 1022.806899 520.929468 1020.373725 505.663413 1014.023046 494.709431 1000.278899 491.966239 983.941872 484.67611 940.755376 465.361028 892.899817 436.876917 844.546349 404.954422 853.283229 373.980771 860.385468 344.970569 865.420917 342.227376 865.92822 339.484183 866.144294 336.75978 866.144294 324.142972 866.144294 311.920734 861.174606 302.855046 852.061945L172.807046 721.685138C161.768514 710.637211 156.789431 694.863853 159.466862 679.466275 164.502312 650.390312 171.576367 619.341505 180.27567 587.362642 132.100697 558.822165 84.376661 539.450716 41.302899 532.151193 25.00345 529.370422 11.287486 518.41644 4.98378 503.103413-1.319927 487.809174 0.662312 470.316624 10.254092 456.826128 80.581284 357.958459 191.971817 297.185468 311.591927 289.857761 361.053945 214.495119 422.31545 147.061431 496.081028 98.895853 636.030826 7.54378 802.350972 0 974.730569 0 1001.223046 0 1022.680073 21.494606 1022.680073 48.034055 1022.680073 213.997211 1015.061138 387.72022 924.009688 527.92367ZM558.122275 918.528C601.506055 876.187009 631.784514 822.328367 645.81989 763.744294 602.680367 785.86833 558.563817 804.553982 515.067303 819.989138 533.358385 853.161101 548.023193 886.267303 558.122275 918.528ZM106.566459 465.807266C138.705028 475.915743 171.717284 490.627523 204.804697 508.937394 220.192881 465.337541 238.803376 421.117651 260.871046 377.865394 202.493651 391.947743 148.822899 422.282569 106.566459 465.807266ZM548.398972 179.444257C395.794789 279.09167 294.681835 493.94378 258.522422 671.678239L352.749211 766.121101C530.00455 729.877138 744.283596 628.510532 843.667963 475.474202 912.557798 369.39156 924.742459 236.562789 926.527413 96.387523 786.699743 98.172477 654.227963 110.385321 548.398972 179.444257ZM687.071119 416.617688C642.93578 416.617688 607.161541 380.74011 607.161541 336.492037 607.161541 292.234569 642.93578 256.37578 687.071119 256.37578 731.206459 256.37578 766.971303 292.234569 766.971303 336.492037 766.971303 380.74011 731.206459 416.617688 687.071119 416.617688ZM67.222312 858.008661C77.171083 825.118532 107.646826 801.171963 143.702899 801.171963 187.838239 801.171963 223.603083 837.040147 223.603083 881.297615 223.603083 917.438239 199.722275 948.017321 166.926092 957.975486L52.46356 992.763303C50.998018 993.204844 49.438532 993.458495 47.813284 993.458495 38.973064 993.458495 31.823853 986.290495 31.823853 977.431486 31.823853 975.806239 32.058716 974.237358 32.519046 972.771817L67.222312 858.008661Z">
<local:MyListItem.Buttons>
<x:Array Type="{x:Type local:MyIconButton}">
<local:MyIconButton Tag="0" ToolTip="初始化本页设置" ToolTipService.Placement="Right" ToolTipService.ShowDuration="2333333" ToolTipService.InitialShowDelay="200" Click="Reset" Logo="M835.072 184.32l-77.824 81.92c-64.512-66.56-153.6-106.496-251.904-106.496-195.584 0-355.328 159.744-355.328 354.304 0 195.584 159.744 354.304 355.328 354.304 147.456 0 304.128-80.896 337.92-245.76 3.072-15.36-9.216-23.552-21.504-23.552l-72.704 0c-15.36 0-28.672 14.336-29.696 24.576 0 2.048 0 3.072-1.024 3.072-32.768 96.256-107.52 119.808-212.992 119.808-128 0-232.448-104.448-232.448-232.448s104.448-231.424 232.448-231.424c64.512 0 121.856 26.624 165.888 69.632l-101.376 100.352c-1.024 0-1.024 1.024-2.048 1.024-20.48 22.528-12.288 37.888 11.264 37.888l256 0c22.528 0 36.864-15.36 36.864-37.888L871.936 193.536C870.912 174.08 857.6 166.912 835.072 184.32z" LogoScale="0.9" />
</x:Array>
</local:MyListItem.Buttons>
</local:MyListItem>
<local:MyListItem x:Name="ItemUI" IsScaleAnimationEnabled="False" Tag="1" PaddingRight="38" Height="36" VerticalAlignment="Top" Title="个性化" Logo="M10.5 24h-7c-1.4 0-2.5-1.14-2.5-2.5v-11.64c-.662-.473-1-1.201-1-1.941 0-.376.089-.75.289-1.129 1.065-1.898 2.153-3.783 3.265-5.654.462-.737 1.211-1.136 2.045-1.136.635 0 .972.204 1.445.479.662.386 9 5.352 12.512 7.441.087.052 3.366 1.988 3.449 2.045.663.49.995 1.197.995 1.934 0 .375-.092.745-.295 1.13-1.064 1.899-2.153 3.784-3.265 5.655-.577.92-1.615 1.29-2.496 1.088-.392.234-5.826 3.75-6.252 3.968-.413.212-.762.26-1.192.26m-7.5-10.763v8.263c0 .274.221.5.5.5h4.588c-1.72-2.906-3.417-5.827-5.088-8.763m1.606-1.238c.053.092 5.681 9.797 5.726 9.859.108.139.299.181.455.098.164-.092 5.081-3.251 5.081-3.251-.639-.377-8.144-4.851-11.262-6.706m.659-9.829c-.913 1.456-3.199 5.525-3.235 5.61-.07.171-.008.366.149.464.201.12 16.023 9.547 16.177 9.571.151.022.297-.045.377-.174.942-1.584 3.206-5.55 3.232-5.601.069-.172.007-.367-.15-.465-.201-.12-15.983-9.499-16.09-9.546-.18-.074-.365-.002-.46.141m1.557 2.695c1.104 0 2 .897 2 2 0 1.104-.896 2-2 2s-2-.896-2-2c0-1.103.896-2 2-2" Type="RadioBox">
<local:MyListItem.Buttons>
<x:Array Type="{x:Type local:MyIconButton}">
<local:MyIconButton Tag="1" ToolTip="初始化本页设置" ToolTipService.Placement="Right" ToolTipService.ShowDuration="2333333" ToolTipService.InitialShowDelay="200" Click="Reset" Logo="M835.072 184.32l-77.824 81.92c-64.512-66.56-153.6-106.496-251.904-106.496-195.584 0-355.328 159.744-355.328 354.304 0 195.584 159.744 354.304 355.328 354.304 147.456 0 304.128-80.896 337.92-245.76 3.072-15.36-9.216-23.552-21.504-23.552l-72.704 0c-15.36 0-28.672 14.336-29.696 24.576 0 2.048 0 3.072-1.024 3.072-32.768 96.256-107.52 119.808-212.992 119.808-128 0-232.448-104.448-232.448-232.448s104.448-231.424 232.448-231.424c64.512 0 121.856 26.624 165.888 69.632l-101.376 100.352c-1.024 0-1.024 1.024-2.048 1.024-20.48 22.528-12.288 37.888 11.264 37.888l256 0c22.528 0 36.864-15.36 36.864-37.888L871.936 193.536C870.912 174.08 857.6 166.912 835.072 184.32z" LogoScale="0.9" />
</x:Array>
</local:MyListItem.Buttons>
</local:MyListItem>
<local:MyListItem x:Name="ItemSystem" IsScaleAnimationEnabled="False" Tag="2" PaddingRight="38" Height="36" VerticalAlignment="Top" Title="启动器" Type="RadioBox"
LogoScale="0.87" Logo="M1091.291429 0H78.935771C35.34848 0.035109 0.029257 35.354331 0 78.935771v863.331475c0 43.534629 35.401143 78.994286 78.935771 78.994285H1091.291429c43.534629 0 78.994286-35.401143 78.994285-78.994285V78.871406C1170.156983 35.319223 1134.849463 0.064366 1091.291429 0z m-8.835658 87.771429v78.754377H87.771429v-78.760229h994.684342zM87.771429 933.425737V254.232869h994.684342v679.140205H87.771429v0.058515zM724.95104 340.00896l-206.19264 547.605943a43.903269 43.903269 0 0 1-82.154057-31.012572l206.139977-547.547428a43.944229 43.944229 0 0 1 82.20672 30.954057zM369.558674 545.909029l-85.489371 85.489371 85.489371 85.542034a43.885714 43.885714 0 0 1-62.025143 62.083657l-116.554605-116.560457a43.8272 43.8272 0 0 1 0-62.025143l116.560457-116.49024a43.885714 43.885714 0 0 1 62.019291 61.966629z m610.567315-37.566172a43.885714 43.885714 0 0 1 0 62.083657l-116.560458 116.560457a43.768686 43.768686 0 0 1-62.019291 0 43.885714 43.885714 0 0 1 0-62.083657l85.547886-85.547885-85.547886-85.542035a43.897417 43.897417 0 0 1 62.083657-62.083657l116.496092 116.618972z">
<local:MyListItem.Buttons>
<x:Array Type="{x:Type local:MyIconButton}">
<local:MyIconButton Tag="2" ToolTip="初始化本页设置" ToolTipService.Placement="Right" ToolTipService.ShowDuration="2333333" ToolTipService.InitialShowDelay="200" Click="Reset" Logo="M835.072 184.32l-77.824 81.92c-64.512-66.56-153.6-106.496-251.904-106.496-195.584 0-355.328 159.744-355.328 354.304 0 195.584 159.744 354.304 355.328 354.304 147.456 0 304.128-80.896 337.92-245.76 3.072-15.36-9.216-23.552-21.504-23.552l-72.704 0c-15.36 0-28.672 14.336-29.696 24.576 0 2.048 0 3.072-1.024 3.072-32.768 96.256-107.52 119.808-212.992 119.808-128 0-232.448-104.448-232.448-232.448s104.448-231.424 232.448-231.424c64.512 0 121.856 26.624 165.888 69.632l-101.376 100.352c-1.024 0-1.024 1.024-2.048 1.024-20.48 22.528-12.288 37.888 11.264 37.888l256 0c22.528 0 36.864-15.36 36.864-37.888L871.936 193.536C870.912 174.08 857.6 166.912 835.072 184.32z" LogoScale="0.9" />
</x:Array>
</local:MyListItem.Buttons>
</local:MyListItem>
<local:MyListItem x:Name="ItemLink" IsScaleAnimationEnabled="False" Tag="3" PaddingRight="38" Height="36" VerticalAlignment="Top" Title="联机" Type="RadioBox"
LogoScale="0.75" Logo="M512 817c-48.601 0-88-39.399-88-88s39.399-88 88-88 88 39.399 88 88-39.399 88-88 88zM237.671 565.74C308.335 474.58 397.369 429 504.774 429c118.433 0 214.225 55.421 287.377 166.264l-53.407 30.369c-13.84 7.87-31.362 4.367-41.114-8.219-50.291-64.911-114.577-97.367-192.856-97.367-86.851 0-156.835 40.318-209.95 120.953l-47.995-28.02c-15.263-8.91-20.412-28.507-11.502-43.77a32 32 0 0 1 2.344-3.47zM107.691 419.47C205.24 278.491 337.805 208 505.379 208c178.77 0 317.694 80.224 416.772 240.672l-56.54 31.73c-13.686 7.68-30.922 4.303-40.697-7.975C735.581 360.213 629.07 303.009 505.38 300.815 373.997 298.485 261.637 362.88 168.3 494l-50.116-28.505c-15.362-8.738-20.732-28.275-11.994-43.637a32 32 0 0 1 1.5-2.387z" >
<local:MyListItem.Buttons>
<x:Array Type="{x:Type local:MyIconButton}">
<local:MyIconButton Tag="3" ToolTip="初始化本页设置" ToolTipService.Placement="Right" ToolTipService.ShowDuration="2333333" ToolTipService.InitialShowDelay="200" Click="Reset" Logo="M835.072 184.32l-77.824 81.92c-64.512-66.56-153.6-106.496-251.904-106.496-195.584 0-355.328 159.744-355.328 354.304 0 195.584 159.744 354.304 355.328 354.304 147.456 0 304.128-80.896 337.92-245.76 3.072-15.36-9.216-23.552-21.504-23.552l-72.704 0c-15.36 0-28.672 14.336-29.696 24.576 0 2.048 0 3.072-1.024 3.072-32.768 96.256-107.52 119.808-212.992 119.808-128 0-232.448-104.448-232.448-232.448s104.448-231.424 232.448-231.424c64.512 0 121.856 26.624 165.888 69.632l-101.376 100.352c-1.024 0-1.024 1.024-2.048 1.024-20.48 22.528-12.288 37.888 11.264 37.888l256 0c22.528 0 36.864-15.36 36.864-37.888L871.936 193.536C870.912 174.08 857.6 166.912 835.072 184.32z" LogoScale="0.9" />
</x:Array>
</local:MyListItem.Buttons>
</local:MyListItem>
</StackPanel>
</local:MyPageLeft>
@@ -0,0 +1,169 @@
Public Class PageSetupLeft
Private IsLoad As Boolean = False
Private IsPageSwitched As Boolean = False '如果在 Loaded 前切换到其他页面,会导致触发 Loaded 时再次切换一次
Private Sub PageSetupLeft_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
'是否处于隐藏的子页面
Dim IsHiddenPage As Boolean = False
If ItemLaunch.Checked AndAlso Setup.Get("UiHiddenSetupLaunch") Then IsHiddenPage = True
If ItemUI.Checked AndAlso Setup.Get("UiHiddenSetupUi") Then IsHiddenPage = True
If ItemSystem.Checked AndAlso Setup.Get("UiHiddenSetupSystem") Then IsHiddenPage = True
If ItemLink.Checked AndAlso Setup.Get("UiHiddenSetupLink") Then IsHiddenPage = True
If PageSetupUI.HiddenForceShow Then IsHiddenPage = False
'若页面错误,或尚未加载,则继续
If IsLoad AndAlso Not IsHiddenPage Then Exit Sub
IsLoad = True
'刷新子页面隐藏情况
PageSetupUI.HiddenRefresh()
'选择第一个未被禁用的子页面
If IsPageSwitched Then Exit Sub
If Not Setup.Get("UiHiddenSetupLaunch") Then
ItemLaunch.SetChecked(True, False, False)
ElseIf Not Setup.Get("UiHiddenSetupUi") Then
ItemUI.SetChecked(True, False, False)
ElseIf Not Setup.Get("UiHiddenSetupSystem") Then
ItemSystem.SetChecked(True, False, False)
ElseIf Not Setup.Get("UiHiddenSetupLink") Then
ItemLink.SetChecked(True, False, False)
Else
ItemLaunch.SetChecked(True, False, False)
End If
End Sub
Private Sub PageOtherLeft_Unloaded(sender As Object, e As RoutedEventArgs) Handles Me.Unloaded
IsPageSwitched = False
End Sub
#Region "页面切换"
''' <summary>
''' 当前页面的编号。从左往右从 0 开始计算。
''' </summary>
Public PageID As FormMain.PageSubType
Public Sub New()
InitializeComponent()
'选择第一个未被禁用的子页面
If Not Setup.Get("UiHiddenSetupLaunch") Then
PageID = FormMain.PageSubType.SetupLaunch
ElseIf Not Setup.Get("UiHiddenSetupUi") Then
PageID = FormMain.PageSubType.SetupUI
ElseIf Not Setup.Get("UiHiddenSetupSystem") Then
PageID = FormMain.PageSubType.SetupSystem
ElseIf Not Setup.Get("UiHiddenSetupLink") Then
PageID = FormMain.PageSubType.SetupLink
Else
PageID = FormMain.PageSubType.SetupLaunch
End If
End Sub
''' <summary>
''' 勾选事件改变页面。
''' </summary>
Private Sub PageCheck(sender As MyListItem, e As EventArgs) Handles ItemLaunch.Check, ItemSystem.Check, ItemUI.Check, ItemLink.Check
'尚未初始化控件属性时,sender.Tag 为 Nothing,会跳过切换,且由于 PageID 默认为 0 而切换到第一个页面
'若使用 IsLoaded,则会导致模拟点击不被执行(模拟点击切换页面时,控件的 IsLoaded 为 False)
If sender.Tag IsNot Nothing Then PageChange(Val(sender.Tag))
End Sub
''' <summary>
''' 获取当前导航指定的右页面。
''' </summary>
Public Function PageGet(Optional ID As FormMain.PageSubType = -1)
If ID = -1 Then ID = PageID
Select Case ID
Case FormMain.PageSubType.SetupLaunch
If FrmSetupLaunch Is Nothing Then FrmSetupLaunch = New PageSetupLaunch
Return FrmSetupLaunch
Case FormMain.PageSubType.SetupUI
If FrmSetupUI Is Nothing Then FrmSetupUI = New PageSetupUI
Return FrmSetupUI
Case FormMain.PageSubType.SetupLink
If FrmSetupLink Is Nothing Then FrmSetupLink = New PageSetupLink
Return FrmSetupLink
Case FormMain.PageSubType.SetupSystem
If FrmSetupSystem Is Nothing Then FrmSetupSystem = New PageSetupSystem
Return FrmSetupSystem
Case Else
Throw New Exception("未知的设置子页面种类:" & ID)
End Select
End Function
''' <summary>
''' 切换现有页面。
''' </summary>
Public Sub PageChange(ID As FormMain.PageSubType)
If PageID = ID Then Exit Sub
AniControlEnabled += 1
IsPageSwitched = True
Try
Select Case ID
Case FormMain.PageSubType.SetupLaunch
If IsNothing(FrmSetupLaunch) Then FrmSetupLaunch = New PageSetupLaunch
PageChangeRun(FrmSetupLaunch)
Case FormMain.PageSubType.SetupUI
If IsNothing(FrmSetupUI) Then FrmSetupUI = New PageSetupUI
PageChangeRun(FrmSetupUI)
Case FormMain.PageSubType.SetupLink
If IsNothing(FrmSetupLink) Then FrmSetupLink = New PageSetupLink
PageChangeRun(FrmSetupLink)
Case FormMain.PageSubType.SetupSystem
If IsNothing(FrmSetupSystem) Then FrmSetupSystem = New PageSetupSystem
PageChangeRun(FrmSetupSystem)
Case Else
Throw New Exception("未知的设置子页面种类:" & ID)
End Select
PageID = ID
Catch ex As Exception
Log(ex, "切换设置分页面失败(ID " & ID & ")", LogLevel.Feedback)
Finally
AniControlEnabled -= 1
End Try
End Sub
Private Shared Sub PageChangeRun(Target As MyPageRight)
AniStop("FrmMain PageChangeRight") '停止主页面的右页面切换动画,防止它与本动画一起触发多次 PageOnEnter
If Target.Parent IsNot Nothing Then Target.SetValue(ContentPresenter.ContentProperty, Nothing)
FrmMain.PageRight = Target
CType(FrmMain.PanMainRight.Child, MyPageRight).PageOnExit()
AniStart({
AaCode(Sub()
CType(FrmMain.PanMainRight.Child, MyPageRight).PageOnForceExit()
FrmMain.PanMainRight.Child = FrmMain.PageRight
FrmMain.PageRight.Opacity = 0
End Sub, 130),
AaCode(Sub()
'延迟触发页面通用动画,以使得在 Loaded 事件中加载的控件得以处理
FrmMain.PageRight.Opacity = 1
FrmMain.PageRight.PageOnEnter()
End Sub, 30, True)
}, "PageLeft PageChange")
End Sub
#End Region
Public Sub Reset(sender As Object, e As EventArgs)
Select Case Val(sender.Tag)
Case FormMain.PageSubType.SetupLaunch
If MyMsgBox("是否要初始化启动页的所有设置?该操作不可撤销。", "初始化确认",, "取消", IsWarn:=True) = 1 Then
If IsNothing(FrmSetupLaunch) Then FrmSetupLaunch = New PageSetupLaunch
FrmSetupLaunch.Reset()
End If
Case FormMain.PageSubType.SetupUI
If MyMsgBox("是否要初始化个性化页的所有设置?该操作不可撤销。" & vbCrLf & "(背景图片与音乐、自定义主页等外部文件不会被删除)", "初始化确认",, "取消", IsWarn:=True) = 1 Then
If IsNothing(FrmSetupUI) Then FrmSetupUI = New PageSetupUI
FrmSetupUI.Reset()
End If
Case FormMain.PageSubType.SetupSystem
If MyMsgBox("是否要初始化启动器页的所有设置?该操作不可撤销。", "初始化确认",, "取消", IsWarn:=True) = 1 Then
If IsNothing(FrmSetupSystem) Then FrmSetupSystem = New PageSetupSystem
FrmSetupSystem.Reset()
End If
Case FormMain.PageSubType.SetupLink
If MyMsgBox("是否要初始化联机页的所有设置?该操作不可撤销。", "初始化确认",, "取消", IsWarn:=True) = 1 Then
If IsNothing(FrmSetupLink) Then FrmSetupLink = New PageSetupLink
FrmSetupLink.Reset()
End If
End Select
End Sub
End Class
@@ -0,0 +1,35 @@
<local:MyPageRight
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:PCL" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" x:Class="PageSetupLink"
d:DesignWidth="800" d:DesignHeight="800">
<local:MyScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" x:Name="PanBack">
<StackPanel x:Name="PanMain" Margin="25,10">
<local:MyCard Margin="0,20,0,-5" Title="通用设置">
<StackPanel Margin="25,40,25,15">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Name" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="28" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" VerticalAlignment="Center" HorizontalAlignment="Left" Text="玩家名" Margin="0,0,25,0" />
<local:MyTextBox x:Name="TextLinkName" Grid.Row="0" Grid.ColumnSpan="2" Tag="LinkName" Grid.Column="1">
<local:MyTextBox.ValidateRules>
<local:ValidateNullable />
<local:ValidateNullOrWhiteSpace />
<local:ValidateLength Max="20" />
<local:ValidateFilter />
</local:MyTextBox.ValidateRules>
</local:MyTextBox>
</Grid>
<local:MyCheckBox Text="打开启动器时启动联机模块" Height="22" x:Name="CheckLinkAuto" Tag="LinkAuto" ToolTipService.ShowDuration="2333333" Margin="0,10,0,4"
ToolTip="开启联机模块的人越多,所有使用 PCL2 的玩家的初次连接速度就会越快。因此,启用此项可以为大家作出贡献。&#13;联机模块仅使用少许网络带宽,几乎不使用硬盘与 CPU。" />
</StackPanel>
</local:MyCard>
</StackPanel>
</local:MyScrollViewer>
</local:MyPageRight>
@@ -0,0 +1,47 @@
Class PageSetupLink
Private Shadows IsLoaded As Boolean = False
Private Sub PageSetupLink_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
'重复加载部分
PanBack.ScrollToHome()
'非重复加载部分
If IsLoaded Then Exit Sub
IsLoaded = True
AniControlEnabled += 1
Reload()
AniControlEnabled -= 1
End Sub
Public Sub Reload()
CheckLinkAuto.Checked = Setup.Get("LinkAuto")
TextLinkName.Text = Setup.Get("LinkName")
End Sub
'初始化
Public Sub Reset()
Try
Setup.Reset("LinkAuto")
Setup.Reset("LinkName")
Log("[Setup] 已初始化联机页设置")
Hint("已初始化联机页设置!", HintType.Finish, False)
Catch ex As Exception
Log(ex, "初始化联机页设置失败", LogLevel.Msgbox)
End Try
Reload()
End Sub
'将控件改变路由到设置改变
Private Shared Sub CheckBoxChange(sender As MyCheckBox, e As Object) Handles CheckLinkAuto.Change
If AniControlEnabled = 0 Then Setup.Set(sender.Tag, sender.Checked)
End Sub
Private Shared Sub TextBoxChange(sender As MyTextBox, e As Object) Handles TextLinkName.ValidatedTextChanged
If AniControlEnabled = 0 Then Setup.Set(sender.Tag, sender.Text)
End Sub
End Class
@@ -0,0 +1,158 @@
<local:MyPageRight
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:PCL" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" x:Class="PageSetupSystem"
d:DesignWidth="800" d:DesignHeight="800">
<local:MyScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" x:Name="PanBack">
<StackPanel x:Name="PanMain" Margin="25,10">
<local:MyCard Margin="0,15" Title="下载">
<StackPanel Margin="25,37,25,12">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Name" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="28" />
<RowDefinition Height="7" />
<RowDefinition Height="28" />
<RowDefinition Height="7" />
<RowDefinition Height="27" />
<RowDefinition Height="27" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Left" Text="版本列表获取" Margin="0,0,25,0" />
<local:MyComboBox x:Name="ComboDownloadVersion" Grid.ColumnSpan="2" Tag="ToolDownloadVersion" Grid.Column="1">
<local:MyComboBoxItem Content="尽量使用镜像源(加载快,但版本可能不是最新的)" IsSelected="True" />
<local:MyComboBoxItem Content="在官方源加载缓慢时改用镜像源(平衡)" />
<local:MyComboBoxItem Content="尽量使用官方源(保证版本为最新,但加载非常缓慢)" />
</local:MyComboBox>
<TextBlock Grid.Row="2" VerticalAlignment="Center" HorizontalAlignment="Left" Text="Mod 命名风格" Margin="0,0,25,0" />
<local:MyComboBox Grid.Row="2" x:Name="ComboDownloadTranslate" Grid.ColumnSpan="2" Tag="ToolDownloadTranslate" Grid.Column="1"
ToolTip="决定下载的 Mod 的默认文件名中,中文译名应该放在哪个位置" ToolTipService.ShowDuration="2333333">
<local:MyComboBoxItem Content="译名位于文件名开头:[遗物] relics-0.1.14" IsSelected="True" />
<local:MyComboBoxItem Content="译名位于文件名开头:遗物-relics-0.1.14" />
<local:MyComboBoxItem Content="译名位于文件名末尾:relics-0.1.14-遗物" />
<local:MyComboBoxItem Content="不添加中文译名:relics-0.1.14" />
</local:MyComboBox>
<TextBlock Grid.Row="4" VerticalAlignment="Center" HorizontalAlignment="Left" Text="最大线程数" Margin="0,0,25,0" />
<local:MySlider x:Name="SliderDownloadThread" Grid.Row="4" Tag="ToolDownloadThread" MaxValue="255" Value="63" Grid.Column="1"
ToolTipService.ShowDuration="2333333" ToolTip="线程数越多,限速的文件下载越快,但过高的线程数会造成下载时非常严重的卡顿。&#xA;一般而言,64 线程已可以保证足够的下载速度。" />
<TextBlock VerticalAlignment="Center" Grid.Row="5" HorizontalAlignment="Left" Text="速度限制" Margin="0,0,25,0" />
<local:MySlider x:Name="SliderDownloadSpeed" Grid.Row="5" Tag="ToolDownloadSpeed" MaxValue="42" Value="42" Grid.Column="1" />
<TextBlock VerticalAlignment="Top" Grid.Row="6" HorizontalAlignment="Left" Text="目标文件夹" Margin="0,5,25,5" />
<TextBlock Margin="0,5" HorizontalAlignment="Left" Text="请在 启动 → 版本选择 → 文件夹列表 中更改下载目标文件夹。&#xA;在某个文件夹或游戏版本上右键,即可选择打开对应文件夹。" Grid.Row="6" Grid.Column="1" VerticalAlignment="Center" />
<!--<local:MyCheckBox Text="若版本列表并非从官方源获取,显示版本列表可能过期的提示" Grid.ColumnSpan="2" Grid.Row="3" x:Name="CheckDownloadOutOfDate" Tag="ToolDownloadOutOfDate" Height="22" Margin="0,2,0,8" />-->
</Grid>
</StackPanel>
</local:MyCard>
<local:MyCard Margin="0,0,0,15" Title="辅助功能">
<Grid Margin="25,40,25,17">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Name" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="50" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="22" />
<RowDefinition Height="8" />
<RowDefinition Height="22" />
</Grid.RowDefinitions>
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Left" Text="游戏更新提示" Margin="0,0,25,0" />
<local:MyCheckBox Text="正式版更新提示" Grid.Column="1" x:Name="CheckUpdateRelease" Tag="ToolUpdateRelease" ToolTip="在 Minecraft 正式版更新时弹窗提示" />
<local:MyCheckBox Text="测试版更新提示" Grid.Column="3" Height="22" x:Name="CheckUpdateSnapshot" Tag="ToolUpdateSnapshot" ToolTip="在 Minecraft 测试版(快照、预发布版)更新时弹窗提示" />
<TextBlock VerticalAlignment="Center" Grid.Row="2" HorizontalAlignment="Left" Text="游戏语言" Margin="0,0,25,0" />
<local:MyCheckBox Text="默认设置为中文" Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="5" x:Name="CheckHelpChinese" Tag="ToolHelpChinese" />
</Grid>
</local:MyCard>
<local:MyCard Margin="0,0,0,15" Title="系统">
<Grid Margin="25,40,25,20">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Name" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="28" />
<RowDefinition Height="9" />
<RowDefinition Height="28" />
<RowDefinition Height="9" />
<RowDefinition Height="28" />
<RowDefinition Height="9" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Left" Text="启动器更新" Margin="0,0,25,0" />
<local:MyComboBox x:Name="ComboSystemUpdate" Tag="SystemSystemUpdate" Grid.Column="1">
<local:MyComboBoxItem Content="在有新版本时自动下载" x:Name="ItemSystemUpdateDownload" />
<local:MyComboBoxItem Content="在有新版本时显示提示" />
<local:MyComboBoxItem Content="仅在有重大漏洞更新时显示提示" />
<local:MyComboBoxItem Content="关闭更新提示" />
</local:MyComboBox>
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Left" Text="启动器公告" Margin="0,0,25,0" Grid.Row="2" />
<local:MyComboBox x:Name="ComboSystemActivity" Tag="SystemSystemActivity" Grid.Column="1" Grid.Row="2">
<local:MyComboBoxItem Content="显示所有公告" ToolTip="显示包括启动器功能调查、活动等在内的全部公告" />
<local:MyComboBoxItem Content="仅在有重要通知时显示公告" />
<local:MyComboBoxItem Content="关闭所有公告" />
</local:MyComboBox>
<TextBlock Grid.Row="4" VerticalAlignment="Center" HorizontalAlignment="Left" Text="缓存文件夹" Margin="0,0,25,0" />
<local:MyTextBox x:Name="TextSystemCache" Grid.Row="4" Grid.ColumnSpan="2" Tag="SystemSystemCache" Grid.Column="1" ToolTip="PCL2 的下载、皮肤等缓存文件的存储位置,留空即为默认值,重启后生效" ToolTipService.ShowDuration="2333333" HintText="默认">
<local:MyTextBox.ValidateRules>
<local:ValidateNullable />
<local:ValidateFolderPath UseMinecraftCharCheck="False" />
</local:MyTextBox.ValidateRules>
</local:MyTextBox>
<Grid Height="35" Grid.Row="6" Grid.ColumnSpan="5" Margin="0,5,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
</Grid.ColumnDefinitions>
<local:MyButton x:Name="BtnSystemUpdate" MinWidth="140" Text="检查更新" Padding="13,0" Margin="0,0,20,0" />
<local:MyButton x:Name="BtnSystemCacheClear" MinWidth="140" Text="清理缓存" Padding="13,0" Margin="0,0,20,0" Grid.Column="1" />
</Grid>
</Grid>
</local:MyCard>
<!-- <local:MyCard x:Name="CardMain" Margin="0,15" Title="全局设置">
<StackPanel Margin="25,40,25,15">
<Grid x:Name="PanMainLang" Height="28" Margin="0,0,0,10" Visibility="Collapsed">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Name" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Left" Text="语言" Margin="0,0,25,0" />
<local:MyComboBox x:Name="ComboBackgroundSuit" Tag="UiBackgroundSuit" HorizontalAlignment="Left" Width="170" Grid.Column="1">
<local:MyComboBoxItem Content="简体中文" Tag="zh_CN" IsSelected="True" />
<local:MyComboBoxItem Content="繁體中文" Tag="zh_HK" />
<local:MyComboBoxItem Content="English" Tag="en_US" />
</local:MyComboBox>
</Grid>
</StackPanel>
</local:MyCard> -->
<local:MyCard x:Name="CardDebug" Margin="0,0,0,15" Title="调试选项" CanSwap="True" IsSwaped="True">
<StackPanel Margin="25,40,25,15">
<Grid x:Name="PanDebugAnim" Height="22" Margin="0,0,0,10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Name" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Left" Text="动画速度" Margin="0,0,25,0" />
<local:MySlider x:Name="SliderDebugAnim" Tag="SystemDebugAnim" MaxValue="30" Grid.Column="1" />
</Grid>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1.5*" />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<local:MyCheckBox Grid.Column="0" Text="禁止在下载时复制已存在的文件" Height="22" x:Name="CheckDebugSkipCopy" Tag="SystemDebugSkipCopy" ToolTip="在下载时不直接复制已经存在的文件,而是重新下载每个文件。&#x0a;只建议在测试下载速度时开启。" />
<local:MyCheckBox Grid.Column="1" Text="调试模式" Height="22" x:Name="CheckDebugMode" Tag="SystemDebugMode" ToolTip="显示调试信息与更多错误信息。&#x0a;这会导致启动器性能略有下降,若无特殊需要不建议开启。" />
<local:MyCheckBox Grid.Column="2" Text="添加延迟" Height="22" x:Name="CheckDebugDelay" Tag="SystemDebugDelay" ToolTip="在各个环节添加随机的延迟,拖慢加载速度,以测试部分功能是否正常运行。&#x0a;这会严重影响启动器运行,若无特殊需要不建议开启。" />
</Grid>
</StackPanel>
</local:MyCard>
</StackPanel>
</local:MyScrollViewer>
</local:MyPageRight>
@@ -0,0 +1,251 @@
Class PageSetupSystem
#Region "语言"
'Private Sub PageSetupUI_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
' AniControlEnabled -= 1
' '读取设置
' Select Case Lang
' Case "zh_CN"
' ComboLang.SelectedIndex = 0
' Case "zh_HK"
' ComboLang.SelectedIndex = 1
' Case "en_US"
' ComboLang.SelectedIndex = 2
' End Select
' CheckDebug.Checked = ReadReg("SystemDebugMode", "False")
' AniControlEnabled += 1
'End Sub
'Private Sub RefreshLang() Handles ComboLang.SelectionChanged
' If IsLoaded Then
' If Not ComboLang.IsLoaded Then Exit Sub
' Lang = CType(ComboLang.SelectedItem, MyComboBoxItem).Tag
' Application.Current.Resources.MergedDictionaries(1) = New ResourceDictionary With {.Source = New Url("Languages\" & Lang & ".xaml", UrlKind.Relative)}
' WriteReg("Lang", Lang)
' End If
'End Sub
#End Region
Private Shadows IsLoaded As Boolean = False
Private Sub PageSetupSystem_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
'重复加载部分
PanBack.ScrollToHome()
#If Not BETA Then
ItemSystemUpdateDownload.Content = "在有新版本时自动下载(更新快照版可能需要更新密钥)"
#End If
'非重复加载部分
If IsLoaded Then Exit Sub
IsLoaded = True
AniControlEnabled += 1
Reload()
SliderLoad()
AniControlEnabled -= 1
End Sub
Public Sub Reload()
'下载
SliderDownloadThread.Value = Setup.Get("ToolDownloadThread")
SliderDownloadSpeed.Value = Setup.Get("ToolDownloadSpeed")
ComboDownloadVersion.SelectedIndex = Setup.Get("ToolDownloadVersion")
ComboDownloadTranslate.SelectedIndex = Setup.Get("ToolDownloadTranslate")
'Minecraft 更新提示
CheckUpdateRelease.Checked = Setup.Get("ToolUpdateRelease")
CheckUpdateSnapshot.Checked = Setup.Get("ToolUpdateSnapshot")
'辅助设置
CheckHelpChinese.Checked = Setup.Get("ToolHelpChinese")
'系统设置
ComboSystemUpdate.SelectedIndex = Setup.Get("SystemSystemUpdate")
ComboSystemActivity.SelectedIndex = Setup.Get("SystemSystemActivity")
TextSystemCache.Text = Setup.Get("SystemSystemCache")
'调试选项
CheckDebugMode.Checked = Setup.Get("SystemDebugMode")
SliderDebugAnim.Value = Setup.Get("SystemDebugAnim")
CheckDebugDelay.Checked = Setup.Get("SystemDebugDelay")
CheckDebugSkipCopy.Checked = Setup.Get("SystemDebugSkipCopy")
End Sub
'初始化
Public Sub Reset()
Try
Setup.Reset("ToolDownloadThread")
Setup.Reset("ToolDownloadSpeed")
Setup.Reset("ToolDownloadVersion")
Setup.Reset("ToolDownloadTranslate")
Setup.Reset("ToolUpdateRelease")
Setup.Reset("ToolUpdateSnapshot")
Setup.Reset("ToolHelpChinese")
Setup.Reset("SystemDebugMode")
Setup.Reset("SystemDebugAnim")
Setup.Reset("SystemDebugDelay")
Setup.Reset("SystemDebugSkipCopy")
Setup.Reset("SystemSystemCache")
Setup.Reset("SystemSystemUpdate")
Setup.Reset("SystemSystemActivity")
Log("[Setup] 已初始化启动器页设置")
Hint("已初始化启动器页设置!", HintType.Finish, False)
Catch ex As Exception
Log(ex, "初始化启动器页设置失败", LogLevel.Msgbox)
End Try
Reload()
End Sub
'将控件改变路由到设置改变
Private Shared Sub CheckBoxChange(sender As MyCheckBox, e As Object) Handles CheckDebugMode.Change, CheckDebugDelay.Change, CheckDebugSkipCopy.Change, CheckUpdateRelease.Change, CheckUpdateSnapshot.Change, CheckHelpChinese.Change
If AniControlEnabled = 0 Then Setup.Set(sender.Tag, sender.Checked)
End Sub
Private Shared Sub SliderChange(sender As MySlider, e As Object) Handles SliderDebugAnim.Change, SliderDownloadThread.Change, SliderDownloadSpeed.Change
If AniControlEnabled = 0 Then Setup.Set(sender.Tag, sender.Value)
End Sub
Private Shared Sub ComboChange(sender As MyComboBox, e As Object) Handles ComboDownloadVersion.SelectionChanged, ComboDownloadTranslate.SelectionChanged, ComboSystemUpdate.SelectionChanged, ComboSystemActivity.SelectionChanged
If AniControlEnabled = 0 Then Setup.Set(sender.Tag, sender.SelectedIndex)
End Sub
Private Shared Sub TextBoxChange(sender As MyTextBox, e As Object) Handles TextSystemCache.ValidatedTextChanged
If AniControlEnabled = 0 Then Setup.Set(sender.Tag, sender.Text)
End Sub
'滑动条
Private Sub SliderLoad()
SliderDownloadThread.GetHintText = Function(Value As Integer)
Return Value + 1
End Function
SliderDownloadSpeed.GetHintText = Function(Value As Integer)
If Value <= 14 Then
Return (Value + 1) * 0.1 & " M/s"
ElseIf Value <= 31 Then
Return (Value - 11) * 0.5 & " M/s"
ElseIf Value <= 41 Then
Return (Value - 21) & " M/s"
Else
Return "无限制"
End If
End Function
SliderDebugAnim.GetHintText = Function(Value As Integer)
Return If(Value > 29, "关闭", (Value / 10 + 0.1) & "x")
End Function
End Sub
Private Sub SliderDownloadThread_PreviewChange(sender As Object, e As RouteEventArgs) Handles SliderDownloadThread.PreviewChange
If SliderDownloadThread.Value < 100 Then Exit Sub
If Not Setup.Get("HintDownloadThread") Then
Setup.Set("HintDownloadThread", True)
MyMsgBox("如果设置过多的下载线程,可能会导致下载时出现非常严重的卡顿。" & vbCrLf &
"一般设置 64 线程即可满足大多数下载需求,除非你知道你在干什么,否则不建议设置更多的线程数!", "警告", "我知道了", IsWarn:=True)
End If
End Sub
'调试模式
Private Sub CheckDebugMode_Change() Handles CheckDebugMode.Change
If AniControlEnabled = 0 Then Hint("部分调试信息将在刷新或启动器重启后切换显示!",, False)
End Sub
'清理缓存
Private IsClearingCache As Boolean = False
Private Sub BtnSystemCacheClear_Click(sender As Object, e As EventArgs) Handles BtnSystemCacheClear.Click
If HasDownloadingTask() Then
Hint("请在所有下载任务完成后再清理缓存!", HintType.Critical)
Exit Sub
End If
If MyMsgBox("你确定要清理缓存吗?" & vbCrLf & "在清理缓存后,PCL2 会被强制关闭,以避免缓存缺失带来的异常。", "清理缓存", "确定", "取消") = 2 Then
Exit Sub
End If
If IsClearingCache Then Exit Sub
IsClearingCache = True
Try
Dim TotalSize As ULong = DeleteCacheDirectory(PathTemp)
If TotalSize <= 0 Then
Hint("没有可清理的缓存!")
Else
MyMsgBox("已清理 " & GetString(TotalSize) & " 缓存!" & vbCrLf & "PCL2 即将自动关闭。", "缓存已清理", ForceWait:=True)
FrmMain.EndProgram(False)
End If
Catch ex As Exception
Log(ex, "清理缓存失败", LogLevel.Hint)
Finally
IsClearingCache = False
End Try
End Sub
Private Function DeleteCacheDirectory(Path As String, Optional TotalSize As ULong = 0) As ULong
If Not Directory.Exists(Path) Then Return TotalSize
Dim Temp As String()
Temp = Directory.GetFiles(Path)
For Each str As String In Temp
If str = PathTemp & "CustomSkin.png" Then Continue For '不删除自定义皮肤
Try
Dim Info As New FileInfo(str)
Dim FileActualSize = Math.Ceiling(Info.Length / 4096) * 4096
Info.Delete()
TotalSize += FileActualSize
Catch ex As Exception
Log(ex, "删除失败的缓存文件(" & str & ")")
End Try
Next
Temp = Directory.GetDirectories(Path)
For Each str As String In Temp
TotalSize += DeleteCacheDirectory(str)
Next
Return TotalSize
End Function
'自动更新
Private Sub ComboSystemActivity_SizeChanged(sender As Object, e As SelectionChangedEventArgs) Handles ComboSystemActivity.SelectionChanged
If AniControlEnabled <> 0 Then Exit Sub
If ComboSystemActivity.SelectedIndex = 2 Then
If MyMsgBox("若选择此项,即使在将来出现严重问题时,你也无法获取相关通知。" & vbCrLf &
"例如,如果发现某个版本游戏存在严重 Bug,你可能就会因为无法得到通知而导致无法预知的后果。" & vbCrLf & vbCrLf &
"一般选择 仅在有重要通知时显示公告 就可以让你尽量不受打扰了。" & vbCrLf &
"除非你在制作服务器整合包,或时常手动更新启动器,否则极度不推荐选择此项!", "警告", "继续", "取消") = 2 Then
ComboSystemActivity.SelectedItem = e.RemovedItems(0)
End If
End If
End Sub
Private Sub ComboSystemUpdate_SizeChanged(sender As Object, e As SelectionChangedEventArgs) Handles ComboSystemUpdate.SelectionChanged
If AniControlEnabled <> 0 Then Exit Sub
If ComboSystemUpdate.SelectedIndex = 3 Then
If MyMsgBox("若选择此项,即使在启动器将来出现严重问题时,你也无法获取更新并获得修复。" & vbCrLf &
"例如,如果官方修改了登录方式,从而导致现有启动器无法登录,你可能就会因为无法更新而无法开始游戏。" & vbCrLf & vbCrLf &
"一般选择 仅在有重大漏洞更新时显示提示 就可以让你尽量不受打扰了。" & vbCrLf &
"除非你在制作服务器整合包,或时常手动更新启动器,否则极度不推荐选择此项!", "警告", "继续", "取消") = 2 Then
ComboSystemUpdate.SelectedItem = e.RemovedItems(0)
End If
End If
End Sub
Private Sub BtnSystemUpdate_Click(sender As Object, e As EventArgs) Handles BtnSystemUpdate.Click
UpdateCheckByButton()
End Sub
''' <summary>
''' 启动器是否已经是最新版?
''' 若返回 Nothing,则代表无更新缓存文件或出错。
''' </summary>
Public Shared Function IsLauncherNewest() As Boolean?
Try
'确认服务器公告是否正常
Dim ServerContent As String = ReadFile(PathTemp & "Cache\Notice.cfg")
If ServerContent.Split("|").Count < 3 Then Return Nothing
'确认是否为最新
#If BETA Then
Dim NewVersionCode As Integer = ServerContent.Split("|")(2)
#Else
Dim NewVersionCode As Integer = ServerContent.Split("|")(1)
#End If
Return NewVersionCode <= VersionCode
Catch ex As Exception
Log(ex, "确认启动器更新失败", LogLevel.Feedback)
Return Nothing
End Try
End Function
End Class
@@ -0,0 +1,60 @@
<local:MyPageLeft x:Class="PageSpeedLeft"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:PCL"
mc:Ignorable="d"
d:DesignHeight="450" Width="200" HorizontalAlignment="Left">
<Grid.Resources>
<ResourceDictionary>
<Style TargetType="TextBlock" x:Key="Split">
<Setter Property="UseLayoutRounding" Value="True" />
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="Height" Value="2" />
<Setter Property="Margin" Value="25,7" />
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush EndPoint="1,0.5" StartPoint="0,0.5">
<GradientStop Color="{DynamicResource ColorObject9}" Offset="0"/>
<GradientStop Color="{DynamicResource ColorObject3}" Offset="0.02"/>
<GradientStop Color="{DynamicResource ColorObject3}" Offset="0.98"/>
<GradientStop Color="{DynamicResource ColorObject9}" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="1*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="0.6*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="0.6*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="0.6*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="1*" />
</Grid.RowDefinitions>
<TextBlock Text="总进度" Grid.Row="1" HorizontalAlignment="Center" FontSize="14" Foreground="{DynamicResource ColorBrush3}" />
<TextBlock Grid.Row="2" Style="{DynamicResource Split}" />
<TextBlock Text="00.00 %" Grid.Row="3" Name="LabProgress" HorizontalAlignment="Center" FontSize="20" />
<TextBlock Text="下载速度" Grid.Row="5" HorizontalAlignment="Center" FontSize="14" Foreground="{DynamicResource ColorBrush3}" />
<TextBlock Grid.Row="6" Style="{DynamicResource Split}" />
<TextBlock Text="0 B/s" Grid.Row="7" Name="LabSpeed" HorizontalAlignment="Center" FontSize="20" />
<TextBlock Text="剩余文件" Grid.Row="9" HorizontalAlignment="Center" FontSize="14" Foreground="{DynamicResource ColorBrush3}" />
<TextBlock Grid.Row="10" Style="{DynamicResource Split}" />
<TextBlock Text="123456789" Grid.Row="11" Name="LabFile" HorizontalAlignment="Center" FontSize="20" />
<TextBlock Text="剩余线程" Grid.Row="13" HorizontalAlignment="Center" FontSize="14" Foreground="{DynamicResource ColorBrush3}" />
<TextBlock Grid.Row="14" Style="{DynamicResource Split}" />
<TextBlock Text="123456789" Grid.Row="15" Name="LabThread" HorizontalAlignment="Center" FontSize="20" />
</local:MyPageLeft>
@@ -0,0 +1,235 @@
Public Class PageSpeedLeft
Private Const WatcherInterval As Integer = 300
'初始化
Private IsLoad As Boolean = False
Private Sub Page_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
'进入时就刷新一次显示
Watcher()
'如果在页面切换动画的 “上一页消失” 部分已经完成了下载,就直接尝试返回
TryReturnToHome()
If IsLoad Then Exit Sub
IsLoad = True
'监控定时器
Dim timer As New Threading.DispatcherTimer With {.Interval = New TimeSpan(0, 0, 0, 0, WatcherInterval)}
AddHandler timer.Tick, AddressOf Watcher
timer.Start()
'非调试模式隐藏线程数
If Not ModeDebug Then
RowDefinitions(12).Height = New GridLength(0)
RowDefinitions(13).Height = New GridLength(0)
RowDefinitions(14).Height = New GridLength(0)
RowDefinitions(15).Height = New GridLength(0)
End If
End Sub
'定时器任务
Private ReadOnly RightCards As New Dictionary(Of String, MyCard)
Private Sub Watcher()
If Not FrmMain.PageCurrent = FormMain.PageType.DownloadManager Then Exit Sub
Try
#Region "更新左边栏"
If LoaderTaskbar.Count = 0 Then
'无任务
LabProgress.Text = "100 %"
LabSpeed.Text = "0 B/s"
LabFile.Text = "0"
LabThread.Text = "0 / " & NetTaskThreadLimit
Else
'有任务,输出基本信息
Dim RawPercent As Double = LoaderTaskbarProgress
Dim PredictText As String = Math.Floor(RawPercent * 100) & "." & StrFill(Math.Floor((RawPercent * 100 - Math.Floor(RawPercent * 100)) * 100), "0", 2) & " %"
LabProgress.Text = If(RawPercent > 0.999999, "100 %", PredictText)
LabSpeed.Text = GetString(NetManager.Speed) & "/s"
LabFile.Text = If(NetManager.FileRemain < 0, "0*", NetManager.FileRemain)
LabThread.Text = NetTaskThreadCount & " / " & NetTaskThreadLimit
End If
#End Region
Catch ex As Exception
Log(ex, "下载管理左栏监视出错", LogLevel.Feedback)
End Try
If FrmSpeedRight Is Nothing OrElse FrmSpeedRight.PanMain Is Nothing Then Exit Sub
Try
SyncLock LoaderTaskbarLock
For i = 0 To LoaderTaskbar.Count - 1
TaskRefresh(LoaderTaskbar(i))
Next
End SyncLock
Catch ex As Exception
Log(ex, "下载管理右栏监视出错", LogLevel.Feedback)
End Try
End Sub
Public Sub TaskRefresh(Loader As LoaderBase)
If Loader Is Nothing OrElse Not Loader.Show Then Exit Sub
Try
'获取实际加载器列表
Dim LoaderList As List(Of LoaderBase) = CType(Loader, Object).GetLoaderList()
If RightCards.ContainsKey(Loader.Name) Then
'已有此卡片
Dim Card As Grid = RightCards(Loader.Name)
Dim NewValue As Double = Loader.Progress + Loader.State
If Val(Card.Tag) = NewValue Then Exit Sub
Card.Tag = NewValue
If Card.Children.Count <= 3 Then
Log("[Watcher] 元素不足的卡片:" & Loader.Name, LogLevel.Debug)
Exit Sub
End If
Card = Card.Children(3)
Try
Select Case Loader.State
Case LoadState.Failed
#Region "失败,更新卡片"
Card.RowDefinitions.Clear()
Card.Children.Clear()
Card.Children.Add(GetObjectFromXML("<Path xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" Stretch=""Uniform"" Tag=""Failed"" Data=""F1 M2.5,0 L0,2.5 7.5,10 0,17.5 2.5,20 10,12.5 17.5,20 20,17.5 12.5,10 20,2.5 17.5,0 10,7.5 2.5,0Z"" Height=""15"" Width=""15"" HorizontalAlignment=""Center"" Grid.Column=""0"" Grid.Row=""0"" Fill=""{DynamicResource ColorBrush3}"" Margin=""0,1,0,0"" VerticalAlignment=""Top""/>"))
Dim Tb As TextBlock = GetObjectFromXML("<TextBlock xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" TextWrapping=""Wrap"" HorizontalAlignment=""Left"" ToolTipService.ShowDuration=""2333333"" ToolTip=""单击复制错误详情"" Grid.Column=""1"" Grid.Row=""0"" Margin=""0,0,0,5"" />")
Tb.Text = GetString(Loader.Error, False)
AddHandler Tb.MouseDown, Sub(sender As TextBlock, e As EventArgs)
ClipboardSet(sender.Text, False)
Hint("已复制错误详情!", HintType.Finish)
End Sub
Card.Children.Add(Tb)
''删除取消按钮
'For Each Element As FrameworkElement In CType(Card.Parent, Panel).Children
' If Element.Name = "BtnCancel" Then AniDispose(CType(Element, MyIconButton), True)
'Next
#End Region
Case LoadState.Finished
#Region "完成,销毁卡片并返回"
AniDispose(CType(Card.Parent, MyCard), True, AddressOf TryReturnToHome)
#End Region
Case LoadState.Loading, LoadState.Waiting
#Region "进度不同,更新卡片"
Try
If Card.Children.Count < LoaderList.Count * 2 Then
Log("刷新下载管理卡片失败:卡片中仅有 " & Card.Children.Count & " 个子项", LogLevel.Debug)
Exit Try
End If
Dim Row As Integer = 0
For Each SubTask In LoaderList
Select Case SubTask.State
Case LoadState.Waiting
If CType(Card.Children(Row * 2), FrameworkElement).Tag <> "Waiting" Then
Card.Children.RemoveAt(Row * 2)
Card.Children.Insert(Row * 2, GetObjectFromXML("<Path xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"" xmlns:local=""clr-namespace:PCL;assembly=Plain Craft Launcher 2"" Stretch=""Uniform"" Tag=""Waiting"" Data=""F1 M5,0 a5,5 360 1 0 0,0.0001 m15,0 a5,5 360 1 0 0,0.0001 m15,0 a5,5 360 1 0 0,0.0001 Z"" Width=""18"" HorizontalAlignment=""Center"" Grid.Column=""0"" Grid.Row=""" & Row & """ Fill=""{DynamicResource ColorBrush3}"" Margin=""0,7,0,0"" VerticalAlignment=""Top"" Height=""6""/>"))
End If
Case LoadState.Loading
If CType(Card.Children(Row * 2), FrameworkElement).Tag <> "Loading" Then
Card.Children.RemoveAt(Row * 2)
Card.Children.Insert(Row * 2, GetObjectFromXML("<TextBlock xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"" xmlns:local=""clr-namespace:PCL;assembly=Plain Craft Launcher 2"" Text=""" & Math.Floor(SubTask.Progress * 100) & "%"" Tag=""Loading"" HorizontalAlignment=""Center"" Grid.Column=""0"" Grid.Row=""" & Row & """ Foreground=""{DynamicResource ColorBrush3}""/>"))
Else
CType(Card.Children(Row * 2), TextBlock).Text = Math.Floor(SubTask.Progress * 100) & "%"
End If
Case LoadState.Finished
If CType(Card.Children(Row * 2), FrameworkElement).Tag <> "Finished" Then
Card.Children.RemoveAt(Row * 2)
Card.Children.Insert(Row * 2, GetObjectFromXML("<Path xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"" xmlns:local=""clr-namespace:PCL;assembly=Plain Craft Launcher 2"" Stretch=""Uniform"" Tag=""Finished"" Data=""F1 M 23.7501,33.25L 34.8334,44.3333L 52.2499,22.1668L 56.9999,26.9168L 34.8334,53.8333L 19.0001,38L 23.7501,33.25 Z"" Height=""16"" Width=""15"" HorizontalAlignment=""Center"" Grid.Column=""0"" Grid.Row=""" & Row & """ Fill=""{DynamicResource ColorBrush3}"" Margin=""0,3,0,0"" VerticalAlignment=""Top""/>"))
End If
End Select
Row += 1
Next
Catch ex As Exception
Log(ex, "刷新下载管理卡片失败", LogLevel.Feedback)
End Try
#End Region
End Select
Catch ex As Exception
Log(ex, "更新下载管理显示失败(" & Loader.State.ToString & ")", LogLevel.Feedback)
End Try
ElseIf Not (Loader.State = LoadState.Aborted OrElse Loader.State = LoadState.Finished) Then
Try
#Region "没有卡片且未中断或完成,添加新的卡片"
Dim CardXAML As String = "
<local:MyCard xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"" xmlns:local=""clr-namespace:PCL;assembly=Plain Craft Launcher 2""
Tag=""" & (Loader.Progress + Loader.State) & """ Title=""" & EscapeXML(Loader.Name) & """ Margin=""0,0,0,15"">
<Grid Margin=""14,40,15,10"">
<Grid.ColumnDefinitions>
<ColumnDefinition Width=""50""/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>"
For Each SubTask In LoaderList
CardXAML += "<RowDefinition Height=""26""/>"
Next
CardXAML += "</Grid.RowDefinitions>"
Dim Row As Integer = 0
For Each SubTask In LoaderList
Select Case SubTask.State
Case LoadState.Waiting
CardXAML += "<Path Stretch=""Uniform"" Tag=""Waiting"" Data=""F1 M5,0 a5,5 360 1 0 0,0.0001 m15,0 a5,5 360 1 0 0,0.0001 m15,0 a5,5 360 1 0 0,0.0001 Z"" Width=""18"" HorizontalAlignment=""Center"" Grid.Column=""0"" Grid.Row=""" & Row & """ Fill=""{DynamicResource ColorBrush3}"" Margin=""0,7,0,0"" VerticalAlignment=""Top"" Height=""6""/>"
Case LoadState.Loading
CardXAML += "<TextBlock Text=""" & Math.Floor(SubTask.Progress * 100) & "%"" Tag=""Loading"" HorizontalAlignment=""Center"" Grid.Column=""0"" Grid.Row=""" & Row & """ Foreground=""{DynamicResource ColorBrush3}"" />"
Case LoadState.Finished
CardXAML += "<Path Stretch=""Uniform"" Tag=""Finished"" Data=""F1 M 23.7501,33.25L 34.8334,44.3333L 52.2499,22.1668L 56.9999,26.9168L 34.8334,53.8333L 19.0001,38L 23.7501,33.25 Z"" Height=""16"" Width=""15"" HorizontalAlignment=""Center"" Grid.Column=""0"" Grid.Row=""" & Row & """ Fill=""{DynamicResource ColorBrush3}"" Margin=""0,3,0,0"" VerticalAlignment=""Top""/>"
Case Else
CardXAML += "<Path Stretch=""Uniform"" Tag=""Failed"" Data=""F1 M2.5,0 L0,2.5 7.5,10 0,17.5 2.5,20 10,12.5 17.5,20 20,17.5 12.5,10 20,2.5 17.5,0 10,7.5 2.5,0Z"" Height=""15"" Width=""15"" HorizontalAlignment=""Center"" Grid.Column=""0"" Grid.Row=""" & Row & """ Fill=""{DynamicResource ColorBrush3}"" Margin=""0,1,0,0"" VerticalAlignment=""Top""/>"
End Select
CardXAML += "<TextBlock Text=""" & EscapeXML(SubTask.Name) & """ HorizontalAlignment=""Left"" Grid.Column=""1"" Grid.Row=""" & Row & """/>"
Row += 1
Next
CardXAML += "
</Grid>
</local:MyCard>"
'实例化控件
Dim Card As MyCard
Try
Card = GetObjectFromXML(CardXAML)
Catch ex As Exception
Log(ex, "新建下载管理卡片失败")
Log("出错的卡片内容:" & vbCrLf & CardXAML)
Throw
End Try
FrmSpeedRight.PanMain.Children.Insert(0, Card)
RightCards.Add(Loader.Name, Card)
'添加取消按钮
Dim Cancel As New MyIconButton With {.Name = "BtnCancel", .Logo = "F1 M2,0 L0,2 8,10 0,18 2,20 10,12 18,20 20,18 12,10 20,2 18,0 10,8 2,0Z", .Height = 20, .Margin = New Thickness(0, 10, 10, 0), .LogoScale = 1.1, .HorizontalAlignment = HorizontalAlignment.Right, .VerticalAlignment = VerticalAlignment.Top}
Card.Children.Add(Cancel)
AddHandler Cancel.Click, Sub(sender As MyIconButton, e As EventArgs)
AniDispose(sender, False)
AniDispose(Card, True, Sub() If FrmSpeedRight.PanMain.Children.Count = 0 AndAlso FrmMain.PageCurrent = FormMain.PageType.DownloadManager Then FrmMain.PageBack())
RightCards.Remove(Loader.Name)
RunInThread(Sub() Loader.Abort())
End Sub
'如果已经失败,再刷新一次,修改成失败的控件
If Loader.State = LoadState.Failed Then
Card.Tag = Nothing '避免重复导致刷新无效
TaskRefresh(Loader)
End If
#End Region
Catch ex As Exception
Log(ex, "添加下载管理卡片失败", LogLevel.Feedback)
End Try
End If
Catch ex As Exception
Log(ex, "刷新下载管理显示失败", LogLevel.Feedback)
End Try
End Sub
Public Sub TaskRemove(Loader As Object)
If RightCards.ContainsKey(Loader.Name) Then
RunInUiWait(Sub()
'移除已有的卡片
Dim Card As Grid = RightCards(Loader.Name)
FrmSpeedRight.PanMain.Children.Remove(Card)
RightCards.Remove(Loader.Name)
End Sub)
End If
End Sub
''' <summary>
''' 若没有任务,尝试返回主页。
''' </summary>
Private Sub TryReturnToHome()
If FrmSpeedRight.PanMain.Children.Count = 0 AndAlso FrmMain.PageCurrent = FormMain.PageType.DownloadManager Then
FrmMain.PageBack()
End If
End Sub
End Class
@@ -0,0 +1,40 @@
<local:MyPageRight
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:PCL" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" x:Class="PageSpeedRight"
d:DesignWidth="800" d:DesignHeight="800">
<local:MyScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" x:Name="PanBack">
<StackPanel x:Name="PanMain" Margin="25,25,25,10" Grid.IsSharedSizeScope="True">
<!--<local:MyCard Title="UI 的示例下载任务">
<Grid Margin="25,40,15,10" Height="156">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="45" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="26" />
<RowDefinition Height="26" />
<RowDefinition Height="26" />
<RowDefinition Height="26" />
<RowDefinition Height="26" />
<RowDefinition Height="26" />
</Grid.RowDefinitions>
<Path Stretch="Uniform" Data="F1 M 23.7501,33.25L 34.8334,44.3333L 52.2499,22.1668L 56.9999,26.9168L 34.8334,53.8333L 19.0001,38L 23.7501,33.25 Z" Height="16" Width="16" HorizontalAlignment="Center" Grid.Column="0" Grid.Row="0" Fill="{DynamicResource ColorBrush3}" Margin="0,2.5,14,0" VerticalAlignment="Top" />
<TextBlock Text="完成了的分任务" HorizontalAlignment="Left" Grid.Column="1" Grid.Row="0" />
<Path Stretch="Uniform" Data="F1 M2.5,0 L0,2.5 7.5,10 0,17.5 2.5,20 10,12.5 17.5,20 20,17.5 12.5,10 20,2.5 17.5,0 10,7.5 2.5,0Z" Height="15" Width="15" HorizontalAlignment="Center" Grid.Column="0" Grid.Row="1" Fill="{DynamicResource ColorBrush3}" Margin="0,1,14,0" VerticalAlignment="Top" />
<TextBlock Text="搞定" HorizontalAlignment="Left" Grid.Column="1" Grid.Row="1" />
<TextBlock Text="98%" HorizontalAlignment="Center" Grid.Column="0" Grid.Row="2" Foreground="{DynamicResource ColorBrush3}" Margin="0,0.5,14,0" />
<TextBlock Text="正在进行中的分任务示例" HorizontalAlignment="Left" Grid.Column="1" Grid.Row="2" />
<Path Stretch="Uniform" Data="F1 M5,0 a5,5 360 1 0 0,0.0001 m15,0 a5,5 360 1 0 0,0.0001 m15,0 a5,5 360 1 0 0,0.0001 Z" Width="18" HorizontalAlignment="Center" Grid.Column="0" Grid.Row="3" Fill="{DynamicResource ColorBrush3}" Margin="0,7,14,0" VerticalAlignment="Top" Height="6" />
<TextBlock Text="还没开始" HorizontalAlignment="Left" Grid.Column="1" Grid.Row="3" />
<Path Stretch="Uniform" Data="F1 M5,0 a5,5 360 1 0 0,0.0001 m15,0 a5,5 360 1 0 0,0.0001 m15,0 a5,5 360 1 0 0,0.0001 Z" Width="16" HorizontalAlignment="Center" Grid.Column="0" Grid.Row="4" Fill="{DynamicResource ColorBrush3}" Margin="0,7.5,14,0" VerticalAlignment="Top" Height="6" />
<TextBlock Text="等待中 = 摸鱼" HorizontalAlignment="Left" Grid.Column="1" Grid.Row="4" />
<Path Stretch="Uniform" Data="F1 M5,0 a5,5 360 1 0 0,0.0001 m15,0 a5,5 360 1 0 0,0.0001 m15,0 a5,5 360 1 0 0,0.0001 Z" Width="16" HorizontalAlignment="Center" Grid.Column="0" Grid.Row="5" Fill="{DynamicResource ColorBrush3}" Margin="0,7.5,14,0" VerticalAlignment="Top" Height="6" />
<TextBlock Text="摸鱼一时爽,一直摸鱼一直爽" HorizontalAlignment="Left" Grid.Column="1" Grid.Row="5" />
</Grid>
<local:MyIconButton Logo="F1 M2,0 L0,2 8,10 0,18 2,20 10,12 18,20 20,18 12,10 20,2 18,0 10,8 2,0Z" Height="20" Margin="0,10,10,0" ToolTipService.Placement="Top" ToolTipService.HorizontalOffset="-10" ToolTip="取消" ToolTipService.ShowDuration="2333333" LogoScale="1.1" HorizontalAlignment="Right" VerticalAlignment="Top" />
</local:MyCard> -->
</StackPanel>
</local:MyScrollViewer>
</local:MyPageRight>
@@ -0,0 +1,7 @@
Class PageSpeedRight
Private Sub Init() Handles Me.Loaded
PanBack.ScrollToHome()
End Sub
End Class
@@ -0,0 +1,27 @@
<local:MyPageLeft x:Class="PageVersionLeft"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:PCL" AnimatedControl="{Binding ElementName=PanItem, Mode=OneWay}">
<StackPanel Margin="0,12,0,0" Name="PanItem">
<local:MyListItem x:Name="ItemOverall" IsScaleAnimationEnabled="False" Checked="True" Type="RadioBox" Tag="0" PaddingRight="35" Height="36" VerticalAlignment="Top" Title="概览"
Logo="M12 0l-11 6v12.131l11 5.869 11-5.869v-12.066l-11-6.065zm-1 21.2l-6.664-3.555 4.201-2.801c1.08-.719-.066-2.359-1.243-1.575l-4.294 2.862v-7.901l8 4.363v8.607zm-6.867-14.63l6.867-3.746v4.426c0 1.323 2 1.324 2 0v-4.415l6.91 3.811-7.905 4.218-7.872-4.294zm8.867 6.03l8-4.269v7.8l-4.263-2.842c-1.181-.785-2.323.855-1.245 1.574l4.172 2.781-6.664 3.556v-8.6z" />
<local:MyListItem x:Name="ItemSetup" IsScaleAnimationEnabled="False" Tag="1" PaddingRight="38" Height="36" VerticalAlignment="Top" Title="设置" Type="RadioBox"
LogoScale="1.02" Logo="M292.693 787.627c0 30.72-24.746 55.466-55.466 55.466s-55.467-24.746-55.467-55.466 24.747-55.467 55.467-55.467c30.72-0.853 55.466 24.747 55.466 55.467z M1000.96 241.493c-2.56-5.973-4.267-11.946-6.827-17.92-0.853-6.826-4.266-12.8-8.533-17.92-7.68-9.386-18.773-15.36-31.573-15.36-6.827 0-13.654 1.707-19.627 5.12l-15.36 15.36-17.067 17.067-21.333 21.333L749.227 381.44c-14.507 14.507-38.4 14.507-52.907 0l-54.613-54.613c-14.507-14.507-14.507-38.4 0-52.907l132.266-132.267 14.507-14.506 20.48-20.48 16.213-16.214c3.414-5.973 5.12-11.946 5.12-19.626 0-12.8-5.973-24.747-16.213-32.427-5.973-4.267-11.947-6.827-18.773-7.68-5.12-2.56-10.24-4.267-16.214-5.973-36.693-12.8-76.8-19.627-117.76-19.627-7.68 0-14.506 0-22.186 0.853-188.587 11.947-337.92 168.107-337.92 360.96 0 16.214 0.853 32.427 3.413 48.64L56.32 663.04c-73.387 74.24-73.387 193.707 0 267.093l33.28 33.28c73.387 73.387 193.707 73.387 267.093 0l240.64-241.493c21.334 4.267 42.667 5.973 64 5.973 190.294 0 346.454-146.773 360.107-333.653 0.853-8.533 0.853-17.92 0.853-27.307 0.854-44.373-6.826-86.186-21.333-125.44zM658.773 639.147c-28.16 0-54.613-4.267-79.36-11.094-4.266 7.68-10.24 14.507-16.213 21.334l-258.56 258.56c-43.52 43.52-115.2 43.52-158.72 0l-29.013-29.014c-43.52-44.373-43.52-115.2 0-158.72l212.48-212.48 46.08-46.08c5.973-5.973 12.8-11.093 19.626-15.36-8.533-26.453-12.8-54.613-12.8-83.626v-1.707c0-152.747 123.734-275.627 276.48-275.627 18.774 0 37.547 1.707 55.467 5.974L597.333 207.36c-52.053 52.053-52.053 137.387 0 189.44l29.867 29.867c52.053 52.053 137.387 52.053 189.44 0L930.987 312.32c2.56 16.213 4.266 33.28 4.266 50.347 0 152.746-123.733 276.48-276.48 276.48z">
<local:MyListItem.Buttons>
<x:Array Type="{x:Type local:MyIconButton}">
<local:MyIconButton Tag="1" ToolTip="初始化" ToolTipService.Placement="Right" ToolTipService.ShowDuration="2333333" ToolTipService.InitialShowDelay="200" Click="Reset" Logo="M835.072 184.32l-77.824 81.92c-64.512-66.56-153.6-106.496-251.904-106.496-195.584 0-355.328 159.744-355.328 354.304 0 195.584 159.744 354.304 355.328 354.304 147.456 0 304.128-80.896 337.92-245.76 3.072-15.36-9.216-23.552-21.504-23.552l-72.704 0c-15.36 0-28.672 14.336-29.696 24.576 0 2.048 0 3.072-1.024 3.072-32.768 96.256-107.52 119.808-212.992 119.808-128 0-232.448-104.448-232.448-232.448s104.448-231.424 232.448-231.424c64.512 0 121.856 26.624 165.888 69.632l-101.376 100.352c-1.024 0-1.024 1.024-2.048 1.024-20.48 22.528-12.288 37.888 11.264 37.888l256 0c22.528 0 36.864-15.36 36.864-37.888L871.936 193.536C870.912 174.08 857.6 166.912 835.072 184.32z" LogoScale="0.9" />
</x:Array>
</local:MyListItem.Buttons>
</local:MyListItem>
<local:MyListItem x:Name="ItemMod" IsScaleAnimationEnabled="False" Type="RadioBox" Tag="2" PaddingRight="35" Height="36" VerticalAlignment="Top" Title="Mod 管理"
Logo="M789.504 912.896h-195.072a35.328 35.328 0 0 1-34.816-35.328v-77.312a39.936 39.936 0 0 0-40.448-39.936H481.28a40.448 40.448 0 0 0-40.448 39.936v77.312a34.816 34.816 0 0 1-34.816 35.328H204.8a41.984 41.984 0 0 1-40.448-42.496v-200.192a35.328 35.328 0 0 1 35.328-35.328h72.704a39.936 39.936 0 0 0 39.936-39.936v-37.888a39.936 39.936 0 0 0-39.936-40.448H199.68a35.328 35.328 0 0 1-35.328-35.328V287.744A41.984 41.984 0 0 1 204.8 245.76h176.64v-32.768a102.4 102.4 0 0 1 102.4-102.4h33.792a102.4 102.4 0 0 1 102.4 102.4v32.768h170.496a41.984 41.984 0 0 1 41.984 41.984V460.8h28.672a102.4 102.4 0 0 1 102.4 102.4v33.792a102.4 102.4 0 0 1-102.4 102.4h-28.672V870.4a41.984 41.984 0 0 1-43.008 42.496z m-159.744-70.144h131.584V665.6a34.304 34.304 0 0 1 34.816-34.816h64a31.744 31.744 0 0 0 31.744-31.744V563.2a31.744 31.744 0 0 0-31.744-31.744h-64a34.816 34.816 0 0 1-34.816-35.328V316.416h-177.152a35.328 35.328 0 0 1-35.328-35.328V212.992a31.744 31.744 0 0 0-31.744-31.744h-33.792a31.744 31.744 0 0 0-31.744 31.744v68.096a35.328 35.328 0 0 1-34.816 35.328H234.496v130.048h37.888a110.592 110.592 0 0 1 110.08 110.592v37.888a110.592 110.592 0 0 1-110.08 110.592h-37.888v137.216h136.192v-42.496a110.592 110.592 0 0 1 110.592-110.08h37.888a110.592 110.592 0 0 1 110.592 110.08z" >
<local:MyListItem.Buttons>
<x:Array Type="{x:Type local:MyIconButton}">
<local:MyIconButton Tag="2" ToolTip="刷新" ToolTipService.Placement="Right" ToolTipService.ShowDuration="2333333" ToolTipService.InitialShowDelay="200" Click="Refresh" LogoScale="0.85" Logo="M875.52 148.48C783.36 56.32 655.36 0 512 0 291.84 0 107.52 138.24 30.72 332.8l122.88 46.08C204.8 230.4 348.16 128 512 128c107.52 0 199.68 40.96 271.36 112.64L640 384h384V0L875.52 148.48zM512 896c-107.52 0-199.68-40.96-271.36-112.64L384 640H0v384l148.48-148.48C240.64 967.68 368.64 1024 512 1024c220.16 0 404.48-138.24 481.28-332.8L870.4 645.12C819.2 793.6 675.84 896 512 896z" />
</x:Array>
</local:MyListItem.Buttons>
</local:MyListItem>
<local:MyListItem x:Name="ItemModDisabled" IsScaleAnimationEnabled="False" Type="RadioBox" Tag="3" PaddingRight="35" Height="36" VerticalAlignment="Top" Title="Mod 管理"
Logo="M789.504 912.896h-195.072a35.328 35.328 0 0 1-34.816-35.328v-77.312a39.936 39.936 0 0 0-40.448-39.936H481.28a40.448 40.448 0 0 0-40.448 39.936v77.312a34.816 34.816 0 0 1-34.816 35.328H204.8a41.984 41.984 0 0 1-40.448-42.496v-200.192a35.328 35.328 0 0 1 35.328-35.328h72.704a39.936 39.936 0 0 0 39.936-39.936v-37.888a39.936 39.936 0 0 0-39.936-40.448H199.68a35.328 35.328 0 0 1-35.328-35.328V287.744A41.984 41.984 0 0 1 204.8 245.76h176.64v-32.768a102.4 102.4 0 0 1 102.4-102.4h33.792a102.4 102.4 0 0 1 102.4 102.4v32.768h170.496a41.984 41.984 0 0 1 41.984 41.984V460.8h28.672a102.4 102.4 0 0 1 102.4 102.4v33.792a102.4 102.4 0 0 1-102.4 102.4h-28.672V870.4a41.984 41.984 0 0 1-43.008 42.496z m-159.744-70.144h131.584V665.6a34.304 34.304 0 0 1 34.816-34.816h64a31.744 31.744 0 0 0 31.744-31.744V563.2a31.744 31.744 0 0 0-31.744-31.744h-64a34.816 34.816 0 0 1-34.816-35.328V316.416h-177.152a35.328 35.328 0 0 1-35.328-35.328V212.992a31.744 31.744 0 0 0-31.744-31.744h-33.792a31.744 31.744 0 0 0-31.744 31.744v68.096a35.328 35.328 0 0 1-34.816 35.328H234.496v130.048h37.888a110.592 110.592 0 0 1 110.08 110.592v37.888a110.592 110.592 0 0 1-110.08 110.592h-37.888v137.216h136.192v-42.496a110.592 110.592 0 0 1 110.592-110.08h37.888a110.592 110.592 0 0 1 110.592 110.08z" />
</StackPanel>
</local:MyPageLeft>
@@ -0,0 +1,102 @@
Public Class PageVersionLeft
''' <summary>
''' 当前显示设置的 MC 版本。
''' </summary>
Public Shared Version As McVersion
Private Sub PageVersionLeft_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
If Version IsNot Nothing AndAlso Version.Version.Modable Then
ItemMod.Visibility = Visibility.Visible
ItemModDisabled.Visibility = Visibility.Collapsed
Else
ItemMod.Visibility = Visibility.Collapsed
ItemModDisabled.Visibility = Visibility.Visible
End If
End Sub
#Region "页面切换"
''' <summary>
''' 当前页面的编号。从 0 开始计算。
''' </summary>
Public PageID As FormMain.PageSubType = FormMain.PageSubType.Default
''' <summary>
''' 勾选事件改变页面。
''' </summary>
Private Sub PageCheck(sender As MyListItem, e As RouteEventArgs) Handles ItemOverall.Check, ItemMod.Check, ItemModDisabled.Check, ItemSetup.Check
'尚未初始化控件属性时,sender.Tag 为 Nothing,会导致切换到页面 0
'若使用 IsLoaded,则会导致模拟点击不被执行(模拟点击切换页面时,控件的 IsLoaded 为 False)
If sender.Tag IsNot Nothing Then PageChange(Val(sender.Tag))
End Sub
Public Function PageGet(Optional ID As FormMain.PageSubType = -1)
If ID = -1 Then ID = PageID
Select Case ID
Case FormMain.PageSubType.VersionOverall
If FrmVersionOverall Is Nothing Then FrmVersionOverall = New PageVersionOverall
Return FrmVersionOverall
Case FormMain.PageSubType.VersionMod
If FrmVersionMod Is Nothing Then FrmVersionMod = New PageVersionMod
Return FrmVersionMod
Case FormMain.PageSubType.VersionModDisabled
If FrmVersionModDisabled Is Nothing Then FrmVersionModDisabled = New PageVersionModDisabled
Return FrmVersionModDisabled
Case FormMain.PageSubType.VersionSetup
If IsNothing(FrmVersionSetup) Then FrmVersionSetup = New PageVersionSetup
Return FrmVersionSetup
Case Else
Throw New Exception("未知的版本设置子页面种类:" & ID)
End Select
End Function
''' <summary>
''' 切换现有页面。
''' </summary>
Public Sub PageChange(ID As FormMain.PageSubType)
If PageID = ID Then Exit Sub
AniControlEnabled += 1
Try
PageChangeRun(PageGet(ID))
PageID = ID
Catch ex As Exception
Log(ex, "切换设置分页面失败(ID " & ID & ")", LogLevel.Feedback)
Finally
AniControlEnabled -= 1
End Try
End Sub
Private Shared Sub PageChangeRun(Target As MyPageRight)
AniStop("FrmMain PageChangeRight") '停止主页面的右页面切换动画,防止它与本动画一起触发多次 PageOnEnter
If Target.Parent IsNot Nothing Then Target.SetValue(ContentPresenter.ContentProperty, Nothing)
FrmMain.PageRight = Target
CType(FrmMain.PanMainRight.Child, MyPageRight).PageOnExit()
AniStart({
AaCode(Sub()
CType(FrmMain.PanMainRight.Child, MyPageRight).PageOnForceExit()
FrmMain.PanMainRight.Child = FrmMain.PageRight
FrmMain.PageRight.Opacity = 0
End Sub, 130),
AaCode(Sub()
'延迟触发页面通用动画,以使得在 Loaded 事件中加载的控件得以处理
FrmMain.PageRight.Opacity = 1
FrmMain.PageRight.PageOnEnter()
End Sub, 30, True)
}, "PageLeft PageChange")
End Sub
#End Region
Public Sub Refresh(sender As Object, e As EventArgs) '由边栏按钮匿名调用
'强制刷新
If FrmVersionMod IsNot Nothing Then FrmVersionMod.RefreshList(True) '没有 Else,还没加载刷个鬼的新
End Sub
Public Sub Reset(sender As Object, e As EventArgs)
If MyMsgBox("是否要初始化该版本的版本独立设置?该操作不可撤销。", "初始化确认",, "取消", IsWarn:=True) = 1 Then
If IsNothing(FrmVersionSetup) Then FrmVersionSetup = New PageVersionSetup
FrmVersionSetup.Reset()
End If
End Sub
End Class
@@ -0,0 +1,51 @@
<local:MyPageRight
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:PCL" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" x:Class="PageVersionMod"
d:DesignWidth="800" d:DesignHeight="800">
<Grid>
<Grid x:Name="PanAllBack">
<local:MyScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" x:Name="PanBack">
<StackPanel x:Name="PanMain" Margin="25,10" Grid.IsSharedSizeScope="True">
<local:MySearchBox Margin="0,15" HintText="搜索 Mod" x:Name="SearchBox" />
<local:MyCard Grid.Row="0" Margin="0,0,0,15" Title="管理" x:Name="PanManage">
<StackPanel Margin="25,40,15,20">
<TextBlock Margin="0,0,0,11" Text="左键点击某个 Mod 可以单独启用或禁用它。将 Mod 文件拖入窗口可以快速安装 Mod。" TextWrapping="Wrap" />
<Grid Height="35">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
</Grid.ColumnDefinitions>
<local:MyButton x:Name="BtnManageOpen" Grid.Column="0" MinWidth="140" Text="打开 Mod 文件夹" Padding="13,0" Margin="0,0,20,0" HorizontalAlignment="Left" ColorType="Highlight" />
<local:MyButton x:Name="BtnManageEnabled" Grid.Column="1" MinWidth="140" Text="全部启用" Padding="13,0" Margin="0,0,20,0" HorizontalAlignment="Left" />
<local:MyButton x:Name="BtnManageDisabled" Grid.Column="2" MinWidth="140" Text="全部禁用" Padding="13,0" Margin="0,0,20,0" HorizontalAlignment="Left" />
<local:MyButton x:Name="BtnManageCheck" Grid.Column="3" MinWidth="140" Text="检查 Mod" Padding="13,0" Margin="0,0,20,0" HorizontalAlignment="Left" ToolTip="快速检查 Mod 的版本要求、重复、前置缺失等问题。&#xA;结果仅供参考,由于部分 Mod 标注的信息有误,可能并不准确。" Visibility="Collapsed" />
</Grid>
</StackPanel>
</local:MyCard>
<Grid>
<!--虽然不知道为什么但是删掉这个 Grid 在搜索结束的时候就会出现显示问题-->
<local:MyCard x:Name="PanSearch" Visibility="Collapsed" VerticalAlignment="Top" Opacity="0" Margin="0,0,0,15" Title=" " MinHeight="40">
<StackPanel Margin="20,40,18,18" Name="PanSearchList" VerticalAlignment="Top" />
</local:MyCard>
<StackPanel Name="PanList" />
</Grid>
</StackPanel>
</local:MyScrollViewer>
<local:MyCard HorizontalAlignment="Center" VerticalAlignment="Center" Margin="40" x:Name="PanEmpty">
<StackPanel Margin="20,17">
<TextBlock Margin="0,0,0,9" HorizontalAlignment="Center" Text="未找到 Mod" FontSize="19" UseLayoutRounding="True" SnapsToDevicePixels="True" Foreground="{DynamicResource ColorBrush3}" />
<Rectangle HorizontalAlignment="Stretch" Height="2" Fill="{DynamicResource ColorBrush3}" />
<TextBlock Margin="10,15,10,0" Text="要安装 Mod,请直接将 Mod 文件拖入 PCL2 窗口。&#xA;如果你确定你已经安装了 Mod,但仍然看到了这条提示,那么你的版本隔离设置可能有误。请尝试在启动设置中调整版本隔离选项。" TextWrapping="Wrap" />
<local:MyButton Height="35" HorizontalAlignment="Center" x:Name="BtnHintOpen" MinWidth="140" Text="打开 Mod 文件夹" Margin="0,15,0,0" Padding="13,0" ColorType="Highlight" />
</StackPanel>
</local:MyCard>
</Grid>
<local:MyCard HorizontalAlignment="Center" VerticalAlignment="Center" Margin="40,0" SnapsToDevicePixels="True" x:Name="PanLoad" UseAnimation="False">
<local:MyLoading Text="正在加载 Mod 列表" Margin="20,20,20,17" x:Name="Load" HorizontalAlignment="Center" VerticalAlignment="Center" />
</local:MyCard>
</Grid>
</local:MyPageRight>
@@ -0,0 +1,475 @@
Public Class PageVersionMod
#Region "初始化"
Private IsLoad As Boolean = False
Public Sub PageOther_Loaded() Handles Me.Loaded
PanBack.ScrollToHome()
RefreshList()
'非重复加载部分
If IsLoad Then Exit Sub
IsLoad = True
#If DEBUG Then
BtnManageCheck.Visibility = Visibility.Visible
#End If
End Sub
''' <summary>
''' 刷新 Mod 列表。
''' </summary>
Public Sub RefreshList(Optional ForceReload As Boolean = False)
If McModLoader.State = LoadState.Loading Then Exit Sub
If LoaderFolderRun(McModLoader, PageVersionLeft.Version.PathIndie & "mods\", If(ForceReload, LoaderFolderRunType.ForceRun, LoaderFolderRunType.RunOnUpdated)) Then
PanBack.ScrollToHome()
SearchBox.Text = ""
End If
End Sub
Private Sub LoaderInit() Handles Me.Initialized
PageLoaderInit(Load, PanLoad, PanAllBack, Nothing, McModLoader, AddressOf Load_Finish, AutoRun:=False)
End Sub
Private Sub Load_Click(sender As Object, e As MouseButtonEventArgs) Handles Load.Click
If McModLoader.State = LoadState.Failed Then
LoaderFolderRun(McModLoader, PageVersionLeft.Version.PathIndie & "mods\", LoaderFolderRunType.ForceRun)
End If
End Sub
#End Region
#Region "UI 化"
''' <summary>
''' 将 Mod 列表加载为 UI。
''' </summary>
Private Sub Load_Finish(Loader As LoaderTask(Of String, List(Of McMod)))
Dim List As List(Of McMod) = Loader.Output
Try
PanList.Children.Clear()
'判断应该显示哪一个页面
If List.Count = 0 Then
PanEmpty.Visibility = Visibility.Visible
PanBack.Visibility = Visibility.Collapsed
Exit Sub
Else
PanBack.Visibility = Visibility.Visible
PanEmpty.Visibility = Visibility.Collapsed
End If
'建立 StackPanel
Dim NewStack As New StackPanel With {.Margin = New Thickness(20, MyCard.SwapedHeight, 18, If(List.Count > 0, 20, 0)), .VerticalAlignment = VerticalAlignment.Top, .RenderTransform = New TranslateTransform(0, 0)}
For Each ModEntity As McMod In List
NewStack.Children.Add(McModListItem(ModEntity))
Next
'建立 MyCard
Dim NewCard As New MyCard With {.Title = McModGetTitle(List), .Margin = New Thickness(0, 0, 0, 15)}
NewCard.Children.Add(NewStack)
PanList.Children.Add(NewCard)
'显示提示
If List.Count > 0 AndAlso Not Setup.Get("HintModDisable") Then
Setup.Set("HintModDisable", True)
Hint("直接点击某个 Mod 项即可将它禁用!")
End If
Catch ex As Exception
Log(ex, "加载 Mod 列表 UI 失败", LogLevel.Feedback)
End Try
End Sub
''' <summary>
''' 获取 Card 的标题。
''' </summary>
Private Function McModGetTitle(List As List(Of McMod)) As String
Dim Counter = {0, 0, 0}
For Each ModEntity As McMod In List
Counter(ModEntity.State) += 1
Next
If List.Count = 0 Then
'全空
Return "未找到任何 Mod"
ElseIf Counter(McMod.McModState.Disabled) = 0 AndAlso Counter(McMod.McModState.Unavaliable) = 0 Then
'只有启用的 Mod
Return "Mod 列表(" & Counter(McMod.McModState.Fine) & ")"
Else
'混合种类
Dim TypeList As New List(Of String)
If Counter(McMod.McModState.Fine) > 0 Then TypeList.Add("启用 " & Counter(McMod.McModState.Fine))
If Counter(McMod.McModState.Disabled) > 0 Then TypeList.Add("禁用 " & Counter(McMod.McModState.Disabled))
If Counter(McMod.McModState.Unavaliable) > 0 Then TypeList.Add("错误 " & Counter(McMod.McModState.Unavaliable))
Return "Mod 列表(" & Join(TypeList, ",") & ")"
End If
End Function
Private Function McModListItem(Entry As McMod) As MyListItem
'图标
Dim Logo As String
Select Case Entry.State
Case McMod.McModState.Fine
Logo = "pack://application:,,,/images/Blocks/RedstoneLampOn.png"
Case McMod.McModState.Disabled
Logo = "pack://application:,,,/images/Blocks/RedstoneLampOff.png"
Case Else '出错
Logo = "pack://application:,,,/images/Blocks/RedstoneBlock.png"
End Select
'文本
Dim Title As String
If Entry.State = McMod.McModState.Disabled Then
Title = GetFileNameWithoutExtentionFromPath(Entry.Path.Substring(0, Entry.Path.Count - ".disabled".Count)) & "(已禁用)"
Else
Title = GetFileNameWithoutExtentionFromPath(Entry.Path)
End If
Dim Desc As String
If Entry.Version Is Nothing OrElse Entry.Description IsNot Nothing Then
Desc = Entry.Name & If(Entry.Version Is Nothing, "", " (" & Entry.Version & ")") & " : " & If(Entry.Description, Entry.Path)
ElseIf Entry.IsFileAvailable Then
Desc = Entry.Path
Else
Desc = "存在错误 : " & Entry.Path
End If
'Desc = If(Entry.ModId, "无可用名称") & " (" & If(Entry.Version, "无可用版本") & ")"
'If Entry.Dependencies.Count > 0 Then
' Dim DepList As New List(Of String)
' For Each Dep In Entry.Dependencies
' DepList.Add(Dep.Key & If(Dep.Value Is Nothing, "", "@" & Dep.Value))
' Next
' Desc += " : " & Join(DepList, ", ")
'End If
'实例化
Dim NewItem As New MyListItem With {.Logo = Logo, .SnapsToDevicePixels = True, .Title = Title, .Info = Desc, .Height = 42, .Type = MyListItem.CheckType.Clickable, .Tag = Entry}
NewItem.PaddingRight = If(Entry.IsFileAvailable, 73, 55)
'事件
NewItem.ContentHandler = AddressOf McModContent
Return NewItem
End Function
Private Sub McModContent(sender As MyListItem, e As EventArgs)
Dim ModEntity As McMod = sender.Tag
'注册点击事件
AddHandler sender.Click, AddressOf Item_Click
'图标按钮
Dim BtnDel As New MyIconButton With {.LogoScale = 1.1, .Logo = Logo.IconButtonDelete, .Tag = sender}
BtnDel.ToolTip = "删除"
ToolTipService.SetPlacement(BtnDel, Primitives.PlacementMode.Center)
ToolTipService.SetVerticalOffset(BtnDel, 30)
ToolTipService.SetHorizontalOffset(BtnDel, 2)
AddHandler BtnDel.Click, AddressOf Delete_Click
Dim BtnOpen As New MyIconButton With {.LogoScale = 1.15, .Logo = Logo.IconButtonOpen, .Tag = sender}
BtnOpen.ToolTip = "打开文件位置"
ToolTipService.SetPlacement(BtnOpen, Primitives.PlacementMode.Center)
ToolTipService.SetVerticalOffset(BtnOpen, 30)
ToolTipService.SetHorizontalOffset(BtnOpen, 2)
AddHandler BtnOpen.Click, AddressOf Open_Click
If ModEntity.IsFileAvailable Then
Dim BtnCont As New MyIconButton With {.LogoScale = 1.05, .Logo = Logo.IconButtonInfo, .Tag = sender}
BtnCont.ToolTip = "详情"
ToolTipService.SetPlacement(BtnCont, Primitives.PlacementMode.Center)
ToolTipService.SetVerticalOffset(BtnCont, 30)
ToolTipService.SetHorizontalOffset(BtnCont, 2)
AddHandler BtnCont.Click, AddressOf Info_Click
AddHandler sender.MouseRightButtonDown, AddressOf Info_Click
sender.Buttons = {BtnCont, BtnOpen, BtnDel}
Else
sender.Buttons = {BtnOpen, BtnDel}
End If
End Sub
#End Region
#Region "管理"
''' <summary>
''' 打开 Mods 文件夹。
''' </summary>
Private Sub BtnManageOpen_Click(sender As Object, e As EventArgs) Handles BtnManageOpen.Click, BtnHintOpen.Click
Try
Directory.CreateDirectory(PageVersionLeft.Version.PathIndie & "mods\")
OpenExplorer("""" & PageVersionLeft.Version.PathIndie & "mods\""")
Catch ex As Exception
Log(ex, "打开 Mods 文件夹失败", LogLevel.Msgbox)
End Try
End Sub
#If DEBUG Then
''' <summary>
''' 检查 Mod。
''' </summary>
Private Sub BtnManageCheck_Click(sender As Object, e As EventArgs) Handles BtnManageCheck.Click
Try
Dim Result = McModCheck(PageVersionLeft.Version, McModLoader.Output)
If Result.Count > 0 Then
MyMsgBox(Join(Result, vbCrLf & vbCrLf), "Mod 检查结果")
Else
Hint("Mod 检查完成,未发现任何问题!", HintType.Finish)
End If
Catch ex As Exception
Log(ex, "进行 Mod 检查时出错", LogLevel.Feedback)
End Try
End Sub
#End If
''' <summary>
''' 一键启用 / 禁用。
''' </summary>
Private Sub BtnManageChange_Click(sender As MyButton, e As EventArgs) Handles BtnManageEnabled.Click, BtnManageDisabled.Click
Dim IsSuccessful As Boolean = True
Try
Dim IsDisable As Boolean = sender.Text.Contains("禁用")
For Each ModEntity In McModLoader.Output
Dim NewPath As String = Nothing
If ModEntity.State = McMod.McModState.Fine And IsDisable Then
'禁用
NewPath = ModEntity.Path & ".disabled"
ElseIf ModEntity.State = McMod.McModState.Disabled AndAlso Not IsDisable Then
'启用
NewPath = ModEntity.Path.Substring(0, ModEntity.Path.Count - ".disabled".Count)
Else
Continue For
End If
'重命名
Try
If File.Exists(ModEntity.Path) Then
File.Delete(NewPath)
FileSystem.Rename(ModEntity.Path, NewPath)
Else
Throw New FileNotFoundException("未找到文件:" & ModEntity.Path)
End If
Catch ex As Exception
Log(ex, "全局状态改变中重命名 Mod 失败")
IsSuccessful = False
End Try
Next
Catch ex As Exception
Log(ex, "改变全部 Mod 状态失败", LogLevel.Msgbox)
IsSuccessful = False
Finally
If Not IsSuccessful Then Hint("由于文件被占用,部分 Mod 的状态切换失败,请尝试关闭正在运行的游戏后再试!", HintType.Critical)
RefreshList()
End Try
End Sub
#End Region
#Region "单个 Mod 项"
'点击:切换可用状态 / 显示错误原因
Public Sub Item_Click(sender As MyListItem, e As EventArgs)
Try
Dim ModEntity As McMod = sender.Tag
Dim NewPath As String = Nothing
Select Case ModEntity.State
Case McMod.McModState.Fine
'前置检测警告
If ModEntity.IsPresetMod Then
If MyMsgBox("该 Mod 可能为其他 Mod 的前置,如果禁用可能导致其他 Mod 无法使用。" & vbCrLf & "你确定要继续禁用吗?", "警告", "禁用", "取消") = 2 Then Exit Sub
End If
NewPath = ModEntity.Path & ".disabled"
Case McMod.McModState.Disabled
NewPath = ModEntity.Path.Substring(0, ModEntity.Path.Count - ".disabled".Count)
Case McMod.McModState.Unavaliable
MyMsgBox("无法读取此 Mod 的信息。" & vbCrLf & vbCrLf & "详细的错误信息:" & GetString(ModEntity.FileUnavailableReason, False), "Mod 读取失败")
Exit Sub
End Select
'重命名
Dim NewModEntity As New McMod(NewPath)
Try
File.Delete(NewPath)
FileSystem.Rename(ModEntity.Path, NewPath)
Catch ex As FileNotFoundException
Log(ex, "未找到理应存在的 Mod 文件(" & ModEntity.Path & ")")
FileSystem.Rename(NewPath, ModEntity.Path)
NewModEntity = New McMod(ModEntity.Path)
End Try
'更改 Loader 中的列表
Dim IndexOfLoader As Integer = McModLoader.Output.IndexOf(ModEntity)
McModLoader.Output.RemoveAt(IndexOfLoader)
McModLoader.Output.Insert(IndexOfLoader, NewModEntity)
'更改 UI 中的列表
Dim Parent As StackPanel = sender.Parent
Dim IndexOfUi As Integer = Parent.Children.IndexOf(sender)
Parent.Children.RemoveAt(IndexOfUi)
Parent.Children.Insert(IndexOfUi, McModListItem(NewModEntity))
'仅在非搜索页面才执行,以确保搜索页内外显示一致
If String.IsNullOrWhiteSpace(SearchBox.Text) Then
'改变禁用数量的显示
CType(Parent.Parent, MyCard).Title = McModGetTitle(McModLoader.Output)
'更新加载器状态
LoaderFolderRun(McModLoader, PageVersionLeft.Version.PathIndie & "mods\", LoaderFolderRunType.UpdateOnly)
End If
Catch ex As Exception
Log(ex, "单个状态改变中重命名 Mod 失败")
Hint("切换 Mod 状态失败,请尝试关闭正在运行的游戏后再试!")
LoaderFolderRun(McModLoader, PageVersionLeft.Version.PathIndie & "mods\", LoaderFolderRunType.UpdateOnly)
End Try
End Sub
'删除
Public Sub Delete_Click(sender As MyIconButton, e As EventArgs)
Try
Dim ListItem As MyListItem = sender.Tag
Dim ModEntity As McMod = ListItem.Tag
'前置检测警告
If ModEntity.IsPresetMod Then
If MyMsgBox("该 Mod 可能为其他 Mod 的前置,如果删除可能导致其他 Mod 无法使用。" & vbCrLf & "你确定要继续删除吗?", "警告", "删除", "取消", IsWarn:=True) = 2 Then Exit Sub
End If
'删除
If File.Exists(ModEntity.Path) Then
My.Computer.FileSystem.DeleteFile(ModEntity.Path, FileIO.UIOption.OnlyErrorDialogs, FileIO.RecycleOption.SendToRecycleBin)
Else
'在不明原因下删除的文件可能还在列表里,如果玩家又点了一次就会出错,总之加个判断也不碍事
Log("[System] 需要删除的 Mod 文件不存在(" & ModEntity.Path & ")", LogLevel.Hint)
Exit Sub
End If
'更改 Loader 中的列表
McModLoader.Output.Remove(ModEntity)
'更改 UI 中的列表
Dim Parent As StackPanel = ListItem.Parent
Parent.Children.Remove(ListItem)
If Parent.Children.Count = 0 Then
RefreshList(True)
Else
CType(Parent.Parent, MyCard).Title = McModGetTitle(McModLoader.Output)
End If
'显示提示
Hint("已将 " & ModEntity.FileName & " 删除到回收站!", HintType.Finish)
LoaderFolderRun(McModLoader, PageVersionLeft.Version.PathIndie & "mods\", LoaderFolderRunType.UpdateOnly)
Catch ex As Exception
Log(ex, "删除 Mod 失败", LogLevel.Feedback)
End Try
End Sub
'详情
Public Sub Info_Click(sender As Object, e As EventArgs)
Try
Dim ListItem As MyListItem
ListItem = If(TypeOf sender Is MyIconButton, sender.Tag, sender)
Dim ModEntity As McMod = ListItem.Tag
'获取信息
Dim ContentLines As New List(Of String)
If ModEntity.Description IsNot Nothing Then ContentLines.Add(ModEntity.Description & vbCrLf)
If ModEntity.Authors IsNot Nothing Then ContentLines.Add("作者:" & ModEntity.Authors)
ContentLines.Add("文件:" & ModEntity.FileName & "(" & GetString(New FileInfo(ModEntity.Path).Length) & ")")
If ModEntity.Version IsNot Nothing Then ContentLines.Add("版本:" & ModEntity.Version)
If ModeDebug Then
Dim DebugInfo As New List(Of String)
If ModEntity.ModId IsNot Nothing Then
DebugInfo.Add("Mod ID:" & ModEntity.ModId)
End If
If ModEntity.Dependencies.Count > 0 Then
DebugInfo.Add("依赖于:")
For Each Dep In ModEntity.Dependencies
DebugInfo.Add(" - " & Dep.Key & If(Dep.Value Is Nothing, "", ",版本:" & Dep.Value))
Next
End If
If DebugInfo.Count > 0 Then
ContentLines.Add(vbCrLf & "—————— 调试信息 ——————")
ContentLines.AddRange(DebugInfo)
End If
End If
'获取用于搜索的 Mod 名称
Dim ModOriginalName As String = ModEntity.Name.Replace(" ", "+")
Dim ModSearchName As String = ModOriginalName.Substring(0, 1)
For i = 1 To ModOriginalName.Count - 1
Dim IsLastLower As Boolean = ModOriginalName(i - 1).ToString.ToLower.Equals(ModOriginalName(i - 1).ToString)
Dim IsCurrentLower As Boolean = ModOriginalName(i).ToString.ToLower.Equals(ModOriginalName(i).ToString)
If IsLastLower AndAlso Not IsCurrentLower Then
'上一个字母为小写,这一个字母为大写
ModSearchName += "+"
End If
ModSearchName += ModOriginalName(i)
Next
ModSearchName = ModSearchName.Replace("++", "+").Replace("pti+Fine", "ptiFine")
'显示
If ModEntity.Url Is Nothing Then
If MyMsgBox(Join(ContentLines, vbCrLf), ModEntity.Name, "确定", "百科搜索") = 2 Then
OpenWebsite("https://www.mcmod.cn/s?key=" & ModSearchName & "&site=all&filter=0")
End If
Else
Select Case MyMsgBox(Join(ContentLines, vbCrLf), ModEntity.Name, "确定", "百科搜索", "打开官网")
Case 2
OpenWebsite("https://www.mcmod.cn/s?key=" & ModSearchName & "&site=all&filter=0")
Case 3
OpenWebsite(ModEntity.Url)
End Select
End If
Catch ex As Exception
Log(ex, "获取 Mod 详情失败", LogLevel.Feedback)
End Try
End Sub
'打开文件所在的位置
Public Sub Open_Click(sender As MyIconButton, e As EventArgs)
Try
Dim ListItem As MyListItem = sender.Tag
Dim ModEntity As McMod = ListItem.Tag
OpenExplorer("/select,""" & ModEntity.Path & """")
Catch ex As Exception
Log(ex, "打开 Mod 文件位置失败", LogLevel.Feedback)
End Try
End Sub
#End Region
Public Sub SearchRun() Handles SearchBox.TextChanged
If String.IsNullOrWhiteSpace(SearchBox.Text) Then
'隐藏
LoaderFolderRun(McModLoader, PageVersionLeft.Version.PathIndie & "mods\", LoaderFolderRunType.RunOnUpdated)
AniStart({
AaOpacity(PanSearch, -PanSearch.Opacity, 100),
AaCode(Sub()
PanSearch.Height = 0
PanSearch.Visibility = Visibility.Collapsed
PanList.Visibility = Visibility.Visible
PanManage.Visibility = Visibility.Visible
End Sub,, True),
AaOpacity(PanList, 1 - PanList.Opacity, 150, 30),
AaOpacity(PanManage, 1 - PanManage.Opacity, 150, 30)
}, "FrmVersionMod Search Switch", True)
Else
'构造请求
Dim QueryList As New List(Of SearchEntry(Of McMod))
For Each Entry As McMod In McModLoader.Output
QueryList.Add(New SearchEntry(Of McMod) With {
.Item = Entry,
.SearchSource = New List(Of KeyValuePair(Of String, Double)) From {
New KeyValuePair(Of String, Double)(Entry.Name, 1),
New KeyValuePair(Of String, Double)(Entry.FileName, 1),
New KeyValuePair(Of String, Double)(If(Entry.Description, ""), 0.5)
}
})
Next
'进行搜索,构造列表
Dim SearchResult = Search(QueryList, SearchBox.Text, MaxBlurCount:=5, MinBlurSimilarity:=0.35)
PanSearchList.Children.Clear()
If SearchResult.Count = 0 Then
PanSearch.Title = "无搜索结果"
PanSearchList.Visibility = Visibility.Collapsed
Else
PanSearch.Title = "搜索结果"
For Each Result In SearchResult
Dim Item = McModListItem(Result.Item)
If ModeDebug Then Item.Info = If(Result.AbsoluteRight, "完全匹配,", "") & "相似度:" & Math.Round(Result.Similarity, 3) & "," & Item.Info
PanSearchList.Children.Add(Item)
Next
PanSearchList.Visibility = Visibility.Visible
End If
'显示
AniStart({
AaOpacity(PanList, -PanList.Opacity, 100),
AaOpacity(PanManage, -PanManage.Opacity, 100),
AaCode(Sub()
PanList.Visibility = Visibility.Collapsed
PanManage.Visibility = Visibility.Collapsed
PanSearch.Visibility = Visibility.Visible
PanSearch.TriggerForceResize()
End Sub,, True),
AaOpacity(PanSearch, 1 - PanSearch.Opacity, 200, 60)
}, "FrmVersionMod Search Switch", True)
End If
End Sub
End Class
@@ -0,0 +1,30 @@
<local:MyPageRight x:Class="PageVersionModDisabled"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:PCL"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<local:MyCard HorizontalAlignment="Center" VerticalAlignment="Center" Margin="40" x:Name="PanMain">
<Grid Margin="20,17">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.ColumnSpan="4" Margin="0,0,0,9" HorizontalAlignment="Center" Text="该版本不可使用 Mod" FontSize="19" UseLayoutRounding="True" SnapsToDevicePixels="True" Foreground="{DynamicResource ColorBrush3}" />
<Rectangle Grid.Row="1" Grid.ColumnSpan="4" HorizontalAlignment="Stretch" Height="2" Fill="{DynamicResource ColorBrush3}" />
<TextBlock Grid.Row="2" Grid.ColumnSpan="4" Margin="10,15,10,5" Text="你需要先安装 Forge 或 Fabric 才能使用 Mod,请在下载页面重新安装这些版本。&#xA;如果你已经安装过了 Forge 或 Fabric,那么你很可能选择了错误的版本,请点击版本选择按钮切换版本,并注意 Forge 在版本选择列表中的图标为铁砧,Fabric 的图标为丝绸。" TextWrapping="Wrap" />
<local:MyButton Grid.Row="3" Grid.Column="1" Height="35" HorizontalAlignment="Center" x:Name="BtnDownload" MinWidth="140" Text="转到下载页面" Margin="10,10,10,0" Padding="13,0" ColorType="Highlight" />
<local:MyButton Grid.Row="3" Grid.Column="2" Height="35" HorizontalAlignment="Center" x:Name="BtnVersion" MinWidth="140" Text="版本选择" Margin="10,10,10,0" Padding="13,0" />
</Grid>
</local:MyCard>
</local:MyPageRight>
@@ -0,0 +1,19 @@
Class PageVersionModDisabled
Private Sub BtnDownload_Click(sender As Object, e As EventArgs) Handles BtnDownload.Click
FrmMain.PageChange(FormMain.PageType.Download, FormMain.PageSubType.DownloadInstall)
End Sub
Private Sub BtnVersion_Click(sender As Object, e As EventArgs) Handles BtnVersion.Click
FrmMain.PageChange(FormMain.PageType.Launch) '在版本选择页面选定版本的时候只会返回一层,因此如果不先锚定 Launch,在选择版本后会回退到版本设置的这个页面
FrmMain.PageChange(FormMain.PageType.VersionSelect)
End Sub
Public Sub BtnDownload_Loaded() Handles BtnDownload.Loaded
Dim NewVisibility = If((Setup.Get("UiHiddenPageDownload") AndAlso Not PageSetupUI.HiddenForceShow) OrElse If(FrmSelectRight Is Nothing, False, FrmSelectRight.ShowHidden), Visibility.Collapsed, Visibility.Visible)
If BtnDownload.Visibility <> NewVisibility Then
BtnDownload.Visibility = NewVisibility
PanMain.TriggerForceResize()
End If
End Sub
End Class
@@ -0,0 +1,77 @@
<local:MyPageRight
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:PCL" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:System="clr-namespace:System;assembly=mscorlib"
mc:Ignorable="d" x:Class="PageVersionOverall"
d:DesignWidth="800" d:DesignHeight="800" Grid.IsSharedSizeScope="True">
<local:MyScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" x:Name="PanBack">
<StackPanel x:Name="PanMain" Margin="25,10">
<local:MyCard Margin="0,15" Title="个性化" x:Name="PanDisplay">
<StackPanel Margin="25,40,25,15">
<Grid Margin="-7,-3,0,12" Name="PanDisplayItem" />
<Grid x:Name="PanDisplayIcon" Margin="0,0,0,11" HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Name" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="28" />
<RowDefinition Height="9" />
<RowDefinition Height="28" />
</Grid.RowDefinitions>
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Left" Text="版本图标" Margin="0,0,25,0" />
<local:MyComboBox Grid.Column="1" x:Name="ComboDisplayLogo">
<local:MyComboBoxItem Content="自动" IsSelected="True" Tag="" />
<local:MyComboBoxItem Content="自定义..." x:Name="ItemDisplayLogoCustom" />
<local:MyComboBoxItem Content="圆石" Tag="pack://application:,,,/images/Blocks/CobbleStone.png" />
<local:MyComboBoxItem Content="命令方块" Tag="pack://application:,,,/images/Blocks/CommandBlock.png" />
<local:MyComboBoxItem Content="金块" Tag="pack://application:,,,/images/Blocks/GoldBlock.png" />
<local:MyComboBoxItem Content="草方块" Tag="pack://application:,,,/images/Blocks/Grass.png" />
<local:MyComboBoxItem Content="草径" Tag="pack://application:,,,/images/Blocks/GrassPath.png" />
<local:MyComboBoxItem Content="铁砧" Tag="pack://application:,,,/images/Blocks/Anvil.png" />
<local:MyComboBoxItem Content="红石块" Tag="pack://application:,,,/images/Blocks/RedstoneBlock.png" />
<local:MyComboBoxItem Content="红石灯(开)" Tag="pack://application:,,,/images/Blocks/RedstoneLampOn.png" />
<local:MyComboBoxItem Content="红石灯(关)" Tag="pack://application:,,,/images/Blocks/RedstoneLampOff.png" />
<local:MyComboBoxItem Content="鸡蛋" Tag="pack://application:,,,/images/Blocks/Egg.png" />
<local:MyComboBoxItem Content="布料(Fabric)" Tag="pack://application:,,,/images/Blocks/Fabric.png" />
</local:MyComboBox>
<TextBlock VerticalAlignment="Center" Grid.Row="2" HorizontalAlignment="Left" Text="版本分类" Margin="0,0,25,0" />
<local:MyComboBox Grid.Column="1" Grid.Row="2" x:Name="ComboDisplayType">
<local:MyComboBoxItem Content="自动" IsSelected="True" />
<local:MyComboBoxItem Content="从版本列表中隐藏" ToolTip="该版本默认将不会在版本列表中显示。&#xA;在版本列表页面按下 F11,即可查看所有隐藏的版本。" ToolTipService.ShowDuration="2333333" />
<local:MyComboBoxItem Content="可安装 Mod 的版本" />
<local:MyComboBoxItem Content="常规版本" />
<local:MyComboBoxItem Content="不常用版本" />
<local:MyComboBoxItem Content="愚人节版本" />
</local:MyComboBox>
</Grid>
<Grid Margin="0,0,0,7" Height="35">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
</Grid.ColumnDefinitions>
<local:MyButton x:Name="BtnDisplayRename" Text="重命名版本" MinWidth="140" Padding="13,0" Margin="0,0,20,0" />
<local:MyButton x:Name="BtnDisplayDesc" Text="更改描述" MinWidth="140" Padding="13,0" Margin="0,0,20,0" Grid.Column="1" />
<local:MyButton x:Name="BtnDisplayStar" Text="加入收藏夹" MinWidth="140" Padding="13,0" Margin="0,0,20,0" Grid.Column="2" />
</Grid>
</StackPanel>
</local:MyCard>
<local:MyCard Margin="0,0,0,15" Title="管理" x:Name="PanManage">
<StackPanel Margin="25,40,25,15">
<Grid Margin="0,2,0,7" Height="35">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
</Grid.ColumnDefinitions>
<local:MyButton x:Name="BtnManageFolder" Text="打开版本文件夹" MinWidth="140" Padding="13,0" Margin="0,0,20,0" />
<local:MyButton x:Name="BtnManageCheck" Text="补全文件" MinWidth="140" Padding="13,0" Margin="0,0,20,0" Grid.Column="1" ToolTip="校验版本依赖文件是否完整,并重新下载 Assets 索引与缺失、校验失败的文件。&#xa;若游戏缺失音效,请尝试此项。" ToolTipService.ShowDuration="2333333" />
<local:MyButton x:Name="BtnManageDelete" Text="删除版本" MinWidth="140" Padding="13,0" Margin="0,0,20,0" Grid.Column="2" ColorType="Red" />
</Grid>
</StackPanel>
</local:MyCard>
</StackPanel>
</local:MyScrollViewer>
</local:MyPageRight>
@@ -0,0 +1,281 @@
Public Class PageVersionOverall
Private IsLoad As Boolean = False
Private Sub PageSetupLaunch_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
'重复加载部分
PanBack.ScrollToHome()
'更新设置
ItemDisplayLogoCustom.Tag = "PCL\Logo.png"
Reload()
'非重复加载部分
If IsLoad Then Exit Sub
IsLoad = True
PanDisplay.TriggerForceResize()
End Sub
Public ItemVersion As MyListItem
''' <summary>
''' 确保当前页面上的信息已正确显示。
''' </summary>
Private Sub Reload()
AniControlEnabled += 1
'刷新设置项目
ComboDisplayType.SelectedIndex = ReadIni(PageVersionLeft.Version.Path & "PCL\Setup.ini", "DisplayType", McVersionCardType.Auto)
BtnDisplayStar.Text = If(PageVersionLeft.Version.IsStar, "从收藏夹中移除", "加入收藏夹")
'刷新版本显示
PanDisplayItem.Children.Clear()
ItemVersion = PageSelectRight.McVersionListItem(PageVersionLeft.Version)
ItemVersion.IsHitTestVisible = False
PanDisplayItem.Children.Add(ItemVersion)
FrmMain.PageNameRefresh()
'刷新版本图标
ComboDisplayLogo.SelectedIndex = 0
Dim Logo As String = ReadIni(PageVersionLeft.Version.Path & "PCL\Setup.ini", "Logo", "")
Dim LogoCustom As Boolean = ReadIni(PageVersionLeft.Version.Path & "PCL\Setup.ini", "LogoCustom", "False")
If LogoCustom Then
For Each Selection As MyComboBoxItem In ComboDisplayLogo.Items
If Selection.Tag = Logo OrElse (Selection.Tag = "PCL\Logo.png" AndAlso Logo.EndsWith("PCL\Logo.png")) Then
ComboDisplayLogo.SelectedItem = Selection
Exit For
End If
Next
End If
AniControlEnabled -= 1
End Sub
#Region "设置临时接口"
'版本分类
Private Sub ComboDisplayType_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles ComboDisplayType.SelectionChanged
If Not (IsLoad AndAlso AniControlEnabled = 0) Then Exit Sub
If ComboDisplayType.SelectedIndex <> 1 Then
'改为不隐藏
Try
WriteIni(PageVersionLeft.Version.Path & "PCL\Setup.ini", "DisplayType", ComboDisplayType.SelectedIndex)
WriteIni(PathMcFolder & "PCL.ini", "VersionCache", "") '要求刷新缓存
LoaderFolderRun(McVersionListLoader, PathMcFolder, LoaderFolderRunType.ForceRun, MaxDepth:=1, ExtraPath:="versions\")
Catch ex As Exception
Log(ex, "修改版本分类失败(" & PageVersionLeft.Version.Name & ")", LogLevel.Feedback)
End Try
Else
'改为隐藏
Try
If Not Setup.Get("HintHide") Then
If MyMsgBox("确认要从版本列表中隐藏该版本吗?隐藏该版本后,它将不再出现于 PCL 显示的版本列表中。" & vbCrLf & "此后,在版本列表页面按下 F11 才可以查看被隐藏的版本。", "隐藏版本提示",, "取消") <> 1 Then
ComboDisplayType.SelectedIndex = 0
Exit Sub
End If
Setup.Set("HintHide", True)
End If
WriteIni(PageVersionLeft.Version.Path & "PCL\Setup.ini", "DisplayType", McVersionCardType.Hidden)
WriteIni(PathMcFolder & "PCL.ini", "VersionCache", "") '要求刷新缓存
LoaderFolderRun(McVersionListLoader, PathMcFolder, LoaderFolderRunType.ForceRun, MaxDepth:=1, ExtraPath:="versions\")
Catch ex As Exception
Log(ex, "隐藏版本 " & PageVersionLeft.Version.Name & " 失败", LogLevel.Feedback)
End Try
End If
End Sub
'更改描述
Private Sub BtnDisplayDesc_Click(sender As Object, e As EventArgs) Handles BtnDisplayDesc.Click
Try
Dim OldInfo As String = ReadIni(PageVersionLeft.Version.Path & "PCL\Setup.ini", "CustomInfo")
Dim NewInfo As String = MyMsgBoxInput(OldInfo, New ObjectModel.Collection(Of Validate), "留空即为使用默认描述", "更改描述",, "取消")
If NewInfo IsNot Nothing AndAlso OldInfo <> NewInfo Then WriteIni(PageVersionLeft.Version.Path & "PCL\Setup.ini", "CustomInfo", NewInfo)
PageVersionLeft.Version = New McVersion(PageVersionLeft.Version.Name).Load()
Reload()
LoaderFolderRun(McVersionListLoader, PathMcFolder, LoaderFolderRunType.ForceRun, MaxDepth:=1, ExtraPath:="versions\")
Catch ex As Exception
Log(ex, "版本 " & PageVersionLeft.Version.Name & " 描述更改失败", LogLevel.Msgbox)
End Try
End Sub
'重命名版本
Private Sub BtnDisplayRename_Click(sender As Object, e As EventArgs) Handles BtnDisplayRename.Click
Try
'确认输入的新名称
Dim OldName As String = PageVersionLeft.Version.Name
Dim OldPath As String = PageVersionLeft.Version.Path
'修改此部分的同时修改快速安装的版本名检测*
Dim NewName As String = MyMsgBoxInput(OldName, New ObjectModel.Collection(Of Validate) From {New ValidateFolderName(PathMcFolder & "versions", IgnoreCase:=False)},, "重命名版本",, "取消")
If String.IsNullOrWhiteSpace(NewName) Then Exit Sub
Dim NewPath As String = PathMcFolder & "versions\" & NewName & "\"
'获取临时中间名,以防止仅修改大小写的重命名失败
Dim TempName As String = NewName & "_temp"
Dim TempPath As String = PathMcFolder & "versions\" & TempName & "\"
Dim IsCaseChangedOnly As Boolean = NewName.ToLower = OldName.ToLower
'重新加载版本 Json 信息,避免 HMCL 项被合并
Dim JsonObject As JObject
Try
JsonObject = GetJson(ReadFile(PageVersionLeft.Version.Path & PageVersionLeft.Version.Name & ".json"))
Catch ex As Exception
Log(ex, "重命名读取 Json 时失败")
JsonObject = PageVersionLeft.Version.JsonObject
End Try
'重命名主文件夹
My.Computer.FileSystem.RenameDirectory(OldPath, TempName)
My.Computer.FileSystem.RenameDirectory(TempPath, NewName)
'遍历重命名所有文件与文件夹
For Each Entry As DirectoryInfo In New DirectoryInfo(NewPath).EnumerateDirectories
If Not Entry.Name.Contains(OldName) Then Continue For
If IsCaseChangedOnly Then
My.Computer.FileSystem.RenameDirectory(Entry.FullName, Entry.Name & "_temp")
My.Computer.FileSystem.RenameDirectory(Entry.FullName & "_temp", Entry.Name.Replace(OldName, NewName))
Else
DeleteDirectory(NewPath & Entry.Name.Replace(OldName, NewName))
My.Computer.FileSystem.RenameDirectory(Entry.FullName, Entry.Name.Replace(OldName, NewName))
End If
Next
For Each Entry As FileInfo In New DirectoryInfo(NewPath).EnumerateFiles
If Not Entry.Name.Contains(OldName) Then Continue For
If IsCaseChangedOnly Then
My.Computer.FileSystem.RenameFile(Entry.FullName, Entry.Name & "_temp")
My.Computer.FileSystem.RenameFile(Entry.FullName & "_temp", Entry.Name.Replace(OldName, NewName))
Else
If File.Exists(NewPath & Entry.Name.Replace(OldName, NewName)) Then File.Delete(NewPath & Entry.Name.Replace(OldName, NewName))
My.Computer.FileSystem.RenameFile(Entry.FullName, Entry.Name.Replace(OldName, NewName))
End If
Next
'替换版本设置文件中的路径
If File.Exists(NewPath & "PCL\Setup.ini") Then
WriteFile(NewPath & "PCL\Setup.ini", ReadFile(NewPath & "PCL\Setup.ini").Replace(OldPath, NewPath))
End If
'更改已选中的版本
If ReadIni(PathMcFolder & "PCL.ini", "Version") = OldName Then
WriteIni(PathMcFolder & "PCL.ini", "Version", NewName)
End If
'更改版本 Json
If File.Exists(NewPath & NewName & ".json") Then
Try
JsonObject("id") = NewName
WriteFile(NewPath & NewName & ".json", JsonObject.ToString)
Catch ex As Exception
Log(ex, "重命名 Json 时失败")
End Try
End If
'刷新与提示
Hint("重命名成功!", HintType.Finish)
PageVersionLeft.Version = New McVersion(NewName).Load()
If Not IsNothing(McVersionCurrent) AndAlso McVersionCurrent.Equals(PageVersionLeft.Version) Then WriteIni(PathMcFolder & "PCL.ini", "Version", NewName)
Reload()
LoaderFolderRun(McVersionListLoader, PathMcFolder, LoaderFolderRunType.ForceRun, MaxDepth:=1, ExtraPath:="versions\")
Catch ex As Exception
Log(ex, "重命名版本失败", LogLevel.Msgbox)
End Try
End Sub
'收藏夹
Private Sub BtnDisplayStar_Click(sender As Object, e As EventArgs) Handles BtnDisplayStar.Click
Try
WriteIni(PageVersionLeft.Version.Path & "PCL\Setup.ini", "IsStar", Not PageVersionLeft.Version.IsStar)
PageVersionLeft.Version = New McVersion(PageVersionLeft.Version.Name).Load()
Reload()
McVersionListForceRefresh = True
LoaderFolderRun(McVersionListLoader, PathMcFolder, LoaderFolderRunType.ForceRun, MaxDepth:=1, ExtraPath:="versions\")
Catch ex As Exception
Log(ex, "版本 " & PageVersionLeft.Version.Name & " 收藏状态更改失败", LogLevel.Msgbox)
End Try
End Sub
'补全文件
Private Sub BtnManageCheck_Click(sender As Object, e As EventArgs) Handles BtnManageCheck.Click
Try
'重复任务检查
SyncLock LoaderTaskbarLock
For i = 0 To LoaderTaskbar.Count - 1
If LoaderTaskbar(i).Name = PageVersionLeft.Version.Name & " 文件补全" Then
Hint("正在处理中,请稍候!", HintType.Critical)
Exit Sub
End If
Next
End SyncLock
'启动
Dim Loader As New LoaderCombo(Of String)(PageVersionLeft.Version.Name & " 文件补全", DlClientFix(PageVersionLeft.Version, True, AssetsIndexExistsBehaviour.AlwaysDownload, False))
Loader.OnStateChanged = Sub()
Select Case Loader.State
Case LoadState.Finished
Hint(Loader.Name & "成功!", HintType.Finish)
Case LoadState.Failed
Hint(Loader.Name & "失败:" & GetString(Loader.Error), HintType.Critical)
Case LoadState.Aborted
Hint(Loader.Name & "已取消!", HintType.Info)
End Select
End Sub
Loader.Start(PageVersionLeft.Version.Name)
LoaderTaskbarAdd(Loader)
FrmMain.BtnExtraDownload.ShowRefresh()
FrmMain.BtnExtraDownload.Ribble()
Catch ex As Exception
Log(ex, "尝试补全文件失败(" & PageVersionLeft.Version.Name & ")", LogLevel.Msgbox)
End Try
End Sub
'删除版本
Private Sub BtnManageDelete_Click(sender As Object, e As EventArgs) Handles BtnManageDelete.Click
'修改此代码时,同时修改 PageSelectRight 中的代码
Try
Dim IsHintIndie As Boolean = PageVersionLeft.Version.State <> McVersionState.Error AndAlso PageVersionLeft.Version.PathIndie <> PathMcFolder
Select Case MyMsgBox("你确定要删除版本 " & PageVersionLeft.Version.Name & " 吗?" &
If(IsHintIndie, vbCrLf & "由于该版本开启了版本隔离,删除版本时该版本对应的存档、资源包、Mod 等文件也将被一并删除!", ""),
"版本删除确认", , "取消",, True)
Case 1
FileIO.FileSystem.DeleteDirectory(PageVersionLeft.Version.Path, FileIO.UIOption.AllDialogs, FileIO.RecycleOption.SendToRecycleBin)
Hint("版本 " & PageVersionLeft.Version.Name & " 已删除到回收站!", HintType.Finish)
Case 2
' DeleteDirectory(PageVersionLeft.Version.Path)
' Hint("版本 " & PageVersionLeft.Version.Name & " 已永久删除!", HintType.Finish)
'Case 3
Exit Sub
End Select
LoaderFolderRun(McVersionListLoader, PathMcFolder, LoaderFolderRunType.ForceRun, MaxDepth:=1, ExtraPath:="versions\")
FrmMain.PageBack()
Catch ex As Exception
Log(ex, "删除版本 " & PageVersionLeft.Version.Name & " 失败", LogLevel.Msgbox)
End Try
End Sub
'打开版本文件夹
Private Sub BtnManageFolder_Click() Handles BtnManageFolder.Click
OpenVersionFolder(PageVersionLeft.Version)
End Sub
Public Shared Sub OpenVersionFolder(Version As McVersion)
OpenExplorer("""" & Version.Path & """")
End Sub
'版本图标
Private Sub ComboDisplayLogo_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles ComboDisplayLogo.SelectionChanged
If Not (IsLoad AndAlso AniControlEnabled = 0) Then Exit Sub
'选择 自定义 时修改图片
Try
If ComboDisplayLogo.SelectedItem Is ItemDisplayLogoCustom Then
Dim FileName As String = SelectFile("常用图片文件(*.png;*.jpg;*.gif)|*.png;*.jpg;*.gif", "选择图片")
If FileName = "" Then
Reload() '还原选项
Exit Sub
End If
File.Delete(PageVersionLeft.Version.Path & "PCL\Logo.png")
Directory.CreateDirectory(PageVersionLeft.Version.Path & "PCL") '虽然不知道为啥,有时候真没这文件夹
File.Copy(FileName, PageVersionLeft.Version.Path & "PCL\Logo.png")
Else
File.Delete(PageVersionLeft.Version.Path & "PCL\Logo.png")
End If
Catch ex As Exception
Log(ex, "更改自定义版本图标失败(" & PageVersionLeft.Version.Name & ")", LogLevel.Feedback)
End Try
'进行更改
Try
Dim NewLogo As String = ComboDisplayLogo.SelectedItem.Tag
WriteIni(PageVersionLeft.Version.Path & "PCL\Setup.ini", "Logo", NewLogo)
WriteIni(PageVersionLeft.Version.Path & "PCL\Setup.ini", "LogoCustom", Not NewLogo = "")
'刷新显示
WriteIni(PathMcFolder & "PCL.ini", "VersionCache", "") '要求刷新缓存
PageVersionLeft.Version = New McVersion(PageVersionLeft.Version.Name).Load()
Reload()
LoaderFolderRun(McVersionListLoader, PathMcFolder, LoaderFolderRunType.ForceRun, MaxDepth:=1, ExtraPath:="versions\")
Catch ex As Exception
Log(ex, "更改版本图标失败(" & PageVersionLeft.Version.Name & ")", LogLevel.Feedback)
End Try
End Sub
#End Region
End Class
@@ -0,0 +1,194 @@
<local:MyPageRight
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:PCL" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:System="clr-namespace:System;assembly=mscorlib"
mc:Ignorable="d" x:Class="PageVersionSetup"
d:DesignWidth="800" d:DesignHeight="800">
<local:MyScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" x:Name="PanBack">
<StackPanel x:Name="PanMain" Margin="25,10">
<local:MyCard x:Name="CardArgument" Margin="0,15" Title="启动选项">
<StackPanel Margin="25,40,25,21">
<TextBlock Margin="0,-2,0,1" Text="在这个页面修改的设置均只对当前版本生效,这对整合包制作应该会有所帮助。" TextWrapping="Wrap" />
<TextBlock Margin="0,0,0,11" Text="你也可以在设置页面中,修改对全部版本生效的全局设置。" TextWrapping="Wrap" />
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Name" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="60" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="28" />
<RowDefinition Height="9" />
<RowDefinition Height="28" />
<RowDefinition Height="9" />
<RowDefinition Height="28" />
<RowDefinition Height="9" />
<RowDefinition Height="28" />
<RowDefinition Height="9" />
<RowDefinition Height="28" />
<RowDefinition Height="9" />
<RowDefinition Height="28" />
<RowDefinition Height="9" />
<RowDefinition Height="28" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" VerticalAlignment="Center" HorizontalAlignment="Left" Text="游戏窗口标题" Margin="0,0,25,0" />
<local:MyTextBox x:Name="TextArgumentTitle" Grid.Row="0" Grid.ColumnSpan="2" Tag="VersionArgumentTitle" Grid.Column="1" ToolTip="自定义游戏窗口的标题,若留空则使用全局设置的值。&#x0a;支持以下替换标记:&#x0a; - {user}:玩家名字&#x0a; - {login}:玩家的登录方式&#x0a; - {name}:游戏版本名&#x0a; - {time}:当前的系统时间&#x0a; - {version}:游戏对应的原版版本号&#x0a; - {path}:PCL 可执行文件所在路径,以 \ 结尾" ToolTipService.ShowDuration="2333333" HintText="使用全局设置" MaxLength="100" />
<TextBlock Grid.Row="2" VerticalAlignment="Center" HorizontalAlignment="Left" Text="自定义信息" Margin="0,0,25,0" />
<local:MyTextBox x:Name="TextArgumentInfo" Grid.Row="2" Grid.ColumnSpan="2" Tag="VersionArgumentInfo" Grid.Column="1" HintText="使用全局设置" ToolTip="该信息会显示在游戏主界面的左下角,与 F3 调试页面的左上角。&#xa;若留空,则使用全局设置的值。" ToolTipService.ShowDuration="2333333">
<local:MyTextBox.ValidateRules>
<local:ValidateExcept>
<local:ValidateExcept.Excepts>
<System:String>"</System:String>
<System:String>“</System:String>
<System:String>”</System:String>
</local:ValidateExcept.Excepts>
</local:ValidateExcept>
</local:MyTextBox.ValidateRules>
</local:MyTextBox>
<TextBlock Grid.Row="4" VerticalAlignment="Center" HorizontalAlignment="Left" Text="JVM 参数" Margin="0,0,25,0" />
<local:MyTextBox x:Name="TextAdvanceJvm" Grid.Row="4" Grid.ColumnSpan="2" Tag="VersionAdvanceJvm" Grid.Column="1" ToolTip="启动 Minecraft 时使用的额外 JVM 参数,在没有确定把握的情况下请不要尝试修改。&#xA;若留空,则使用全局设置的值。" ToolTipService.ShowDuration="2333333" HintText="使用全局设置" />
<TextBlock Grid.Row="6" VerticalAlignment="Center" HorizontalAlignment="Left" Text="额外参数" Margin="0,0,25,0" />
<local:MyTextBox x:Name="TextAdvanceGame" Grid.Row="6" Grid.ColumnSpan="2" Tag="VersionAdvanceGame" Grid.Column="1" ToolTip="文本框中的内容将会被直接拼合在启动参数的末尾。&#xA;例如输入 --demo 则会以试玩模式启动游戏。&#xA;若留空,则使用全局设置的值。" ToolTipService.ShowDuration="2333333" HintText="使用全局设置" />
<TextBlock Grid.Row="8" VerticalAlignment="Center" HorizontalAlignment="Left" Text="版本隔离" Margin="0,0,25,0" />
<local:MyComboBox x:Name="ComboArgumentIndie" Grid.Row="8" Grid.ColumnSpan="2" Tag="VersionArgumentIndie" Grid.Column="1">
<local:MyComboBoxItem Content="使用全局设置" IsSelected="True" />
<local:MyComboBoxItem Content="开启" ToolTip="让这个版本与其他版本的存档、Mod 等档案相互独立,互不干涉" />
<local:MyComboBoxItem Content="关闭" ToolTip="与其余未开启隔离的版本均使用同一档案,存档、Mod 等均为公用。&#xA;若存在不同版本的 Forge 或 Fabric,可能会由于 Mod 与版本冲突导致未知问题。" />
</local:MyComboBox>
<TextBlock Grid.Row="10" VerticalAlignment="Center" HorizontalAlignment="Left" Text="文件校验" Margin="0,0,25,0" />
<local:MyComboBox x:Name="ComboAdvanceAssets" Grid.Row="10" Grid.ColumnSpan="2" Tag="VersionAdvanceAssets" Grid.Column="1">
<local:MyComboBoxItem Content="使用全局设置" IsSelected="True" />
<local:MyComboBoxItem Content="开启" ToolTip="在启动 Minecraft 时,简单校验并下载缺失或错误的文件。" />
<local:MyComboBoxItem Content="关闭" ToolTip="在启动 Minecraft 时,不校验 libraries 文件夹、第三方登录库与版本主 jar 文件,不更改 assets 文件夹。&#xA;如果你没有修改相关文件,请勿选择此项。" />
</local:MyComboBox>
<TextBlock VerticalAlignment="Center" Grid.Row="12" HorizontalAlignment="Left" Text="游戏 Java" Margin="0,0,25,0" />
<local:MyComboBox x:Name="ComboArgumentJava" Grid.ColumnSpan="2" Grid.Row="12" Grid.Column="1" ToolTip="若将 Java 放在游戏文件夹或 PCL 文件夹,在进行自动选择时 PCL2 会尽量优先选择它" ToolTipService.ShowDuration="2333333">
<ComboBoxItem Content="加载中……" IsSelected="True" />
<!--<local:MyComboBoxItem Content="Java 8 (1.8.0_171),64 位:C:\Program Files (x86)\Common Files\Oracle\Java\javapath\javaw.exe" ToolTipService.Placement="Right" ToolTipService.HorizontalOffset="5" IsSelected="True" ToolTip="C:\Program Files (x86)\Common Files\Oracle\Java\javapath\javaw.exe" />-->
</local:MyComboBox>
</Grid>
</StackPanel>
</local:MyCard>
<local:MyCard Margin="0,0,0,15" Title="游戏内存">
<StackPanel Margin="25,40,25,15">
<local:MyHint x:Name="LabRamWarn" CanClose="False" Text="32 位 Java 最多只能分配 1 GB 内存,建议安装 64 位 Java!" IsWarn="True" Margin="0,0,0,12" />
<Grid Margin="0,0,0,3">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="9" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<local:MyRadioBox Text="使用全局设置" Width="110" Checked="True" x:Name="RadioRamType2" Tag="VersionRamType/2" Margin="0,0,20,9" />
<local:MyRadioBox Grid.Row="1" Text="自动配置" Width="110" x:Name="RadioRamType0" Tag="VersionRamType/0" Margin="0,0,20,0" ToolTip="根据安装的 Mod 量与电脑剩余内存动态调整为游戏分配的内存。" />
<local:MyRadioBox Grid.Row="3" Text="自定义" x:Name="RadioRamType1" Tag="VersionRamType/1" Margin="0,0,20,0" />
<local:MySlider Grid.Row="3" Grid.Column="1" IsEnabled="False" x:Name="SliderRamCustom" Tag="VersionRamCustom" MaxValue="49" Value="13" />
<!--<local:MyTextBox Grid.Row="2" Grid.Column="3" Width="100" VerticalAlignment="Center" Margin="30,0,0,0" Text="2048 MB" />-->
</Grid>
<Grid x:Name="PanRamDisplay" Margin="0,11,2,0" SnapsToDevicePixels="True" Grid.Row="1" Grid.ColumnSpan="2" Grid.Column="1">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="ColumnRamUsed" Width="4.7*"/>
<ColumnDefinition x:Name="ColumnRamGame" Width="2.5*"/>
<ColumnDefinition x:Name="ColumnRamEmpty" Width="0.7*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="4" />
<RowDefinition />
</Grid.RowDefinitions>
<Rectangle x:Name="RectRamUsed" Grid.Row="1" StrokeThickness="0" >
<Rectangle.Fill>
<LinearGradientBrush EndPoint="1,0.5" StartPoint="0,0.5">
<GradientStop Color="{DynamicResource ColorObject3}" Offset="0"/>
<GradientStop Color="{DynamicResource ColorObject2}" Offset="0.5"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Rectangle Grid.Row="1" StrokeThickness="0" Grid.Column="1" Fill="{DynamicResource ColorBrush3}" Opacity="0.5" x:Name="RectRamGame" />
<Rectangle x:Name="RectRamEmpty" Grid.Row="1" StrokeThickness="0" Grid.Column="2" Fill="{DynamicResource ColorBrush6}" Opacity="0.7" />
<TextBlock x:Name="LabRamUsedTitle" Text="已使用内存" Grid.ColumnSpan="3" Opacity="0.7" TextTrimming="None" Margin="2,0,0,5" FontSize="11" HorizontalAlignment="Left" />
<TextBlock x:Name="LabRamGameTitle" Text="游戏分配" Opacity="0.7" Grid.ColumnSpan="3" TextTrimming="None" Margin="2,0,0,5" FontSize="11" HorizontalAlignment="Left" />
<StackPanel Grid.Row="2" Orientation="Horizontal" Grid.ColumnSpan="3" Margin="2,3,0,0" HorizontalAlignment="Left">
<TextBlock x:Name="LabRamUsed" Text="4.7 GB" FontSize="16" Foreground="Black" TextTrimming="None" />
<TextBlock x:Name="LabRamTotal" Text=" / 7.9 GB" FontSize="16" Foreground="Black" TextTrimming="None" />
</StackPanel>
<TextBlock Grid.Row="2" x:Name="LabRamGame" Text="2.5 GB" Grid.ColumnSpan="3" TextTrimming="None" Margin="2,3,0,0" FontSize="16" Foreground="Black" HorizontalAlignment="Left" />
</Grid>
</StackPanel>
</local:MyCard>
<local:MyCard x:Name="CardServer" Margin="0,0,0,15" Title="服务器选项">
<StackPanel Margin="25,42,25,21">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Name" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="28" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="9" />
<RowDefinition Height="28" />
<RowDefinition Height="3" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" VerticalAlignment="Center" HorizontalAlignment="Left" Text="登录方式" Margin="0,0,25,0" />
<local:MyComboBox x:Name="ComboServerLogin" Grid.Row="0" Grid.ColumnSpan="2" Tag="VersionServerLogin" Grid.Column="1">
<local:MyComboBoxItem Content="正版登录或离线登录" IsSelected="True" />
<local:MyComboBoxItem Content="仅正版登录" />
<local:MyComboBoxItem Content="仅离线登录" />
<local:MyComboBoxItem Content="第三方登录:统一通行证" />
<local:MyComboBoxItem Content="第三方登录:Authlib Injector 或 Little Skin" />
</local:MyComboBox>
<TextBlock Name="LabServerNide" Grid.Row="1" VerticalAlignment="Center" HorizontalAlignment="Left" Text="服务器 ID(必填)" Margin="0,8,25,0" Visibility="Collapsed" />
<local:MyTextBox x:Name="TextServerNide" Grid.Row="1" Grid.ColumnSpan="2" ShowValidateResult="False" Tag="VersionServerNide" Grid.Column="1" Margin="0,8,0,0" Visibility="Collapsed" HintText="服主后台 → 集成说明 中提供的服务器 ID">
<local:MyTextBox.ValidateRules>
<local:ValidateLength Min="32" Max="32" />
</local:MyTextBox.ValidateRules>
</local:MyTextBox>
<TextBlock Name="LabServerAuthServer" Grid.Row="1" VerticalAlignment="Center" HorizontalAlignment="Left" Text="认证服务器(必填)" Margin="0,8,25,0" Visibility="Collapsed" />
<local:MyTextBox x:Name="TextServerAuthServer" Grid.Row="1" Grid.ColumnSpan="2" ShowValidateResult="False" Tag="VersionServerAuthServer" Grid.Column="1" Margin="0,8,0,0" Visibility="Collapsed" HintText="Yggdrasil API 认证服务器的完整地址">
<local:MyTextBox.ValidateRules>
<local:ValidateHttp />
</local:MyTextBox.ValidateRules>
</local:MyTextBox>
<TextBlock Name="LabServerAuthRegister" Grid.Row="2" VerticalAlignment="Center" HorizontalAlignment="Left" Text="注册链接" Margin="0,8,25,0" Visibility="Collapsed" />
<local:MyTextBox x:Name="TextServerAuthRegister" Grid.Row="2" Grid.ColumnSpan="2" ShowValidateResult="False" Tag="VersionServerAuthRegister" Grid.Column="1" Margin="0,8,0,0" Visibility="Collapsed" HintText="注册账号的网页地址,如 https://xxxxx.xxx/auth/register">
<local:MyTextBox.ValidateRules>
<local:ValidateHttp />
</local:MyTextBox.ValidateRules>
</local:MyTextBox>
<TextBlock Name="LabServerAuthName" Grid.Row="3" VerticalAlignment="Center" HorizontalAlignment="Left" Text="服务器名称" Margin="0,8,25,0" Visibility="Collapsed" />
<local:MyTextBox x:Name="TextServerAuthName" Grid.Row="3" Grid.ColumnSpan="2" ShowValidateResult="False" Tag="VersionServerAuthName" Grid.Column="1" Margin="0,8,0,0" Visibility="Collapsed" HintText="显示在登录页面的服务器名称" />
<TextBlock VerticalAlignment="Center" Grid.Row="5" HorizontalAlignment="Left" Text="自动进入服务器" Margin="0,0,25,0" />
<local:MyTextBox x:Name="TextServerEnter" Grid.ColumnSpan="2" Grid.Row="5" Tag="VersionServerEnter" Grid.Column="1" ToolTip="在打开 Minecraft 后自动进入某服务器。&#xA;用英文冒号间隔 IP 与端口,例如 233.233.233.233:12345。" ToolTipService.ShowDuration="2333333">
<local:MyTextBox.ValidateRules>
<local:ValidateExcept>
<local:ValidateExcept.Excepts>
<System:String>"</System:String>
<System:String>“</System:String>
<System:String>”</System:String>
</local:ValidateExcept.Excepts>
</local:ValidateExcept>
</local:MyTextBox.ValidateRules>
</local:MyTextBox>
</Grid>
<Grid Height="35" Name="PanServerNide" Margin="0,12,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
<ColumnDefinition Width="Auto" SharedSizeGroup="Button" />
</Grid.ColumnDefinitions>
<local:MyButton x:Name="BtnServerNideWeb" Grid.Column="0" MinWidth="140" Text="服主后台" Padding="13,0" Margin="0,0,20,0" HorizontalAlignment="Left" ColorType="Highlight" />
<local:MyButton x:Name="BtnServerNideBbs" Grid.Column="1" MinWidth="140" Text="查看简介" Padding="13,0" Margin="0,0,20,0" HorizontalAlignment="Left" />
</Grid>
<local:MyButton x:Name="BtnServerAuthLittle" Height="35" MinWidth="150" Margin="0,12,0,0" Text="设置为 Little Skin" HorizontalAlignment="Left" ColorType="Highlight" />
</StackPanel>
</local:MyCard>
</StackPanel>
</local:MyScrollViewer>
</local:MyPageRight>
@@ -0,0 +1,471 @@
Public Class PageVersionSetup
Private Shadows IsLoaded As Boolean = False
Private Sub PageSetupSystem_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
'重复加载部分
PanBack.ScrollToHome()
RefreshRam(False)
'由于各个版本不同,每次都需要重新加载
AniControlEnabled += 1
Reload()
AniControlEnabled -= 1
'非重复加载部分
If IsLoaded Then Exit Sub
IsLoaded = True
'内存自动刷新
Dim timer As New Threading.DispatcherTimer With {.Interval = New TimeSpan(0, 0, 0, 1)}
AddHandler timer.Tick, AddressOf RefreshRam
timer.Start()
End Sub
Public Sub Reload()
Try
'启动参数
TextArgumentTitle.Text = Setup.Get("VersionArgumentTitle", Version:=PageVersionLeft.Version)
TextArgumentInfo.Text = Setup.Get("VersionArgumentInfo", Version:=PageVersionLeft.Version)
Dim Indie As Integer = Setup.Get("VersionArgumentIndie", Version:=PageVersionLeft.Version)
If Indie = -1 Then
Dim ModFolder As New DirectoryInfo(PageVersionLeft.Version.Path & "mods\")
Dim SaveFolder As New DirectoryInfo(PageVersionLeft.Version.Path & "saves\")
If (ModFolder.Exists AndAlso ModFolder.EnumerateFiles.Count > 0) OrElse (SaveFolder.Exists AndAlso SaveFolder.EnumerateFiles.Count > 0) Then
'自动开启
Setup.Set("VersionArgumentIndie", 1, Version:=PageVersionLeft.Version)
Log("[Setup] 已自动开启单版本隔离:" & PageVersionLeft.Version.Name)
Indie = 1
Else
'使用全局设置
Setup.Set("VersionArgumentIndie", 0, Version:=PageVersionLeft.Version)
Log("[Setup] 版本隔离使用全局设置:" & PageVersionLeft.Version.Name)
Indie = 0
End If
End If
ComboArgumentIndie.SelectedIndex = Indie
TextAdvanceJvm.Text = Setup.Get("VersionAdvanceJvm", Version:=PageVersionLeft.Version)
TextAdvanceGame.Text = Setup.Get("VersionAdvanceGame", Version:=PageVersionLeft.Version)
ComboAdvanceAssets.SelectedIndex = Setup.Get("VersionAdvanceAssets", Version:=PageVersionLeft.Version)
RefreshJavaComboBox()
'游戏内存
CType(FindName("RadioRamType" & Setup.Load("VersionRamType", Version:=PageVersionLeft.Version)), MyRadioBox).Checked = True
SliderRamCustom.Value = Setup.Get("VersionRamCustom", Version:=PageVersionLeft.Version)
'服务器
TextServerEnter.Text = Setup.Get("VersionServerEnter", Version:=PageVersionLeft.Version)
ComboServerLogin.SelectedIndex = Setup.Get("VersionServerLogin", Version:=PageVersionLeft.Version)
ComboServerLoginLast = ComboServerLogin.SelectedIndex
ServerLogin(ComboServerLogin.SelectedIndex)
TextServerNide.Text = Setup.Get("VersionServerNide", Version:=PageVersionLeft.Version)
TextServerAuthServer.Text = Setup.Get("VersionServerAuthServer", Version:=PageVersionLeft.Version)
TextServerAuthName.Text = Setup.Get("VersionServerAuthName", Version:=PageVersionLeft.Version)
TextServerAuthRegister.Text = Setup.Get("VersionServerAuthRegister", Version:=PageVersionLeft.Version)
Catch ex As Exception
Log(ex, "重载版本独立设置时出错", LogLevel.Feedback)
End Try
End Sub
'初始化
Public Sub Reset()
Try
Setup.Reset("VersionServerEnter", Version:=PageVersionLeft.Version)
Setup.Reset("VersionServerLogin", Version:=PageVersionLeft.Version)
Setup.Reset("VersionServerNide", Version:=PageVersionLeft.Version)
Setup.Reset("VersionServerAuthServer", Version:=PageVersionLeft.Version)
Setup.Reset("VersionServerAuthRegister", Version:=PageVersionLeft.Version)
Setup.Reset("VersionServerAuthName", Version:=PageVersionLeft.Version)
Setup.Reset("VersionArgumentTitle", Version:=PageVersionLeft.Version)
Setup.Reset("VersionArgumentInfo", Version:=PageVersionLeft.Version)
Setup.Set("VersionArgumentIndie", 0, Version:=PageVersionLeft.Version)
Setup.Reset("VersionRamType", Version:=PageVersionLeft.Version)
Setup.Reset("VersionRamCustom", Version:=PageVersionLeft.Version)
Setup.Reset("VersionAdvanceJvm", Version:=PageVersionLeft.Version)
Setup.Reset("VersionAdvanceGame", Version:=PageVersionLeft.Version)
Setup.Reset("VersionAdvanceAssets", Version:=PageVersionLeft.Version)
Setup.Reset("VersionArgumentJavaSelect", Version:=PageVersionLeft.Version)
JavaSearchLoader.Start(IsForceRestart:=True)
Log("[Setup] 已初始化版本独立设置")
Hint("已初始化版本独立设置!", HintType.Finish, False)
Catch ex As Exception
Log(ex, "初始化版本独立设置失败", LogLevel.Msgbox)
End Try
Reload()
End Sub
'将控件改变路由到设置改变
Private Shared Sub RadioBoxChange(sender As MyRadioBox, e As Object) Handles RadioRamType0.Check, RadioRamType1.Check, RadioRamType2.Check
If AniControlEnabled = 0 Then Setup.Set(sender.Tag.ToString.Split("/")(0), Val(sender.Tag.ToString.Split("/")(1)), Version:=PageVersionLeft.Version)
End Sub
Private Shared Sub TextBoxChange(sender As MyTextBox, e As Object) Handles TextServerEnter.ValidatedTextChanged, TextArgumentInfo.ValidatedTextChanged, TextAdvanceGame.ValidatedTextChanged, TextAdvanceJvm.ValidatedTextChanged, TextServerNide.ValidatedTextChanged, TextServerAuthName.ValidatedTextChanged, TextServerAuthRegister.ValidatedTextChanged, TextServerAuthServer.ValidatedTextChanged, TextArgumentTitle.ValidatedTextChanged
If AniControlEnabled = 0 Then
Dim HandledText As String = sender.Text
If sender.Tag = "VersionServerAuthServer" OrElse sender.Tag = "VersionServerAuthRegister" Then HandledText = HandledText.TrimEnd("/")
Setup.Set(sender.Tag, HandledText, Version:=PageVersionLeft.Version)
End If
End Sub
Private Shared Sub SliderChange(sender As MySlider, e As Object) Handles SliderRamCustom.Change
If AniControlEnabled = 0 Then Setup.Set(sender.Tag, sender.Value, Version:=PageVersionLeft.Version)
End Sub
Private Shared Sub ComboChange(sender As MyComboBox, e As Object) Handles ComboArgumentIndie.SelectionChanged, ComboAdvanceAssets.SelectionChanged
If AniControlEnabled = 0 Then Setup.Set(sender.Tag, sender.SelectedIndex, Version:=PageVersionLeft.Version)
End Sub
#Region "游戏内存"
Public Sub RamType(Type As Integer)
If SliderRamCustom Is Nothing Then Exit Sub
SliderRamCustom.IsEnabled = (Type = 1)
End Sub
''' <summary>
''' 刷新 UI 上的 RAM 显示。
''' </summary>
Public Sub RefreshRam(ShowAnim As Boolean)
If LabRamGame Is Nothing OrElse LabRamUsed Is Nothing OrElse FrmMain.PageCurrent <> FormMain.PageType.VersionSetup OrElse FrmVersionLeft.PageID <> FormMain.PageSubType.VersionSetup Then Exit Sub
'获取内存情况
Dim RamGame As Double = GetRam(PageVersionLeft.Version)
Dim RamTotal As Double = Math.Round(My.Computer.Info.TotalPhysicalMemory / 1024 / 1024 / 1024 * 10) / 10
Dim RamAvailable As Double = Math.Round(My.Computer.Info.AvailablePhysicalMemory / 1024 / 1024 / 1024 * 10) / 10
Dim RamGameActual As Double = Math.Min(RamGame, RamAvailable)
Dim RamUsed As Double = RamTotal - RamAvailable
Dim RamEmpty As Double = Math.Round(MathRange(RamTotal - RamUsed - RamGame, 0, 1000) * 10) / 10
'设置最大可用内存
If RamTotal <= 1.5 Then
SliderRamCustom.MaxValue = Math.Max(Math.Floor((RamTotal - 0.3) / 0.1), 1)
ElseIf RamTotal <= 8 Then
SliderRamCustom.MaxValue = Math.Floor((RamTotal - 1.5) / 0.5) + 12
ElseIf RamTotal <= 16 Then
SliderRamCustom.MaxValue = Math.Floor((RamTotal - 8) / 1) + 25
ElseIf RamTotal <= 32 Then
SliderRamCustom.MaxValue = Math.Floor((RamTotal - 16) / 2) + 33
Else
SliderRamCustom.MaxValue = Math.Min(Math.Floor((RamTotal - 32) / 4) + 41, 49)
End If
'设置文本
LabRamGame.Text = If(RamGame = Math.Floor(RamGame), RamGame & ".0", RamGame) & " GB" &
If(RamGame <> RamGameActual, " (可用 " & If(RamGameActual = Math.Floor(RamGameActual), RamGameActual & ".0", RamGameActual) & " GB)", "")
LabRamUsed.Text = If(RamUsed = Math.Floor(RamUsed), RamUsed & ".0", RamUsed) & " GB"
LabRamTotal.Text = " / " & If(RamTotal = Math.Floor(RamTotal), RamTotal & ".0", RamTotal) & " GB"
LabRamWarn.Visibility = If(RamGame = 1 AndAlso Not JavaUse64Bit(PageVersionLeft.Version) AndAlso Not Is32BitSystem, Visibility.Visible, Visibility.Collapsed)
If ShowAnim Then
'宽度动画
AniStart({
AaGridLengthWidth(ColumnRamUsed, RamUsed - ColumnRamUsed.Width.Value, 800,, New AniEaseOutFluent(AniEasePower.Strong)),
AaGridLengthWidth(ColumnRamGame, RamGameActual - ColumnRamGame.Width.Value, 800,, New AniEaseOutFluent(AniEasePower.Strong)),
AaGridLengthWidth(ColumnRamEmpty, RamEmpty - ColumnRamEmpty.Width.Value, 800,, New AniEaseOutFluent(AniEasePower.Strong))
}, "VersionSetup Ram Grid")
Else
'宽度设置
ColumnRamUsed.Width = New GridLength(RamUsed, GridUnitType.Star)
ColumnRamGame.Width = New GridLength(RamGameActual, GridUnitType.Star)
ColumnRamEmpty.Width = New GridLength(RamEmpty, GridUnitType.Star)
End If
End Sub
Private Sub RefreshRam() Handles SliderRamCustom.Change, RadioRamType0.Check, RadioRamType1.Check, RadioRamType2.Check
RefreshRam(True)
End Sub
Private RamTextLeft As Integer = 2, RamTextRight As Integer = 1
''' <summary>
''' 刷新 UI 上的文本位置。
''' </summary>
Private Sub RefreshRamText() Handles RectRamGame.SizeChanged, RectRamEmpty.SizeChanged, LabRamGame.SizeChanged
'获取宽度信息
Dim RectUsedWidth = RectRamUsed.ActualWidth
Dim TotalWidth = PanRamDisplay.ActualWidth
Dim LabGameWidth = LabRamGame.ActualWidth, LabUsedWidth = LabRamUsed.ActualWidth, LabTotalWidth = LabRamTotal.ActualWidth
Dim LabGameTitleWidth = LabRamGameTitle.ActualWidth, LabUsedTitleWidth = LabRamUsedTitle.ActualWidth
'左侧
Dim Left As Integer
If RectUsedWidth - 30 < LabUsedWidth OrElse RectUsedWidth - 30 < LabUsedTitleWidth Then
'全写不下了
Left = 0
ElseIf RectUsedWidth - 25 < (LabUsedWidth + LabTotalWidth) Then
'显示不下完整数据
Left = 1
Else
'正常
Left = 2
End If
If RamTextLeft <> Left Then
RamTextLeft = Left
Select Case Left
Case 0
AniStart({
AaOpacity(LabRamUsed, -LabRamUsed.Opacity, 100),
AaOpacity(LabRamTotal, -LabRamTotal.Opacity, 100),
AaOpacity(LabRamUsedTitle, -LabRamUsedTitle.Opacity, 100)
}, "VersionSetup Ram TextLeft")
Case 1
AniStart({
AaOpacity(LabRamUsed, 1 - LabRamUsed.Opacity, 100),
AaOpacity(LabRamTotal, -LabRamTotal.Opacity, 100),
AaOpacity(LabRamUsedTitle, 0.7 - LabRamUsedTitle.Opacity, 100)
}, "VersionSetup Ram TextLeft")
Case 2
AniStart({
AaOpacity(LabRamUsed, 1 - LabRamUsed.Opacity, 100),
AaOpacity(LabRamTotal, 1 - LabRamTotal.Opacity, 100),
AaOpacity(LabRamUsedTitle, 0.7 - LabRamUsedTitle.Opacity, 100)
}, "VersionSetup Ram TextLeft")
End Select
End If
'右侧
Dim Right As Integer
If TotalWidth < LabGameWidth + 2 + RectUsedWidth OrElse TotalWidth < LabGameTitleWidth + 2 + RectUsedWidth Then
'挤到最右边
Right = 0
Else
'正常情况
Right = 1
End If
If Right = 0 Then
If AniControlEnabled = 0 AndAlso (RamTextRight <> Right OrElse AniIsRun("VersionSetup Ram TextRight")) Then
'需要动画
AniStart({
AaX(LabRamGame, TotalWidth - LabGameWidth - LabRamGame.Margin.Left, 100,, New AniEaseOutFluent(AniEasePower.Weak)),
AaX(LabRamGameTitle, TotalWidth - LabGameTitleWidth - LabRamGameTitle.Margin.Left, 100,, New AniEaseOutFluent(AniEasePower.Weak))
}, "VersionSetup Ram TextRight")
Else
'不需要动画
LabRamGame.Margin = New Thickness(TotalWidth - LabGameWidth, 3, 0, 0)
LabRamGameTitle.Margin = New Thickness(TotalWidth - LabGameTitleWidth, 0, 0, 5)
End If
Else
If AniControlEnabled = 0 AndAlso (RamTextRight <> Right OrElse AniIsRun("VersionSetup Ram TextRight")) Then
'需要动画
AniStart({
AaX(LabRamGame, 2 + RectUsedWidth - LabRamGame.Margin.Left, 100,, New AniEaseOutFluent(AniEasePower.Weak)),
AaX(LabRamGameTitle, 2 + RectUsedWidth - LabRamGameTitle.Margin.Left, 100,, New AniEaseOutFluent(AniEasePower.Weak))
}, "VersionSetup Ram TextRight")
Else
'不需要动画
LabRamGame.Margin = New Thickness(2 + RectUsedWidth, 3, 0, 0)
LabRamGameTitle.Margin = New Thickness(2 + RectUsedWidth, 0, 0, 5)
End If
End If
RamTextRight = Right
End Sub
''' <summary>
''' 获取当前设置的 RAM 值。单位为 GB。
''' </summary>
Public Shared Function GetRam(Version As McVersion) As Double
'使用全局设置
If Setup.Get("VersionRamType", Version:=Version) = 2 Then
Return PageSetupLaunch.GetRam(Version, True)
End If
'使用当前版本的设置
Dim RamGive As Double
If Setup.Get("VersionRamType", Version:=Version) = 0 Then
'自动配置
Dim RamAvailable As Double = Math.Round(My.Computer.Info.AvailablePhysicalMemory / 1024 / 1024 / 1024 * 10) / 10
'确定需求的内存值
Dim RamMininum As Double '无论如何也需要保证的最低限度内存
Dim RamTarget1 As Double '估计能勉强带动了的内存
Dim RamTarget2 As Double '估计没啥问题了的内存
Dim RamTarget3 As Double '安装过多附加组件需要的内存
If Version IsNot Nothing AndAlso Not Version.IsLoaded Then Version.Load()
If Version IsNot Nothing AndAlso Version.Version.Modable Then
'可安装 Mod 的版本
Dim ModDir As New DirectoryInfo(Version.PathIndie & "mods\")
Dim ModCount As Integer = If(ModDir.Exists, ModDir.GetFiles.Length, 0)
RamMininum = 0.4 + ModCount / 150
RamTarget1 = 1.5 + ModCount / 100
RamTarget2 = 3 + ModCount / 60
RamTarget3 = 6 + ModCount / 30
ElseIf Version IsNot Nothing AndAlso Version.Version.HasOptiFine Then
'OptiFine 版本
RamMininum = 0.3
RamTarget1 = 1.5
RamTarget2 = 3
RamTarget3 = 6
Else
'普通版本
RamMininum = 0.3
RamTarget1 = 1.5
RamTarget2 = 2.5
RamTarget3 = 4
End If
Dim RamDelta As Double
'预分配内存,阶段一,0 ~ T1,100%
RamDelta = RamTarget1
RamAvailable = Math.Max(0, RamAvailable - 0.1)
RamGive += Math.Min(RamAvailable * 1, RamDelta)
RamAvailable -= RamDelta / 1 + 0.1
If RamAvailable < 0.1 Then GoTo PreFin
'预分配内存,阶段二,T1 ~ T2,80%
RamDelta = RamTarget2 - RamTarget1
RamAvailable = Math.Max(0, RamAvailable - 0.1)
RamGive += Math.Min(RamAvailable * 0.8, RamDelta)
RamAvailable -= RamDelta / 0.8 + 0.1
If RamAvailable < 0.1 Then GoTo PreFin
'预分配内存,阶段三,T2 ~ T3,60%
RamDelta = RamTarget3 - RamTarget2
RamAvailable = Math.Max(0, RamAvailable - 0.2)
RamGive += Math.Min(RamAvailable * 0.6, RamDelta)
RamAvailable -= RamDelta / 0.6 + 0.2
If RamAvailable < 0.1 Then GoTo PreFin
'预分配内存,阶段四,T3 ~ T3 * 2,40%
RamDelta = RamTarget3
RamAvailable = Math.Max(0, RamAvailable - 0.3)
RamGive += Math.Min(RamAvailable * 0.4, RamDelta)
RamAvailable -= RamDelta / 0.4 + 0.3
If RamAvailable < 0.1 Then GoTo PreFin
PreFin:
'不低于最低值
RamGive = Math.Round(Math.Max(RamGive, RamMininum), 1)
Else
'手动配置
Dim Value As Integer = Setup.Get("VersionRamCustom", Version:=Version)
If Value <= 12 Then
RamGive = Value * 0.1 + 0.3
ElseIf Value <= 25 Then
RamGive = (Value - 12) * 0.5 + 1.5
ElseIf Value <= 33 Then
RamGive = (Value - 25) * 1 + 8
ElseIf Value <= 41 Then
RamGive = (Value - 33) * 2 + 16
Else
RamGive = (Value - 41) * 4 + 32
End If
End If
'若使用 32 位 Java,则限制为 1G
If Not JavaUse64Bit(PageVersionLeft.Version) Then RamGive = Math.Min(1, RamGive)
Return RamGive
End Function
#End Region
#Region "服务器"
'全局
Private ComboServerLoginLast As Integer
Private Sub ComboServerLogin_Changed() Handles ComboServerLogin.SelectionChanged, TextServerNide.ValidatedTextChanged, TextServerAuthServer.ValidatedTextChanged, TextServerAuthRegister.ValidatedTextChanged
If AniControlEnabled <> 0 Then Exit Sub
ServerLogin(ComboServerLogin.SelectedIndex)
'检查是否输入正确,正确才触发设置改变
If ComboServerLogin.SelectedIndex = 3 AndAlso TextServerNide.ValidateResult <> "" Then Exit Sub
If ComboServerLogin.SelectedIndex = 4 AndAlso TextServerAuthServer.ValidateResult <> "" Then Exit Sub
'检查结果是否发生改变,未改变则不触发设置改变
If ComboServerLoginLast = ComboServerLogin.SelectedIndex Then Exit Sub
'触发
ComboServerLoginLast = ComboServerLogin.SelectedIndex
ComboChange(ComboServerLogin, Nothing)
End Sub
Public Sub ServerLogin(Type As Integer)
If LabServerNide Is Nothing Then Exit Sub
LabServerNide.Visibility = If(Type = 3, Visibility.Visible, Visibility.Collapsed)
TextServerNide.Visibility = If(Type = 3, Visibility.Visible, Visibility.Collapsed)
PanServerNide.Visibility = If(Type = 3, Visibility.Visible, Visibility.Collapsed)
LabServerAuthName.Visibility = If(Type = 4, Visibility.Visible, Visibility.Collapsed)
TextServerAuthName.Visibility = If(Type = 4, Visibility.Visible, Visibility.Collapsed)
LabServerAuthRegister.Visibility = If(Type = 4, Visibility.Visible, Visibility.Collapsed)
TextServerAuthRegister.Visibility = If(Type = 4, Visibility.Visible, Visibility.Collapsed)
LabServerAuthServer.Visibility = If(Type = 4, Visibility.Visible, Visibility.Collapsed)
TextServerAuthServer.Visibility = If(Type = 4, Visibility.Visible, Visibility.Collapsed)
BtnServerAuthLittle.Visibility = If(Type = 4, Visibility.Visible, Visibility.Collapsed)
CardServer.TriggerForceResize()
End Sub
'统一通行证
Private Sub BtnServerNideWeb_Click(sender As Object, e As EventArgs) Handles BtnServerNideWeb.Click
OpenWebsite("https://login.mc-user.com:233/server/intro")
End Sub
Private Sub BtnServerNideBbs_Click(sender As Object, e As EventArgs) Handles BtnServerNideBbs.Click
OpenWebsite("https://www.mcbbs.net/thread-729821-1-1.html")
End Sub
'Little Skin
Private Sub BtnServerAuthLittle_Click(sender As Object, e As EventArgs) Handles BtnServerAuthLittle.Click
TextServerAuthServer.Text = "https://littleskin.cn/api/yggdrasil"
TextServerAuthRegister.Text = "https://littleskin.cn/auth/register"
TextServerAuthName.Text = "Little Skin 登录"
End Sub
#End Region
#Region "Java 选择"
'刷新 Java 下拉框显示
Public Sub RefreshJavaComboBox()
If ComboArgumentJava Is Nothing Then Exit Sub
'初始化列表
ComboArgumentJava.Items.Clear()
ComboArgumentJava.Items.Add(New MyComboBoxItem With {.Content = "使用全局设置", .Tag = "使用全局设置"})
ComboArgumentJava.Items.Add(New MyComboBoxItem With {.Content = "自动选择适合所选游戏版本的 Java", .Tag = "自动选择"})
'更新列表
Dim SelectedItem As MyComboBoxItem = Nothing
Dim SelectedBySetup As String = Setup.Get("VersionArgumentJavaSelect", Version:=PageVersionLeft.Version)
Try
For Each Java In JavaList
Dim ListItem = New MyComboBoxItem With {.Content = Java.ToString, .ToolTip = Java.PathFolder, .Tag = Java}
ToolTipService.SetPlacement(ListItem, Primitives.PlacementMode.Right)
ToolTipService.SetHorizontalOffset(ListItem, 5)
ComboArgumentJava.Items.Add(ListItem)
'判断人为选中
If SelectedBySetup = "" OrElse SelectedBySetup = "使用全局设置" Then Continue For
If JavaEntry.FromJson(GetJson(SelectedBySetup)).PathFolder = Java.PathFolder Then SelectedItem = ListItem
Next
Catch ex As Exception
Setup.Set("VersionArgumentJavaSelect", "使用全局设置", Version:=PageVersionLeft.Version)
Log(ex, "更新版本设置 Java 下拉框失败", LogLevel.Feedback)
End Try
'更新选择项
If SelectedItem Is Nothing AndAlso JavaList.Count > 0 Then
If SelectedBySetup = "" Then
SelectedItem = ComboArgumentJava.Items(1) '选中 “自动选择”
Else
SelectedItem = ComboArgumentJava.Items(0) '选中 “使用全局设置”
End If
End If
ComboArgumentJava.SelectedItem = SelectedItem
'结束处理
If SelectedItem Is Nothing Then
ComboArgumentJava.Items.Clear()
ComboArgumentJava.Items.Add(New ComboBoxItem With {.Content = "未找到可用的 Java", .IsSelected = True})
End If
RefreshRam(True)
End Sub
'阻止在特定情况下展开下拉框
Private Sub ComboArgumentJava_DropDownOpened(sender As Object, e As EventArgs) Handles ComboArgumentJava.DropDownOpened
If ComboArgumentJava.SelectedItem Is Nothing OrElse ComboArgumentJava.Items(0).Content = "未找到可用的 Java" OrElse ComboArgumentJava.Items(0).Content = "加载中……" Then
ComboArgumentJava.IsDropDownOpen = False
End If
End Sub
'下拉框选择更改
Private Sub JavaSelectionUpdate() Handles ComboArgumentJava.SelectionChanged
If AniControlEnabled <> 0 Then Exit Sub
'Java 不可用时也不清空,会导致刷新时找不到对象
If ComboArgumentJava.SelectedItem Is Nothing OrElse ComboArgumentJava.SelectedItem.Tag Is Nothing Then Exit Sub
'设置新的 Java
Dim SelectedJava = ComboArgumentJava.SelectedItem.Tag
If "使用全局设置".Equals(SelectedJava) Then
'选择 “自动”
Setup.Set("VersionArgumentJavaSelect", "使用全局设置", Version:=PageVersionLeft.Version)
Log("[Java] 修改版本 Java 选择设置:使用全局设置")
ElseIf "自动选择".Equals(SelectedJava) Then
'选择 “自动”
Setup.Set("VersionArgumentJavaSelect", "", Version:=PageVersionLeft.Version)
Log("[Java] 修改版本 Java 选择设置:自动选择")
Else
'选择指定项
Setup.Set("VersionArgumentJavaSelect", CType(SelectedJava.ToJson(), JObject).ToString(Newtonsoft.Json.Formatting.None), Version:=PageVersionLeft.Version)
Log("[Java] 修改版本 Java 选择设置:" & SelectedJava.ToString)
End If
RefreshRam(True)
End Sub
#End Region
End Class