Skip to content

Commit add4153

Browse files
committed
2.10.4
1 parent 3e474b8 commit add4153

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+2714
-2081
lines changed

Plain Craft Launcher 2/App.config

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@
3030
<assemblyIdentity name="System.ValueTuple" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral"/>
3131
<bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0"/>
3232
</dependentAssembly>
33+
<dependentAssembly>
34+
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral"/>
35+
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="13.0.0.0"/>
36+
</dependentAssembly>
3337
</assemblyBinding>
3438
</runtime>
35-
</configuration>
39+
</configuration>

Plain Craft Launcher 2/Application.xaml.vb

Lines changed: 20 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -181,53 +181,29 @@ WaitRetry:
181181
End Sub
182182

183183
'动态 DLL 调用
184-
Private Shared AssemblyNAudio As Assembly
185-
Private Shared AssemblyJson As Assembly
186-
Private Shared AssemblyDialog As Assembly
187-
Private Shared AssemblyImazenWebp As Assembly
188-
Private Shared ReadOnly AssemblyNAudioLock As New Object
189-
Private Shared ReadOnly AssemblyJsonLock As New Object
190-
Private Shared ReadOnly AssemblyDialogLock As New Object
191-
Private Shared ReadOnly AssemblyImazenWebpLock As New Object
192184
Private Declare Function SetDllDirectory Lib "kernel32" Alias "SetDllDirectoryA" (lpPathName As String) As Boolean
193-
Public Shared Function AssemblyResolve(sender As Object, args As ResolveEventArgs) As Assembly
194-
If args.Name.StartsWithF("NAudio") Then
195-
SyncLock AssemblyNAudioLock
196-
If AssemblyNAudio Is Nothing Then
197-
Log("[Start] 加载 DLL:NAudio")
198-
AssemblyNAudio = Assembly.Load(GetResources("NAudio"))
199-
End If
200-
Return AssemblyNAudio
201-
End SyncLock
202-
ElseIf args.Name.StartsWithF("Newtonsoft.Json") Then
203-
SyncLock AssemblyJsonLock
204-
If AssemblyJson Is Nothing Then
205-
Log("[Start] 加载 DLL:Json")
206-
AssemblyJson = Assembly.Load(GetResources("Json"))
207-
End If
208-
Return AssemblyJson
209-
End SyncLock
210-
ElseIf args.Name.StartsWithF("Ookii.Dialogs.Wpf") Then
211-
SyncLock AssemblyDialogLock
212-
If AssemblyDialog Is Nothing Then
213-
Log("[Start] 加载 DLL:Dialogs")
214-
AssemblyDialog = Assembly.Load(GetResources("Dialogs"))
215-
End If
216-
Return AssemblyDialog
217-
End SyncLock
218-
ElseIf args.Name.StartsWithF("Imazen.WebP") Then
219-
SyncLock AssemblyImazenWebpLock
220-
If AssemblyImazenWebp Is Nothing Then
221-
Log("[Start] 加载 DLL:Imazen.WebP")
222-
AssemblyImazenWebp = Assembly.Load(GetResources("Imazen_WebP"))
223-
SetDllDirectory(PathPure.TrimEnd("\"))
185+
Public Shared Function AssemblyResolve(sender As Object, Args As ResolveEventArgs) As Assembly
186+
'缓存
187+
Static Prefixes As String() = {"NAudio", "Newtonsoft.Json", "Ookii.Dialogs.Wpf", "Imazen.WebP", "CacheCow.Common", "CacheCow.Client.FileStore", "CacheCow.Client", "System.Net.Http.Formatting"}
188+
Static Locks As New Dictionary(Of String, Object)(StringComparer.Ordinal)
189+
Static LoadedAssembly As New Dictionary(Of String, Assembly)(StringComparer.Ordinal)
190+
'查找对应的 DLL
191+
Dim Prefix As String = Prefixes.FirstOrDefault(Function(p) Args.Name.StartsWithF(p))
192+
If Prefix Is Nothing Then Return Nothing
193+
'加载 DLL
194+
If Not Locks.ContainsKey(Prefix) Then Locks(Prefix) = New Object()
195+
SyncLock Locks(Prefix)
196+
If Not LoadedAssembly.ContainsKey(Prefix) Then
197+
Log($"[Start] 加载 DLL:{Prefix}")
198+
LoadedAssembly(Prefix) = Assembly.Load(GetResources(Prefix))
199+
'WebP 特判
200+
If Prefix = "Imazen.WebP" Then
201+
SetDllDirectory(PathPure.TrimEnd("\"c))
224202
WriteFile(PathPure & "libwebp.dll", GetResources("libwebp64"))
225203
End If
226-
Return AssemblyImazenWebp
227-
End SyncLock
228-
Else
229-
Return Nothing
230-
End If
204+
End If
205+
Return LoadedAssembly(Prefix)
206+
End SyncLock
231207
End Function
232208

233209
'切换窗口

Plain Craft Launcher 2/FormMain.xaml.vb

Lines changed: 33 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,13 @@ Public Class FormMain
8383
'3:BUG+ IMP* FEAT-
8484
'2:BUG* IMP-
8585
'1:BUG-
86+
If LastVersion < 363 Then 'Snapshot 2.10.4
87+
FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "优化:下载资源时,会单独记忆每种资源上次下载到的文件夹,以防混淆"))
88+
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "优化:网络底层框架与下载稳定性"))
89+
FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复:无法启动一部分 LabyMod 和 GTNH 客户端"))
90+
FeatureCount += 22
91+
BugCount += 26
92+
End If
8693
If LastVersion < 362 Then 'Snapshot 2.10.3
8794
FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "修复:无法安装部分使用老版本 PCL 导出的整合包"))
8895
End If
@@ -204,8 +211,6 @@ Public Class FormMain
204211
End Sub, "UpdateLog Output")
205212
End Sub
206213

