This commit is contained in:
龙腾猫跃
2026-05-21 01:15:20 +08:00
parent 8c3896da36
commit c86fdc3af1
36 changed files with 275 additions and 255 deletions
-1
View File
@@ -368,7 +368,6 @@
<Setter Property="FocusVisualStyle" Value="{x:Null}" /> <Setter Property="FocusVisualStyle" Value="{x:Null}" />
<Setter Property="FontSize" Value="13" /> <Setter Property="FontSize" Value="13" />
<Setter Property="MaxDropDownHeight" Value="320" /> <Setter Property="MaxDropDownHeight" Value="320" />
<Setter Property="Cursor" Value="Hand" />
<Setter Property="Template"> <Setter Property="Template">
<Setter.Value> <Setter.Value>
<ControlTemplate TargetType="ComboBox"> <ControlTemplate TargetType="ComboBox">
+26 -56
View File
@@ -91,37 +91,8 @@ RetryCacheCheck:
End Try End Try
DirectoryUtils.Create(PathTemp & "Cache\") DirectoryUtils.Create(PathTemp & "Cache\")
DirectoryUtils.Create(PathAppdata) DirectoryUtils.Create(PathAppdata)
#If DEBUG Then
Dim FileLockPath = Path.Combine(PathAppdata.TrimEnd("\"), "PCL.dev.Lock")
#Else
Dim FileLockPath = Path.Combine(PathAppdata.TrimEnd("\"), "PCL.Lock")
#End If
'要求单例 '要求单例
If BuildType <> BuildTypes.Debug Then WaitingMutex(e)
If Not GetProgramLock(FileLockPath) Then
Dim IsLocked = False
Dim ShouldWaitForExit As Boolean = e.Args.Length > 0 AndAlso e.Args(0) = "--wait" '要求等待已有的 PCL 退出
If Not ShouldWaitForExit Then
DropToTopByLock(FileLockPath)
Beep()
Environment.Exit(ProcessReturnValues.Cancel)
End If
For i = 0 To 10
If GetProgramLock(FileLockPath) Then
IsLocked = True
Exit For
End If
Thread.Sleep(500)
Next
If Not IsLocked Then
DropToTopByLock(FileLockPath)
Beep()
Environment.Exit(ProcessReturnValues.Cancel)
End If
End If
End If
'设置 ToolTipService 默认值 '设置 ToolTipService 默认值
ToolTipService.InitialShowDelayProperty.OverrideMetadata(GetType(DependencyObject), New FrameworkPropertyMetadata(300)) ToolTipService.InitialShowDelayProperty.OverrideMetadata(GetType(DependencyObject), New FrameworkPropertyMetadata(300))
ToolTipService.BetweenShowDelayProperty.OverrideMetadata(GetType(DependencyObject), New FrameworkPropertyMetadata(400)) ToolTipService.BetweenShowDelayProperty.OverrideMetadata(GetType(DependencyObject), New FrameworkPropertyMetadata(400))
@@ -173,38 +144,37 @@ RetryCacheCheck:
FormMain.EndProgramForce(ProcessReturnValues.Exception) FormMain.EndProgramForce(ProcessReturnValues.Exception)
End Try End Try
End Sub End Sub
Private Shared KernelLock As Mutex
''' <summary> ''' <summary>
''' 尝试获取单例锁 ''' 要求程序以单例运行。
''' 如果已在运行,则将其窗口拖出来并播放提示音,然后结束当前进程。
''' </summary> ''' </summary>
''' <param name="LockPath">文件锁位置</param> Private Shared Sub WaitingMutex(e As StartupEventArgs)
''' <returns>一个值用于指示是否获得文件锁</returns> If BuildType = BuildTypes.Debug Then Return
Private Function GetProgramLock(LockPath As String) As Boolean
Try Try
Dim IsLocked = False Dim MutexCreatedNew As Boolean
KernelLock = New Mutex(True, "Local\Plain Craft Launcher", IsLocked) PclMutex = New Mutex(True, "PCL_SingletonMutex", MutexCreatedNew)
If Not IsLocked Then Return False If MutexCreatedNew Then Return
Logger.Info("获取单例锁成功") Logger.Warn("已有一个 PCL 实例正在运行")
File.WriteAllText(LockPath, Process.GetCurrentProcess().Id.ToString()) '等待已有的 PCL 退出
Return IsLocked If e.Args.Length > 0 AndAlso e.Args(0) = "--wait" Then
Try
If PclMutex.WaitOne(10000) Then Return '等待至多 10 秒
Catch Ignored As AbandonedMutexException
Return '已有实例异常退出,继续启动
End Try
End If
'将已有的 PCL 窗口拖出来
Dim WindowHwnd As IntPtr = FindWindow(Nothing, "Plain Craft Launcher ")
If WindowHwnd = IntPtr.Zero Then WindowHwnd = FindWindow(Nothing, "Plain Craft Launcher 2 ")
If WindowHwnd <> IntPtr.Zero Then ShowWindowToTop(WindowHwnd)
'播放提示音并退出
Beep()
Environment.[Exit](ProcessReturnValues.Cancel)
Catch ex As Exception Catch ex As Exception
Logger.Warn(ex, "单例检查失败")
End Try End Try
Return False
End Function
''' <summary>
''' 从文件锁中尝试拖出进程
''' </summary>
Public Sub DropToTopByLock(LockPath As String)
Dim Pid As Integer
If Not Integer.TryParse(File.ReadAllText(LockPath), Pid) Then Return
Dim Handle = Process.GetProcessById(Pid)?.MainWindowHandle
If Handle <> Intptr.Zero Then ShowWindowToTop(Handle)
End Sub End Sub
Private Shared PclMutex As Mutex
'结束 '结束
Private Sub Application_SessionEnding(sender As Object, e As SessionEndingCancelEventArgs) Handles Me.SessionEnding Private Sub Application_SessionEnding(sender As Object, e As SessionEndingCancelEventArgs) Handles Me.SessionEnding
@@ -2,7 +2,7 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
FocusVisualStyle="{x:Null}" x:Name="PanBack" FocusVisualStyle="{x:Null}" x:Name="PanBack"
Focusable="True" UseLayoutRounding="False" SnapsToDevicePixels="False" Background="{StaticResource ColorBrushSemiTransparent}" Cursor="Hand"> Focusable="True" UseLayoutRounding="False" SnapsToDevicePixels="False" Background="{StaticResource ColorBrushSemiTransparent}">
<Border CornerRadius="3" x:Name="PanFore" BorderThickness="1" BorderBrush="{DynamicResource ColorBrush1}" RenderTransformOrigin="0.5,0.5" Background="{StaticResource ColorBrushHalfWhite}"> <Border CornerRadius="3" x:Name="PanFore" BorderThickness="1" BorderBrush="{DynamicResource ColorBrush1}" RenderTransformOrigin="0.5,0.5" Background="{StaticResource ColorBrushHalfWhite}">
<Border.RenderTransform> <Border.RenderTransform>
<ScaleTransform /> <ScaleTransform />
@@ -3,7 +3,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 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" mc:Ignorable="d" x:Class="MyCheckBox" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" x:Class="MyCheckBox"
FocusVisualStyle="{x:Null}" FocusVisualStyle="{x:Null}"
MinWidth="20" x:Name="PanBack" UseLayoutRounding="False" SnapsToDevicePixels="False" MinHeight="20" Background="{StaticResource ColorBrushSemiTransparent}" Focusable="True" d:DesignWidth="126.4" d:DesignHeight="44.8" Cursor="Hand"> MinWidth="20" x:Name="PanBack" UseLayoutRounding="False" SnapsToDevicePixels="False" MinHeight="20" Background="{StaticResource ColorBrushSemiTransparent}" Focusable="True" d:DesignWidth="126.4" d:DesignHeight="44.8">
<TextBlock IsHitTestVisible="False" FontSize="13" x:FieldModifier="Public" x:Name="LabText" Padding="0" Margin="26,0,0,0" Foreground="{DynamicResource ColorBrush1}" HorizontalAlignment="Left" VerticalAlignment="Center" /> <TextBlock IsHitTestVisible="False" FontSize="13" x:FieldModifier="Public" x:Name="LabText" Padding="0" Margin="26,0,0,0" Foreground="{DynamicResource ColorBrush1}" HorizontalAlignment="Left" VerticalAlignment="Center" />
<Border IsHitTestVisible="False" x:Name="ShapeBorder" BorderThickness="1.1" HorizontalAlignment="Left" VerticalAlignment="Center" Width="18" Height="18" BorderBrush="{DynamicResource ColorBrush1}" CornerRadius="3" Margin="1,0,0,0" Background="{StaticResource ColorBrushHalfWhite}" /> <Border IsHitTestVisible="False" x:Name="ShapeBorder" BorderThickness="1.1" HorizontalAlignment="Left" VerticalAlignment="Center" Width="18" Height="18" BorderBrush="{DynamicResource ColorBrush1}" CornerRadius="3" Margin="1,0,0,0" Background="{StaticResource ColorBrushHalfWhite}" />
<Path IsHitTestVisible="False" x:Name="ShapeCheck" HorizontalAlignment="Left" VerticalAlignment="Center" Fill="{Binding BorderBrush, ElementName=ShapeBorder}" Width="12" Height="12" Margin="4,0,0,0" Data="M0,6L1.5,4.5 4.5,7.5 10.5,1.5 12,3 4.5,10.5 0,6z"> <Path IsHitTestVisible="False" x:Name="ShapeCheck" HorizontalAlignment="Left" VerticalAlignment="Center" Fill="{Binding BorderBrush, ElementName=ShapeBorder}" Width="12" Height="12" Margin="4,0,0,0" Data="M0,6L1.5,4.5 4.5,7.5 10.5,1.5 12,3 4.5,10.5 0,6z">
@@ -2,7 +2,7 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 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" x:Name="PanBack" mc:Ignorable="d" x:Class="MyExtraButton" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" x:Name="PanBack" mc:Ignorable="d" x:Class="MyExtraButton"
Width="40" RenderTransformOrigin="0.5,0.5" ToolTipService.Placement="Left" ToolTipService.VerticalOffset="16" ToolTipService.HorizontalOffset="-8" Height="0" Cursor="Hand"> Width="40" RenderTransformOrigin="0.5,0.5" ToolTipService.Placement="Left" ToolTipService.VerticalOffset="16" ToolTipService.HorizontalOffset="-8" Height="0">
<Grid.RenderTransform> <Grid.RenderTransform>
<ScaleTransform ScaleX="0" ScaleY="0" /> <ScaleTransform ScaleX="0" ScaleY="0" />
</Grid.RenderTransform> </Grid.RenderTransform>
@@ -1,7 +1,7 @@
<Border x:Name="PanBack" x:Class="MyIconTextButton" <Border x:Name="PanBack" x:Class="MyIconTextButton"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
HorizontalAlignment="Center" VerticalAlignment="Center" Background="{StaticResource ColorBrushSemiTransparent}" CornerRadius="13.5" MinHeight="27" MaxHeight="27" Cursor="Hand"> HorizontalAlignment="Center" VerticalAlignment="Center" Background="{StaticResource ColorBrushSemiTransparent}" CornerRadius="13.5" MinHeight="27" MaxHeight="27">
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<Path x:Name="ShapeLogo" HorizontalAlignment="Left" RenderTransformOrigin="0.5,0.5" Margin="12,0,0,0" Stretch="Uniform" Fill="White" MaxHeight="16" MaxWidth="16" VerticalAlignment="Center" /> <Path x:Name="ShapeLogo" HorizontalAlignment="Left" RenderTransformOrigin="0.5,0.5" Margin="12,0,0,0" Stretch="Uniform" Fill="White" MaxHeight="16" MaxWidth="16" VerticalAlignment="Center" />
<TextBlock x:Name="LabText" VerticalAlignment="Center" Grid.Column="1" Foreground="White" Margin="7,0,12,1" Grid.ColumnSpan="2" SnapsToDevicePixels="False" UseLayoutRounding="False" /> <TextBlock x:Name="LabText" VerticalAlignment="Center" Grid.Column="1" Foreground="White" Margin="7,0,12,1" Grid.ColumnSpan="2" SnapsToDevicePixels="False" UseLayoutRounding="False" />
+1 -1
View File
@@ -112,7 +112,7 @@
End If End If
'从缓存加载网络图片 '从缓存加载网络图片
Dim EnableCache As Boolean = Me.EnableCache Dim EnableCache As Boolean = Me.EnableCache
Dim TempPath As String = $"{PathTemp}MyImage\{GetHash(Source)}.png{If(EnableCache, "", GetUuid())}" '不启用缓存时在末尾加上随机字符串,避免冲突 Dim TempPath As String = $"{PathTemp}MyImage\{Source.GetStableHashCode()}.png{If(EnableCache, "", GetUuid())}" '不启用缓存时在末尾加上随机字符串,避免冲突
Dim TempFile = FileUtils.GetInfo(TempPath) Dim TempFile = FileUtils.GetInfo(TempPath)
If EnableCache AndAlso TempFile.Exists Then If EnableCache AndAlso TempFile.Exists Then
ActualSource = TempPath '显示缓存的图片 ActualSource = TempPath '显示缓存的图片
@@ -2,7 +2,7 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Name="PanBack" x:Name="PanBack"
RenderTransformOrigin="0.5,0.5" Background="{StaticResource ColorBrushSemiTransparent}" Height="42" Cursor="Hand"> RenderTransformOrigin="0.5,0.5" Background="{StaticResource ColorBrushSemiTransparent}" Height="42">
<Grid.RenderTransform> <Grid.RenderTransform>
<ScaleTransform ScaleX="1" ScaleY="1" /> <ScaleTransform ScaleX="1" ScaleY="1" />
</Grid.RenderTransform> </Grid.RenderTransform>
@@ -2,7 +2,7 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
FocusVisualStyle="{x:Null}" FocusVisualStyle="{x:Null}"
MinWidth="20" x:Name="PanBack" UseLayoutRounding="False" SnapsToDevicePixels="False" MinHeight="20" Background="{StaticResource ColorBrushSemiTransparent}" Focusable="True" Cursor="Hand"> MinWidth="20" x:Name="PanBack" UseLayoutRounding="False" SnapsToDevicePixels="False" MinHeight="20" Background="{StaticResource ColorBrushSemiTransparent}" Focusable="True">
<TextBlock IsHitTestVisible="False" x:Name="LabText" FontSize="13" Padding="0" Margin="26,0,0,0" Foreground="{DynamicResource ColorBrush1}" HorizontalAlignment="Left" VerticalAlignment="Center"/> <TextBlock IsHitTestVisible="False" x:Name="LabText" FontSize="13" Padding="0" Margin="26,0,0,0" Foreground="{DynamicResource ColorBrush1}" HorizontalAlignment="Left" VerticalAlignment="Center"/>
<Ellipse IsHitTestVisible="False" x:Name="ShapeBorder" StrokeThickness="1.1" HorizontalAlignment="Left" VerticalAlignment="Center" Width="18" Height="18" Stroke="{DynamicResource ColorBrush1}" Margin="1,0,0,0" Fill="{StaticResource ColorBrushHalfWhite}" /> <Ellipse IsHitTestVisible="False" x:Name="ShapeBorder" StrokeThickness="1.1" HorizontalAlignment="Left" VerticalAlignment="Center" Width="18" Height="18" Stroke="{DynamicResource ColorBrush1}" Margin="1,0,0,0" Fill="{StaticResource ColorBrushHalfWhite}" />
<Ellipse IsHitTestVisible="False" x:Name="ShapeDot" HorizontalAlignment="Left" VerticalAlignment="Center" Fill="{Binding Stroke, ElementName=ShapeBorder}" Width="0" Height="0" Margin="10,0,0,0" StrokeThickness="0" /> <Ellipse IsHitTestVisible="False" x:Name="ShapeDot" HorizontalAlignment="Left" VerticalAlignment="Center" Fill="{Binding Stroke, ElementName=ShapeBorder}" Width="0" Height="0" Margin="10,0,0,0" StrokeThickness="0" />
@@ -99,7 +99,6 @@ Public Class MyRadioBox
End Try End Try
End Sub End Sub
Private Sub SyncUI() Private Sub SyncUI()
Cursor = If(Checked, Nothing, Cursors.Hand)
If AniControlEnabled = 0 AndAlso IsLoaded Then '防止默认属性变更触发动画 If AniControlEnabled = 0 AndAlso IsLoaded Then '防止默认属性变更触发动画
If Checked Then If Checked Then
'由无变有 '由无变有
@@ -198,9 +197,6 @@ Public Class MyRadioBox
Private Const AnimationTimeOfMouseIn As Integer = 100 '鼠标指向动画长度 Private Const AnimationTimeOfMouseIn As Integer = 100 '鼠标指向动画长度
Private Const AnimationTimeOfMouseOut As Integer = 200 '鼠标指向动画长度 Private Const AnimationTimeOfMouseOut As Integer = 200 '鼠标指向动画长度
Private Const AnimationTimeOfCheck As Integer = 150 '勾选状态变更动画长度 Private Const AnimationTimeOfCheck As Integer = 150 '勾选状态变更动画长度
Private Sub MyRadioBox_Loaded() Handles Me.Loaded
Cursor = If(Checked, Nothing, Cursors.Hand)
End Sub
Private Sub Radiobox_IsEnabledChanged() Handles Me.IsEnabledChanged Private Sub Radiobox_IsEnabledChanged() Handles Me.IsEnabledChanged
If Me.IsLoaded AndAlso AniControlEnabled = 0 Then '防止默认属性变更触发动画 If Me.IsLoaded AndAlso AniControlEnabled = 0 Then '防止默认属性变更触发动画
'有动画 '有动画
@@ -1,7 +1,7 @@
<Border x:Name="PanBack" x:Class="MyRadioButton" <Border x:Name="PanBack" x:Class="MyRadioButton"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
HorizontalAlignment="Center" VerticalAlignment="Center" Background="{StaticResource ColorBrushSemiTransparent}" CornerRadius="13.5" MinHeight="27" MaxHeight="27" Cursor="Hand"> HorizontalAlignment="Center" VerticalAlignment="Center" Background="{StaticResource ColorBrushSemiTransparent}" CornerRadius="13.5" MinHeight="27" MaxHeight="27">
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<Path x:Name="ShapeLogo" HorizontalAlignment="Left" RenderTransformOrigin="0.5,0.5" Margin="12,0,0,0" Stretch="Uniform" Fill="White" MaxHeight="16" MaxWidth="16" VerticalAlignment="Center" /> <Path x:Name="ShapeLogo" HorizontalAlignment="Left" RenderTransformOrigin="0.5,0.5" Margin="12,0,0,0" Stretch="Uniform" Fill="White" MaxHeight="16" MaxWidth="16" VerticalAlignment="Center" />
<TextBlock x:Name="LabText" VerticalAlignment="Center" Grid.Column="1" Foreground="White" Margin="8,0,12,0" Grid.ColumnSpan="2" SnapsToDevicePixels="False" UseLayoutRounding="False" /> <TextBlock x:Name="LabText" VerticalAlignment="Center" Grid.Column="1" Foreground="White" Margin="8,0,12,0" Grid.ColumnSpan="2" SnapsToDevicePixels="False" UseLayoutRounding="False" />
@@ -167,7 +167,6 @@ Public Class MyRadioButton
Private Const AnimationTimeOfMouseOut As Integer = 150 '鼠标移出动画长度 Private Const AnimationTimeOfMouseOut As Integer = 150 '鼠标移出动画长度
Private Const AnimationTimeOfCheck As Integer = 120 '勾选状态变更动画长度 Private Const AnimationTimeOfCheck As Integer = 120 '勾选状态变更动画长度
Private Sub RefreshColor(Optional obj = Nothing, Optional e = Nothing) Handles Me.MouseEnter, Me.MouseLeave, Me.Loaded Private Sub RefreshColor(Optional obj = Nothing, Optional e = Nothing) Handles Me.MouseEnter, Me.MouseLeave, Me.Loaded
Cursor = If(Checked, Nothing, Cursors.Hand)
Try Try
If IsLoaded AndAlso AniControlEnabled = 0 AndAlso Not False.Equals(e) Then '防止默认属性变更触发动画,若强制不执行动画,则 e 为 False If IsLoaded AndAlso AniControlEnabled = 0 AndAlso Not False.Equals(e) Then '防止默认属性变更触发动画,若强制不执行动画,则 e 为 False
+8 -3
View File
@@ -11,10 +11,10 @@ Public Class FormMain
Dim FeatureList As New List(Of KeyValuePair(Of Integer, String)) Dim FeatureList As New List(Of KeyValuePair(Of Integer, String))
'统计更新日志条目 '统计更新日志条目
If BuildType = BuildTypes.Release Then If BuildType = BuildTypes.Release Then
If LastVersion < 400 Then 'Release 2.12.8.0 If LastVersion < 402 Then 'Release 2.12.8.1
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "优化:升级框架到 .NET Framework 4.8")) FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "优化:升级框架到 .NET Framework 4.8"))
FeatureCount += 28 FeatureCount += 35
BugCount += 19 BugCount += 21
End If End If
If LastVersion < 398 Then 'Release 2.12.7.3 If LastVersion < 398 Then 'Release 2.12.7.3
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "优化:下载游戏、整合包的稳定性")) FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "优化:下载游戏、整合包的稳定性"))
@@ -74,6 +74,11 @@ Public Class FormMain
'3:BUG+ IMP* FEAT- '3:BUG+ IMP* FEAT-
'2:BUG* IMP- '2:BUG* IMP-
'1:BUG- '1:BUG-
If LastVersion < 401 Then 'Snapshot 2.12.8.1
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复:可能无法更换披风"))
FeatureCount += 8
BugCount += 6
End If
If LastVersion < 399 Then 'Snapshot 2.12.8.0 If LastVersion < 399 Then 'Snapshot 2.12.8.0
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "优化:升级框架到 .NET Framework 4.8")) FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "优化:升级框架到 .NET Framework 4.8"))
FeatureCount += 28 FeatureCount += 28
+14 -33
View File
@@ -10,12 +10,12 @@ Public Module ModBase
#Region "声明" #Region "声明"
'下列版本信息由更新器自动修改 '下列版本信息由更新器自动修改
Public Const VersionBaseName As String = "2.12.8.0" '显示用版本名 Public Const VersionBaseName As String = "2.12.8.1" '显示用版本名
Public Const CommitHash As String = "" 'Commit Hash,由 GitHub Workflow 自动替换 Public Const CommitHash As String = "" 'Commit Hash,由 GitHub Workflow 自动替换
#If RELEASE Then #If RELEASE Then
Public Const VersionCode As Integer = 400 '正式版 Public Const VersionCode As Integer = 402 '正式版
#Else #Else
Public Const VersionCode As Integer = 399 '快照版 Public Const VersionCode As Integer = 401 '快照版
#End If #End If
'版本信息 '版本信息
@@ -710,13 +710,13 @@ Public Module ModBase
End If End If
If Not String.IsNullOrEmpty(Hash) Then If Not String.IsNullOrEmpty(Hash) Then
If Hash.Length < 35 Then 'MD5 If Hash.Length < 35 Then 'MD5
Dim md5 As String = HashUtils.ComputeFromFile(LocalPath, HashUtils.HashMethod.Md5) Dim md5 As String = CryptographyUtils.ComputeFileHash(LocalPath, CryptographyUtils.HashMethod.Md5)
If Hash.Lower <> md5 Then Return "文件 MD5 应为 " & Hash & ",实际为 " & md5 If Hash.Lower <> md5 Then Return "文件 MD5 应为 " & Hash & ",实际为 " & md5
ElseIf Hash.Length = 64 Then 'SHA256 ElseIf Hash.Length = 64 Then 'SHA256
Dim sha256 As String = HashUtils.ComputeFromFile(LocalPath, HashUtils.HashMethod.Sha256) Dim sha256 As String = CryptographyUtils.ComputeFileHash(LocalPath, CryptographyUtils.HashMethod.Sha256)
If Hash.Lower <> sha256 Then Return "文件 SHA256 应为 " & Hash & ",实际为 " & sha256 If Hash.Lower <> sha256 Then Return "文件 SHA256 应为 " & Hash & ",实际为 " & sha256
Else 'SHA1 (40) Else 'SHA1 (40)
Dim sha1 As String = HashUtils.ComputeFromFile(LocalPath, HashUtils.HashMethod.Sha1) Dim sha1 As String = CryptographyUtils.ComputeFileHash(LocalPath, CryptographyUtils.HashMethod.Sha1)
If Hash.Lower <> sha1 Then Return "文件 SHA1 应为 " & Hash & ",实际为 " & sha1 If Hash.Lower <> sha1 Then Return "文件 SHA1 应为 " & Hash & ",实际为 " & sha1
End If End If
End If End If
@@ -793,30 +793,6 @@ Public Module ModBase
End Try End Try
End Function End Function
''' <summary>
''' 获取字符串哈希值。
''' </summary>
Public Function GetHash(Str As String) As ULong
Dim Result As ULong = 5381
For Each v In Str
Result = (Result << 5) Xor Result Xor CType(AscW(v), ULong)
Next
Return Result Xor &HA98F501BC684032FUL
End Function
''' <summary>
''' 获取字符串 MD5。
''' </summary>
Public Function GetStringMD5(Str As String) As String
Using h = MD5Cng.Create()
Dim hashedDataBytes = h.ComputeHash(Encoding.UTF8.GetBytes(Str))
Dim tmp As New StringBuilder(hashedDataBytes.Length * 2)
For Each i As Byte In hashedDataBytes
tmp.Append(i.ToString("x2"))
Next
Return tmp.ToString()
End Using
End Function
''' <summary> ''' <summary>
''' 不会报错的 Val。 ''' 不会报错的 Val。
''' 如果输入有误,返回 0。 ''' 如果输入有误,返回 0。
@@ -1399,12 +1375,17 @@ Public Module ModBase
''' 将程序中的资源释放到文件。 ''' 将程序中的资源释放到文件。
''' </summary> ''' </summary>
Public Sub ExtractResources(FilePath As String, ResourceName As String) Public Sub ExtractResources(FilePath As String, ResourceName As String)
Logger.Info($"将资源写入到文件:{ResourceName} → {FilePath}")
Dim Resource = My.Resources.ResourceManager.GetObject(ResourceName) Dim Resource = My.Resources.ResourceManager.GetObject(ResourceName)
If TypeOf Resource Is Byte() Then If TypeOf Resource Is Byte() Then
FileUtils.Write(FilePath, DirectCast(Resource, Byte())) Dim Bytes = DirectCast(Resource, Byte())
If FileUtils.Exists(FilePath) AndAlso CryptographyUtils.ComputeFileHash(FilePath) = CryptographyUtils.ComputeHash(Bytes) Then Return
Logger.Info($"将资源写入到文件:{ResourceName} → {FilePath}")
FileUtils.Write(FilePath, Bytes)
ElseIf TypeOf Resource Is String Then ElseIf TypeOf Resource Is String Then
FileUtils.Write(FilePath, DirectCast(Resource, String)) Dim Content = DirectCast(Resource, String)
If FileUtils.Exists(FilePath) AndAlso FileUtils.ReadAsString(FilePath) = Content Then Return
Logger.Info($"将资源写入到文件:{ResourceName} → {FilePath}")
FileUtils.Write(FilePath, Content)
Else Else
Throw New Exception($"资源 {ResourceName} 的类型不支持:{Resource.GetType.Name}") Throw New Exception($"资源 {ResourceName} 的类型不支持:{Resource.GetType.Name}")
End If End If
@@ -8,7 +8,6 @@
Implements ILoadingTrigger Implements ILoadingTrigger
Public ReadOnly Property IsLoader As Boolean = True Implements ILoadingTrigger.IsLoader Public ReadOnly Property IsLoader As Boolean = True Implements ILoadingTrigger.IsLoader
Protected Shared LogBlackList As String() = {"EasyTier CLI"}
'基础属性 '基础属性
''' <summary> ''' <summary>
@@ -90,7 +89,7 @@
Dim OldState = _State Dim OldState = _State
If value = LoadState.Finished AndAlso Settings.Get(Of Boolean)("SystemDebugDelay") Then Thread.Sleep(RandomInteger(100, 2000)) If value = LoadState.Finished AndAlso Settings.Get(Of Boolean)("SystemDebugDelay") Then Thread.Sleep(RandomInteger(100, 2000))
_State = value _State = value
If Not LogBlackList.Contains(Name) Then Logger.Info($"加载器 {Name} 状态改变:{value}") Logger.Log($"加载器 {Name} 状态改变:{value}", If(value = LoadState.Failed, LogLevel.Error, LogLevel.Info))
'实现 ILoadingTrigger 接口与 OnStateChanged 回调 '实现 ILoadingTrigger 接口与 OnStateChanged 回调
RunInUi( RunInUi(
Sub() Sub()
@@ -319,13 +318,13 @@
Sub() Sub()
Try Try
IsForceRestarting = IsForceRestart IsForceRestarting = IsForceRestart
If Not LogBlackList.Contains(Name) Then Logger.Trace(Function() $"加载线程 {Name} ({Thread.CurrentThread.ManagedThreadId}) 已{If(IsForceRestarting, "强制", "")}启动") Logger.Trace(Function() $"加载线程 {Name} ({Thread.CurrentThread.ManagedThreadId}) 已{If(IsForceRestarting, "强制", "")}启动")
LoadDelegate(Me) LoadDelegate(Me)
If IsInterrupted Then If IsInterrupted Then
Logger.Warn($"加载线程 {Name} ({Thread.CurrentThread.ManagedThreadId}) 已中断但线程正常运行至结束,输出被弃用(最新线程:{If(LastRunningThread Is Nothing, -1, LastRunningThread.ManagedThreadId)})") Logger.Warn($"加载线程 {Name} ({Thread.CurrentThread.ManagedThreadId}) 已中断但线程正常运行至结束,输出被弃用(最新线程:{If(LastRunningThread Is Nothing, -1, LastRunningThread.ManagedThreadId)})")
Return Return
End If End If
If Not LogBlackList.Contains(Name) Then Logger.Trace(Function() $"加载线程 {Name} ({Thread.CurrentThread.ManagedThreadId}) 已完成") Logger.Trace(Function() $"加载线程 {Name} ({Thread.CurrentThread.ManagedThreadId}) 已完成")
RaisePreviewFinish() RaisePreviewFinish()
State = LoadState.Finished State = LoadState.Finished
LastFinishedTime = GetTimeMs() '未中断,本次输出有效 LastFinishedTime = GetTimeMs() '未中断,本次输出有效
@@ -261,8 +261,11 @@ Retry:
}) })
End If End If
End SyncLock End SyncLock
CancelToken.Dispose() : CancelToken = New CancellationTokenSource(Timeout) ResilientUtils.RetryOn(Of FileNotFoundException, IOException)( 'CacheCow 读取缓存时若文件被占用,会调用不存在的 System.Net.Http.Formatting.resources,抛出此异常(#8150)
Response = RequestClient.SendAsync(Request, HttpCompletionOption.ResponseHeadersRead, CancelToken.Token).GetResultWithTimeout(CancelToken, Timeout) Sub()
CancelToken.Dispose() : CancelToken = New CancellationTokenSource(Timeout)
Response = RequestClient.SendAsync(Request, HttpCompletionOption.ResponseHeadersRead, CancelToken.Token).GetResultWithTimeout(CancelToken, Timeout)
End Sub)
Dim ResponseBytes As Byte() Dim ResponseBytes As Byte()
CancelToken.Dispose() : CancelToken = New CancellationTokenSource(Timeout) CancelToken.Dispose() : CancelToken = New CancellationTokenSource(Timeout)
Using ResponseStream = Response.Content.ReadAsStreamAsync().GetResultWithTimeout(CancelToken, Timeout) Using ResponseStream = Response.Content.ReadAsStreamAsync().GetResultWithTimeout(CancelToken, Timeout)
@@ -286,9 +289,6 @@ Retry:
Throw Throw
Catch ex As HttpRequestException Catch ex As HttpRequestException
Throw Throw
Catch ex As FileNotFoundException
'由于 CacheCow 读取缓存失败,然后系统调用不存在的 System.Net.Http.Formatting.resources 抛出(#8150)
Throw New Exception($"网络请求时读取缓存失败", ex)
Catch ex As Exception Catch ex As Exception
RecordIPReliability(HostIp, -1) RecordIPReliability(HostIp, -1)
If TypeOf ex Is OperationCanceledException OrElse TypeOf ex Is TimeoutException Then 'CancellationToken 超时 If TypeOf ex Is OperationCanceledException OrElse TypeOf ex Is TimeoutException Then 'CancellationToken 超时
@@ -333,7 +333,7 @@ NextInner:
Me.Type = Type Me.Type = Type
End Sub End Sub
Public Overrides Function GetHashCode() As Integer Public Overrides Function GetHashCode() As Integer
Return GetHash(UserName & Password & BaseUrl & Token & Type) Mod Integer.MaxValue Return (UserName & Password & BaseUrl & Token & Type).GetStableHashCode() Mod Integer.MaxValue
End Function End Function
End Class End Class
@@ -353,7 +353,7 @@ NextInner:
Type = McLoginType.Ms Type = McLoginType.Ms
End Sub End Sub
Public Overrides Function GetHashCode() As Integer Public Overrides Function GetHashCode() As Integer
Return GetHash(OAuthRefreshToken & AccessToken & Uuid & UserName & ProfileJson) Mod Integer.MaxValue Return (OAuthRefreshToken & AccessToken & Uuid & UserName & ProfileJson).GetStableHashCode() Mod Integer.MaxValue
End Function End Function
End Class End Class
Public Class McLoginLegacy Public Class McLoginLegacy
@@ -375,7 +375,7 @@ NextInner:
Type = McLoginType.Legacy Type = McLoginType.Legacy
End Sub End Sub
Public Overrides Function GetHashCode() As Integer Public Overrides Function GetHashCode() As Integer
Return GetHash(UserName & SkinType & SkinName & Type) Mod Integer.MaxValue Return (UserName & SkinType & SkinName & Type).GetStableHashCode() Mod Integer.MaxValue
End Function End Function
End Class End Class
@@ -535,21 +535,15 @@ NextInner:
Data.Progress = 0.05 Data.Progress = 0.05
'检查是否已经登录完成 '检查是否已经登录完成
Dim ExpiresAt = Settings.Get(Of Long)("CacheMsV2Expires") Dim ExpiresAt = Settings.Get(Of Long)("CacheMsV2Expires")
If Not Data.IsForceRestarting AndAlso '不要求强行重启 If Not Data.IsForceRestarting AndAlso '不要求强行重启
ExpiresAt > 0 AndAlso ExpiresAt > GetUnixTimestampUtc() Then 'AccessToken 尚未过期 ExpiresAt > 0 AndAlso ExpiresAt > GetUnixTimestampUtc() AndAlso 'AccessToken 尚未过期
'https://github.com/Meloong-Git/PCL/issues/8638 Input.UserName = Settings.Get(Of String)("CacheMsV2Name") Then
'如果是程序刚启动时调用的登录,此时加载器的状态为 Waiting,GetLoginData 函数会返回不带 ProfileJson 的数据作为输入
If String.IsNullOrEmpty(Input.ProfileJson) Then
Input = PageLoginMsSkin.GetLoginData(True)
End If
Data.Output = New McLoginResult With { Data.Output = New McLoginResult With {
.AccessToken = Input.AccessToken, .Name = Input.UserName, .Type = "Microsoft",
.Name = Input.UserName, .AccessToken = Settings.Get(Of String)("CacheMsV2Access"),
.Uuid = Input.Uuid, .Uuid = Settings.Get(Of String)("CacheMsV2Uuid"),
.Type = "Microsoft", .ClientToken = Settings.Get(Of String)("CacheMsV2Uuid"),
.ClientToken = Input.Uuid, .ProfileJson = Settings.Get(Of String)("CacheMsV2ProfileJson")
.ProfileJson = Input.ProfileJson
} }
McLaunchLog("无需登录,AccessToken 尚未过期") McLaunchLog("无需登录,AccessToken 尚未过期")
GoTo SkipLogin GoTo SkipLogin
@@ -1018,16 +1012,18 @@ Retry:
Result = NetRequestByClientRetry("https://api.minecraftservices.com/authentication/login_with_xbox", HttpMethod.Post, Result = NetRequestByClientRetry("https://api.minecraftservices.com/authentication/login_with_xbox", HttpMethod.Post,
Content:=Request, ContentType:="application/json", RequireJson:=True) Content:=Request, ContentType:="application/json", RequireJson:=True)
Catch ex As HttpRequestCodeException Catch ex As HttpRequestCodeException
Select Case ex.StatusCode If ex.StatusCode = 429 Then
Case 429 Logger.Warn(ex, "微软登录第 4 步汇报 429")
Logger.Warn(ex, "微软登录第 4 步汇报 429") Throw New Exception("$登录尝试太过频繁,请等待几分钟后再试!")
Throw New Exception("$登录尝试太过频繁,请等待几分钟后再试!") ElseIf ex.StatusCode = HttpStatusCode.Forbidden Then
Case HttpStatusCode.Forbidden Logger.Warn(ex, "微软登录第 4 步汇报 403")
Logger.Warn(ex, "微软登录第 4 步汇报 403") Throw New Exception("$当前 IP 的登录尝试异常。" & vbCrLf & "如果你使用了 VPN 或加速器,请把它们关掉或更换节点后再试!")
Throw New Exception("$当前 IP 的登录尝试异常。" & vbCrLf & "如果你使用了 VPN 或加速器,请把它们关掉或更换节点后再试!") ElseIf ex.Response?.Contains("ACCOUNT_SUSPENDED") Then '#8655
Case Else MyMsgBox("该账号似乎已被微软封禁,无法登录。", "登录失败", "我知道了", IsWarn:=True)
Throw Throw New Exception("$$")
End Select Else
Throw
End If
End Try End Try
Dim ResultJson As JObject = GetJson(Result) Dim ResultJson As JObject = GetJson(Result)
@@ -1152,7 +1148,7 @@ Retry:
Return Uuid Return Uuid
End Function End Function
Public Function McLoginLegacyUuid(Name As String) Public Function McLoginLegacyUuid(Name As String)
Dim FullUuid As String = Name.Length.ToString("X").EnsureLength("0", 16) & GetHash(Name).ToString("X").EnsureLength("0", 16) Dim FullUuid As String = Name.Length.ToString("X").EnsureLength("0", 16) & Name.GetStableHashCode().ToString("X").EnsureLength("0", 16)
Return FullUuid.Substring(0, 12) & "3" & FullUuid.Substring(13, 3) & "9" & FullUuid.Substring(17, 15) Return FullUuid.Substring(0, 12) & "3" & FullUuid.Substring(13, 3) & "9" & FullUuid.Substring(17, 15)
End Function End Function
@@ -1445,14 +1441,13 @@ NextInstance:
End If End If
'JLW 'JLW
'修复 Java 18- 在 Windows UTF-8 Beta 模式(非 GBK 编码)下命令行参数乱码的问题(JDK-8272352) '非 GBK 编码下命令行参数乱码的问题(JDK-8272352)
Dim UseJLW As Boolean = Dim UseJLW As Boolean =
Not Settings.Get(Of Boolean)("LaunchAdvanceDisableJLW") AndAlso Not Settings.Get(Of Boolean)("VersionAdvanceDisableJLW", McInstanceSelected) AndAlso Not Settings.Get(Of Boolean)("LaunchAdvanceDisableJLW") AndAlso Not Settings.Get(Of Boolean)("VersionAdvanceDisableJLW", McInstanceSelected) AndAlso
McLaunchJavaSelected.MajorVersion <= 18 AndAlso 'Java 19+ 已经修复了该 Bug
Not IsGBKEncoding AndAlso Not McFolderSelected.IsAsciiOnly() '仅在该环境下才会触发该 Bug Not IsGBKEncoding AndAlso Not McFolderSelected.IsAsciiOnly() '仅在该环境下才会触发该 Bug
If UseJLW AndAlso CustomArg.Contains("-javaagent") Then If UseJLW AndAlso CustomArg.Contains("-javaagent") Then
UseJLW = False UseJLW = False
McLaunchLog("由于使用自定义 javaagent,已禁用 JLW,这可能导致游戏崩溃!", LogLevel.Warn) McLaunchLog("由于使用了自定义 javaagent,已禁用 JLW,这可能导致游戏崩溃!", LogLevel.Warn)
End If End If
If UseJLW Then If UseJLW Then
If McLaunchJavaSelected.MajorVersion >= 9 Then If McLaunchJavaSelected.MajorVersion >= 9 Then
@@ -1286,7 +1286,7 @@ ExitDataLoad:
GoTo OnLoaded GoTo OnLoaded
End If End If
'有可用版本 '有可用版本
Dim FolderListCheck As Integer = GetHash(Versions.MCINSTANCE_CACHE_VERSION & "#" & FolderList.Join("#"c)) Mod (Integer.MaxValue - 1) '根据文件夹名列表生成辨识码 Dim FolderListCheck As Integer = (Versions.MCINSTANCE_CACHE_VERSION & "#" & FolderList.Join("#"c)).GetStableHashCode() Mod (Integer.MaxValue - 1) '根据文件夹名列表生成辨识码
If Not McInstanceListForceRefresh AndAlso Val(ReadIni(PathMc & "PCL.ini", "InstanceCache")) = FolderListCheck Then If Not McInstanceListForceRefresh AndAlso Val(ReadIni(PathMc & "PCL.ini", "InstanceCache")) = FolderListCheck Then
'可以使用缓存 '可以使用缓存
Dim Result = InitMcInstanceListWithCache(PathMc) Dim Result = InitMcInstanceListWithCache(PathMc)
@@ -1747,7 +1747,7 @@ OnLoaded:
''' </summary> ''' </summary>
Public Function McSkinDownload(Address As String) As String Public Function McSkinDownload(Address As String) As String
Dim SkinName As String = PathUtils.GetLastPart(Address) Dim SkinName As String = PathUtils.GetLastPart(Address)
Dim FileAddress As String = PathTemp & "Cache\Skin\" & GetHash(Address) & ".png" Dim FileAddress As String = PathTemp & "Cache\Skin\" & Address.GetStableHashCode() & ".png"
SyncLock McSkinDownloadLock SyncLock McSkinDownloadLock
If Not FileUtils.Exists(FileAddress) Then If Not FileUtils.Exists(FileAddress) Then
NetDownloadByClient(Address, FileAddress & ".PCLDownloading") NetDownloadByClient(Address, FileAddress & ".PCLDownloading")
@@ -162,11 +162,11 @@
'Else 'Else
If State = MinecraftState.Loading Then If State = MinecraftState.Loading Then
'窗口未出现 '窗口未出现
WatcherLog("Minecraft 尚未加载完成,可能已崩溃") WatcherLog("Minecraft 尚未加载完成,可能已崩溃", LogLevel.Error)
Crashed() Crashed()
ElseIf GameProcess.ExitCode <> 0 AndAlso State = MinecraftState.Running AndAlso Instance.ReleaseTime.Year >= 2012 Then ElseIf GameProcess.ExitCode <> 0 AndAlso State = MinecraftState.Running AndAlso Instance.ReleaseTime.Year >= 2012 Then
'返回值不为 0 且未结束 '返回值不为 0 且未结束
WatcherLog("Minecraft 返回值异常,可能已崩溃") WatcherLog("Minecraft 返回值异常,可能已崩溃", LogLevel.Error)
Crashed() Crashed()
ElseIf State <> MinecraftState.Crashed Then ElseIf State <> MinecraftState.Crashed Then
'正常关闭 '正常关闭
@@ -215,15 +215,15 @@
ElseIf Text.Contains("Crash report saved to") OrElse Text.Contains("This crash report has been saved to:") Then ElseIf Text.Contains("Crash report saved to") OrElse Text.Contains("This crash report has been saved to:") Then
' Text.Contains("Minecraft ran into a problem! Report saved to:") Then ' Text.Contains("Minecraft ran into a problem! Report saved to:") Then
'Minecraft 崩溃,忽略 VanillaFix 'Minecraft 崩溃,忽略 VanillaFix
WatcherLog("识别为崩溃的 Log:" & Text) WatcherLog("识别为崩溃的 Log:" & Text, LogLevel.Error)
Crashed() Crashed()
ElseIf Text.Contains("Could not save crash report to") Then ElseIf Text.Contains("Could not save crash report to") Then
'Minecraft 崩溃,无法保存崩溃日志 'Minecraft 崩溃,无法保存崩溃日志
WatcherLog("识别为崩溃的 Log:" & Text) WatcherLog("识别为崩溃的 Log:" & Text, LogLevel.Error)
Crashed() Crashed()
ElseIf Text.Contains("/ERROR]: Unable to launch") OrElse Text.Contains("An exception was thrown, the game will display an error screen and halt.") Then ElseIf Text.Contains("/ERROR]: Unable to launch") OrElse Text.Contains("An exception was thrown, the game will display an error screen and halt.") Then
'Forge 崩溃 'Forge 崩溃
WatcherLog("识别为崩溃的 Log:" & Text) WatcherLog("识别为崩溃的 Log:" & Text, LogLevel.Error)
Crashed() Crashed()
'ElseIf Text.Contains("Shutdown failure!") Then 'ElseIf Text.Contains("Shutdown failure!") Then
' 'Minecraft 强行崩溃,由于点 X 强行关闭也会触发这句话,所以不可用 ' 'Minecraft 强行崩溃,由于点 X 强行关闭也会触发这句话,所以不可用
@@ -231,8 +231,8 @@
End If End If
End If End If
End Sub End Sub
Private Sub WatcherLog(Text As String) Private Sub WatcherLog(Text As String, Optional Level As LogLevel = LogLevel.Info)
McLaunchLog("[" & PID & "] " & Text) McLaunchLog("[" & PID & "] " & Text, Level)
End Sub End Sub
'进度更新 '进度更新
@@ -349,7 +349,7 @@
If State = MinecraftState.Crashed OrElse State = MinecraftState.Ended Then Return If State = MinecraftState.Crashed OrElse State = MinecraftState.Ended Then Return
State = MinecraftState.Crashed State = MinecraftState.Crashed
'崩溃分析 '崩溃分析
WatcherLog("Minecraft 已崩溃,将在 2 秒后开始崩溃分析") WatcherLog("Minecraft 已崩溃,将在 2 秒后开始崩溃分析", LogLevel.Error)
Hint("检测到 Minecraft 出现错误,错误分析已开始……", HintType.Red) Hint("检测到 Minecraft 出现错误,错误分析已开始……", HintType.Red)
FeedbackInfo() FeedbackInfo()
RunInNewThread( RunInNewThread(
+3 -2
View File
@@ -850,7 +850,8 @@ NextFile:
Text = Text.Replace("{path}", Replacer(PathUtils.CurrentFolder)) Text = Text.Replace("{path}", Replacer(PathUtils.CurrentFolder))
Text = Text.Replace("{path_with_name}", Replacer(PathExe)) Text = Text.Replace("{path_with_name}", Replacer(PathExe))
Text = Text.Replace("{path_temp}", Replacer(PathTemp)) Text = Text.Replace("{path_temp}", Replacer(PathTemp))
Text = Text.Replace("{pcl_md5}", Function() Replacer(HashUtils.ComputeFromFile(PathExe, HashUtils.HashMethod.Md5))) Text = Text.Replace("{pcl_md5}", Function() Replacer(CryptographyUtils.ComputeFileHash(PathExe, CryptographyUtils.HashMethod.Md5)))
Text = Text.Replace("{pcl_sha1}", Function() Replacer(CryptographyUtils.ComputeFileHash(PathExe, CryptographyUtils.HashMethod.Sha1)))
'时间 '时间
If ReplaceTime Then '在窗口标题中,时间会被后续动态替换,所以此时不应该替换 If ReplaceTime Then '在窗口标题中,时间会被后续动态替换,所以此时不应该替换
Text = Text.Replace("{date}", Replacer(Date.Now.ToString("yyyy'/'M'/'d"))) Text = Text.Replace("{date}", Replacer(Date.Now.ToString("yyyy'/'M'/'d")))
@@ -976,7 +977,7 @@ NextFile:
''' </summary> ''' </summary>
Public Sub FeedbackInfo() Public Sub FeedbackInfo()
On Error Resume Next On Error Resume Next
Logger.Info($"诊断信息:{vbCrLf}" & Logger.Warn($"诊断信息:{vbCrLf}" &
"操作系统:" & My.Computer.Info.OSFullName & "(32 位:" & Is32BitSystem & ")" & vbCrLf & "操作系统:" & My.Computer.Info.OSFullName & "(32 位:" & Is32BitSystem & ")" & vbCrLf &
"剩余内存:" & Int(My.Computer.Info.AvailablePhysicalMemory / 1024 / 1024) & " M / " & Int(My.Computer.Info.TotalPhysicalMemory / 1024 / 1024) & " M" & vbCrLf & "剩余内存:" & Int(My.Computer.Info.AvailablePhysicalMemory / 1024 / 1024) & " M / " & Int(My.Computer.Info.TotalPhysicalMemory / 1024 / 1024) & " M" & vbCrLf &
"DPI:" & DPI & "(" & Math.Round(DPI / 96, 2) * 100 & "%)" & vbCrLf & "DPI:" & DPI & "(" & Math.Round(DPI / 96, 2) * 100 & "%)" & vbCrLf &
@@ -1,7 +1,5 @@
'由于包含加解密等安全信息,本文件中的部分代码已被删除 '由于包含加解密等安全信息,本文件中的部分代码已被删除
Imports System.Security.Cryptography
Friend Module ModSecret Friend Module ModSecret
'标注 PCL 的不同分支,仅用于替换标记 '标注 PCL 的不同分支,仅用于替换标记
@@ -40,51 +38,6 @@ Friend Module ModSecret
#End Region #End Region
#Region "字符串加解密"
''' <summary>
''' 获取八位密钥。
''' </summary>
Private Function SecretKeyGet(Key As String) As String
Return "00000000"
End Function
''' <summary>
''' 加密字符串。
''' </summary>
Friend Function SecretEncrypt(SourceString As String, Optional Key As String = "") As String
Key = SecretKeyGet(Key)
Dim btKey As Byte() = Encoding.UTF8.GetBytes(Key)
Dim btIV As Byte() = Encoding.UTF8.GetBytes("87160295")
Dim des As New DESCryptoServiceProvider
Using MS As New MemoryStream
Dim inData As Byte() = Encoding.UTF8.GetBytes(SourceString)
Using cs As New CryptoStream(MS, des.CreateEncryptor(btKey, btIV), CryptoStreamMode.Write)
cs.Write(inData, 0, inData.Length)
cs.FlushFinalBlock()
Return Convert.ToBase64String(MS.ToArray())
End Using
End Using
End Function
''' <summary>
''' 解密字符串。
''' </summary>
Friend Function SecretDecrypt(SourceString As String, Optional Key As String = "") As String
Key = SecretKeyGet(Key)
Dim btKey As Byte() = Encoding.UTF8.GetBytes(Key)
Dim btIV As Byte() = Encoding.UTF8.GetBytes("87160295")
Dim des As New DESCryptoServiceProvider
Using MS As New MemoryStream
Dim inData As Byte() = Convert.FromBase64String(SourceString)
Using cs As New CryptoStream(MS, des.CreateDecryptor(btKey, btIV), CryptoStreamMode.Write)
cs.Write(inData, 0, inData.Length)
cs.FlushFinalBlock()
Return Encoding.UTF8.GetString(MS.ToArray())
End Using
End Using
End Function
#End Region
#Region "主题" #Region "主题"
Public Color1 As New MyColor(52, 61, 74) Public Color1 As New MyColor(52, 61, 74)
@@ -418,7 +418,7 @@ Finished:
Get Get
If _CurseForgeHash Is Nothing Then If _CurseForgeHash Is Nothing Then
'读取缓存 '读取缓存
Dim CacheKey As String = GetHash($"{EnabledFullName}-{File.LastWriteTime.ToLongTimeString}-{File.Length}-C") Dim CacheKey As String = $"{EnabledFullName}-{File.LastWriteTime.ToLongTimeString}-{File.Length}-C".GetStableHashCode()
Dim Cached As String = ReadIni(PathTemp & "Cache\ModHash.ini", CacheKey) Dim Cached As String = ReadIni(PathTemp & "Cache\ModHash.ini", CacheKey)
If Cached <> "" AndAlso Cached.RegexCheck("^\d+$") Then '#5062 If Cached <> "" AndAlso Cached.RegexCheck("^\d+$") Then '#5062
_CurseForgeHash = Cached _CurseForgeHash = Cached
@@ -473,14 +473,14 @@ Finished:
Get Get
If _ModrinthHash Is Nothing Then If _ModrinthHash Is Nothing Then
'读取缓存 '读取缓存
Dim CacheKey As String = GetHash($"{EnabledFullName}-{File.LastWriteTime.ToLongTimeString}-{File.Length}-M") Dim CacheKey As String = $"{EnabledFullName}-{File.LastWriteTime.ToLongTimeString}-{File.Length}-M".GetStableHashCode()
Dim Cached As String = ReadIni(PathTemp & "Cache\ModHash.ini", CacheKey) Dim Cached As String = ReadIni(PathTemp & "Cache\ModHash.ini", CacheKey)
If Cached <> "" Then If Cached <> "" Then
_ModrinthHash = Cached _ModrinthHash = Cached
Return _ModrinthHash Return _ModrinthHash
End If End If
'计算 SHA1 '计算 SHA1
_ModrinthHash = HashUtils.ComputeFromFile(File.FullName, HashUtils.HashMethod.Sha1) _ModrinthHash = CryptographyUtils.ComputeFileHash(File.FullName, CryptographyUtils.HashMethod.Sha1)
'写入缓存 '写入缓存
WriteIni(PathTemp & "Cache\ModHash.ini", CacheKey, _ModrinthHash) WriteIni(PathTemp & "Cache\ModHash.ini", CacheKey, _ModrinthHash)
End If End If
@@ -189,6 +189,7 @@
#Region "中文搜索" #Region "中文搜索"
Dim RawSearchText As String = If(Request.SearchText, "").Trim Dim RawSearchText As String = If(Request.SearchText, "").Trim
RawSearchText = StrConv(RawSearchText, VbStrConv.SimplifiedChinese) '繁体转简体
RawSearchText = RawSearchText.Lower RawSearchText = RawSearchText.Lower
Logger.Info($"工程列表搜索原始文本:{RawSearchText}") Logger.Info($"工程列表搜索原始文本:{RawSearchText}")
@@ -51,6 +51,6 @@ Imports System.Runtime.InteropServices
' 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号 ' 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
' 方法是按如下所示使用“*” ' 方法是按如下所示使用“*”
<Assembly: AssemblyVersion("2.12.8.0")> <Assembly: AssemblyVersion("2.12.8.1")>
<Assembly: AssemblyFileVersion("2.12.8.0")> <Assembly: AssemblyFileVersion("2.12.8.1")>
<Assembly: NeutralResourcesLanguage("")> <Assembly: NeutralResourcesLanguage("")>
@@ -3,7 +3,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:PCL;assembly=" xmlns:local="clr-namespace:PCL;assembly="
x:Name="PanBack" Height="44" x:Name="PanBack" Height="44"
RenderTransformOrigin="0.5,0.5" Background="{StaticResource ColorBrushSemiTransparent}" SnapsToDevicePixels="True" Cursor="Hand"> RenderTransformOrigin="0.5,0.5" Background="{StaticResource ColorBrushSemiTransparent}" SnapsToDevicePixels="True">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="6" /> <ColumnDefinition Width="6" />
<ColumnDefinition Width="34" /> <ColumnDefinition Width="34" />
@@ -222,6 +222,15 @@
<StackPanel Margin="30,0,0,0" x:Name="PanOptionsSaves" <StackPanel Margin="30,0,0,0" x:Name="PanOptionsSaves"
Visibility="{Binding Checked, ElementName=CheckOptionsSaves, Converter={StaticResource BooleanToVisibilityConverter}}"> Visibility="{Binding Checked, ElementName=CheckOptionsSaves, Converter={StaticResource BooleanToVisibilityConverter}}">
</StackPanel> </StackPanel>
<local:MyCheckBox>
<local:MyCheckBox.Tag>
<local:ExportOption
Title="协议"
Description="Licence 文件"
Rules="LICEN*"
DefaultChecked="True" />
</local:MyCheckBox.Tag>
</local:MyCheckBox>
<local:MyCheckBox> <local:MyCheckBox>
<local:MyCheckBox.Tag> <local:MyCheckBox.Tag>
<local:ExportOption <local:ExportOption
@@ -119,7 +119,7 @@ Public Class PageInstanceExport
If Rule.StartsWithF("!") Then Return False '只看正向规则 If Rule.StartsWithF("!") Then Return False '只看正向规则
'检查前两级 '检查前两级
Try Try
If AllEntries.Any(Function(Entry) Entry Like Rule) Then Return True If AllEntries.Any(Function(Entry) Entry.Lower Like Rule.Lower) Then Return True
Catch ex As Exception Catch ex As Exception
Logger.Error(ex, $"错误的规则:{Rule}", LogBehavior.Toast) Logger.Error(ex, $"错误的规则:{Rule}", LogBehavior.Toast)
Return False Return False
@@ -482,7 +482,7 @@ Public Class PageInstanceExport
Dim ShouldKeep As Boolean = False Dim ShouldKeep As Boolean = False
For Each Rule In AllRules For Each Rule In AllRules
Dim Revert = Rule.StartsWithF("!") Dim Revert = Rule.StartsWithF("!")
If RelativePath Like Rule.TrimStart("!") Then ShouldKeep = Not Revert If RelativePath.Lower Like Rule.TrimStart("!").Lower Then ShouldKeep = Not Revert
Next Next
If Not ShouldKeep Then Continue For If Not ShouldKeep Then Continue For
Dim TargetPath As String = OverridesFolder & RelativePath Dim TargetPath As String = OverridesFolder & RelativePath
@@ -641,7 +641,7 @@ Public Class PageInstanceExport
Dim ModFile As LocalResourceFile = Pair.Key Dim ModFile As LocalResourceFile = Pair.Key
Files.Add(New JObject From { Files.Add(New JObject From {
{"path", PathUtils.RemoveExtendedPrefix(ModFile.File.FullName).AfterFirst(OverridesFolder).Replace("\", "/")}, {"path", PathUtils.RemoveExtendedPrefix(ModFile.File.FullName).AfterFirst(OverridesFolder).Replace("\", "/")},
{"hashes", New JObject From {{"sha1", ModFile.ModrinthHash}, {"sha512", HashUtils.ComputeFromFile(ModFile.File.FullName, HashUtils.HashMethod.Sha512)}}}, {"hashes", New JObject From {{"sha1", ModFile.ModrinthHash}, {"sha512", CryptographyUtils.ComputeFileHash(ModFile.File.FullName, CryptographyUtils.HashMethod.Sha512)}}},
{"downloads", New JArray(Pair.Value.OrderBy(Function(u) u.Contains("modrinth.com")))}, '不优先选择 Modrinth {"downloads", New JArray(Pair.Value.OrderBy(Function(u) u.Contains("modrinth.com")))}, '不优先选择 Modrinth
{"fileSize", ModFile.File.Length} {"fileSize", ModFile.File.Length}
}) })
@@ -483,7 +483,7 @@ Install:
If FileUtils.Exists(NewPath) Then If FileUtils.Exists(NewPath) Then
If FileUtils.Exists(ModEntity.File.FullName) Then If FileUtils.Exists(ModEntity.File.FullName) Then
'同时存在两个名称的 Mod '同时存在两个名称的 Mod
If HashUtils.ComputeFromFile(ModEntity.File.FullName, HashUtils.HashMethod.Md5) <> HashUtils.ComputeFromFile(NewPath, HashUtils.HashMethod.Md5) Then If CryptographyUtils.ComputeFileHash(ModEntity.File.FullName) <> CryptographyUtils.ComputeFileHash(NewPath) Then
MyMsgBox($"目前同时存在启用和禁用的两个 Mod 文件:{vbCrLf} - {PathUtils.GetLastPart(NewPath)}{vbCrLf} - {ModEntity.File.Name}{vbCrLf}{vbCrLf}注意,这两个文件的内容并不相同。{vbCrLf}在手动删除或重命名其中一个文件后,才能继续操作。", "存在文件冲突") MyMsgBox($"目前同时存在启用和禁用的两个 Mod 文件:{vbCrLf} - {PathUtils.GetLastPart(NewPath)}{vbCrLf} - {ModEntity.File.Name}{vbCrLf}{vbCrLf}注意,这两个文件的内容并不相同。{vbCrLf}在手动删除或重命名其中一个文件后,才能继续操作。", "存在文件冲突")
Continue For Continue For
End If End If
@@ -608,8 +608,8 @@ Install:
Next Next
For Each Entry As KeyValuePair(Of String, String) In FileCopyList For Each Entry As KeyValuePair(Of String, String) In FileCopyList
If FileUtils.Exists(Entry.Value) Then If FileUtils.Exists(Entry.Value) Then
FileUtils.Delete(Entry.Value, True)
Logger.Warn($"更新后的 Mod 文件已存在,将会把它放入回收站:{Entry.Value}") Logger.Warn($"更新后的 Mod 文件已存在,将会把它放入回收站:{Entry.Value}")
FileUtils.Delete(Entry.Value, True)
End If End If
If DirectoryUtils.Exists(PathUtils.RemoveLastPart(Entry.Value)) Then If DirectoryUtils.Exists(PathUtils.RemoveLastPart(Entry.Value)) Then
FileUtils.Move(Entry.Key, Entry.Value) FileUtils.Move(Entry.Key, Entry.Value)
@@ -723,18 +723,10 @@ Install:
End If End If
'显示结果提示 '显示结果提示
If Not IsSuccessful Then Return If Not IsSuccessful Then Return
If IsShiftPressed Then If ModList.IsSingle Then
If ModList.IsSingle Then Hint($"已删除 {ModList.Single.File.Name}!", HintType.Green)
Hint($"已彻底删除 {ModList.Single.File.Name}!", HintType.Green)
Else
Hint($"已彻底删除 {ModList.Count} 个文件!", HintType.Green)
End If
Else Else
If ModList.IsSingle Then Hint($"已删除 {ModList.Count} 个文件!", HintType.Green)
Hint($"已将 {ModList.Single.File.Name} 删除到回收站!", HintType.Green)
Else
Hint($"已将 {ModList.Count} 个文件删除到回收站!", HintType.Green)
End If
End If End If
Catch ex As OperationCanceledException Catch ex As OperationCanceledException
Logger.Warn(ex, "删除 Mod 被主动取消") Logger.Warn(ex, "删除 Mod 被主动取消")
@@ -149,7 +149,7 @@
RunInThread( RunInThread(
Sub() Sub()
Try Try
Hint("正在刷新头像……") Hint("正在刷新皮肤……")
'清空缓存 '清空缓存
Logger.Info("正在清空皮肤缓存") Logger.Info("正在清空皮肤缓存")
If DirectoryUtils.Exists(PathTemp & "Cache\Skin") Then DirectoryUtils.Delete(PathTemp & "Cache\Skin") If DirectoryUtils.Exists(PathTemp & "Cache\Skin") Then DirectoryUtils.Delete(PathTemp & "Cache\Skin")
@@ -162,7 +162,7 @@
For Each SkinLoader In If(sender IsNot Nothing, {sender}, {PageLaunchLeft.SkinLegacy, PageLaunchLeft.SkinMs}) For Each SkinLoader In If(sender IsNot Nothing, {sender}, {PageLaunchLeft.SkinLegacy, PageLaunchLeft.SkinMs})
SkinLoader.WaitForExit(IsForceRestart:=True) SkinLoader.WaitForExit(IsForceRestart:=True)
Next Next
Hint("已刷新头像!", HintType.Green) Hint("已刷新皮肤!", HintType.Green)
Catch ex As Exception Catch ex As Exception
Logger.Error(ex, "刷新皮肤缓存失败", LogBehavior.Alert) Logger.Error(ex, "刷新皮肤缓存失败", LogBehavior.Alert)
End Try End Try
@@ -216,13 +216,13 @@
Hint("登录失败,无法更改披风!", HintType.Red) Hint("登录失败,无法更改披风!", HintType.Red)
Return Return
End If End If
Hint("正在获取披风列表,请稍候……") If McLoginMsLoader.State <> LoadState.Finished Then Hint("正在获取披风列表,请稍候……")
IsChanging = True IsChanging = True
'开始实际获取 '开始实际获取
RunInNewThread( RunInNewThread(
Sub() Sub()
Try
Retry: Retry:
Try
'获取登录信息 '获取登录信息
If McLoginMsLoader.State <> LoadState.Finished Then McLoginMsLoader.WaitForExit(PageLoginMsSkin.GetLoginData()) If McLoginMsLoader.State <> LoadState.Finished Then McLoginMsLoader.WaitForExit(PageLoginMsSkin.GetLoginData())
If McLoginMsLoader.State <> LoadState.Finished Then If McLoginMsLoader.State <> LoadState.Finished Then
@@ -256,7 +256,7 @@ Retry:
Next Next
SelectedIndex = MyMsgBoxSelect(SelectionControl, "选择披风", "确定", "取消") SelectedIndex = MyMsgBoxSelect(SelectionControl, "选择披风", "确定", "取消")
Catch ex As Exception Catch ex As Exception
Logger.Error(ex, "获取玩家披风列表失败") Logger.Error(ex, "获取玩家皮肤列表失败")
End Try End Try
End Sub) End Sub)
If SelectedIndex Is Nothing Then Return If SelectedIndex Is Nothing Then Return
@@ -279,7 +279,29 @@ Retry:
McLoginMsLoader.Output.ProfileJson = SkinData.ToString() McLoginMsLoader.Output.ProfileJson = SkinData.ToString()
End If End If
Catch ex As Exception Catch ex As Exception
Logger.Error(ex, "更改披风失败", LogBehavior.Toast) If TypeOf ex Is HttpRequestCodeException Then
Dim requestException As HttpRequestCodeException = CType(ex, HttpRequestCodeException)
Select Case requestException.StatusCode
Case HttpStatusCode.BadRequest
Logger.Warn(ex, "更改披风时遭遇 400 错误")
If requestException.Response?.Contains("""error""") Then
Hint("更改披风失败:" & GetJson(requestException.Response)("error").ToString, HintType.Red)
Return
ElseIf requestException.Response?.Contains("""errorMessage""") Then
Hint("更改披风失败:" & GetJson(requestException.Response)("errorMessage").ToString, HintType.Red)
Return
End If
Case HttpStatusCode.Unauthorized
Logger.Warn(ex, "更改披风时遭遇 401 错误")
Hint("正在重新登录,将在登录后自动更改披风……")
McLoginMsLoader.Start(PageLoginMsSkin.GetLoginData(), IsForceRestart:=True)
GoTo Retry
End Select
ElseIf ex.IsBadNetwork Then
Hint("更改披风失败:连接 Mojang 服务器超时,请稍后再试,或使用 VPN 改善网络环境", HintType.Red)
Else
Logger.Error(ex, "更改披风失败", LogBehavior.Toast)
End If
Finally Finally
IsChanging = False IsChanging = False
End Try End Try
@@ -170,7 +170,7 @@ Public Class PageLaunchRight
Settings.Set("CacheSavedPageVersion", Version) Settings.Set("CacheSavedPageVersion", Version)
FileUtils.Write(PathTemp & "Cache\Custom.xaml", FileContent) FileUtils.Write(PathTemp & "Cache\Custom.xaml", FileContent)
'若内容变更则要求刷新 '若内容变更则要求刷新
If LoadedContentHash <> FileContent.GetHashCode() AndAlso ShouldRefresh Then Refresh() If LoadedContentHash <> FileContent.GetStableHashCode() AndAlso ShouldRefresh Then Refresh()
Catch ex As Exception Catch ex As Exception
Logger.Error(ex, $"下载主页失败({Address})", If(ModeDebug, LogBehavior.Alert, LogBehavior.Toast)) Logger.Error(ex, $"下载主页失败({Address})", If(ModeDebug, LogBehavior.Alert, LogBehavior.Toast))
End Try End Try
@@ -196,7 +196,7 @@ Public Class PageLaunchRight
''' 清空主页缓存信息。 ''' 清空主页缓存信息。
''' </summary> ''' </summary>
Private Sub ClearCache() Private Sub ClearCache()
LoadedContentHash = -1 LoadedContentHash = Nothing
OnlineLoader.Input = ("", True) OnlineLoader.Input = ("", True)
Settings.Set("CacheSavedPageUrl", "") Settings.Set("CacheSavedPageUrl", "")
Settings.Set("CacheSavedPageVersion", "") Settings.Set("CacheSavedPageVersion", "")
@@ -211,7 +211,7 @@ Public Class PageLaunchRight
Try Try
SyncLock LoadContentLock SyncLock LoadContentLock
'如果加载目标内容一致则不加载 '如果加载目标内容一致则不加载
Dim Hash = If(Content, "").GetHashCode() Dim Hash = If(Content, "").GetStableHashCode()
If Hash = LoadedContentHash Then Return If Hash = LoadedContentHash Then Return
LoadedContentHash = Hash LoadedContentHash = Hash
'实际加载内容 '实际加载内容
@@ -261,7 +261,7 @@ Public Class PageLaunchRight
OnLoadContentFailed(e.Exception) OnLoadContentFailed(e.Exception)
End Sub End Sub
Private LoadedContentHash As Integer = -1 Private LoadedContentHash As ULong? = Nothing
Private LoadContentLock As New Object Private LoadContentLock As New Object
#End Region #End Region
@@ -23,11 +23,11 @@
<local:MyIconButton.ContextMenu> <local:MyIconButton.ContextMenu>
<ContextMenu Closed="HidePanel" HorizontalOffset="10" VerticalOffset="18"> <ContextMenu Closed="HidePanel" HorizontalOffset="10" VerticalOffset="18">
<local:MyMenuItem Click="BtnSkinEdit_Click" Header="修改皮肤"/> <local:MyMenuItem Click="BtnSkinEdit_Click" Header="修改皮肤"/>
<local:MyMenuItem Click="BtnSkinRefresh_Click" Header="刷新皮肤"/>
<local:MyMenuItem Click="BtnSkinSave_Click" Header="保存皮肤文件"/> <local:MyMenuItem Click="BtnSkinSave_Click" Header="保存皮肤文件"/>
<Separator /> <Separator />
<local:MyMenuItem Click="BtnSkinCape_Click" Header="修改披风"/> <local:MyMenuItem Click="BtnSkinCape_Click" Header="修改披风"/>
<Separator /> <local:MyMenuItem Click="BtnSkinCapeRefresh_Click" Header="刷新披风列表"/>
<local:MyMenuItem Click="BtnSkinRefresh_Click" Header="刷新"/>
</ContextMenu> </ContextMenu>
</local:MyIconButton.ContextMenu> </local:MyIconButton.ContextMenu>
</local:MyIconButton> </local:MyIconButton>
@@ -18,8 +18,8 @@
''' <summary> ''' <summary>
''' 获取当前页面的登录信息。 ''' 获取当前页面的登录信息。
''' </summary> ''' </summary>
Public Shared Function GetLoginData(Optional IgnoreState As Boolean = False) As McLoginMs Public Shared Function GetLoginData() As McLoginMs
If IgnoreState OrElse McLoginMsLoader.State = LoadState.Finished Then If McLoginMsLoader.State = LoadState.Finished Then
Return New McLoginMs With {.OAuthRefreshToken = Settings.Get(Of String)("CacheMsV2OAuthRefresh"), .UserName = Settings.Get(Of String)("CacheMsV2Name"), .AccessToken = Settings.Get(Of String)("CacheMsV2Access"), .Uuid = Settings.Get(Of String)("CacheMsV2Uuid"), .ProfileJson = Settings.Get(Of String)("CacheMsV2ProfileJson")} Return New McLoginMs With {.OAuthRefreshToken = Settings.Get(Of String)("CacheMsV2OAuthRefresh"), .UserName = Settings.Get(Of String)("CacheMsV2Name"), .AccessToken = Settings.Get(Of String)("CacheMsV2Access"), .Uuid = Settings.Get(Of String)("CacheMsV2Uuid"), .ProfileJson = Settings.Get(Of String)("CacheMsV2ProfileJson")}
Else Else
Return New McLoginMs With {.OAuthRefreshToken = Settings.Get(Of String)("CacheMsV2OAuthRefresh"), .UserName = Settings.Get(Of String)("CacheMsV2Name")} Return New McLoginMs With {.OAuthRefreshToken = Settings.Get(Of String)("CacheMsV2OAuthRefresh"), .UserName = Settings.Get(Of String)("CacheMsV2Name")}
@@ -105,9 +105,6 @@ Retry:
Hint("正在重新登录,将在登录后自动更改皮肤……") Hint("正在重新登录,将在登录后自动更改皮肤……")
McLoginMsLoader.Start(GetLoginData(), IsForceRestart:=True) McLoginMsLoader.Start(GetLoginData(), IsForceRestart:=True)
GoTo Retry GoTo Retry
ElseIf Result.Contains("""error""") Then
Hint("更改皮肤失败:" & GetJson(Result)("error").ToString, HintType.Red)
Return
End If End If
'获取新皮肤地址 '获取新皮肤地址
Logger.Info($"皮肤修改返回值:{vbCrLf}{Result}") Logger.Info($"皮肤修改返回值:{vbCrLf}{Result}")
@@ -121,13 +118,26 @@ Retry:
Next Next
Throw New Exception("未知错误(" & Result & ")") Throw New Exception("未知错误(" & Result & ")")
Catch ex As Exception Catch ex As Exception
If ex.IsBadNetwork Then If TypeOf ex Is HttpRequestCodeException Then
Hint("更改皮肤失败:连接皮肤服务器超时,请稍后再试,或使用 VPN 改善网络环境", HintType.Red) Dim requestException As HttpRequestCodeException = CType(ex, HttpRequestCodeException)
ElseIf TypeOf ex Is HttpRequestCodeException AndAlso CType(ex, HttpRequestCodeException).StatusCode = HttpStatusCode.Unauthorized Then Select Case requestException.StatusCode
Logger.Warn(ex, "更改皮肤时遭遇 401 错误") Case HttpStatusCode.BadRequest
Hint("正在重新登录,将在登录后自动更改皮肤……") Logger.Warn(ex, "更改皮肤时遭遇 400 错误")
McLoginMsLoader.Start(GetLoginData(), IsForceRestart:=True) If requestException.Response?.Contains("""error""") Then
GoTo Retry Hint("更改皮肤失败:" & GetJson(requestException.Response)("error").ToString, HintType.Red)
Return
ElseIf requestException.Response?.Contains("""errorMessage""") Then
Hint("更改皮肤失败:" & GetJson(requestException.Response)("errorMessage").ToString, HintType.Red)
Return
End If
Case HttpStatusCode.Unauthorized
Logger.Warn(ex, "更改皮肤时遭遇 401 错误")
Hint("正在重新登录,将在登录后自动更改皮肤……")
McLoginMsLoader.Start(GetLoginData(), IsForceRestart:=True)
GoTo Retry
End Select
ElseIf ex.IsBadNetwork Then
Hint("更改皮肤失败:连接 Mojang 服务器超时,请稍后再试,或使用 VPN 改善网络环境", HintType.Red)
Else Else
Logger.Error(ex, "更改皮肤失败", LogBehavior.Toast) Logger.Error(ex, "更改皮肤失败", LogBehavior.Toast)
End If End If
@@ -151,6 +161,24 @@ Retry:
Skin.BtnSkinCape_Click() Skin.BtnSkinCape_Click()
End Sub End Sub
'刷新披风
Public Sub BtnSkinCapeRefresh_Click(sender As Object, e As RoutedEventArgs)
RunInThread(
Sub()
Try
Hint("正在刷新披风列表……")
If McLaunchLoader.State = LoadState.Loading Then
McLoginMsLoader.WaitForExit()
Else
McLoginMsLoader.WaitForExit(GetLoginData(), IsForceRestart:=True)
End If
Hint("已刷新披风列表!", HintType.Green)
Catch ex As Exception
Logger.Error(ex, "刷新披风列表失败", LogBehavior.Toast)
End Try
End Sub)
End Sub
#End Region #End Region
End Class End Class
@@ -522,7 +522,7 @@ Public Class PageLinkMain
'获取启动参数 '获取启动参数
Dim Arguments As String = ServerConfig("Link")("Argument") Dim Arguments As String = ServerConfig("Link")("Argument")
Arguments += $" --network-name={NetworkName} --network-secret={NetworkSecret} --listeners {ListenersPort} --rpc-portal {RPCPort} --private-mode true" Arguments += $" --network-name={NetworkName} --network-secret={NetworkSecret} --listeners {ListenersPort} --rpc-portal {RPCPort} --private-mode true"
Dim HostName = If(IsServerSide, "Server-", "Client-") & Math.Abs(Identify.GetHashCode).ConvertRadix(36) Dim HostName = If(IsServerSide, "Server-", "Client-") & Identify.GetStableHashCode().ConvertRadix(36).TrimStart("-"c).EnsureLength("0", 6)
If IsServerSide Then If IsServerSide Then
Arguments += $" -i 10.114.114.114 --hostname={HostName} --tcp-whitelist={ServerPort} --udp-whitelist={ServerPort}" Arguments += $" -i 10.114.114.114 --hostname={HostName} --tcp-whitelist={ServerPort} --udp-whitelist={ServerPort}"
Else Else
@@ -123,6 +123,7 @@
<TextBlock Margin="0,1.5,6,0" Text="IT" /> <TextBlock Margin="0,1.5,6,0" Text="IT" />
<TextBlock Margin="0,1.5,6,0" Text="卓" /> <TextBlock Margin="0,1.5,6,0" Text="卓" />
<TextBlock Margin="0,1.5,6,0" Text="玖" /> <TextBlock Margin="0,1.5,6,0" Text="玖" />
<TextBlock Margin="0,1.5,6,0" Text="自" />
<TextBlock Margin="0,1.5,6,0" Text="辰" /> <TextBlock Margin="0,1.5,6,0" Text="辰" />
<TextBlock Margin="0,1.5,6,0" Text="顺" /> <TextBlock Margin="0,1.5,6,0" Text="顺" />
<TextBlock Margin="0,1.5,6,0" Text="茧" /> <TextBlock Margin="0,1.5,6,0" Text="茧" />
@@ -150,6 +151,8 @@
<TextBlock Margin="0,1.5,6,0" Text="柒ᝰ" /> <TextBlock Margin="0,1.5,6,0" Text="柒ᝰ" />
<TextBlock Margin="0,1.5,6,0" Text="廖" /> <TextBlock Margin="0,1.5,6,0" Text="廖" />
<TextBlock Margin="0,1.5,6,0" Text="烨" /> <TextBlock Margin="0,1.5,6,0" Text="烨" />
<TextBlock Margin="0,1.5,6,0" Text="煌" />
<TextBlock Margin="0,1.5,6,0" Text="雲" />
<TextBlock Margin="0,1.5,6,0" Text="yu" /> <TextBlock Margin="0,1.5,6,0" Text="yu" />
<TextBlock Margin="0,1.5,6,0" Text="💬" /> <TextBlock Margin="0,1.5,6,0" Text="💬" />
<TextBlock Margin="0,1.5,6,0" Text="7%" /> <TextBlock Margin="0,1.5,6,0" Text="7%" />
@@ -164,7 +167,9 @@
<TextBlock Margin="0,1.5,6,0" Text="PFF" /> <TextBlock Margin="0,1.5,6,0" Text="PFF" />
<TextBlock Margin="0,1.5,6,0" Text="ZYL" /> <TextBlock Margin="0,1.5,6,0" Text="ZYL" />
<TextBlock Margin="0,1.5,6,0" Text="LSP" /> <TextBlock Margin="0,1.5,6,0" Text="LSP" />
<TextBlock Margin="0,1.5,6,0" Text="110" />
<TextBlock Margin="0,1.5,6,0" Text="Van" /> <TextBlock Margin="0,1.5,6,0" Text="Van" />
<TextBlock Margin="0,1.5,6,0" Text="TKK" />
<TextBlock Margin="0,1.5,6,0" Text="hhh" /> <TextBlock Margin="0,1.5,6,0" Text="hhh" />
<TextBlock Margin="0,1.5,6,0" Text="bbb" /> <TextBlock Margin="0,1.5,6,0" Text="bbb" />
<TextBlock Margin="0,1.5,6,0" Text="阿宅" /> <TextBlock Margin="0,1.5,6,0" Text="阿宅" />
@@ -179,6 +184,7 @@
<TextBlock Margin="0,1.5,6,0" Text="沐清" /> <TextBlock Margin="0,1.5,6,0" Text="沐清" />
<TextBlock Margin="0,1.5,6,0" Text="阳仔" /> <TextBlock Margin="0,1.5,6,0" Text="阳仔" />
<TextBlock Margin="0,1.5,6,0" Text="吸管" /> <TextBlock Margin="0,1.5,6,0" Text="吸管" />
<TextBlock Margin="0,1.5,6,0" Text="灭宇" />
<TextBlock Margin="0,1.5,6,0" Text="冰块" /> <TextBlock Margin="0,1.5,6,0" Text="冰块" />
<TextBlock Margin="0,1.5,6,0" Text="莫林" /> <TextBlock Margin="0,1.5,6,0" Text="莫林" />
<TextBlock Margin="0,1.5,6,0" Text="Gun" /> <TextBlock Margin="0,1.5,6,0" Text="Gun" />
@@ -198,6 +204,7 @@
<TextBlock Margin="0,1.5,6,0" Text="白芷" /> <TextBlock Margin="0,1.5,6,0" Text="白芷" />
<TextBlock Margin="0,1.5,6,0" Text="汤圆" /> <TextBlock Margin="0,1.5,6,0" Text="汤圆" />
<TextBlock Margin="0,1.5,6,0" Text="黑猫" /> <TextBlock Margin="0,1.5,6,0" Text="黑猫" />
<TextBlock Margin="0,1.5,6,0" Text="言慎" />
<TextBlock Margin="0,1.5,6,0" Text="柠檬" /> <TextBlock Margin="0,1.5,6,0" Text="柠檬" />
<TextBlock Margin="0,1.5,6,0" Text="愚者" /> <TextBlock Margin="0,1.5,6,0" Text="愚者" />
<TextBlock Margin="0,1.5,6,0" Text="久蛊" /> <TextBlock Margin="0,1.5,6,0" Text="久蛊" />
@@ -236,25 +243,40 @@
<TextBlock Margin="0,1.5,6,0" Text="玄狐" /> <TextBlock Margin="0,1.5,6,0" Text="玄狐" />
<TextBlock Margin="0,1.5,6,0" Text="tusk" /> <TextBlock Margin="0,1.5,6,0" Text="tusk" />
<TextBlock Margin="0,1.5,6,0" Text="星甲" /> <TextBlock Margin="0,1.5,6,0" Text="星甲" />
<TextBlock Margin="0,1.5,6,0" Text="亚心" />
<TextBlock Margin="0,1.5,6,0" Text="千羽" />
<TextBlock Margin="0,1.5,6,0" Text="阿勺" />
<TextBlock Margin="0,1.5,6,0" Text="小鱼" />
<TextBlock Margin="0,1.5,6,0" Text="白杨" />
<TextBlock Margin="0,1.5,6,0" Text="蜼鸣" />
<TextBlock Margin="0,1.5,6,0" Text="皮皮" />
<TextBlock Margin="0,1.5,6,0" Text="YmY" /> <TextBlock Margin="0,1.5,6,0" Text="YmY" />
<TextBlock Margin="0,1.5,6,0" Text="Enss" />
<TextBlock Margin="0,1.5,6,0" Text="ZHH" /> <TextBlock Margin="0,1.5,6,0" Text="ZHH" />
<TextBlock Margin="0,1.5,6,0" Text="z666" />
<TextBlock Margin="0,1.5,6,0" Text="GUO" /> <TextBlock Margin="0,1.5,6,0" Text="GUO" />
<TextBlock Margin="0,1.5,6,0" Text="gino" /> <TextBlock Margin="0,1.5,6,0" Text="gino" />
<TextBlock Margin="0,1.5,6,0" Text="luoo" /> <TextBlock Margin="0,1.5,6,0" Text="luoo" />
<TextBlock Margin="0,1.5,6,0" Text="9787" /> <TextBlock Margin="0,1.5,6,0" Text="9787" />
<TextBlock Margin="0,1.5,6,0" Text="Ilyen" /> <TextBlock Margin="0,1.5,6,0" Text="Ilyen" />
<TextBlock Margin="0,1.5,6,0" Text="1950" /> <TextBlock Margin="0,1.5,6,0" Text="1950" />
<TextBlock Margin="0,1.5,6,0" Text="QAQ" />
<TextBlock Margin="0,1.5,6,0" Text="AL76" /> <TextBlock Margin="0,1.5,6,0" Text="AL76" />
<TextBlock Margin="0,1.5,6,0" Text="WAR" /> <TextBlock Margin="0,1.5,6,0" Text="WAR" />
<TextBlock Margin="0,1.5,6,0" Text="yfble" />
<TextBlock Margin="0,1.5,6,0" Text="。_。" /> <TextBlock Margin="0,1.5,6,0" Text="。_。" />
<TextBlock Margin="0,1.5,6,0" Text="vbird" /> <TextBlock Margin="0,1.5,6,0" Text="vbird" />
<TextBlock Margin="0,1.5,6,0" Text="空调c" /> <TextBlock Margin="0,1.5,6,0" Text="空调c" />
<TextBlock Margin="0,1.5,6,0" Text="Brant" /> <TextBlock Margin="0,1.5,6,0" Text="Brant" />
<TextBlock Margin="0,1.5,6,0" Text="⁣    ​" /> <TextBlock Margin="0,1.5,6,0" Text="⁣    ​" />
<TextBlock Margin="0,1.5,6,0" Text="RKRK" /> <TextBlock Margin="0,1.5,6,0" Text="RKRK" />
<TextBlock Margin="0,1.5,6,0" Text="Neko" />
<TextBlock Margin="0,1.5,6,0" Text="verge" /> <TextBlock Margin="0,1.5,6,0" Text="verge" />
<TextBlock Margin="0,1.5,6,0" Text="ciel希" />
<TextBlock Margin="0,1.5,6,0" Text="Tarka" /> <TextBlock Margin="0,1.5,6,0" Text="Tarka" />
<TextBlock Margin="0,1.5,6,0" Text="Elysia" /> <TextBlock Margin="0,1.5,6,0" Text="Elysia" />
<TextBlock Margin="0,1.5,6,0" Text="onlye" />
<TextBlock Margin="0,1.5,6,0" Text="Spark" />
<TextBlock Margin="0,1.5,6,0" Text="Eiligo" /> <TextBlock Margin="0,1.5,6,0" Text="Eiligo" />
<TextBlock Margin="0,1.5,6,0" Text="友人A" /> <TextBlock Margin="0,1.5,6,0" Text="友人A" />
<TextBlock Margin="0,1.5,6,0" Text="jiagar" /> <TextBlock Margin="0,1.5,6,0" Text="jiagar" />
@@ -266,6 +288,7 @@
<TextBlock Margin="0,1.5,6,0" Text="ToTxT" /> <TextBlock Margin="0,1.5,6,0" Text="ToTxT" />
<TextBlock Margin="0,1.5,6,0" Text="HzzzT" /> <TextBlock Margin="0,1.5,6,0" Text="HzzzT" />
<TextBlock Margin="0,1.5,6,0" Text="EAger" /> <TextBlock Margin="0,1.5,6,0" Text="EAger" />
<TextBlock Margin="0,1.5,6,0" Text="fufulb" />
<TextBlock Margin="0,1.5,6,0" Text="ziqian" /> <TextBlock Margin="0,1.5,6,0" Text="ziqian" />
<TextBlock Margin="0,1.5,6,0" Text="kunsir" /> <TextBlock Margin="0,1.5,6,0" Text="kunsir" />
<TextBlock Margin="0,1.5,6,0" Text="LiarCT" /> <TextBlock Margin="0,1.5,6,0" Text="LiarCT" />
@@ -273,11 +296,15 @@
<TextBlock Margin="0,1.5,6,0" Text="Lloora" /> <TextBlock Margin="0,1.5,6,0" Text="Lloora" />
<TextBlock Margin="0,1.5,6,0" Text="咕咕柒" /> <TextBlock Margin="0,1.5,6,0" Text="咕咕柒" />
<TextBlock Margin="0,1.5,6,0" Text="xuque" /> <TextBlock Margin="0,1.5,6,0" Text="xuque" />
<TextBlock Margin="0,1.5,6,0" Text="绮晓络" />
<TextBlock Margin="0,1.5,6,0" Text="希希希" /> <TextBlock Margin="0,1.5,6,0" Text="希希希" />
<TextBlock Margin="0,1.5,6,0" Text="飞猪侠" /> <TextBlock Margin="0,1.5,6,0" Text="飞猪侠" />
<TextBlock Margin="0,1.5,6,0" Text="门东山" />
<TextBlock Margin="0,1.5,6,0" Text="流星陨" />
<TextBlock Margin="0,1.5,6,0" Text="狐猫喵" /> <TextBlock Margin="0,1.5,6,0" Text="狐猫喵" />
<TextBlock Margin="0,1.5,6,0" Text="祤之锌" /> <TextBlock Margin="0,1.5,6,0" Text="祤之锌" />
<TextBlock Margin="0,1.5,6,0" Text="柳贯一" /> <TextBlock Margin="0,1.5,6,0" Text="柳贯一" />
<TextBlock Margin="0,1.5,6,0" Text="汐月语" />
<TextBlock Margin="0,1.5,6,0" Text="徐炳文" /> <TextBlock Margin="0,1.5,6,0" Text="徐炳文" />
<TextBlock Margin="0,1.5,6,0" Text="大鱻鱼" /> <TextBlock Margin="0,1.5,6,0" Text="大鱻鱼" />
<TextBlock Margin="0,1.5,6,0" Text="颠修钩" /> <TextBlock Margin="0,1.5,6,0" Text="颠修钩" />
@@ -323,6 +350,17 @@
<TextBlock Margin="0,1.5,6,0" Text="陈两仪" /> <TextBlock Margin="0,1.5,6,0" Text="陈两仪" />
<TextBlock Margin="0,1.5,6,0" Text="叶辛梓" /> <TextBlock Margin="0,1.5,6,0" Text="叶辛梓" />
<TextBlock Margin="0,1.5,6,0" Text="窗锁昼" /> <TextBlock Margin="0,1.5,6,0" Text="窗锁昼" />
<TextBlock Margin="0,1.5,6,0" Text="泠晖晖" />
<TextBlock Margin="0,1.5,6,0" Text="悠悠子" />
<TextBlock Margin="0,1.5,6,0" Text="Kiheki" />
<TextBlock Margin="0,1.5,6,0" Text="顾冉竹" />
<TextBlock Margin="0,1.5,6,0" Text="小化哥" />
<TextBlock Margin="0,1.5,6,0" Text="27A03" />
<TextBlock Margin="0,1.5,6,0" Text="白逍遥" />
<TextBlock Margin="0,1.5,6,0" Text="陈钫浩" />
<TextBlock Margin="0,1.5,6,0" Text="滑稽君" />
<TextBlock Margin="0,1.5,6,0" Text="悔轮台" />
<TextBlock Margin="0,1.5,6,0" Text="懒洋洋" />
<TextBlock Margin="0,1.5,6,0" Text="ITMTX" /> <TextBlock Margin="0,1.5,6,0" Text="ITMTX" />
<TextBlock Margin="0,1.5,6,0" Text="SEKGY" /> <TextBlock Margin="0,1.5,6,0" Text="SEKGY" />
<TextBlock Margin="0,1.5,6,0" Text="111sui" /> <TextBlock Margin="0,1.5,6,0" Text="111sui" />
@@ -343,11 +381,13 @@
<TextBlock Margin="0,1.5,6,0" Text="cmly03" /> <TextBlock Margin="0,1.5,6,0" Text="cmly03" />
<TextBlock Margin="0,1.5,6,0" Text="jiduhui" /> <TextBlock Margin="0,1.5,6,0" Text="jiduhui" />
<TextBlock Margin="0,1.5,6,0" Text="424241" /> <TextBlock Margin="0,1.5,6,0" Text="424241" />
<TextBlock Margin="0,1.5,6,0" Text="Rig_kill" />
<TextBlock Margin="0,1.5,6,0" Text="XIruotE" /> <TextBlock Margin="0,1.5,6,0" Text="XIruotE" />
<TextBlock Margin="0,1.5,6,0" Text="Dr.Ayin" /> <TextBlock Margin="0,1.5,6,0" Text="Dr.Ayin" />
<TextBlock Margin="0,1.5,6,0" Text="onlong" /> <TextBlock Margin="0,1.5,6,0" Text="onlong" />
<TextBlock Margin="0,1.5,6,0" Text="zuozhe" /> <TextBlock Margin="0,1.5,6,0" Text="zuozhe" />
<TextBlock Margin="0,1.5,6,0" Text="Secular" /> <TextBlock Margin="0,1.5,6,0" Text="Secular" />
<TextBlock Margin="0,1.5,6,0" Text="之苏ing" />
<TextBlock Margin="0,1.5,6,0" Text="zxxxfan" /> <TextBlock Margin="0,1.5,6,0" Text="zxxxfan" />
<TextBlock Margin="0,1.5,6,0" Text="MY17IT" /> <TextBlock Margin="0,1.5,6,0" Text="MY17IT" />
<TextBlock Margin="0,1.5,6,0" Text="張 懙 李" /> <TextBlock Margin="0,1.5,6,0" Text="張 懙 李" />
@@ -367,6 +407,7 @@
<TextBlock Margin="0,1.5,6,0" Text="Flawless" /> <TextBlock Margin="0,1.5,6,0" Text="Flawless" />
<TextBlock Margin="0,1.5,6,0" Text="Buyihan" /> <TextBlock Margin="0,1.5,6,0" Text="Buyihan" />
<TextBlock Margin="0,1.5,6,0" Text="我不在线" /> <TextBlock Margin="0,1.5,6,0" Text="我不在线" />
<TextBlock Margin="0,1.5,6,0" Text="憨憨剑踏" />
<TextBlock Margin="0,1.5,6,0" Text="跳水的鱼" /> <TextBlock Margin="0,1.5,6,0" Text="跳水的鱼" />
<TextBlock Margin="0,1.5,6,0" Text="咸鱼雷音" /> <TextBlock Margin="0,1.5,6,0" Text="咸鱼雷音" />
<TextBlock Margin="0,1.5,6,0" Text="云映鹤影" /> <TextBlock Margin="0,1.5,6,0" Text="云映鹤影" />
@@ -374,12 +415,15 @@
<TextBlock Margin="0,1.5,6,0" Text="气息荒古" /> <TextBlock Margin="0,1.5,6,0" Text="气息荒古" />
<TextBlock Margin="0,1.5,6,0" Text="milenter" /> <TextBlock Margin="0,1.5,6,0" Text="milenter" />
<TextBlock Margin="0,1.5,6,0" Text="霜木翔凤" /> <TextBlock Margin="0,1.5,6,0" Text="霜木翔凤" />
<TextBlock Margin="0,1.5,6,0" Text="丨丨丨丨" />
<TextBlock Margin="0,1.5,6,0" Text="唐吉課德" /> <TextBlock Margin="0,1.5,6,0" Text="唐吉課德" />
<TextBlock Margin="0,1.5,6,0" Text="童年的梦" /> <TextBlock Margin="0,1.5,6,0" Text="童年的梦" />
<TextBlock Margin="0,1.5,6,0" Text="时灵风逝" /> <TextBlock Margin="0,1.5,6,0" Text="时灵风逝" />
<TextBlock Margin="0,1.5,6,0" Text="望月悠月" /> <TextBlock Margin="0,1.5,6,0" Text="望月悠月" />
<TextBlock Margin="0,1.5,6,0" Text="三金知日" />
<TextBlock Margin="0,1.5,6,0" Text="有事掘坟" /> <TextBlock Margin="0,1.5,6,0" Text="有事掘坟" />
<TextBlock Margin="0,1.5,6,0" Text="爱源神!" /> <TextBlock Margin="0,1.5,6,0" Text="爱源神!" />
<TextBlock Margin="0,1.5,6,0" Text="亮黑晚钟" />
<TextBlock Margin="0,1.5,6,0" Text="鸡鸡鸡鸡" /> <TextBlock Margin="0,1.5,6,0" Text="鸡鸡鸡鸡" />
<TextBlock Margin="0,1.5,6,0" Text="阿元颜月" /> <TextBlock Margin="0,1.5,6,0" Text="阿元颜月" />
<TextBlock Margin="0,1.5,6,0" Text="不想社交" /> <TextBlock Margin="0,1.5,6,0" Text="不想社交" />
@@ -390,6 +434,7 @@
<TextBlock Margin="0,1.5,6,0" Text="凌瑶雪莹" /> <TextBlock Margin="0,1.5,6,0" Text="凌瑶雪莹" />
<TextBlock Margin="0,1.5,6,0" Text="wswsing" /> <TextBlock Margin="0,1.5,6,0" Text="wswsing" />
<TextBlock Margin="0,1.5,6,0" Text="漆黑噤默" /> <TextBlock Margin="0,1.5,6,0" Text="漆黑噤默" />
<TextBlock Margin="0,1.5,6,0" Text="爆炎龙王" />
<TextBlock Margin="0,1.5,6,0" Text="云水莫伊" /> <TextBlock Margin="0,1.5,6,0" Text="云水莫伊" />
<TextBlock Margin="0,1.5,6,0" Text="孤星隐耀" /> <TextBlock Margin="0,1.5,6,0" Text="孤星隐耀" />
<TextBlock Margin="0,1.5,6,0" Text="蓝莓蛋糕" /> <TextBlock Margin="0,1.5,6,0" Text="蓝莓蛋糕" />
@@ -427,8 +472,14 @@
<TextBlock Margin="0,1.5,6,0" Text="阿克华孜" /> <TextBlock Margin="0,1.5,6,0" Text="阿克华孜" />
<TextBlock Margin="0,1.5,6,0" Text="yunwuyi" /> <TextBlock Margin="0,1.5,6,0" Text="yunwuyi" />
<TextBlock Margin="0,1.5,6,0" Text="落幕星空" /> <TextBlock Margin="0,1.5,6,0" Text="落幕星空" />
<TextBlock Margin="0,1.5,6,0" Text="黑耀黄昏" />
<TextBlock Margin="0,1.5,6,0" Text="金木萧雨" />
<TextBlock Margin="0,1.5,6,0" Text="隔壁的熊" />
<TextBlock Margin="0,1.5,6,0" Text="星辰彼方" />
<TextBlock Margin="0,1.5,6,0" Text="霜笙雪落" />
<TextBlock Margin="0,1.5,6,0" Text="muming" /> <TextBlock Margin="0,1.5,6,0" Text="muming" />
<TextBlock Margin="0,1.5,6,0" Text="纸币ORZ" /> <TextBlock Margin="0,1.5,6,0" Text="纸币ORZ" />
<TextBlock Margin="0,1.5,6,0" Text="Thorium" />
<TextBlock Margin="0,1.5,6,0" Text="西蛮qwq" /> <TextBlock Margin="0,1.5,6,0" Text="西蛮qwq" />
<TextBlock Margin="0,1.5,6,0" Text="nyanmjc" /> <TextBlock Margin="0,1.5,6,0" Text="nyanmjc" />
<TextBlock Margin="0,1.5,6,0" Text="J_danzai" /> <TextBlock Margin="0,1.5,6,0" Text="J_danzai" />
@@ -443,6 +494,7 @@
<TextBlock Margin="0,1.5,6,0" Text="xiaoyuya" /> <TextBlock Margin="0,1.5,6,0" Text="xiaoyuya" />
<TextBlock Margin="0,1.5,6,0" Text="N3W04H" /> <TextBlock Margin="0,1.5,6,0" Text="N3W04H" />
<TextBlock Margin="0,1.5,6,0" Text="久遠 蓮華" /> <TextBlock Margin="0,1.5,6,0" Text="久遠 蓮華" />
<TextBlock Margin="0,1.5,6,0" Text="小山7132" />
<TextBlock Margin="0,1.5,6,0" Text="HHHbbb" /> <TextBlock Margin="0,1.5,6,0" Text="HHHbbb" />
<TextBlock Margin="0,1.5,6,0" Text="Whelone" /> <TextBlock Margin="0,1.5,6,0" Text="Whelone" />
<TextBlock Margin="0,1.5,6,0" Text="Beholder" /> <TextBlock Margin="0,1.5,6,0" Text="Beholder" />
@@ -457,6 +509,7 @@
<TextBlock Margin="0,1.5,6,0" Text="CHLSama" /> <TextBlock Margin="0,1.5,6,0" Text="CHLSama" />
<TextBlock Margin="0,1.5,6,0" Text="wanglizhi" /> <TextBlock Margin="0,1.5,6,0" Text="wanglizhi" />
<TextBlock Margin="0,1.5,6,0" Text="chen0701" /> <TextBlock Margin="0,1.5,6,0" Text="chen0701" />
<TextBlock Margin="0,1.5,6,0" Text="FXXKGUN" />
<TextBlock Margin="0,1.5,6,0" Text="江寒_John" /> <TextBlock Margin="0,1.5,6,0" Text="江寒_John" />
<TextBlock Margin="0,1.5,6,0" Text="bentianjia" /> <TextBlock Margin="0,1.5,6,0" Text="bentianjia" />
<TextBlock Margin="0,1.5,6,0" Text="yukihomu" /> <TextBlock Margin="0,1.5,6,0" Text="yukihomu" />
@@ -469,6 +522,7 @@
<TextBlock Margin="0,1.5,6,0" Text="飞天大锅饭" /> <TextBlock Margin="0,1.5,6,0" Text="飞天大锅饭" />
<TextBlock Margin="0,1.5,6,0" Text="烟熏秋刀鱼" /> <TextBlock Margin="0,1.5,6,0" Text="烟熏秋刀鱼" />
<TextBlock Margin="0,1.5,6,0" Text="人海不可爱" /> <TextBlock Margin="0,1.5,6,0" Text="人海不可爱" />
<TextBlock Margin="0,1.5,6,0" Text="安静不会错" />
<TextBlock Margin="0,1.5,6,0" Text="摆地摊的王" /> <TextBlock Margin="0,1.5,6,0" Text="摆地摊的王" />
<TextBlock Margin="0,1.5,6,0" Text="团结起来!" /> <TextBlock Margin="0,1.5,6,0" Text="团结起来!" />
<TextBlock Margin="0,1.5,6,0" Text="BeiWu_CN" /> <TextBlock Margin="0,1.5,6,0" Text="BeiWu_CN" />
@@ -496,14 +550,19 @@
<TextBlock Margin="0,1.5,6,0" Text="落雨乄北辰" /> <TextBlock Margin="0,1.5,6,0" Text="落雨乄北辰" />
<TextBlock Margin="0,1.5,6,0" Text="一条闲鲨鱼" /> <TextBlock Margin="0,1.5,6,0" Text="一条闲鲨鱼" />
<TextBlock Margin="0,1.5,6,0" Text="一只木元鸽" /> <TextBlock Margin="0,1.5,6,0" Text="一只木元鸽" />
<TextBlock Margin="0,1.5,6,0" Text="这是江江叭" />
<TextBlock Margin="0,1.5,6,0" Text="柒月贰拾捌" />
<TextBlock Margin="0,1.5,6,0" Text="kiboAlong" />
<TextBlock Margin="0,1.5,6,0" Text="W.D.gaster" /> <TextBlock Margin="0,1.5,6,0" Text="W.D.gaster" />
<TextBlock Margin="0,1.5,6,0" Text="星野源.小毅" /> <TextBlock Margin="0,1.5,6,0" Text="星野源.小毅" />
<TextBlock Margin="0,1.5,6,0" Text="Kimonomc" /> <TextBlock Margin="0,1.5,6,0" Text="Kimonomc" />
<TextBlock Margin="0,1.5,6,0" Text="翎安Lingan" /> <TextBlock Margin="0,1.5,6,0" Text="翎安Lingan" />
<TextBlock Margin="0,1.5,6,0" Text="Michael_蒋" />
<TextBlock Margin="0,1.5,6,0" Text="Stevens520" /> <TextBlock Margin="0,1.5,6,0" Text="Stevens520" />
<TextBlock Margin="0,1.5,6,0" Text="123456。?" /> <TextBlock Margin="0,1.5,6,0" Text="123456。?" />
<TextBlock Margin="0,1.5,6,0" Text="蛋白质_变质" /> <TextBlock Margin="0,1.5,6,0" Text="蛋白质_变质" />
<TextBlock Margin="0,1.5,6,0" Text="LMY666888" /> <TextBlock Margin="0,1.5,6,0" Text="LMY666888" />
<TextBlock Margin="0,1.5,6,0" Text="青灯诗酒Lily" />
<TextBlock Margin="0,1.5,6,0" Text="sheng_1062" /> <TextBlock Margin="0,1.5,6,0" Text="sheng_1062" />
<TextBlock Margin="0,1.5,6,0" Text="Zerovaluelh" /> <TextBlock Margin="0,1.5,6,0" Text="Zerovaluelh" />
<TextBlock Margin="0,1.5,6,0" Text="JUST LIKE IT" /> <TextBlock Margin="0,1.5,6,0" Text="JUST LIKE IT" />
@@ -511,6 +570,7 @@
<TextBlock Margin="0,1.5,6,0" Text="一叶,知秋~" /> <TextBlock Margin="0,1.5,6,0" Text="一叶,知秋~" />
<TextBlock Margin="0,1.5,6,0" Text="joinwick789" /> <TextBlock Margin="0,1.5,6,0" Text="joinwick789" />
<TextBlock Margin="0,1.5,6,0" Text="250的敌敌畏" /> <TextBlock Margin="0,1.5,6,0" Text="250的敌敌畏" />
<TextBlock Margin="0,1.5,6,0" Text="-ET0RN1TY-" />
<TextBlock Margin="0,1.5,6,0" Text="forever_晨风" /> <TextBlock Margin="0,1.5,6,0" Text="forever_晨风" />
<TextBlock Margin="0,1.5,6,0" Text="Fakecaptain" /> <TextBlock Margin="0,1.5,6,0" Text="Fakecaptain" />
<TextBlock Margin="0,1.5,6,0" Text="C.肥宅快乐水" /> <TextBlock Margin="0,1.5,6,0" Text="C.肥宅快乐水" />
@@ -518,6 +578,7 @@
<TextBlock Margin="0,1.5,6,0" Text="while(true){}" /> <TextBlock Margin="0,1.5,6,0" Text="while(true){}" />
<TextBlock Margin="0,1.5,6,0" Text="Haobot2026" /> <TextBlock Margin="0,1.5,6,0" Text="Haobot2026" />
<TextBlock Margin="0,1.5,6,0" Text="粉色妖精小姐" /> <TextBlock Margin="0,1.5,6,0" Text="粉色妖精小姐" />
<TextBlock Margin="0,1.5,6,0" Text="打包还是带走" />
<TextBlock Margin="0,1.5,6,0" Text="Romarunner" /> <TextBlock Margin="0,1.5,6,0" Text="Romarunner" />
<TextBlock Margin="0,1.5,6,0" Text="双狼天下第一" /> <TextBlock Margin="0,1.5,6,0" Text="双狼天下第一" />
<TextBlock Margin="0,1.5,6,0" Text="丿地狱天使丿" /> <TextBlock Margin="0,1.5,6,0" Text="丿地狱天使丿" />
@@ -528,16 +589,19 @@
<TextBlock Margin="0,1.5,6,0" Text="这位是非人类" /> <TextBlock Margin="0,1.5,6,0" Text="这位是非人类" />
<TextBlock Margin="0,1.5,6,0" Text="红白巫女です" /> <TextBlock Margin="0,1.5,6,0" Text="红白巫女です" />
<TextBlock Margin="0,1.5,6,0" Text="吃满保底之人" /> <TextBlock Margin="0,1.5,6,0" Text="吃满保底之人" />
<TextBlock Margin="0,1.5,6,0" Text="转电表的霍格" />
<TextBlock Margin="0,1.5,6,0" Text="Sylph_茜尔芙" /> <TextBlock Margin="0,1.5,6,0" Text="Sylph_茜尔芙" />
<TextBlock Margin="0,1.5,6,0" Text="dadadadada" /> <TextBlock Margin="0,1.5,6,0" Text="dadadadada" />
<TextBlock Margin="0,1.5,6,0" Text="longmao666" /> <TextBlock Margin="0,1.5,6,0" Text="longmao666" />
<TextBlock Margin="0,1.5,6,0" Text="Awolfofcolor" /> <TextBlock Margin="0,1.5,6,0" Text="Awolfofcolor" />
<TextBlock Margin="0,1.5,6,0" Text="请不要打luosi" /> <TextBlock Margin="0,1.5,6,0" Text="请不要打luosi" />
<TextBlock Margin="0,1.5,6,0" Text="Fly with You!!" />
<TextBlock Margin="0,1.5,6,0" Text="ン黑色幽默🏮" /> <TextBlock Margin="0,1.5,6,0" Text="ン黑色幽默🏮" />
<TextBlock Margin="0,1.5,6,0" Text="Rinshonagon" /> <TextBlock Margin="0,1.5,6,0" Text="Rinshonagon" />
<TextBlock Margin="0,1.5,6,0" Text="esj554611445" /> <TextBlock Margin="0,1.5,6,0" Text="esj554611445" />
<TextBlock Margin="0,1.5,6,0" Text="Chara&Chara" /> <TextBlock Margin="0,1.5,6,0" Text="Chara&Chara" />
<TextBlock Margin="0,1.5,6,0" Text="lightning_bolt" /> <TextBlock Margin="0,1.5,6,0" Text="lightning_bolt" />
<TextBlock Margin="0,1.5,6,0" Text="卡壬纳_Karena" />
<TextBlock Margin="0,1.5,6,0" Text="123456789000" /> <TextBlock Margin="0,1.5,6,0" Text="123456789000" />
<TextBlock Margin="0,1.5,6,0" Text="捞猴子的月亮呐" /> <TextBlock Margin="0,1.5,6,0" Text="捞猴子的月亮呐" />
<TextBlock Margin="0,1.5,6,0" Text="躁郁钢管大魅魔" /> <TextBlock Margin="0,1.5,6,0" Text="躁郁钢管大魅魔" />
@@ -549,11 +613,13 @@
<TextBlock Margin="0,1.5,6,0" Text="再来一笼小笼包" /> <TextBlock Margin="0,1.5,6,0" Text="再来一笼小笼包" />
<TextBlock Margin="0,1.5,6,0" Text="玩魔术的暗杀者" /> <TextBlock Margin="0,1.5,6,0" Text="玩魔术的暗杀者" />
<TextBlock Margin="0,1.5,6,0" Text="只留清白在人间" /> <TextBlock Margin="0,1.5,6,0" Text="只留清白在人间" />
<TextBlock Margin="0,1.5,6,0" Text="最美不过你深爱" />
<TextBlock Margin="0,1.5,6,0" Text="maboyuaneasy" /> <TextBlock Margin="0,1.5,6,0" Text="maboyuaneasy" />
<TextBlock Margin="0,1.5,6,0" Text="Kiana Kasiana" /> <TextBlock Margin="0,1.5,6,0" Text="Kiana Kasiana" />
<TextBlock Margin="0,1.5,6,0" Text="南ིྀ熙ིྀ寒ིྀ笙ིྀ" /> <TextBlock Margin="0,1.5,6,0" Text="南ིྀ熙ིྀ寒ིྀ笙ིྀ" />
<TextBlock Margin="0,1.5,6,0" Text="18949212459aa" /> <TextBlock Margin="0,1.5,6,0" Text="18949212459aa" />
<TextBlock Margin="0,1.5,6,0" Text="M3GALOVANIA" /> <TextBlock Margin="0,1.5,6,0" Text="M3GALOVANIA" />
<TextBlock Margin="0,1.5,6,0" Text="Samuel Bridges" />
<TextBlock Margin="0,1.5,6,0" Text="WeimingFanzhe" /> <TextBlock Margin="0,1.5,6,0" Text="WeimingFanzhe" />
<TextBlock Margin="0,1.5,6,0" Text="筱筱雨吖_Official" /> <TextBlock Margin="0,1.5,6,0" Text="筱筱雨吖_Official" />
<TextBlock Margin="0,1.5,6,0" Text="大笨蛋你在里面吗" /> <TextBlock Margin="0,1.5,6,0" Text="大笨蛋你在里面吗" />
@@ -564,7 +630,9 @@
<TextBlock Margin="0,1.5,6,0" Text="好好吃饭好好睡觉" /> <TextBlock Margin="0,1.5,6,0" Text="好好吃饭好好睡觉" />
<TextBlock Margin="0,1.5,6,0" Text="六月に舞う雪の鳶" /> <TextBlock Margin="0,1.5,6,0" Text="六月に舞う雪の鳶" />
<TextBlock Margin="0,1.5,6,0" Text="AAALLLAAANNN" /> <TextBlock Margin="0,1.5,6,0" Text="AAALLLAAANNN" />
<TextBlock Margin="0,1.5,6,0" Text="a cat wear a hear" />
<TextBlock Margin="0,1.5,6,0" Text="Minecraft_DeBug" /> <TextBlock Margin="0,1.5,6,0" Text="Minecraft_DeBug" />
<TextBlock Margin="0,1.5,6,0" Text="爱吃蛋白的丶圆周率" />
<TextBlock Margin="0,1.5,6,0" Text="祖国未来的狗尾巴草" /> <TextBlock Margin="0,1.5,6,0" Text="祖国未来的狗尾巴草" />
<TextBlock Margin="0,1.5,6,0" Text="化权埵萨柯摩,隆奎" /> <TextBlock Margin="0,1.5,6,0" Text="化权埵萨柯摩,隆奎" />
<TextBlock Margin="0,1.5,6,0" Text="AAA今州耙耙柑批发" /> <TextBlock Margin="0,1.5,6,0" Text="AAA今州耙耙柑批发" />
@@ -574,6 +642,7 @@
<TextBlock Margin="0,1.5,6,0" Text="牛至涂芥末越冲越上头" /> <TextBlock Margin="0,1.5,6,0" Text="牛至涂芥末越冲越上头" />
<TextBlock Margin="0,1.5,6,0" Text="正电荷PositiveCharge" /> <TextBlock Margin="0,1.5,6,0" Text="正电荷PositiveCharge" />
<TextBlock Margin="0,1.5,6,0" Text="(ꐦ°᷄д°᷅)咱也不敢问啊" /> <TextBlock Margin="0,1.5,6,0" Text="(ꐦ°᷄д°᷅)咱也不敢问啊" />
<TextBlock Margin="0,1.5,6,0" Text="༺东༃方༒闲༒人༃家༻" />
<TextBlock Margin="0,1.5,6,0" Text="去撞南墙再撞北墙然后西墙最后东墙" /> <TextBlock Margin="0,1.5,6,0" Text="去撞南墙再撞北墙然后西墙最后东墙" />
</WrapPanel> </WrapPanel>
<Grid Height="35"> <Grid Height="35">
@@ -1,4 +1,5 @@
Public Class Settings Public Class Settings
'TODO: 目前仅有此处在使用 DES 加密,后续考虑更换加密算法
Public Shared ReadOnly Entries As Dictionary(Of String, Setting) = (New List(Of Setting) From { Public Shared ReadOnly Entries As Dictionary(Of String, Setting) = (New List(Of Setting) From {
New Setting("Identify", "", Source:=Sources.Registry), New Setting("Identify", "", Source:=Sources.Registry),
New Setting("WindowHeight", 550), New Setting("WindowHeight", 550),
@@ -248,7 +249,7 @@
If Encrypted Then If Encrypted Then
Try Try
If Value Is Nothing Then Value = "" If Value Is Nothing Then Value = ""
Value = SecretEncrypt(Value, "PCL" & Identify) Value = CryptographyUtils.DesEncrypt(Value, "PCL" & Identify)
Catch ex As Exception Catch ex As Exception
Logger.Warn(ex, $"加密设置失败:{Key}") Logger.Warn(ex, $"加密设置失败:{Key}")
End Try End Try
@@ -318,7 +319,7 @@
'正常读取 '正常读取
Try Try
Dim GotValue As String = Nothing '先用 String 储存,避免类型转换 Dim GotValue As String = Nothing '先用 String 储存,避免类型转换
Dim DefaultValue As String = If(Entry.Encrypted, SecretEncrypt(Entry.DefaultValue, "PCL" & Identify), Entry.DefaultValue) Dim DefaultValue As String = If(Entry.Encrypted, CryptographyUtils.DesEncrypt(Entry.DefaultValue, "PCL" & Identify), Entry.DefaultValue)
Select Case Entry.Source Select Case Entry.Source
Case Sources.Normal Case Sources.Normal
GotValue = ReadIni("Setup", Key, DefaultValue) GotValue = ReadIni("Setup", Key, DefaultValue)
@@ -336,7 +337,7 @@
GotValue = Entry.DefaultValue GotValue = Entry.DefaultValue
Else Else
Try Try
GotValue = SecretDecrypt(GotValue, "PCL" & Identify) GotValue = CryptographyUtils.DesDecrypt(GotValue, "PCL" & Identify)
Catch ex As Exception Catch ex As Exception
Logger.Warn(ex, $"解密设置失败:{Key}") Logger.Warn(ex, $"解密设置失败:{Key}")
GotValue = Entry.DefaultValue GotValue = Entry.DefaultValue