207-
Private ReadOnly Helper As New DragFileHelper()
208-
209214
'窗口加载
210215
Private IsWindowLoadFinished As Boolean = False
211216
Public Sub New()
@@ -228,7 +233,7 @@ Public Class FormMain
228233
If Not Setup.IsUnset("LaunchArgumentIndie") Then
229234
Log("[Start] 从老 PCL 迁移版本隔离")
230235
Setup.Set("LaunchArgumentIndieV2", Setup.Get("LaunchArgumentIndie"))
231-
ElseIf Not Setup.IsUnset("WindowHeight") Then
236+
ElseIf Not Setup.IsUnset("LaunchVersionSelect") Then
232237
Log("[Start] 从老 PCL 升级,但此前未调整版本隔离,使用老的版本隔离默认值")
233238
Setup.Set("LaunchArgumentIndieV2", Setup.GetDefault("LaunchArgumentIndie"))
234239
Else
@@ -244,36 +249,24 @@ Public Class FormMain
244249
[AddHandler](DragDrop.DragOverEvent, New DragEventHandler(AddressOf HandleDrag), handledEventsToo:=True)
245250
'加载 UI
246251
InitializeComponent()
247-
248-
249-
250252
Opacity = 0
251-
'旧代码
252-
''开启管理员权限下的文件拖拽,但下列代码也没用(#2531)
253-
'If IsAdmin() Then
254-
' Log("[Start] PCL 正以管理员权限运行")
255-
' ChangeWindowMessageFilter(&H233, 1)
256-
' ChangeWindowMessageFilter(&H4A, 1)
257-
' ChangeWindowMessageFilter(&H49, 1)
258-
'End If
259-
260253
'开启管理员权限下的文件拖拽
261254
If IsAdmin() Then
262-
AddHandler Me.SourceInitialized,
263-
Sub(sender, e)
264-
Dim wpfHelper As New WindowInteropHelper(Me)
265-
Helper.HwndIntPtrSource = HwndSource.FromHwnd(wpfHelper.Handle)
255+
Static Helper As New DragHelper
256+
AddHandler SourceInitialized,
257+
Sub()
258+
Dim WpfHelper As New WindowInteropHelper(Me)
259+
Helper.HwndIntPtrSource = HwndSource.FromHwnd(WpfHelper.Handle)
266260
Helper.AddHook()
267261
End Sub
268-
AddHandler Me.Closing,
269-
Sub(sender, e)
270-
Helper.RemoveDragHook()
271-
End Sub
272-
AddHandler Helper.DragDrop,
273-
Sub(sender, e)
274-
Me.FileDrag(Helper.DropFilePaths)
275-
End Sub
262+
AddHandler Closing, Sub() Helper.RemoveDragHook()
263+
AddHandler Helper.DragDrop, Sub() FileDrag(Helper.DropFilePaths)
276264
End If
265+
'If IsAdmin() Then '下列代码没用(#2531)
266+
' ChangeWindowMessageFilter(&H233, 1)
267+
' ChangeWindowMessageFilter(&H4A, 1)
268+
' ChangeWindowMessageFilter(&H49, 1)
269+
'End If
277270
'切换到首页
278271
If Not IsNothing(FrmLaunchLeft.Parent) Then FrmLaunchLeft.SetValue(ContentPresenter.ContentProperty, Nothing)
279272
If Not IsNothing(FrmLaunchRight.Parent) Then FrmLaunchRight.SetValue(ContentPresenter.ContentProperty, Nothing)
@@ -390,7 +383,7 @@ Public Class FormMain
390383
Catch ex As Exception
391384
Log(ex, "清理自动更新文件失败")
392385
End Try
393-
End Sub, "Start Loader", ThreadPriority.Lowest)
386+
End Sub, "初始化", ThreadPriority.Lowest)
394387

395388
Log("[Start] 第三阶段加载用时:" & GetTimeTick() - ApplicationStartTick & " ms")
396389
End Sub
@@ -616,11 +609,12 @@ Public Class FormMain
616609
'按键事件
617610
Private Sub FormMain_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
618611
If e.IsRepeat Then Return
619-
'调用弹窗:回车选择第一个,Esc 选择最后一个
620-
If PanMsg.Children.Count > 0 Then
612+
'修复按下 Alt 后误认为弹出系统菜单导致的冻结
613+
If e.SystemKey = Key.LeftAlt OrElse e.SystemKey = Key.RightAlt Then e.Handled = True
614+
'在有弹窗时:回车选择第一个,Esc 选择最后一个
615+
If PanMsg.Children.Any Then
621616
If e.Key = Key.Enter Then
622617
CType(PanMsg.Children(0), Object).Btn1_Click()
623-
Return
624618
ElseIf e.Key = Key.Escape Then
625619
Dim Msg As Object = PanMsg.Children(0)
626620
If TypeOf Msg IsNot MyMsgInput AndAlso TypeOf Msg IsNot MyMsgSelect AndAlso Msg.Btn3.Visibility = Visibility.Visible Then
@@ -630,9 +624,14 @@ Public Class FormMain
630624
Else
631625
Msg.Btn1_Click()
632626
End If
633-
Return
634627
End If
628+
Return
635629
End If
630+
631+
'==========================
632+
' 在没有弹窗时:继续检查……
633+
'==========================
634+
636635
'按 ESC 返回上一级
637636
If e.Key = Key.Escape Then TriggerPageBack()
638637
'更改隐藏版本可见性
@@ -666,8 +665,6 @@ Public Class FormMain
666665
FrmLaunchLeft.LaunchButtonClick()
667666
End If
668667
End If
669-
'修复按下 Alt 后误认为弹出系统菜单导致的冻结
670-
If e.SystemKey = Key.LeftAlt OrElse e.SystemKey = Key.RightAlt Then e.Handled = True
671668
End Sub
672669
Private Sub FormMain_MouseDown(sender As Object, e As MouseButtonEventArgs) Handles Me.MouseDown
673670
'鼠标侧键返回上一级
@@ -732,6 +729,7 @@ Public Class FormMain
732729
End Sub
733730
Private Sub FrmMain_Drop(sender As Object, e As DragEventArgs) Handles Me.Drop
734731
Try
732+
ShowWindowToTop()
735733
If e.Data.GetDataPresent(DataFormats.Text) Then
736734
'获取文本
737735
Try
@@ -1505,4 +1503,4 @@ Public Class FormMain
15051503
lastMouseArg = e
15061504
End Sub
15071505

1508-
End Class
1506+
End Class

Plain Craft Launcher 2/Modules/Base/ModBase.vb

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@ Public Module ModBase
1313
#Region "声明"
1414

1515
'下列版本信息由更新器自动修改
16-
Public Const VersionBaseName As String = "2.10.3" '不含分支前缀的显示用版本名
17-
Public Const VersionStandardCode As String = "2.10.3." & VersionBranchCode '标准格式的四段式版本号
16+
Public Const VersionBaseName As String = "2.10.4" '不含分支前缀的显示用版本名
17+
Public Const VersionStandardCode As String = "2.10.4." & VersionBranchCode '标准格式的四段式版本号
1818
Public Const CommitHash As String = "" 'Commit Hash,由 GitHub Workflow 自动替换
1919
#If BETA Then
2020
Public Const VersionCode As Integer = 361 'Release
2121
#Else
22-
Public Const VersionCode As Integer = 362 'Snapshot
22+
Public Const VersionCode As Integer = 363 'Snapshot
2323
#End If
2424
'自动生成的版本信息
2525
Public Const VersionDisplayName As String = VersionBranchName & " " & VersionBaseName
@@ -1551,7 +1551,7 @@ RetryDir:
15511551
''' <summary>
15521552
''' 获取 JSON 对象。
15531553
''' </summary>
1554-
Public Function GetJson(Data As String)
1554+
Public Function GetJson(Data As String) As JToken
15551555
Try
15561556
Return JsonConvert.DeserializeObject(Data, New JsonSerializerSettings With {.DateTimeZoneHandling = DateTimeZoneHandling.Local})
15571557
Catch ex As Exception
@@ -2131,6 +2131,19 @@ RetryDir:
21312131
End Function
21322132
End Class
21332133

2134+
''' <summary>
2135+
''' 将二维数组转换为字典。
2136+
''' </summary>
2137+
<Extension> Public Function ToDictionary(Of T)(arr As T(,)) As Dictionary(Of T, T)
2138+
Dim result As New Dictionary(Of T, T)
2139+
If arr.Length = 0 Then Return result
2140+
If arr.GetLength(1) <> 2 Then Throw New ArgumentException("数组必须为两列,第一列为 Key,第二列为 Value。")
2141+
For i As Integer = 0 To arr.GetLength(0) - 1
2142+
result(arr(i, 0)) = arr(i, 1)
2143+
Next
2144+
Return result
2145+
End Function
2146+
21342147
''' <summary>
21352148
''' 可用于临时存放文件的,不含任何特殊字符的文件夹路径,以“\”结尾。
21362149
''' </summary>
@@ -2179,10 +2192,10 @@ RetryDir:
21792192
End Function
21802193

21812194
''' <summary>
2182-
''' 判断当前系统语言是否为 zh-CN
2195+
''' 判断当前系统语言是否为中文
21832196
''' </summary>
21842197
Public Function IsSystemLanguageChinese() As Boolean
2185-
Return CultureInfo.CurrentCulture.Name = "zh-CN" OrElse CultureInfo.CurrentUICulture.Name = "zh-CN"
2198+
Return CultureInfo.CurrentCulture.Name.StartsWithF("zh-") OrElse CultureInfo.CurrentUICulture.Name.StartsWithF("zh-")
21862199
End Function
21872200

21882201
Private Uuid As Integer = 1
@@ -2225,6 +2238,9 @@ NextElement:
22252238
Next i
22262239
Return ResultArray
22272240
End Function
2241+
<Extension> Public Function Any(Arr As UIElementCollection) As Boolean
2242+
Return Arr?.Count > 0
2243+
End Function
22282244

22292245
''' <summary>
22302246
''' 获取格式类似于“11:08:52.037”的当前时间的字符串。
@@ -2462,7 +2478,7 @@ NextElement:
24622478
''' </summary>
24632479
Public Sub RunInThread(Action As Action)
24642480
If RunInUi() Then
2465-
RunInNewThread(Action, "Runtime Invoke " & GetUuid() & "#")
2481+
RunInNewThread(Action, "Invoke " & GetUuid())
24662482
Else
24672483
Action()
24682484
End If
@@ -2760,11 +2776,11 @@ Retry:
27602776
Using Reader As New XamlXmlReader(Stream)
27612777
While Reader.Read()
27622778
For Each BlackListType In {GetType(WebBrowser), GetType(Frame), GetType(MediaElement), GetType(ObjectDataProvider), GetType(XamlReader), GetType(Window), GetType(XmlDataProvider)}
2763-
If Reader.Type IsNot Nothing AndAlso BlackListType.IsAssignableFrom(Reader.Type.UnderlyingType) Then Throw New UnauthorizedAccessException($"不允许使用 {BlackListType.Name} 类型。")
2764-
If Reader.Value IsNot Nothing AndAlso Reader.Value = BlackListType.Name Then Throw New UnauthorizedAccessException($"不允许使用 {BlackListType.Name} 值。")
2779+
If Reader.Type IsNot Nothing AndAlso BlackListType.IsAssignableFrom(Reader.Type.UnderlyingType) Then Throw New UnauthorizedAccessException($"基于安全考虑,不允许使用 {BlackListType.Name} 类型。")
2780+
If Reader.Value IsNot Nothing AndAlso Reader.Value = BlackListType.Name Then Throw New UnauthorizedAccessException($"基于安全考虑,不允许使用 {BlackListType.Name} 值。")
27652781
Next
27662782
For Each BlackListMember In {"Code", "FactoryMethod", "Static"}
2767-
If Reader.Member IsNot Nothing AndAlso Reader.Member.Name = BlackListMember Then Throw New UnauthorizedAccessException($"不允许使用 {BlackListMember} 成员。")
2783+
If Reader.Member IsNot Nothing AndAlso Reader.Member.Name = BlackListMember Then Throw New UnauthorizedAccessException($"基于安全考虑,不允许使用 {BlackListMember} 成员。")
27682784
Next
27692785
End While
27702786
End Using
@@ -2922,7 +2938,7 @@ Retry:
29222938
'处理错误会导致再次调用 Log() 导致无限循环
29232939

29242940
'输出日志
2925-
Dim AppendText As String = "[" & GetTimeNow() & "] " & Text & vbCrLf '减轻同步锁占用
2941+
Dim AppendText As String = $"[{GetTimeNow()}] <{If(Thread.CurrentThread.Name = "", "主线程", Thread.CurrentThread.Name)}> {Text}{vbCrLf}" '减轻同步锁占用
29262942
If ModeDebug Then
29272943
SyncLock LogListLock
29282944
LogList.Append(AppendText)
@@ -2986,7 +3002,7 @@ Retry:
29863002
Dim ExFull As String = Desc & ":" & GetExceptionDetail(Ex)
29873003

29883004
'输出日志
2989-
Dim AppendText As String = "[" & GetTimeNow() & "] " & Desc & ":" & GetExceptionDetail(Ex, True) & vbCrLf '减轻同步锁占用
3005+
Dim AppendText As String = $"[{GetTimeNow()}] <{If(Thread.CurrentThread.Name = "", "主线程", Thread.CurrentThread.Name)}> {Desc}:{GetExceptionDetail(Ex, True)}{vbCrLf}" '减轻同步锁占用
29903006
If ModeDebug Then
29913007
SyncLock LogListLock
29923008
LogList.Append(AppendText)
@@ -3048,7 +3064,7 @@ Retry:
30483064
If ForceOpenLog OrElse (ShowMsgbox AndAlso MyMsgBox("若你在汇报一个 Bug,请点击 打开文件夹 按钮,并上传 Log(1~5).txt 中包含错误信息的文件。" & vbCrLf & "游戏崩溃一般与启动器无关,请不要因为游戏崩溃而提交反馈。", "反馈提交提醒", "打开文件夹", "不需要") = 1) Then
30493065
OpenExplorer(Path & "PCL\Log1.txt")
30503066
End If
3051-
OpenWebsite("https://github.com/Hex-Dragon/PCL2/issues/")
3067+
OpenWebsite("https://github.com/Meloong-Git/PCL/issues/")
30523068
End Sub
30533069
Public Function CanFeedback(ShowHint As Boolean) As Boolean
30543070
If False.Equals(PageSetupSystem.IsLauncherNewest) Then

Plain Craft Launcher 2/Modules/Base/ModLoader.vb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@
339339
[Error] = ex
340340
State = LoadState.Failed
341341
End Try
342-
End Sub) With {.Name = Name, .Priority = ThreadPriority}
342+
End Sub) With {.Name = "L/" & Name, .Priority = ThreadPriority}
343343
LastRunningThread.Start() '不能使用 RunInNewThread,否则在函数返回前线程就会运行完,导致误判 IsAborted
344344
End Sub
345345
Public Overrides Sub Abort()

0 commit comments

Comments
 (0)