From ef3217959853d378af825220d222601774c2d6cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BE=99=E8=85=BE=E7=8C=AB=E8=B7=83?= <1043137532@qq.com> Date: Thu, 3 Nov 2022 22:29:41 +0800 Subject: [PATCH] 2.4.1 --- .../Controls/MyMsg/MyMsgInput.xaml | 6 +- .../Controls/MyMsg/MyMsgInput.xaml.vb | 4 +- .../Controls/MyMsg/MyMsgSelect.xaml | 6 +- .../Controls/MyMsg/MyMsgSelect.xaml.vb | 4 +- .../Controls/MyMsg/MyMsgText.xaml | 6 +- .../Controls/MyMsg/MyMsgText.xaml.vb | 4 +- Plain Craft Launcher 2/FormMain.xaml.vb | 42 +- Plain Craft Launcher 2/Images/Skins/Alex.png | Bin 2144 -> 999 bytes Plain Craft Launcher 2/Images/Skins/Ari.png | Bin 0 -> 912 bytes Plain Craft Launcher 2/Images/Skins/Efe.png | Bin 0 -> 1001 bytes Plain Craft Launcher 2/Images/Skins/Kai.png | Bin 0 -> 1279 bytes .../Images/Skins/Makena.png | Bin 0 -> 1110 bytes Plain Craft Launcher 2/Images/Skins/Noor.png | Bin 0 -> 861 bytes Plain Craft Launcher 2/Images/Skins/Steve.png | Bin 1350 -> 958 bytes Plain Craft Launcher 2/Images/Skins/Sunny.png | Bin 0 -> 988 bytes Plain Craft Launcher 2/Images/Skins/Zuri.png | Bin 0 -> 947 bytes .../Modules/Base/ModBase.vb | 12 +- Plain Craft Launcher 2/Modules/Base/ModNet.vb | 8 +- .../Modules/Minecraft/ModCrash.vb | 6 +- .../Modules/Minecraft/ModDownload.vb | 146 +- .../Modules/Minecraft/ModLaunch.vb | 204 +- .../Modules/Minecraft/ModMinecraft.vb | 39 +- .../Modules/Minecraft/ModModpack.vb | 2 +- .../Modules/Minecraft/ModWatcher.vb | 18 +- .../My Project/AssemblyInfo.vb | 4 +- .../My Project/Resources.resx | 2 +- .../Pages/PageDownload/ModDownloadLib.vb | 9 +- .../PageDownload/PageDownloadCfDetail.xaml.vb | 13 +- .../PageDownload/PageDownloadClient.xaml.vb | 4 +- .../PageDownload/PageDownloadInstall.xaml.vb | 49 +- .../Pages/PageLaunch/MySkin.xaml.vb | 5 +- .../Pages/PageLaunch/PageLaunchLeft.xaml.vb | 6 +- .../Pages/PageLaunch/PageLoginLegacy.xaml.vb | 9 +- .../Pages/PageLink/PageLinkFeedback.xaml | 2 +- .../Pages/PageLink/PageLinkHiper.xaml | 4 +- .../Pages/PageLink/PageLinkIoi.xaml | 2 +- .../Pages/PageSetup/PageSetupSystem.xaml | 5 +- .../Pages/PageSetup/PageSetupSystem.xaml.vb | 4 +- .../Plain Craft Launcher 2.vbproj | 4 +- Plain Craft Launcher 2/Resources/Help.zip | Bin 72426 -> 72553 bytes Plain Craft Launcher 2/Resources/ModData.json | 1 - Plain Craft Launcher 2/Resources/ModData.txt | 3769 +++++++++++++++++ 42 files changed, 4212 insertions(+), 187 deletions(-) create mode 100644 Plain Craft Launcher 2/Images/Skins/Ari.png create mode 100644 Plain Craft Launcher 2/Images/Skins/Efe.png create mode 100644 Plain Craft Launcher 2/Images/Skins/Kai.png create mode 100644 Plain Craft Launcher 2/Images/Skins/Makena.png create mode 100644 Plain Craft Launcher 2/Images/Skins/Noor.png create mode 100644 Plain Craft Launcher 2/Images/Skins/Sunny.png create mode 100644 Plain Craft Launcher 2/Images/Skins/Zuri.png delete mode 100644 Plain Craft Launcher 2/Resources/ModData.json create mode 100644 Plain Craft Launcher 2/Resources/ModData.txt diff --git a/Plain Craft Launcher 2/Controls/MyMsg/MyMsgInput.xaml b/Plain Craft Launcher 2/Controls/MyMsg/MyMsgInput.xaml index f3767ab..d61111d 100644 --- a/Plain Craft Launcher 2/Controls/MyMsg/MyMsgInput.xaml +++ b/Plain Craft Launcher 2/Controls/MyMsg/MyMsgInput.xaml @@ -15,9 +15,9 @@ - - - + + + diff --git a/Plain Craft Launcher 2/Controls/MyMsg/MyMsgInput.xaml.vb b/Plain Craft Launcher 2/Controls/MyMsg/MyMsgInput.xaml.vb index 6ddfa8f..2b48920 100644 --- a/Plain Craft Launcher 2/Controls/MyMsg/MyMsgInput.xaml.vb +++ b/Plain Craft Launcher 2/Controls/MyMsg/MyMsgInput.xaml.vb @@ -109,13 +109,13 @@ MyConverter.Result = TextCaption.Text Close() End Sub - Private Sub Btn2_Click() Handles Btn2.Click + Public Sub Btn2_Click() Handles Btn2.Click If MyConverter.IsExited Then Exit Sub MyConverter.IsExited = True MyConverter.Result = Nothing Close() End Sub - Private Sub Btn3_Click() Handles Btn3.Click + Public Sub Btn3_Click() Handles Btn3.Click If MyConverter.IsExited Then Exit Sub MyConverter.IsExited = True MyConverter.Result = Nothing diff --git a/Plain Craft Launcher 2/Controls/MyMsg/MyMsgSelect.xaml b/Plain Craft Launcher 2/Controls/MyMsg/MyMsgSelect.xaml index 6965e8f..1a7b0d2 100644 --- a/Plain Craft Launcher 2/Controls/MyMsg/MyMsgSelect.xaml +++ b/Plain Craft Launcher 2/Controls/MyMsg/MyMsgSelect.xaml @@ -20,8 +20,8 @@ - - - + + + diff --git a/Plain Craft Launcher 2/Controls/MyMsg/MyMsgSelect.xaml.vb b/Plain Craft Launcher 2/Controls/MyMsg/MyMsgSelect.xaml.vb index 6174649..318baec 100644 --- a/Plain Craft Launcher 2/Controls/MyMsg/MyMsgSelect.xaml.vb +++ b/Plain Craft Launcher 2/Controls/MyMsg/MyMsgSelect.xaml.vb @@ -112,13 +112,13 @@ MyConverter.Result = SelectedIndex Close() End Sub - Private Sub Btn2_Click() Handles Btn2.Click + Public Sub Btn2_Click() Handles Btn2.Click If MyConverter.IsExited Then Exit Sub MyConverter.IsExited = True MyConverter.Result = Nothing Close() End Sub - Private Sub Btn3_Click() Handles Btn3.Click + Public Sub Btn3_Click() Handles Btn3.Click If MyConverter.IsExited Then Exit Sub MyConverter.IsExited = True MyConverter.Result = Nothing diff --git a/Plain Craft Launcher 2/Controls/MyMsg/MyMsgText.xaml b/Plain Craft Launcher 2/Controls/MyMsg/MyMsgText.xaml index 0a198de..2855843 100644 --- a/Plain Craft Launcher 2/Controls/MyMsg/MyMsgText.xaml +++ b/Plain Craft Launcher 2/Controls/MyMsg/MyMsgText.xaml @@ -20,8 +20,8 @@ - - - + + + diff --git a/Plain Craft Launcher 2/Controls/MyMsg/MyMsgText.xaml.vb b/Plain Craft Launcher 2/Controls/MyMsg/MyMsgText.xaml.vb index a554fd8..4fe08c8 100644 --- a/Plain Craft Launcher 2/Controls/MyMsg/MyMsgText.xaml.vb +++ b/Plain Craft Launcher 2/Controls/MyMsg/MyMsgText.xaml.vb @@ -104,13 +104,13 @@ MyConverter.Result = 1 Close() End Sub - Private Sub Btn2_Click() Handles Btn2.Click + Public Sub Btn2_Click() Handles Btn2.Click If MyConverter.IsExited Then Exit Sub MyConverter.IsExited = True MyConverter.Result = 2 Close() End Sub - Private Sub Btn3_Click() Handles Btn3.Click + Public Sub Btn3_Click() Handles Btn3.Click If MyConverter.IsExited Then Exit Sub MyConverter.IsExited = True MyConverter.Result = 3 diff --git a/Plain Craft Launcher 2/FormMain.xaml.vb b/Plain Craft Launcher 2/FormMain.xaml.vb index f06d035..0c3adc0 100644 --- a/Plain Craft Launcher 2/FormMain.xaml.vb +++ b/Plain Craft Launcher 2/FormMain.xaml.vb @@ -10,6 +10,16 @@ Public Class FormMain Dim FeatureList As New List(Of KeyValuePair(Of Integer, String)) '统计更新日志条目 #If BETA Then + If LastVersion < 268 Then 'Release 2.4.1 + FeatureList.Add(New KeyValuePair(Of Integer, String)(5, "追加新的联机方式(HiPer 联机模块)")) + FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "游戏崩溃的弹窗添加了直接查看日志的选项")) + FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "在更多分类下添加了新功能投票选项")) + FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "自动安装时支持检查 OptiFine 对 Forge 的具体版本需求")) + FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "优化自动 Java 选择的准确度")) + FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "优化 Mod 中文名的显示")) + FeatureCount += 12 + BugCount += 30 + End If If LastVersion < 265 Then 'Release 2.3.5 FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "修复部分情况下无法启动路径带有中文的游戏的 Bug")) FeatureList.Add(New KeyValuePair(Of Integer, String)(1, "修复多个可能导致 OptiFine、Forge 安装失败的 Bug")) @@ -90,6 +100,14 @@ Public Class FormMain '3:BUG+ IMP* FEAT- '2:BUG* IMP- '1:BUG- + If LastVersion < 267 Then 'Snapshot 2.4.1 + If LastVersion = 266 Then FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "优化 HiPer 联机模块的使用体验")) + FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "自动安装时支持检查 OptiFine 对 Forge 的具体版本需求")) + FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "优化自动 Java 选择的准确度")) + FeatureList.Add(New KeyValuePair(Of Integer, String)(2, "优化 Mod 中文名的显示")) + FeatureCount += 12 + BugCount += 22 + End If If LastVersion < 266 Then 'Snapshot 2.4.0 FeatureList.Add(New KeyValuePair(Of Integer, String)(5, "追加新的联机方式(HiPer 联机模块)")) FeatureList.Add(New KeyValuePair(Of Integer, String)(3, "游戏崩溃的弹窗添加了直接查看日志的选项")) @@ -575,11 +593,25 @@ Reopen: '按键事件 Private Sub FormMain_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown If e.IsRepeat Then Exit Sub - '调用弹窗回车 - If e.Key = Key.Enter AndAlso PanMsg.Children.Count > 0 Then - CType(PanMsg.Children(0), Object).Btn1_Click() - Exit Sub + '调用弹窗:回车选择第一个,Esc 选择最后一个 + If PanMsg.Children.Count > 0 Then + If e.Key = Key.Enter Then + CType(PanMsg.Children(0), Object).Btn1_Click() + Exit Sub + ElseIf e.Key = Key.Escape Then + Dim Msg As Object = PanMsg.Children(0) + If Msg.Btn3.Visibility = Visibility.Visible Then + Msg.Btn3_Click() + ElseIf Msg.Btn2.Visibility = Visibility.Visible Then + Msg.Btn2_Click() + Else + Msg.Btn1_Click() + End If + Exit Sub + End If End If + '按 ESC 返回上一级 + If e.Key = Key.Escape Then TriggerPageBack() '更改隐藏版本可见性 If e.Key = Key.F11 AndAlso PageCurrent = FormMain.PageType.VersionSelect Then FrmSelectRight.ShowHidden = Not FrmSelectRight.ShowHidden @@ -607,8 +639,6 @@ Reopen: End If '修复按下 Alt 后误认为弹出系统菜单导致的冻结 If e.SystemKey = Key.LeftAlt OrElse e.SystemKey = Key.RightAlt Then e.Handled = True - '按 ESC 返回上一级 - If e.Key = Key.Escape Then TriggerPageBack() End Sub Private Sub FormMain_MouseDown(sender As Object, e As MouseButtonEventArgs) Handles Me.MouseDown '鼠标侧键返回上一级 diff --git a/Plain Craft Launcher 2/Images/Skins/Alex.png b/Plain Craft Launcher 2/Images/Skins/Alex.png index 0193041bcbc102e607a6ddfbb83cddcf9ca03142..984d92b72053fac384174c36c7232037b00646ce 100644 GIT binary patch delta 988 zcmV<210($45a$Pw8Gi!+005o0f$RVP0A^53R7C&)02nwHBVr^dC@3pbC^j}WKR-WD zPfu7_SX?_NWI-%tWo2weE^lvdajR}}PBwK=ID4{qd{;hzf?9^Tgp9t5l$L9h$dc5z zkKTbU-^8NjjX&#{KkLx2@4K<@+Q0LtSpWb3SLc2700001bbnG#Qvg8b*k%9#120KL zK~z}7?N)1JqA(EDD)NxR1&I(63jP0o@@6){g4Zhe^}0xe=*&(wkKNran040Rvep@V zoZD?R2Q$X7eU)Gw3HC~y-ArJO_iTj0ne7Tj7#h!G%?k>wa~MF^A`?Agvz&Tk2r1lg>5KpWI>mgiADJ zM4)+2KzDQvhJNUKVX)#{Se^%ygQn~L^KBU3K6~$4Vq&1gteHNGzz>sk_7)Q}u31pr zeF6XRF<=ngXh-9W2*7X86%Ks6XCS>zc#ey5Ovi*`nE1}HfT zSPURKC8%aR@U2J@_FC^Z-dq7u?}ANEaeU$|G=EAL1R)-nWV}5hASemoI7#CDet%^A zb)nS}FW}%+OavIjodSRYIN^;+D2_z#k4HZ98@9jUpPUo+C|M_6L^9;!|M>-$HOd3%~a8xE_7NVb*_%f!RS4&uj4A znt#OlSirJSyV9oP;JQk|?=tw`4cTmwY@OEI4w3tU!&%+-TL{v-bU)gS3P>V?E7)5+E-AZk`GY$lLY zKdTpRb@*xpvwDFh0o)RUdA&fB(yX77`wD_kFPx`(K`Md=3jP93B7vM`wD`>c0000< KMNUMnLSTY5Le5+O delta 2142 zcmV-k2%-1q2jCEp8Gi-<0063Kaozv`00v@9M??UO0Js2(OLZf900009a7bBm000XU z000XU0RWnu7ytkW07*naRCwCun(uEEMHt8TuP|zS=Z}!+3(!DFiYX*gpd3;g2}z|j z1xp$l1EQo_(zF@^0!0lP5)$E!CSnt}j*W10eTsQe;OcD zVU{2SKm>&5-+$lU6cZt25dkm^vjiakA|Nz>u%|gDLdYZnVgOV(KzY>xM1~yz)eTTS zB>*4+pt=M00pRk_A5Y@1%>VQIuqf8j1ZG;^g3(dN-z;_E)+o$h|1B?ywKRd5mbYMZlsN#lRoS;$ z#yrj6K7W5Syn6CukscJ?Z|GJwkbK?3wyM1Y=ncmIJ@;+NV`8mrAo;pQ5DRJ3%E-g$ zojZ5J2iHF&=5Js6LGma=oqj4TH701lIv)$^$P8N<+slm)1cm zF0Fj=M`>x>+AOzG;UHS0o^BD_mo8xXJi}bf(r}cH9{XHGIE3XOB#iWWP_<)=?eh$C zF-s6pdh__Oh;RtYK}ZMbh(S^&WC&jdjJE&;&DVdSd;faZ~IT0A#^W()u~m=>hRhAg{4CIB4K zh$=4PwKY$M{Vj{b7aO0DeSly(@ZBC!?|&CPB6n_dKI$w0`!wjCcbMDg>-oNL@6k6y z-QxUxl*@mcYezZjgQ1~7R8EWY$6<2o(+dOuq|GzGIX7S6KsZ)k055RQ-ip9LFN>?3cULVuY&=6BB0)GlAO>0xyTnxZayiaQYOszTn7_LFEj%nEdR;*YN zQZU%k(h|0|wu+EPnLcLKs#W3IwQEJlTL8B8ts&cGbc-|3a|uA3C4lR{4$1zFKfW%^ zN(Uv?kLncxfZE&J!>+C_5%RXa2tYpG1$g1?3ffEzfH__ttIvTk8bx}2WPcpO=(*!k ze(mHZ;pqAA$Ki|&PaXhU+6O>Kfdz2y!h6E|>+f^v>i%2|fF2W2hhu!l%dwxm5<3TV zFsLN}qRANcVVretk~WzLfC;F%x!HAr4I4Iy*ac9>;~Ei#a|4{UxefF=cC-MV!}5rDGE0I+?Yx3kz7;5puo z8!V@BniZ3gQP#1Zg(%63TDyrTefTwA&)YB%<|>S!(1*WLf-c{io3_QriC$~ zOzr~tWB^vE6XQ`|cK}ou&{0qkfa%&gIyx#labO?_1_vd@P^5 z3~+V=C`15F6GSHO17`fDx_~ubn*iF{f?(68aqZYK1_9FL(Ej~n>ggHRUB9hd83di3 zW9sW0o8cWf5(I}2kL^Rc4k8GsCL%xsfO#67l>pH4FgaTyVCz$l1_z#BBHFd4F5ojh zgnfwhEPtzWjZ;kmz<(2-q^i7T0d&+o;sqd@Z2+`M3qW^|ngn25Sp%@+LrsnW7JwcD zY;^Rt=A3F8K+;{HCIL_|h0sR&(z1C$@9G6kET2{YX%|;z^~kgQUG`*$lci|7Jmv2T z(gM&+XcYl~`3S_cyf4TC0M-)i@^{$=2%wNo%lm@V0ASwp0e?i<0H*qVf&G2}-xP51 zR4=RR<#oOAp?b7k4CE+>9ppbYZ+fug1HQtSVCU%-ts zLPi2-i@GlB*`fsiQ%GTutIK6AubcIM-xna>^?yWw27vbk*z|O{+5q&@IlnORg})C# z>h*sM0LHQD7k?&G1)!4e3(~It<3WiV=L3uYJ}F|W+H5iH_XTO!|C0ddxk6O|r2W1i zY5kvO_42rH{U5W%83Uk_?+dg+tO4rvf0kqYKMBB^J)nD+Yu zz4q@+s`Y;j!POPy8w7O(==TM749Il4oc8+y7-L_zYy93%U_1bP?+Z{@&ijJ@0ga8Y UJ`Uq>p#T5?07*qoM6N<$f-q0>asU7T diff --git a/Plain Craft Launcher 2/Images/Skins/Ari.png b/Plain Craft Launcher 2/Images/Skins/Ari.png new file mode 100644 index 0000000000000000000000000000000000000000..6b29537082d4c4f7d25829a55c167a314cafe8b0 GIT binary patch literal 912 zcmV;B18@9^P)FcOD17?VF9okb#}M>w2Ov5QYW1g}P0GB+bd*|8?%1A_ujk`gHftehNl(-pmXkGlzpno6+cT z)TC*e4&T*?0Bwr>_W=fGhr_V>0|1{j!FJw6H9ex@C=sJJ`1DIVIpFkc4qbg3pxdNcalt%b- zA{qKlrs$Yf`yr??IdETpzNYm0sUZxPcz%t9{RL#SPw@WuKnLLLb@ED50hE0JPUbyk zz&XqU$SJsyXl*L*f>M+7oCEKsi}1lzRcoOE4MX40dC?){oLf=39&@(n<4r){55pW5 ztN<56+mJ4Ri~xUQnQuM7>`k`-=UNZ4ch27lVe3Kp6HNtgOG3c;jH4W52+`UI)-bjK zWMOmxbRsmyBZ90wd$7-Fie`{d%l7bTEnQpzUO-*bbm$4scLrqwkRiP@jROMW7VrxI zZQJ3&fJ|BfV!6Z~Y(fBg0)S>f45Wz0GNuGj8p2f$)_{nq3kAV>S?exDr zK=YLcH#eDwe)>xQ^YZ}eam;o3S^li{xBBY>w)xzvmxt$M)RTa>w;%98HYDCBms{HH zBpm+hpKDueabNX*XA}9V+~W$ECZ8Vm0Q!Rblm{3>wFlHE%uPcpwT;Tts;u7=8ZCPU z><6Sc)3FP{K7slLDwk~=2vEvfxbxswxQ5pv67fL@M{lz|D+b@)UKn`C8kbVIlhXL!k mn|*M*fNj4Z{Y24~2Y&#eg=iZ&;-Xh5cDNvX-mt8z@NbTF{b%fWzD z*PS%#-c$GYu>b%6HfkDu00001bW%=J06^y0W&i*KA4x<(R9M69mkV>EFc5%iDa2@N zX&xM;$0ZlV{{Me?`v^*`RdjCVW^THJB+%@a-A%}DA0CouYmK$qbV(j=70?EPv0Yb# z+yMZ6Fv42W2f{r7BvUCKUrf8?~EA$j2-x{e?Vu$JmhFa{p$ct`v*9Eu&TEt;EzEn{P8+K+3gmFnm(Xt z(AjRSrafWcngKAO#^E2YA-sNo`E4DHh6upT7&RmMrVFiZTQVTDt$GigQ5yw80K|0w zj4?mom2H28x3}=?9b6iW-t-&O!=~8uR{`!H5wfuqcWJMgboh4;Q`l-bd)U=%%xm5<_qx zFrWlM04g|Cfd&CCQqNBTFl#kI(5%ia77hm^0B;~PzvFfa5T%f!s+a&RTkVR%H4I=4 zCOB%q!jmNg)02Kx5dem<+c73Zw%jF~G62VbF(SF(ar&4D_!wi8$pirY3sDrK9hF0Y zxZ{)#1CEw7(d9A$fNoLj_S78Zao9hmo}*QK>@vv!Aj44=Lm?z=j*8tX*|zdBU?RBt zmsMH8g}w5r6eV0w{IQZYv=;zrQN_5pOSWLi`j9bdBuoIqZdBb3!+t*qUX1Z4EB>IW zWB~(iPki67a+;3Xa5f)4w;&AmW-ZL94GoYfU!_Wg+ofGr0)Do^CguGj7lk< zDwV7iU#jyTae74dVz`@n%~cMfnz|)>9j7OGl5P8J{!)h0@VwG z9FXF)E{O5U$xswkRxf;+*1wYCq+sB5KFVxBkpT{f?jAsmMZuWd=Nw%p^#WA{7cBS# Xo!5N&J`Y)900000NkvXXu0mjfvWKpr literal 0 HcmV?d00001 diff --git a/Plain Craft Launcher 2/Images/Skins/Kai.png b/Plain Craft Launcher 2/Images/Skins/Kai.png new file mode 100644 index 0000000000000000000000000000000000000000..435c5c9c2542fa5a1dae93a73c52b0817e86bdcf GIT binary patch literal 1279 zcmVGf6DueaD?%I`LuXS+94Sa6BTFeMOf5)HEiGp) zLu?f;ZbWN$Lm+`JE{8&3jyE@vV34J9fU0LOvYW27ay-t6PT!VT=(=s|zs~NZX7bM3 z^3RC&(~bAlcKhOr`|XkZ^s4{={}653BLDyZ0d!JMQvg8b*k%9#1T0BJK~z}7rI(9( zn=lN83mEKq%f?c+jwQg_kN|uC2i!RlP7^|)U6p*qQ1tsqzNrrnqji0M>bq07+tsk$ z?%}=G_izVeH`==aUDuzwzU%%QAOZB<2Naw>s-R;EKcD~rM$pS3U>N>m6yOc3M|;ok zjjnny{tgUWB3p&tf$bnN@b$G$(V1KRfGWdH%*Ftmo3 zm$n7raTp$t>wvaxn+n|yf4?-%m%l_+4IZ{fs2Yy#8vs?^bWkn=nttfJrmjd}Q0+RP z+ErCuBU?@L;|BnJSJxFEwoGDMtpdi0cOrrQr!W;ICvTikSrkRzVc|XwmZWkG&yzGs z0KJ`LnTgET&!4}Z0d=+8RrNezZnKF@HVa4+y2t4m0K%+-DB5nWLSP>2n!Ts|TmhyE z*n5<1H_QVf$y9d*qkAF%K1x*$k@ChFV6qI~?IwzVFvidc($N{kqn$Dj>>CJtaLd1? z7XX9r7S0(NhW&{@`%S?TSK@f(b46doPd8DYMG(WcG;|d%GQ|y?hy^Oc#e>hl=vk8UJC%K^?6?-`@u? zabpN@w=xdsdE#F#03cJ7=$S2M&dS$G^5o(drZf}hIS*XUw>j?O_vWIjpiU}q{4Lfc z-va0&fa1cxcr$?EN{B8*ZSCU3nVK2*XKpUsru9%wlKNs7!l2wwB99mzR6Op{&cdn8 zlI1ng3(MMwX}!R6VphS@#-ai;!w`7r1i+O7yRe*jQu3gaGZ(D!q|?#>=M@){t_Uj& zd#2op^q|w@UI5`xXTvH$mL%4un=QEHkklhn>IE${5;IH_fw%?+rT17N;H8X}lK9pq(nn_2RN=Kq{7_L)Lw0aD+pP0UY4atZN$+4-^krva-#@m$< z;GZYp#k}XLIro&nMgRZ+0d!JMQvg8b*k%9#1CL2WK~z}7?N`y3qA(2AU7)x#6}Jj# z#V{R^|Nq3jNr8iiGu3_AmyIK}J>=#lZIjGu)r*dm(y`V`#qzg$Rqs$7 z3{mmZ0HO;I;`k>dejdQ9M>0wGPamtvr>2N@8cpS|RQVg|hgD@N?N z!Un{$3;je#f`;*X%d7=8yc`>&8AV|DNHI)6@PP1x^)nTl3}%0be#9UA2-ts>v8Bw2 zWNa1>^@Iz0m*8#l`DV=9r-5Fw)9gYNg}I>gZinC>JcC1~d9L(8BEW?xS@ZT8^ZpJO zzpvxUi#D6CZCyL6d35zXK#}KT z5SavjWDiF$Dv4?$9_#5g=B&vf>_=FjCKn-iV4Vjef7|z*Z!t~)e$50HJQ8DK(vbg% zy69*7{S@GG`Q6Lq!pE6S50}Uj@mN0F;MSvN9Hs!Q^l`oR!}U6z%;9wQ_aQTxAeht~ zZd_Q*QohRFtv3`{_2s}XBqP`9P=MuiYX1_TYg8Eh8}?H6m428Hmi^b$>dOJu5A(qi zz->A3DgI$TSj5n?xr$Z~^TC6r;cn?+J_wbvs+aS@zn4>SIw2>XPx!&(>c5B_XT`Rq z<|d6%(>({!bPf&7&eR>FpLEjMg_Mi@F zd;3OV+y&nd^zA`FKA86lQqRpG0SxB-!q5@;{vZHg-Y=jZKvQt&{~HManD-0l2SnfZ c2lwy)0nNmhhc&|m<^TWy07*qoM6N<$f+NlMDgXcg literal 0 HcmV?d00001 diff --git a/Plain Craft Launcher 2/Images/Skins/Noor.png b/Plain Craft Launcher 2/Images/Skins/Noor.png new file mode 100644 index 0000000000000000000000000000000000000000..d1f8a24e528b77586f367958ace5299d9bad2d81 GIT binary patch literal 861 zcmV-j1ETziP)8+b2}$^76yVkB#}okmLd?RDHW$&L#b9exiK8MXG+a^TmS$68L`J=00001bW%=J z06^y0W&i*Jt4TybR9M69meFGBAPk19wXF`pZC!<8aqs_@CxM{AsHOJy{7kE^`3Qj~ zsVWlVOmM+CXKqw$MRuD2!dkK`h`k9ATL8kwKx_c;FBpPJ1jzRRS^_~z{T2Y1p-Jnu z&;5PT4$=ie0xK%rzK&~ygLjYpbk{`y&IEr_o4WyNiN|rxi3H>OT}WeYH}{g_e&^PQ zt`MNXMw{F3r!k+uH=}{31)Ae1i2-=e%~P7=IyyfV0Ud`;M;Y_;1Li0R00sl!3jkMp z^uP}rLwgXf4!}wPsHSb3^T+w)xvY-k`rD&b>wi~D!5ldN2<*=RfH4GELK^|}bp{Z5 zfR7}+wWRePU>vpn0~m82w4uP?9%c7M_Mt}9KpIm3E|diS?)zaUWsO(-QUGwF0yPZ* z>iVz(K%0g3O#^}Idj?C zeY@{{#Oy1)$(R6eL4AK;y!^pB28Rn}=xNtDLckeyxtzToC({Gyl#mB#9(%B|09TvD z#AX2B2B^3wm<2?)3H;2%oZ(pnc?Ytg$n*;_AV>(=%#!IBW&zcV2T{Ke z0@P5D75?-KuDns9&rF;?&S|xtt;+8LC?PnFnS8JW2v?NN3;LxB9;CEipoV~cD*&YZ n0v2@XnX&+o_6x3|nD^ix!7p)xB>!Tv00000NkvXXu0mjfr+#jj literal 0 HcmV?d00001 diff --git a/Plain Craft Launcher 2/Images/Skins/Steve.png b/Plain Craft Launcher 2/Images/Skins/Steve.png index 90d4fa236b5512e124a1aaaa2a2a357cca907e99..c5426101d179bc9b912bf7058a4417727991560c 100644 GIT binary patch delta 947 zcmV;k15EtJ3cd%B8Gi!+005o0f$RVP0CiAIR7C&)003xc0Dpe~q@)0^uK>)<1A2M{ zm6ZjEhzh*CBp3)L8VV>VC@UTfGb9l-B@#C`H##wiKPnYJKR-b=n?fB5MmnWQB@jwV zN>V+ERaI4LKrnVoGj~EYfm1n;UOtdnKa^lTn`23;a#^!^UVpcPYybcMN-miO00001 zbW%=J06^y0W&i*J_en%SR9M69mhD=jFc5`nK}p$?1&UQyg>2IG{x5OQnMss(s}23T z4oD|F&dYoRW>%{xO=EG|W{k30Dvj-N67T}K1^{Co?nT61;Q<1`-}Qh-gK!$ca)4zH zo4y|%Q|PAUfPY?Mu+yl=6*;iXV>3<uPK;6{NPvdVlJ%7Bu-a{ED?{JfVCI>J&*po2c zKis4K4h!$N9e+SF-^vcsw%cu5-v%Ijxb32(`(;@c2sNAqY`1Ou4uCxfX8}l)yX?Vd zfDHjT9()o)At9W2Fbv(W-|sv83{biXg6E*DMX7p$D@ExqKn#ZjFn4#RfC(?uNg%5f^P&;}7Uuyt?;y#DI^%|3tfSmO z_U>id14&NggS*hP??22>R)m0oom`e$jMCb*IIEKL%!05D}EU0=xqJ9MHBq z8tz)r+PI}r7GpFoVByLFXbznqR^Rep%0`9zx+tN1XXIP5=7o8)Wl!SgXc1uE?g?=I zOn+O?_h3_=oeLItP`KRhpw0_J>ehqK1KQe;=7O&PVySb(UfX#j%;$oy0A1|&2~b62 zLh?Nz09u*{lBDlJ`ab*%IGGo89?*8ezIfRK?XfztKxZ$Cqd~|jM$B(XhbY@)OiG!~coxz7Zg&I`#tB`o10;B;O{^FT_&Wx&b2pcQ2LbUrx!|G(p3 Vcgte-PO$(0002ovPDHLkV1lV2rd+f>o>DPSE>~H$b;hY)w zqRy^!;L9A({Lb0=e$HjjdM1$wN%gB160~8(Jd$~6&EiVBaep`+s6?qJHk@9wNJ#>K zV6t!THhO%j$-6>j1%S=h)l^skB$G*>P*xTIxcBvGz-46*K$^t}faG+T697!+!vJ)o z>dFTI8{fQgfy!g`*8!MRHUQYT6pxIO{~AoyRuBYJn`$eS+3m^2v~{hk^xB2gu-aV* zQY$OfLWo$D0e=9;p$_Vz4czB;!}bx80sw7UU8Rh`;EoN|>dM03`|FobYyC162Ou1S zIw<3IB!HlO#H<5Q552`ntwjsy+Yp~4XW#x;XxY9T%g}0 z85+BGObIcFMIF>d9&Mpb{2jKBh|Cmlr@;bBE}u_N&bH9lrGwOxTB^(=b?hFYA9t=Q z^T;Cs3Stn8I;e{_WSe38i0A-tddwZR)%2*Nkw!1>qo?Pa9dn21+npZz^&sPYz5RJQ zKp*-J(|@qD=SK`;Q3rL=2KT;P1a13>NUQ;PPz>9iwlux%J3((Q9q@k8yy|Lm4DO{{ z`*-^EvTG0BKh>;a5Q{pfi#F60$WDi_eZ;H-;9qZSdhF^E)uYeO?V{^P(lm5%3k|l_ zE3?q;<2&f#>0L_5BL=bWd)rmrHpIo-P|HW3{cuS#A#QKls0A(X)s>+4rn{I@Nh zV}JDfT%R=+05F&j07!jkZ?7xl`N6XgJoEfOG9HqqrMMj#%Lcg)1J&>61Hfi56oBag z`62Ou7!lH>jE79-Wg8~IGG^8RVA%5mATK|h0mw32JjcPH%SI&Jdg5%p@cTmwWq&e8zn>QXHYZ1b6@WAY7!rWVm;}aCz*HwY z)J*_JhdMojTwYWFIj;da0NML;#g+i%8lah$K%_Yx0IntgsyrJr<*&iK0qAou41oSE zV2ZT>(0f=1V45OD0T6UQa1qkK0dxSSMN5-3X9EzlMuY-rZEYne3;@UV_xJnc8Gqu9 z2=|`e`!)bF-mo4>bEY{i0mv!9*C_+A84SBGrwFb(KySw=0O%VpZ$ag0;)oYv8vr(G z8X>a=z%+t<5FBHnTWcpqmgzn0TL2xI)`*+{#3@d3ic_586sI`FDNb>UQ=H-yr#Kaw z3O-yd_TgvA0npC>=N0+9!h>-z=#-(KIjf|UGMy6Js_Tn|5^0>F0P zdiu*CY$r*j1R&^s;7O6`c)aWZ6#M*tCIA%je!;Y#|IZWv(@|G00K$&GA`PIBDWC(8 z$67i7`F_BZ&;O$Wz&1tn!%g}2hkp8-*YWpE0m%3L0)2>^02K5B#B`@Z-#0HXo$uQK zn5IZ%0OWhTZtCHnm!QfLfNvob3!MH6%yai_@% diff --git a/Plain Craft Launcher 2/Images/Skins/Sunny.png b/Plain Craft Launcher 2/Images/Skins/Sunny.png new file mode 100644 index 0000000000000000000000000000000000000000..aa0e6f2e976039f250d289543c991973ef42b722 GIT binary patch literal 988 zcmV<210(#2P)p#uf0S{MymC%8cAF-5Lm+pDoqC%x zepx+#Q8R**tA&Myg{e1;TRNX+Kcl0guw^&8y1Kz~KiGsz*x1u_v~dv9ddCpjgrFvOCj<}k0tm1Kyfk#bUNA*E z_79jSgoTE{^T0WUV6j+SU0v~X&`^WAG`RT4Sd0>Ex7)flThBb78*~0_ysfG0?F&W; zilU%HE6UoT{6Ys=0AC43F-pK`gM+K<`+L%YBjm9kjPc{NnUCDT{>Y-TgGsp{qe!mj z^L5kD1ca!}cWB17(h4G9C72VMz7lXkEB^yyPmt+M*X9*feFd5cl3GAgvCgQ06Y6cAeT$4Kx&1_Qx*6Pfgl?Lk8!M=0&v8!j4ylW5-gXE3zDNoEuzq| z0}YD<1j5DuL8O-LlP`i~fa^h$z(`W??Yqj^J%Qf?$7G2m0v#bA1b1q~xsFrh#$kep z6hslbC4CW*2H8BVB%w=S?2~8>eVBknlV6Anhgh}<%z)tKKLpN;h$KWVH+%^`QMYHc z3Gfij*Xwy>;e?OlurcraK=-cj%${}etE zz7raIG{K6X@9uPCf1R`qaC^IH>|nyf2*EY5*<3evFyY&&5>F=h{8uK;;I^g(5V-WQP8g!-n^CHCg|1+Z`K8e2-@|+dlc;J1>8veYkl;+00M#A zea83GfME2!(61M`TulgRir;edebB$|Q)AMEa=;=@M&Ad00_>dTJG*|Dr=vma*9!?F zwJy+S3PGn{NRm9?dyr31(61L#-u*xf`smjSd6HxOZfD~#Q1BCG!K^_81F(FY=QC~hOY(6J#NHBFgD1K8ne#Rle6*zc9Zf4&&=@~JflijzP#^8mVD)7P4_ z7&sGvN};uqLeAffg6^A^4Bp<50W74G7|sHQnO87F^OKm)ET2%0bRZ3%%Lc(s>D&*J zbHn-2_rX+E{SfzAsB_8{Hmco7T zo=QORxWJDAQ5+BfFHcv)DqZhs%tKNSL|_B3VEqli@rghJpl7q>Abm4J%ZbJS#Ji3y zL>CZ*5J0@;a2j}>W+saUcPSuP;v=UZ;i#B}d&CDV^Bo90E#|%kFPrSx*Zv|qqBv&zA= zUqA|r9iUCP-1iGMZIsw!{gV8#&t3Zk-p(zy_khDL08s3xUyz0(q<+CK07M2{`-N#= zfb}3P4OkZ1X8@VgX-69R0llh2NIy#;6VBT*`2HT8ch2Iv;*h|hW=m{Fzpwp9VpNbNCNePgP-*t VegO>y4BG$z002ovPDHLkV1hD6q{jdN literal 0 HcmV?d00001 diff --git a/Plain Craft Launcher 2/Modules/Base/ModBase.vb b/Plain Craft Launcher 2/Modules/Base/ModBase.vb index 7d20b7a..97f6af3 100644 --- a/Plain Craft Launcher 2/Modules/Base/ModBase.vb +++ b/Plain Craft Launcher 2/Modules/Base/ModBase.vb @@ -10,12 +10,12 @@ Public Module ModBase #Region "声明" '下列版本信息由更新器自动修改 - Public Const VersionBaseName As String = "2.4.0" '不含分支前缀的显示用版本名 - Public Const VersionStandardCode As String = "2.4.0." & VersionBranchCode '标准格式的四段式版本号 + Public Const VersionBaseName As String = "2.4.1" '不含分支前缀的显示用版本名 + Public Const VersionStandardCode As String = "2.4.1." & VersionBranchCode '标准格式的四段式版本号 #If BETA Then - Public Const VersionCode As Integer = 265 'Release + Public Const VersionCode As Integer = 268 'Release #Else - Public Const VersionCode As Integer = 266 'Snapshot + Public Const VersionCode As Integer = 267 'Snapshot #End If '自动生成的版本信息 Public Const VersionDisplayName As String = VersionBranchName & " " & VersionBaseName @@ -1236,7 +1236,7 @@ Re: Directory.CreateDirectory(DestDirectory) If CompressFilePath.EndsWith(".zip") OrElse CompressFilePath.EndsWith(".jar") Then '以 zip 方式解压 - ZipFile.ExtractToDirectory(CompressFilePath, DestDirectory, If(Encode, Encoding.Default)) + ZipFile.ExtractToDirectory(CompressFilePath, DestDirectory, If(Encode, Encoding.GetEncoding("GB18030"))) Return True ElseIf CompressFilePath.EndsWith(".gz") Then '以 gz 方式解压 @@ -2301,7 +2301,7 @@ Retry: RunInNewThread(Sub() Dim IsInitSuccess As Boolean = True Try - For i = 4 To 1 + For i = 4 To 1 Step -1 If File.Exists(Path & "PCL\Log" & i & ".txt") Then If File.Exists(Path & "PCL\Log" & (i + 1) & ".txt") Then File.Delete(Path & "PCL\Log" & (i + 1) & ".txt") CopyFile(Path & "PCL\Log" & i & ".txt", Path & "PCL\Log" & (i + 1) & ".txt") diff --git a/Plain Craft Launcher 2/Modules/Base/ModNet.vb b/Plain Craft Launcher 2/Modules/Base/ModNet.vb index 586a6ed..6ce6665 100644 --- a/Plain Craft Launcher 2/Modules/Base/ModNet.vb +++ b/Plain Craft Launcher 2/Modules/Base/ModNet.vb @@ -96,7 +96,9 @@ Retry: ''' ''' 网页的 Url。 ''' 网页的编码,通常为 UTF-8。 - Public Function NetGetCodeByRequestRetry(Url As String, Optional Encode As Encoding = Nothing, Optional Accept As String = "", Optional IsJson As Boolean = False) + ''' 如果第一次尝试失败,换用的备用 URL。 + Public Function NetGetCodeByRequestRetry(Url As String, Optional Encode As Encoding = Nothing, Optional Accept As String = "", + Optional IsJson As Boolean = False, Optional BackupUrl As String = Nothing) Dim RetryCount As Integer = 0 Dim RetryException As Exception = Nothing Dim StartTime As Long = GetTimeTick() @@ -107,12 +109,12 @@ Retry: Return NetGetCodeRequest(Url, Encode, 10000, IsJson, Accept) Case 1 '慢速重试 Thread.Sleep(500) - Return NetGetCodeRequest(Url, Encode, 30000, IsJson, Accept) + Return NetGetCodeRequest(If(BackupUrl, Url), Encode, 30000, IsJson, Accept) Case Else '快速重试 If GetTimeTick() - StartTime > 5500 Then '若前两次加载耗费 5 秒以上,才进行重试 Thread.Sleep(500) - Return NetGetCodeRequest(Url, Encode, 4000, IsJson, Accept) + Return NetGetCodeRequest(If(BackupUrl, Url), Encode, 4000, IsJson, Accept) Else Throw RetryException End If diff --git a/Plain Craft Launcher 2/Modules/Minecraft/ModCrash.vb b/Plain Craft Launcher 2/Modules/Minecraft/ModCrash.vb index ec52624..6a19aa1 100644 --- a/Plain Craft Launcher 2/Modules/Minecraft/ModCrash.vb +++ b/Plain Craft Launcher 2/Modules/Minecraft/ModCrash.vb @@ -458,7 +458,9 @@ Done: If LogMc.Contains("Cannot read field ""ofTelemetry"" because ""net.optifine.Config.gameSettings"" is null") Then AppendReason(CrashReason.OptiFine与Forge不兼容) If LogMc.Contains("TRANSFORMER/net.optifine/net.optifine.reflect.Reflector.(Reflector.java") Then AppendReason(CrashReason.OptiFine与Forge不兼容) If LogMc.Contains("Open J9 is not supported") OrElse LogMc.Contains("OpenJ9 is incompatible") OrElse LogMc.Contains(".J9VMInternals.") Then AppendReason(CrashReason.使用OpenJ9) + If LogMc.Contains("Unsupported class file major version") Then AppendReason(CrashReason.Java版本过高) If LogMc.Contains("because module java.base does not export") Then AppendReason(CrashReason.Java版本过高) + If LogMc.Contains("java.lang.ClassNotFoundException: jdk.nashorn.api.scripting.NashornScriptEngineFactory") Then AppendReason(CrashReason.Java版本过高) If LogMc.Contains("java.lang.ClassNotFoundException: java.lang.invoke.LambdaMetafactory") Then AppendReason(CrashReason.Java版本过高) If LogMc.Contains("The directories below appear to be extracted jar files. Fix this before you continue.") Then AppendReason(CrashReason.Mod文件被解压) If LogMc.Contains("Extracted mod jars found, loading will NOT continue") Then AppendReason(CrashReason.Mod文件被解压) @@ -468,7 +470,7 @@ Done: If LogMc.Contains("1282: Invalid operation") Then AppendReason(CrashReason.光影或资源包导致OpenGL1282错误) If LogMc.Contains("signer information does not match signer information of other classes in the same package") Then AppendReason(CrashReason.文件或内容校验失败, If(RegexSeek(LogMc, "(?<=class "")[^']+(?=""'s signer information)"), "").TrimEnd(vbCrLf)) If LogMc.Contains("An exception was thrown, the game will display an error screen and halt.") Then AppendReason(CrashReason.Forge报错, If(RegexSeek(LogMc, "(?<=the game will display an error screen and halt[\s\S]+?Exception: )[\s\S]+?(?=\n\tat)"), "").TrimEnd(vbCrLf)) - If LogMc.Contains("A potential solution has been determined:") Then AppendReason(CrashReason.Fabric报错并给出解决方案, Join(RegexSearch(If(RegexSeek(LogMc, "(?<=A potential solution has been determined:\n)(\t - [^\n]+\n)+"), ""), "(?<=\t)[^\n]+"), vbLf)) + If LogMc.Contains("A potential solution has been determined:") Then AppendReason(CrashReason.Fabric报错并给出解决方案, Join(RegexSearch(If(RegexSeek(LogMc, "(?<=A potential solution has been determined:\n)((\t)+ - [^\n]+\n)+"), ""), "(?<=(\t)+)[^\n]+"), vbLf)) If LogMc.Contains("Maybe try a lower resolution resourcepack?") Then AppendReason(CrashReason.材质过大或显卡配置不足) If LogMc.Contains("java.lang.NoSuchMethodError: net.minecraft.world.server.ChunkManager$ProxyTicketManager.shouldForceTicks(J)Z") AndAlso LogMc.Contains("OptiFine") Then AppendReason(CrashReason.OptiFine导致无法加载世界) If LogMc.Contains("Could not reserve enough space") Then @@ -773,7 +775,7 @@ Redo: Case CrashReason.使用JDK ResultString = "游戏似乎因为使用 JDK,或 Java 版本过高而崩溃了。\n请在启动设置的 Java 选择一项中改用 JRE 8(Java 8),然后再启动游戏。\n如果你没有安装 JRE 8,你可以从网络中下载、安装一个。" Case CrashReason.Java版本过高 - ResultString = "游戏似乎因为你所使用的 Java 版本过高而崩溃了。\n请在启动设置的 Java 选择一项中改用 JRE 8(Java 8),然后再启动游戏。\n如果你没有安装 JRE 8,你可以从网络中下载、安装一个。" + ResultString = "游戏似乎因为你所使用的 Java 版本过高而崩溃了。\n请在启动设置的 Java 选择一项中改用较低版本的 Java,然后再启动游戏。\n如果没有,可以从网络中下载、安装一个。" Case CrashReason.使用32位Java导致JVM无法分配足够多的内存 If Environment.Is64BitOperatingSystem Then ResultString = "你似乎正在使用 32 位 Java,这会导致 Minecraft 无法使用 1GB 以上的内存,进而造成崩溃。\n\n请在启动设置的 Java 选择一项中改用 64 位的 Java 再启动游戏,然后再启动游戏。\n如果你没有安装 64 位的 Java,你可以从网络中下载、安装一个。" diff --git a/Plain Craft Launcher 2/Modules/Minecraft/ModDownload.vb b/Plain Craft Launcher 2/Modules/Minecraft/ModDownload.vb index 9c8d1a3..a3fb70b 100644 --- a/Plain Craft Launcher 2/Modules/Minecraft/ModDownload.vb +++ b/Plain Craft Launcher 2/Modules/Minecraft/ModDownload.vb @@ -237,7 +237,9 @@ ''' Public DlClientListBmclapiLoader As New LoaderTask(Of Integer, DlClientListResult)("DlClientList Bmclapi", AddressOf DlClientListBmclapiMain) Private Sub DlClientListBmclapiMain(Loader As LoaderTask(Of Integer, DlClientListResult)) - Dim Json As JObject = NetGetCodeByRequestRetry("https://bmclapi2.bangbang93.com/mc/game/version_manifest.json", IsJson:=True) + Dim Json As JObject = NetGetCodeByRequestRetry("https://bmclapi2.bangbang93.com/mc/game/version_manifest.json", + BackupUrl:="https://download.mcbbs.net/mc/game/version_manifest.json", + IsJson:=True) Try Dim Versions As JArray = Json("versions") If Versions.Count < 200 Then Throw New Exception("获取到的版本列表长度不足(" & Json.ToString & ")") @@ -331,6 +333,10 @@ ''' 发布时间,格式为“yyyy/mm/dd”。OptiFine 源无此数据。 ''' Public ReleaseTime As String + ''' + ''' 需要的最低 Forge 版本。空字符串为无限制,“28.1.56” 表示版本号,“1161” 表示版本号的最后一位。 + ''' + Public RequiredForgeVersion As String End Class ''' @@ -365,21 +371,23 @@ Dim Result As String = NetGetCodeByClient("https://optifine.net/downloads", Encoding.Default) If Result.Length < 200 Then Throw New Exception("获取到的版本列表长度不足(" & Result & ")") '获取所有版本信息 - Dim ReleaseTime As List(Of String) = RegexSearch(Result, "(?<=Date'>)[^<]+") + Dim Forge As List(Of String) = RegexSearch(Result, "(?<=colForge'>)[^<]*") + Dim ReleaseTime As List(Of String) = RegexSearch(Result, "(?<=colDate'>)[^<]+") Dim Name As List(Of String) = RegexSearch(Result, "(?<=OptiFine_)[0-9A-Za-z_.]+(?=.jar"")") If Not ReleaseTime.Count = Name.Count Then Throw New Exception("版本与发布时间数据无法对应") + If Not Forge.Count = Name.Count Then Throw New Exception("版本与 Forge 兼容数据无法对应") If ReleaseTime.Count < 10 Then Throw New Exception("获取到的版本数量不足(" & Result & ")") '转化为列表输出 Dim Versions As New List(Of DlOptiFineListEntry) For i = 0 To ReleaseTime.Count - 1 Name(i) = Name(i).Replace("_", " ") Dim Entry As New DlOptiFineListEntry With { - .NameDisplay = Name(i).ToString.Replace("HD U ", "").Replace(".0 ", " "), + .NameDisplay = Name(i).Replace("HD U ", "").Replace(".0 ", " "), .ReleaseTime = Join({ReleaseTime(i).Split(".")(2), ReleaseTime(i).Split(".")(1), ReleaseTime(i).Split(".")(0)}, "/"), - .IsPreview = Name(i).ToString.ToLower.Contains("pre"), + .IsPreview = Name(i).ToLower.Contains("pre"), .Inherit = Name(i).ToString.Split(" ")(0), - .NameFile = If(Name(i).ToString.ToLower.Contains("pre"), "preview_", "") & - "OptiFine_" & Name(i).ToString.Replace(" ", "_") & ".jar"} + .NameFile = If(Name(i).ToLower.Contains("pre"), "preview_", "") & "OptiFine_" & Name(i).Replace(" ", "_") & ".jar", + .RequiredForgeVersion = Forge(i).Replace("Forge ", "").Replace("#", "")} Entry.NameVersion = Entry.Inherit & "-OptiFine_" & Name(i).ToString.Replace(" ", "_").Replace(Entry.Inherit & "_", "") Versions.Add(Entry) Next @@ -391,7 +399,8 @@ ''' Public DlOptiFineListBmclapiLoader As New LoaderTask(Of Integer, DlOptiFineListResult)("DlOptiFineList Bmclapi", AddressOf DlOptiFineListBmclapiMain) Private Sub DlOptiFineListBmclapiMain(Loader As LoaderTask(Of Integer, DlOptiFineListResult)) - Dim Json As JArray = NetGetCodeByRequestRetry("https://bmclapi2.bangbang93.com/optifine/versionList", IsJson:=True) + Dim Json As JArray = NetGetCodeByRequestRetry("https://bmclapi2.bangbang93.com/optifine/versionList", + BackupUrl:="https://download.mcbbs.net/optifine/versionList", IsJson:=True) Try Dim Versions As New List(Of DlOptiFineListEntry) For Each Token As JObject In Json @@ -400,7 +409,8 @@ .ReleaseTime = "", .IsPreview = Token("patch").ToString.ToLower.Contains("pre"), .Inherit = Token("mcversion").ToString, - .NameFile = Token("filename").ToString + .NameFile = Token("filename").ToString, + .RequiredForgeVersion = If(Token("forge"), "").ToString.Replace("Forge ", "").Replace("#", "") } Entry.NameVersion = Entry.Inherit & "-OptiFine_" & (Token("type").ToString & " " & Token("patch").ToString).Replace(".0 ", " ").Replace(" ", "_").Replace(Entry.Inherit & "_", "") Versions.Add(Entry) @@ -473,7 +483,8 @@ ''' Public DlForgeListBmclapiLoader As New LoaderTask(Of Integer, DlForgeListResult)("DlForgeList Bmclapi", AddressOf DlForgeListBmclapiMain) Private Sub DlForgeListBmclapiMain(Loader As LoaderTask(Of Integer, DlForgeListResult)) - Dim Result As String = NetGetCodeByRequestRetry("https://bmclapi2.bangbang93.com/forge/minecraft", Encoding.Default) + Dim Result As String = NetGetCodeByRequestRetry("https://bmclapi2.bangbang93.com/forge/minecraft", Encoding.Default, + BackupUrl:="https://download.mcbbs.net/forge/minecraft") If Result.Length < 200 Then Throw New Exception("获取到的版本列表长度不足(" & Result & ")") '获取所有版本信息 Dim Names As List(Of String) = RegexSearch(Result, "[0-9.]+(_pre[0-9]?)?") @@ -665,7 +676,8 @@ ''' Forge 版本列表,BMCLAPI。 ''' Public Sub DlForgeVersionBmclapiMain(Loader As LoaderTask(Of String, List(Of DlForgeVersionEntry))) - Dim Json As JArray = NetGetCodeByRequestRetry("https://bmclapi2.bangbang93.com/forge/minecraft/" & Loader.Input, IsJson:=True) + Dim Json As JArray = NetGetCodeByRequestRetry("https://bmclapi2.bangbang93.com/forge/minecraft/" & Loader.Input, + BackupUrl:="https://download.mcbbs.net/forge/minecraft/" & Loader.Input, IsJson:=True) Dim Versions As New List(Of DlForgeVersionEntry) Try Dim Recommended As String = McDownloadForgeRecommendedGet(Loader.Input) @@ -812,7 +824,7 @@ .IsPreview = RealEntry("stream").ToString.ToLower = "snapshot", .FileName = "liteloader-installer-" & Pair.Key & If(Pair.Key = "1.8" OrElse Pair.Key = "1.9", ".0", "") & "-00-SNAPSHOT.jar", .MD5 = RealEntry("md5"), - .ReleaseTime = GetLocalTime(GetDate(RealEntry("timestamp"))).ToString("yyyy/MM/dd HH:mm:ss"), + .ReleaseTime = GetLocalTime(GetDate(RealEntry("timestamp"))).ToString("yyyy/MM/dd HH:mm"), .JsonToken = RealEntry }) Next @@ -827,7 +839,8 @@ ''' Public DlLiteLoaderListBmclapiLoader As New LoaderTask(Of Integer, DlLiteLoaderListResult)("DlLiteLoaderList Bmclapi", AddressOf DlLiteLoaderListBmclapiMain) Private Sub DlLiteLoaderListBmclapiMain(Loader As LoaderTask(Of Integer, DlLiteLoaderListResult)) - Dim Result As JObject = NetGetCodeByRequestRetry("https://bmclapi2.bangbang93.com/maven/com/mumfrey/liteloader/versions.json", IsJson:=True) + Dim Result As JObject = NetGetCodeByRequestRetry("https://bmclapi2.bangbang93.com/maven/com/mumfrey/liteloader/versions.json", + BackupUrl:="https://download.mcbbs.net/maven/com/mumfrey/liteloader/versions.json", IsJson:=True) Try Dim Json As JObject = Result("versions") Dim Versions As New List(Of DlLiteLoaderListEntry) @@ -840,7 +853,7 @@ .IsPreview = RealEntry("stream").ToString.ToLower = "snapshot", .FileName = "liteloader-installer-" & Pair.Key & If(Pair.Key = "1.8" OrElse Pair.Key = "1.9", ".0", "") & "-00-SNAPSHOT.jar", .MD5 = RealEntry("md5"), - .ReleaseTime = GetLocalTime(GetDate(RealEntry("timestamp"))).ToString("yyyy/MM/dd HH:mm:ss"), + .ReleaseTime = GetLocalTime(GetDate(RealEntry("timestamp"))).ToString("yyyy/MM/dd HH:mm"), .JsonToken = RealEntry }) Next @@ -913,7 +926,8 @@ ''' Public DlFabricListBmclapiLoader As New LoaderTask(Of Integer, DlFabricListResult)("DlFabricList Bmclapi", AddressOf DlFabricListBmclapiMain) Private Sub DlFabricListBmclapiMain(Loader As LoaderTask(Of Integer, DlFabricListResult)) - Dim Result As JObject = NetGetCodeByRequestRetry("https://bmclapi2.bangbang93.com/fabric-meta/v2/versions", IsJson:=True) + Dim Result As JObject = NetGetCodeByRequestRetry("https://bmclapi2.bangbang93.com/fabric-meta/v2/versions", + BackupUrl:="https://download.mcbbs.net/fabric-meta/v2/versions", IsJson:=True) Try Dim Output = New DlFabricListResult With {.IsOfficial = False, .SourceName = "BMCLAPI", .Value = Result} If Output.Value("game") Is Nothing OrElse Output.Value("loader") Is Nothing OrElse Output.Value("installer") Is Nothing Then Throw New Exception("获取到的列表缺乏必要项") @@ -939,7 +953,7 @@ #Region "DlCfProject | CurseForge 工程" - Private DlCfProjectDb As Dictionary(Of String, String) = Nothing + Private DlCfProjectDb As Dictionary(Of String, DlCfDbEntry) = Nothing Private DlCfProjectCache As New Dictionary(Of Integer, DlCfProject) ''' @@ -988,7 +1002,6 @@ Public Id As Integer Public Name As String - Public McWikiId As Integer = 0 Public Description As String Public Website As String Public DateUpdate As Date @@ -1000,22 +1013,19 @@ Public IsModPack As Boolean Public FileIndexes As New List(Of Integer) Public Files As List(Of DlCfFile) - Private _MCBBS As String - Public Property MCBBS As String + Private _MCBBS As Integer? + Public Property MCBBS As Integer? Get ReleaseCfDatabase() If _MCBBS Is Nothing Then If Website IsNot Nothing Then Dim Keyword As String = Website.TrimEnd("/").Split("/").Last - If DlCfProjectDb.ContainsKey(Keyword) Then - Dim Result As String() = DlCfProjectDb(Keyword).ToString.Split("|") - If Result.Length = 3 Then _MCBBS = Result.Last - End If + If DlCfProjectDb.ContainsKey(Keyword) Then _MCBBS = DlCfProjectDb(Keyword).MCBBS End If End If Return _MCBBS End Get - Set(value As String) + Set(value As Integer?) _MCBBS = value End Set End Property @@ -1028,20 +1038,42 @@ If Website IsNot Nothing Then Dim Keyword As String = Website.TrimEnd("/").Split("/").Last If DlCfProjectDb.ContainsKey(Keyword) Then - Dim Result As String = DlCfProjectDb(Keyword) - McWikiId = Result.Split("|")(0) - If Not Result.Split("|")(1) = "~" Then '使用原名 - _ChineseName = Result.Split("|")(1) + Dim Result = DlCfProjectDb(Keyword) + If Not String.IsNullOrEmpty(Result.ChineseName) Then '使用原名 + _ChineseName = Result.ChineseName End If End If End If End If Return _ChineseName End Get - Set(ByVal value As String) + Set(value As String) _ChineseName = value End Set End Property + Private _WikiId As Integer = -1 + ''' + ''' MCMOD 的页面 ID。若为 0 则代表没有对应页面。 + ''' + Public Property WikiId As Integer + Get + ReleaseCfDatabase() + If _WikiId = -1 Then + If Website IsNot Nothing Then + Dim Keyword As String = Website.TrimEnd("/").Split("/").Last + If DlCfProjectDb.ContainsKey(Keyword) Then + _WikiId = DlCfProjectDb(Keyword).WikiId + Else + _WikiId = 0 + End If + End If + End If + Return _WikiId + End Get + Set(value As Integer) + _WikiId = value + End Set + End Property ''' ''' 从 CurseForge 工程 Json 项中初始化实例。若出错会抛出异常。 @@ -1180,7 +1212,8 @@ If(ShowVersionDesc, GameVersionDesc, "") & Join(CategoryDesc, ",") & " (" & GetTimeSpanString(DateUpdate - Date.Now) & "更新" & - If(DownloadCount > 0, "," & If(DownloadCount > 100000, Math.Round(DownloadCount / 10000) & " 万次下载)", DownloadCount & " 次下载)"), "") + If(DownloadCount > 0, + "," & If(DownloadCount > 100000, Math.Round(DownloadCount / 10000) & " 万次下载", DownloadCount & " 次下载"), "") & ")" If Thumb Is Nothing Then NewItem.Logo = "pack://application:,,,/images/Icons/NoIcon.png" Else @@ -1217,8 +1250,9 @@ ''' CurseForge 工程列表获取事件。 ''' Public Sub DlCfProjectSub(Task As LoaderTask(Of DlCfProjectRequest, DlCfProjectResult)) - Dim RawFilter As String = If(Task.Input.SearchFilter, "").Trim.ToLower + Dim RawFilter As String = If(Task.Input.SearchFilter, "").Trim Task.Input.SearchFilter = RawFilter + RawFilter = RawFilter.ToLower Log("[Download] CurseForge 工程列表搜索原始文本:" & RawFilter) '中文请求关键字处理 Dim IsChineseSearch As Boolean = RegexCheck(RawFilter, "[\u4e00-\u9fbb]") @@ -1227,12 +1261,12 @@ ReleaseCfDatabase() '构造搜索请求 Dim SearchEntries As New List(Of SearchEntry(Of String)) - For Each Entry In DlCfProjectDb - If Entry.Value.ToString.Contains("动态的树") Then Continue For '傻逼 Mod 的附属太多了 + For Each Entry In DlCfProjectDb.Values + If If(Entry.ChineseName, "").Contains("动态的树") Then Continue For '傻逼 Mod 的附属太多了 SearchEntries.Add(New SearchEntry(Of String) With { - .Item = Entry.Value.ToString.Split("|")(1), + .Item = Entry.ChineseName, .SearchSource = New List(Of KeyValuePair(Of String, Double)) From { - New KeyValuePair(Of String, Double)(Entry.Value.ToString.Replace(" (", "|").Split("|")(1), 1) + New KeyValuePair(Of String, Double)(Entry.ChineseName & Entry.CurseForgeId, 1) } }) Next @@ -1258,12 +1292,12 @@ '驼峰英文请求关键字处理 Dim SpacedKeywords = RegexReplace(Task.Input.SearchFilter, "$& ", "([A-Z]+|[a-z]+?)(?=[A-Z]+[a-z]+[a-z ]*)") Dim ConnectedKeywords = Task.Input.SearchFilter.Replace(" ", "") - Dim AllPossibleKeywords = SpacedKeywords & " " & If(IsChineseSearch, Task.Input.SearchFilter, ConnectedKeywords & " " & RawFilter) + Dim AllPossibleKeywords = (SpacedKeywords & " " & If(IsChineseSearch, Task.Input.SearchFilter, ConnectedKeywords & " " & RawFilter)).ToLower '最终处理关键字:分割、去重 Dim RightKeywords As New List(Of String) For Each Keyword In AllPossibleKeywords.Split(" ") If Keyword.Trim = "" Then Continue For - If Keyword = "forge" OrElse Keyword = "fabric" OrElse Keyword = "for" Then 'https://github.com/Hex-Dragon/PCL2/issues/208 + If Keyword = "forge" OrElse Keyword = "fabric" OrElse Keyword = "for" OrElse Keyword = "mod" Then 'https://github.com/Hex-Dragon/PCL2/issues/208 Log("[Download] 已跳过搜索关键词 " & Keyword, LogLevel.Developer) Continue For End If @@ -1342,16 +1376,42 @@ ''' Private Sub ReleaseCfDatabase() If DlCfProjectDb IsNot Nothing Then Exit Sub - DlCfProjectDb = New Dictionary(Of String, String) - For Each Entry In CType(GetJson(DecodeBytes(GetResources("ModData"))), JObject) - Dim Result As String = Entry.Value.ToString - If Not Result.Split("|")(1) = "~" Then '处理 * - Result = Result.Replace("*", " (" & - String.Join(" ", Entry.Key.Split("-").Select(Function(w) w.Substring(0, 1).ToUpper & w.Substring(1, w.Length - 1))) & ")") + DlCfProjectDb = New Dictionary(Of String, DlCfDbEntry) + For Each Line In DecodeBytes(GetResources("ModData")).Split(vbLf) + Dim Entry = New DlCfDbEntry + Dim SplitedLine = Line.Split("|") + Entry.CurseForgeId = SplitedLine(0) + Entry.WikiId = SplitedLine(1) + Entry.ChineseName = SplitedLine(2) + Entry.MCBBS = If(SplitedLine.Count = 4, SplitedLine(3), Nothing) + If Entry.ChineseName.Contains("*") Then '处理 * + Entry.ChineseName = Entry.ChineseName.Replace("*", " (" & + String.Join(" ", Entry.CurseForgeId.Split("-").Select(Function(w) w.Substring(0, 1).ToUpper & w.Substring(1, w.Length - 1))) & ")") End If - DlCfProjectDb.Add(Entry.Key, Result) + DlCfProjectDb.Add(Entry.CurseForgeId, Entry) Next End Sub + Public Class DlCfDbEntry + ''' + ''' McMod 的 ID。 + ''' + Public WikiId As Integer + ''' + ''' 中文译名。若为 Nothing 或空字符串则使用英文名。 + ''' + Public ChineseName As String + ''' + ''' MCBBS 发布帖编号(例如 195107)。若为 Nothing 则没有发布帖。 + ''' + Public MCBBS As Integer? + ''' + ''' CurseForge ID(例如 advanced-solar-panels)。 + ''' + Public CurseForgeId As String + Public Overrides Function ToString() As String + Return CurseForgeId & "|" & WikiId & "|" & ChineseName & If(MCBBS Is Nothing, "", "|" & MCBBS) + End Function + End Class #End Region diff --git a/Plain Craft Launcher 2/Modules/Minecraft/ModLaunch.vb b/Plain Craft Launcher 2/Modules/Minecraft/ModLaunch.vb index e417841..dffc6c8 100644 --- a/Plain Craft Launcher 2/Modules/Minecraft/ModLaunch.vb +++ b/Plain Craft Launcher 2/Modules/Minecraft/ModLaunch.vb @@ -56,6 +56,7 @@ Public Module ModLaunch New LoaderTask(Of Process, Integer)("等待游戏窗口出现", AddressOf McLaunchWait) With {.ProgressWeight = 1}, New LoaderTask(Of Integer, Integer)("结束处理", AddressOf McLaunchEnd) With {.ProgressWeight = 1} }) With {.Show = False} + If McLoginLoader.State = LoadState.Finished Then McLoginLoader.State = LoadState.Waiting '要求重启登录主加载器,它会自行决定是否启动副加载器 '等待加载器执行并更新 UI McLaunchLoaderReal = LaunchLoader LaunchLoader.Start() @@ -378,7 +379,7 @@ NextInner: Return LoginData End Function Private Sub McLoginStart(Data As LoaderTask(Of McLoginData, McLoginResult)) - McLaunchLog("登录线程已启动") + McLaunchLog("登录加载已开始") '校验登录信息 Dim CheckResult As String = McLoginAble(Data.Input) If Not CheckResult = "" Then Throw New ArgumentException(CheckResult) @@ -390,7 +391,13 @@ NextInner: Case McLoginType.Ms Loader = McLoginMsLoader Case McLoginType.Legacy - Loader = McLoginLegacyLoader + If PageLinkHiper.HiperState = LoadState.Finished Then + '使用 HiPer 内网验证 + Loader = McLoginHiperLoader + Else + '默认的离线验证 + Loader = McLoginLegacyLoader + End If Case McLoginType.Nide Loader = McLoginNideLoader Case McLoginType.Auth @@ -400,6 +407,7 @@ NextInner: Loader.WaitForExit(Data.Input, McLoginLoader, Data.IsForceRestarting) Data.Output = CType(Loader, Object).Output RunInUi(Sub() FrmLaunchLeft.RefreshPage(True, False)) '刷新自动填充列表 + McLaunchLog("登录加载已结束") End Sub #End Region @@ -411,6 +419,7 @@ NextInner: Public McLoginLegacyLoader As New LoaderTask(Of McLoginLegacy, McLoginResult)("Loader Login Legacy", AddressOf McLoginLegacyStart) Public McLoginNideLoader As New LoaderTask(Of McLoginServer, McLoginResult)("Loader Login Nide", AddressOf McLoginServerStart) With {.ReloadTimeout = 60000} Public McLoginAuthLoader As New LoaderTask(Of McLoginServer, McLoginResult)("Loader Login Auth", AddressOf McLoginServerStart) With {.ReloadTimeout = 60000} + Public McLoginHiperLoader As New LoaderTask(Of McLoginLegacy, McLoginResult)("Loader Login HiPer", AddressOf McLoginHiperStart) With {.ReloadTimeout = 60000} '主加载函数,返回所有需要的登录信息 Private Sub McLoginMsStart(Data As LoaderTask(Of McLoginMs, McLoginResult)) @@ -545,43 +554,9 @@ LoginFinish: Data.Progress = 0.1 With Data.Output .Name = Input.UserName - .Uuid = McLoginLegacyUuid(Input.UserName) + .Uuid = McLoginLegacyUuidWithCustomSkin(Input.UserName, Input.SkinType, Input.SkinName) .Type = "Legacy" End With - '根据离线皮肤获取实际使用的 Uuid - Select Case Input.SkinType - Case 0 - '默认,不需要处理 - Case 1 - 'Steve - Do Until McSkinSex(Data.Output.Uuid) = "Steve" - If Data.Output.Uuid.EndsWith("FFFFF") Then Data.Output.Uuid = Mid(Data.Output.Uuid, 1, 32 - 5) & "00000" - Data.Output.Uuid = Mid(Data.Output.Uuid, 1, 32 - 5) & (Long.Parse(Right(Data.Output.Uuid, 5), Globalization.NumberStyles.AllowHexSpecifier) + 1).ToString("X") - Loop - Case 2 - 'Alex - Do Until McSkinSex(Data.Output.Uuid) = "Alex" - If Data.Output.Uuid.EndsWith("FFFFF") Then Data.Output.Uuid = Mid(Data.Output.Uuid, 1, 32 - 5) & "00000" - Data.Output.Uuid = Mid(Data.Output.Uuid, 1, 32 - 5) & (Long.Parse(Right(Data.Output.Uuid, 5), Globalization.NumberStyles.AllowHexSpecifier) + 1).ToString("X") - Loop - Case 3 - '使用正版用户名 - Try - If Not Input.SkinName = "" Then - Log("[Skin] 由于离线皮肤设置,使用正版 UUID:" & Input.SkinName) - Data.Output.Uuid = McLoginMojangUuid(Input.SkinName, False) - End If - Catch ex As Exception - Log(ex, "离线启动时使用的正版皮肤获取失败") - MyMsgBox("由于设置的离线启动时使用的正版皮肤获取失败,游戏将以无皮肤的方式启动。" & vbCrLf & "请检查你的网络是否通畅,或尝试使用 VPN!" & vbCrLf & vbCrLf & "详细的错误信息:" & ex.Message, "皮肤获取失败") - End Try - Case 4 - '自定义 - Do Until McSkinSex(Data.Output.Uuid) = If(Setup.Get("LaunchSkinSlim"), "Alex", "Steve") - If Data.Output.Uuid.EndsWith("FFFFF") Then Data.Output.Uuid = Mid(Data.Output.Uuid, 1, 32 - 5) & "00000" - Data.Output.Uuid = Mid(Data.Output.Uuid, 1, 32 - 5) & (Long.Parse(Right(Data.Output.Uuid, 5), Globalization.NumberStyles.AllowHexSpecifier) + 1).ToString("X") - Loop - End Select '将结果扩展到所有项目中 'Data.Output.AccessToken = Setup.Get("CacheMojangAccess") '不能优先使用缓存的 AccessToken,这会导致离线用户名设置失效 'If Data.Output.AccessToken.Length < 300 Then @@ -596,6 +571,46 @@ LoginFinish: Names.Insert(0, Input.UserName) Setup.Set("LoginLegacyName", Join(Names.ToArray, "¨")) End Sub + Private Sub McLoginHiperStart(Data As LoaderTask(Of McLoginLegacy, McLoginResult)) + Dim Input As McLoginLegacy = Data.Input + McLaunchLog("登录方式:联机离线(" & Input.UserName & ")") + Data.Progress = 0.05 + '尝试登录 + Try + McLaunchLog("登录开始(Login, HiPer)") + Dim LoginJson As JObject = GetJson(NetRequestRetry( + Url:="http://hiperauth.tech/api/yggdrasil-hiper/authserver/authenticate", + Method:="POST", + Data:="{""agent"": {""name"": ""Minecraft"",""version"": 1},""username"":""" & Data.Input.UserName & """,""password"":""" & + McLoginLegacyUuidWithCustomSkin(Input.UserName, Input.SkinType, Input.SkinName) & """,""requestUser"":true}", + ContentType:="application/json; charset=utf-8")) + '将登录结果输出 + Data.Output.AccessToken = LoginJson("accessToken").ToString + Data.Output.ClientToken = LoginJson("clientToken").ToString + Data.Output.Name = LoginJson("selectedProfile")("name").ToString + Data.Output.Uuid = LoginJson("selectedProfile")("id").ToString + Data.Output.Type = "Auth" + Data.Output.Email = Data.Input.UserName + McLaunchLog("登录成功(Login, HiPer)") + '保存启动记录 + Dim Names As New List(Of String) + If Not Setup.Get("LoginLegacyName") = "" Then Names.AddRange(Setup.Get("LoginLegacyName").ToString.Split("¨")) + Names.Remove(Input.UserName) + Names.Insert(0, Input.UserName) + Setup.Set("LoginLegacyName", Join(Names.ToArray, "¨")) + Catch ex As Exception + Dim AllMessage As String = GetString(ex) + Log(ex, "登录失败原始错误信息", LogLevel.Normal) + Dim ThrowEx As Exception = ex + If AllMessage.Contains("403") Then + ThrowEx = New Exception("登录尝试过于频繁,导致被系统暂时屏蔽。请不要操作,等待 10 分钟后再试。", ex) + ElseIf AllMessage.Contains("超时") OrElse AllMessage.Contains("imeout") OrElse AllMessage.Contains("网络请求失败") Then + ThrowEx = New Exception("$登录失败:连接登录服务器超时。" & vbCrLf & "请检查 HiPer 联机模块的连接状况是否良好,或选择其他登录方式!") + End If + McLaunchLog("登录失败:" & GetString(ThrowEx)) + Throw ThrowEx + End Try + End Sub 'Server 登录:三种验证方式的请求 Private Sub McLoginRequestValidate(ByRef Data As LoaderTask(Of McLoginServer, McLoginResult)) @@ -752,10 +767,8 @@ LoginFinish: If(Data.Input.UserName.Contains("@"), "", " - 登录账号应为邮箱或统一通行证账号,而非游戏角色 ID。" & vbCrLf) & " - 只注册了账号,但没有加入对应服务器。") End Select - ElseIf AllMessage.Contains("超时") OrElse AllMessage.Contains("imeout") Then + ElseIf AllMessage.Contains("超时") OrElse AllMessage.Contains("imeout") OrElse AllMessage.Contains("网络请求失败") Then Throw New Exception("$登录失败:连接登录服务器超时。" & vbCrLf & "请检查你的网络状况是否良好,或尝试使用 VPN!") - ElseIf AllMessage.Contains("网络请求失败") Then - Throw New Exception("$登录失败:连接登录服务器失败。" & vbCrLf & "请检查你的网络状况是否良好,或尝试使用 VPN!") ElseIf ex.Message.StartsWith("$") Then Throw Else @@ -845,7 +858,7 @@ SystemBrowser: Try Result = NetRequestMuity("https://login.live.com/oauth20_token.srf", "POST", Request, "application/x-www-form-urlencoded", 1) Catch ex As Exception - If ex.Message.Contains("must sign in again") Then + If ex.Message.Contains("must sign in again") OrElse ex.Message.Contains("invalid_grant") Then 'Fix Hex-Dragon/PCL2#269 Return {"Relogin", ""} Else Throw @@ -895,7 +908,11 @@ SystemBrowser: Result = NetRequestMuity("https://xsts.auth.xboxlive.com/xsts/authorize", "POST", Request, "application/json", 3) Catch ex As Net.WebException If ex.Message.Contains("2148916233") Then - Throw New Exception("$该微软账号尚未购买 Minecraft Java 版或注册 XBox 账户!") + If MyMsgBox("该微软账号尚未购买 Minecraft Java 版,或尚未注册 XBox 账户。" & vbCrLf & + "如果你确定该账号完成了上述步骤,请先在游戏官网登录一次,然后再在启动器登录。", "登录提示", "打开游戏官网", "取消") = 1 Then + OpenWebsite("https://www.minecraft.net/") + End If + Throw New Exception("$$") ElseIf ex.Message.Contains("2148916238") Then If MyMsgBox("该账号年龄不足,你需要先修改出生日期,然后才能登录。" & vbCrLf & "该账号目前填写的年龄是否在 13 岁以上?", "登录提示", "13 岁以上", "12 岁以下", "我不知道") = 1 Then @@ -968,7 +985,46 @@ SystemBrowser: Return {UUID, UserName, Result} End Function - '根据用户名返回对应 Uuid,需要多线程 + '返回符合离线皮肤设置的 UUID + Private Function McLoginLegacyUuidWithCustomSkin(UserName As String, SkinType As Integer, SkinName As String) As String + Dim Uuid As String = McLoginLegacyUuid(UserName) + '根据离线皮肤获取实际使用的 Uuid + Select Case SkinType + Case 0 + '默认,不需要处理 + Case 1 + 'Steve + Do Until McSkinSex(Uuid) = "Steve" + If Uuid.EndsWith("FFFFF") Then Uuid = Mid(Uuid, 1, 32 - 5) & "00000" + Uuid = Mid(Uuid, 1, 32 - 5) & (Long.Parse(Right(Uuid, 5), Globalization.NumberStyles.AllowHexSpecifier) + 1).ToString("X") + Loop + Case 2 + 'Alex + Do Until McSkinSex(Uuid) = "Alex" + If Uuid.EndsWith("FFFFF") Then Uuid = Mid(Uuid, 1, 32 - 5) & "00000" + Uuid = Mid(Uuid, 1, 32 - 5) & (Long.Parse(Right(Uuid, 5), Globalization.NumberStyles.AllowHexSpecifier) + 1).ToString("X") + Loop + Case 3 + '使用正版用户名 + Try + If Not SkinName = "" Then + Log("[Skin] 由于离线皮肤设置,使用正版 UUID:" & SkinName) + Uuid = McLoginMojangUuid(SkinName, False) + End If + Catch ex As Exception + Log(ex, "离线启动时使用的正版皮肤获取失败") + MyMsgBox("由于设置的离线启动时使用的正版皮肤获取失败,游戏将以无皮肤的方式启动。" & vbCrLf & "请检查你的网络是否通畅,或尝试使用 VPN!" & vbCrLf & vbCrLf & "详细的错误信息:" & ex.Message, "皮肤获取失败") + End Try + Case 4 + '自定义 + Do Until McSkinSex(Uuid) = If(Setup.Get("LaunchSkinSlim"), "Alex", "Steve") + If Uuid.EndsWith("FFFFF") Then Uuid = Mid(Uuid, 1, 32 - 5) & "00000" + Uuid = Mid(Uuid, 1, 32 - 5) & (Long.Parse(Right(Uuid, 5), Globalization.NumberStyles.AllowHexSpecifier) + 1).ToString("X") + Loop + End Select + Return Uuid + End Function + '根据用户名返回对应 UUID,需要多线程 Public Function McLoginMojangUuid(Name As String, ThrowOnNotFound As Boolean) If Name.Trim.Length = 0 Then Return StrFill("", "0", 32) '从缓存获取 @@ -1017,8 +1073,8 @@ SystemBrowser: ElseIf McVersionCurrent.ReleaseTime.Year >= 2017 Then 'Minecraft 1.12 与 1.11 的分界线正好是 2017 年,太棒了 '1.12+:至少 Java 8 MinVer = New Version(1, 8, 0, 0) - ElseIf McVersionCurrent.ReleaseTime.Year >= 2001 Then '避免某些版本的 1960 癌 - '1.11-:最高 Java 12 + ElseIf McVersionCurrent.ReleaseTime <= New Date(2013, 5, 1) AndAlso McVersionCurrent.ReleaseTime.Year >= 2001 Then '避免某些版本的 1960 癌 + '1.5.2-:最高 Java 12 MaxVer = New Version(1, 12, 999, 999) End If @@ -1027,15 +1083,29 @@ SystemBrowser: If McVersionCurrent.Version.McName = "1.7.2" Then '1.7.2:必须 Java 7 MinVer = New Version(1, 7, 0, 0) : MaxVer = New Version(1, 7, 999, 999) - ElseIf McVersionCurrent.Version.McCodeMain <= 12 AndAlso McVersionCurrent.Version.McCodeMain <> -1 AndAlso VersionSortBoolean("14.23.5.2855", McVersionCurrent.Version.ForgeVersion) Then + ElseIf McVersionCurrent.Version.McCodeMain <= 12 AndAlso McVersionCurrent.Version.McCodeMain > 0 AndAlso VersionSortBoolean("14.23.5.2855", McVersionCurrent.Version.ForgeVersion) Then '1.12,Forge 14.23.5.2855 及更低:Java 8 MaxVer = New Version(1, 8, 999, 999) - ElseIf McVersionCurrent.Version.McCodeMain <= 14 AndAlso McVersionCurrent.Version.McCodeMain <> -1 AndAlso VersionSortBoolean("28.2.23", McVersionCurrent.Version.ForgeVersion) Then + ElseIf McVersionCurrent.Version.McCodeMain <= 14 AndAlso McVersionCurrent.Version.McCodeMain > 0 AndAlso VersionSortBoolean("28.2.23", McVersionCurrent.Version.ForgeVersion) Then '1.13 - 1.14,Forge 28.2.23 及更低:Java 8 - 10 MinVer = New Version(1, 8, 0, 0) : MaxVer = New Version(1, 10, 999, 999) - ElseIf McVersionCurrent.Version.McCodeMain <= 16 AndAlso McVersionCurrent.Version.McCodeMain <> -1 Then - '1.15 - 1.16:Java 8 - 12, 12 - 15未测试 + ElseIf McVersionCurrent.Version.McCodeMain <= 16 AndAlso McVersionCurrent.Version.McCodeMain > 0 Then + '1.15 - 1.16:Java 8 - 15 MinVer = New Version(1, 8, 0, 0) : MaxVer = New Version(1, 15, 999, 999) + ElseIf McVersionCurrent.Version.McCodeMain >= 18 AndAlso McVersionCurrent.Version.McCodeMain < 99 AndAlso McVersionCurrent.Version.HasOptiFine Then '#305 + '1.18+:若安装了 OptiFine,最高 Java 18 + MaxVer = New Version(1, 18, 999, 999) + End If + End If + + 'Fabric 检测 + If McVersionCurrent.Version.HasFabric Then + If McVersionCurrent.Version.McCodeMain >= 15 AndAlso McVersionCurrent.Version.McCodeMain <= 16 AndAlso McVersionCurrent.Version.McCodeMain <> -1 Then + '1.15 - 1.16:Java 8 - 15 + MinVer = New Version(1, 8, 0, 0) : MaxVer = New Version(1, 15, 999, 999) + ElseIf McVersionCurrent.Version.McCodeMain >= 18 AndAlso McVersionCurrent.Version.McCodeMain < 99 Then + '1.18+:Java 17 - 18 + MinVer = New Version(1, 17, 0, 0) : MaxVer = New Version(1, 18, 999, 999) End If End If @@ -1084,9 +1154,17 @@ SystemBrowser: ''' Public Function ExtractJavaWrapper() As String Dim WrapperPath As String = PathAppdata & "JavaWrapper.jar" + If Encoding.UTF8.GetByteCount(WrapperPath) <> WrapperPath.Length Then + Log("[Java] AppData 路径中包含非 ASCII 字符,换用 Temp 目录") + WrapperPath = PathTemp & "JavaWrapper.jar" + If Encoding.UTF8.GetByteCount(PathTemp) <> PathTemp.Length Then + Log("[Java] Temp 路径中包含非 ASCII 字符,换用 C 盘根目录") + WrapperPath = "C:\PCL\JavaWrapper.jar" + End If + End If If Not File.Exists(WrapperPath) OrElse New FileInfo(WrapperPath).Length > 20 * 1024 Then WriteFile(WrapperPath, GetResources("JavaWrapper")) - McLaunchLog("已自动释放 Java Wrapper") + Log("[Java] 已自动释放 Java Wrapper:" & WrapperPath) End If Return WrapperPath End Function @@ -1173,14 +1251,16 @@ SystemBrowser: '统一通行证 If McLoginLoader.Output.Type = "Nide" Then - DataList.Insert(0, "-Dnide8auth.client=true -javaagent:nide8auth.jar=" & Setup.Get("VersionServerNide", Version:=McVersionCurrent)) + DataList.Insert(0, "-Dnide8auth.client=true -javaagent:""" & PathAppdata & "nide8auth.jar""=" & Setup.Get("VersionServerNide", Version:=McVersionCurrent)) End If 'Authlib-Injector If McLoginLoader.Output.Type = "Auth" Then - Dim Server As String = Setup.Get("VersionServerAuthServer", Version:=McVersionCurrent) + Dim Server As String = If(McLoginLoader.Input.Type = McLoginType.Legacy, + "http://hiperauth.tech/api/yggdrasil-hiper/", 'HiPer 登录 + Setup.Get("VersionServerAuthServer", Version:=McVersionCurrent)) Try Dim Response As String = NetGetCodeByRequestRetry(Server, Encoding.UTF8) - DataList.Insert(0, "-javaagent:authlib-injector.jar=" & Server & + DataList.Insert(0, "-javaagent:""" & PathAppdata & "authlib-injector.jar""=" & Server & " -Dauthlibinjector.side=client" & " -Dauthlibinjector.yggdrasil.prefetched=" & Convert.ToBase64String(Encoding.UTF8.GetBytes(Response))) Catch ex As Exception @@ -1237,14 +1317,16 @@ NextVersion: '统一通行证 If McLoginLoader.Output.Type = "Nide" Then - DataList.Insert(0, "-javaagent:nide8auth.jar=" & Setup.Get("VersionServerNide", Version:=McVersionCurrent)) + DataList.Insert(0, "-javaagent:""" & PathAppdata & "nide8auth.jar""=" & Setup.Get("VersionServerNide", Version:=McVersionCurrent)) End If 'Authlib-Injector If McLoginLoader.Output.Type = "Auth" Then - Dim Server As String = Setup.Get("VersionServerAuthServer", Version:=McVersionCurrent) + Dim Server As String = If(McLoginLoader.Input.Type = McLoginType.Legacy, + "http://hiperauth.tech/api/yggdrasil-hiper/", 'HiPer 登录 + Setup.Get("VersionServerAuthServer", Version:=McVersionCurrent)) Try Dim Response As String = NetGetCodeByRequestRetry(Server, Encoding.UTF8) - DataList.Insert(0, "-javaagent:authlib-injector.jar=" & Server & + DataList.Insert(0, "-javaagent:""" & PathAppdata & "authlib-injector.jar""=" & Server & " -Dauthlibinjector.side=client" & " -Dauthlibinjector.yggdrasil.prefetched=" & Convert.ToBase64String(Encoding.UTF8.GetBytes(Response))) Catch ex As Exception @@ -1420,7 +1502,9 @@ NextVersion: GameArguments.Add("${assets_index_name}", McAssetsGetIndexName(Version)) '支持库参数 - Dim LibList As List(Of McLibToken) = McLibListGet(Version, Not (Version.Version.HasForge AndAlso Version.Version.McCodeMain >= 17)) + 'Dim LibList As List(Of McLibToken) = McLibListGet(Version, + ' Not (Version.Version.HasForge AndAlso Version.Version.McCodeMain >= 17)) '包含版本 Jar 的条件是不为 1.17+ 的 Forge + Dim LibList As List(Of McLibToken) = McLibListGet(Version, True) '如果在 1.19.x Forge 不包含版本 Jar 会导致 #188 Loader.Output = LibList Dim CpStrings As New List(Of String) Dim OptiFineCp As String = Nothing @@ -1539,7 +1623,7 @@ NextVersion: '更新文件 Dim Profiles As JObject = GetJson(ReadFile(PathMcFolder & "launcher_profiles.json")) Profiles.Merge(ReplaceJson) - WriteFile(PathMcFolder & "launcher_profiles.json", Profiles.ToString, Encoding:=Encoding.Default) + WriteFile(PathMcFolder & "launcher_profiles.json", Profiles.ToString, Encoding:=Encoding.GetEncoding("GB18030")) McLaunchLog("已更新 launcher_profiles.json") Catch ex As Exception Log(ex, "更新 launcher_profiles.json 失败,将在删除文件后重试") @@ -1570,7 +1654,7 @@ NextVersion: '更新文件 Dim Profiles As JObject = GetJson(ReadFile(PathMcFolder & "launcher_profiles.json")) Profiles.Merge(ReplaceJson) - WriteFile(PathMcFolder & "launcher_profiles.json", Profiles.ToString, Encoding:=Encoding.Default) + WriteFile(PathMcFolder & "launcher_profiles.json", Profiles.ToString, Encoding:=Encoding.GetEncoding("GB18030")) McLaunchLog("已在删除后更新 launcher_profiles.json") Catch exx As Exception Log(exx, "更新 launcher_profiles.json 失败", LogLevel.Feedback) @@ -1770,7 +1854,7 @@ IgnoreCustomSkin: """" & McLaunchJavaSelected.PathJava & """ " & McLaunchArgument & vbCrLf & "echo 游戏已退出。" & vbCrLf & "pause" - WriteFile(Path & "PCL\LatestLaunch.bat", CmdString, Encoding:=Encoding.Default) + WriteFile(Path & "PCL\LatestLaunch.bat", CmdString, Encoding:=Encoding.GetEncoding("GB18030")) Catch ex As Exception Log(ex, "输出启动脚本失败") End Try diff --git a/Plain Craft Launcher 2/Modules/Minecraft/ModMinecraft.vb b/Plain Craft Launcher 2/Modules/Minecraft/ModMinecraft.vb index 72c3f81..b458f1a 100644 --- a/Plain Craft Launcher 2/Modules/Minecraft/ModMinecraft.vb +++ b/Plain Craft Launcher 2/Modules/Minecraft/ModMinecraft.vb @@ -484,10 +484,22 @@ RetryGet: End If Next Log("[Java] 发现用户指定的不兼容 Java:" & UserJava.ToString) - If MyMsgBox("你在启动设置中指定了使用下列 Java:" & vbCrLf & - " - " & UserJava.ToString & vbCrLf & + '弹窗要求选择 + Dim Requirement As String = "" + If (MinVersion Is Nothing OrElse MinVersion.Minor = 0) AndAlso (MaxVersion IsNot Nothing AndAlso MaxVersion.Minor < 99) Then + Requirement = "最高兼容到 Java " & MaxVersion.Minor & If(MaxVersion.MinorRevision < 99, "." & MaxVersion.MinorRevision & "." & MaxVersion.Revision, "") + ElseIf (MinVersion IsNot Nothing AndAlso MinVersion.Minor > 0) AndAlso (MaxVersion Is Nothing OrElse MaxVersion.Minor >= 99) Then + Requirement = "至少需要 Java " & MinVersion.Minor & If(MinVersion.MinorRevision > 0 OrElse MinVersion.Revision > 0, "." & MinVersion.MinorRevision & "." & MinVersion.Revision, "") + ElseIf (MinVersion IsNot Nothing AndAlso MinVersion.Minor > 0) AndAlso (MaxVersion IsNot Nothing AndAlso MaxVersion.Minor < 99) Then + Dim Left As String = MinVersion.Minor & If(MinVersion.MinorRevision > 0 OrElse MinVersion.Revision > 0, "." & MinVersion.MinorRevision & "." & MinVersion.Revision, "") + Dim Right As String = MaxVersion.Minor & If(MaxVersion.MinorRevision < 99, "." & MaxVersion.MinorRevision & "." & MaxVersion.Revision, "") + Requirement = "需要 Java " & If(Left = Right, Left, Left & " ~ " & Right) + End If + If MyMsgBox("你在启动设置中指定了使用 Java " & UserJava.VersionCode & ",但当前版本" & Requirement & "。" & vbCrLf & + "如果强制使用该 Java,可能会导致游戏崩溃。" & vbCrLf & vbCrLf & - "该 Java 可能不兼容当前游戏版本,游戏存在崩溃风险。是否要强制使用该 Java?", "Java 兼容性警告", "取消,让 PCL2 自动选择", "继续") = 2 Then + " - 指定的 Java:" & UserJava.ToString, + "Java 兼容性警告", "让 PCL2 自动选择", "强制使用该 Java") = 2 Then '强制使用指定的 Java Log("[Java] 已强制使用用户指定的不兼容 Java") AllowedJavaList = New List(Of JavaEntry) From {UserJava} @@ -581,8 +593,8 @@ UserPass: If Not Left.IsJre AndAlso Right.IsJre Then Return False '4. Java 大版本 If Left.VersionCode <> Right.VersionCode Then - ' Java 7 8 9 10 11 12 13 14 15 16 17 18 19 - Dim Weight = {0, 1, 2, 3, 4, 5, 6, 14, 29, 10, 11, 12, 13, 9, 8, 7, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28} + ' Java 7 8 9 10 11 12 13 14 15 16 17 18 19 20... + Dim Weight = {0, 1, 2, 3, 4, 5, 6, 14, 29, 10, 11, 12, 13, 9, 8, 7, 15, 30, 29, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28} Return Weight.ElementAtOrDefault(Left.VersionCode) >= Weight.ElementAtOrDefault(Right.VersionCode) End If '5. 最次级版本号更接近 51 @@ -773,7 +785,7 @@ UserPass: ""selectedProfile"": ""PCL2"", ""clientToken"": ""23323323323323323323323323323333"" }" - WriteFile(Folder & "launcher_profiles.json", ResultJson, Encoding:=Encoding.Default) + WriteFile(Folder & "launcher_profiles.json", ResultJson, Encoding:=Encoding.GetEncoding("GB18030")) Log("[Minecraft] 已创建 launcher_profiles.json:" & Folder) Catch ex As Exception Log(ex, "创建 launcher_profiles.json 失败(" & Folder & ")", LogLevel.Feedback) @@ -2486,22 +2498,23 @@ NextVersion: '统一通行证文件 If Setup.Get("VersionServerLogin", Version:=Version) = 3 Then - Dim TargetFile = Version.PathIndie & "nide8auth.jar" + Dim TargetFile = PathAppdata & "nide8auth.jar" Dim Checker As New FileChecker(MinSize:=173000) If (IsSetupSkip AndAlso File.Exists(TargetFile)) OrElse Checker.Check(TargetFile) IsNot Nothing Then Result.Add(New NetFile({"https://login.mc-user.com:233/index/jar"}, TargetFile, Checker)) End If End If 'Authlib-Injector 文件 - If Setup.Get("VersionServerLogin", Version:=Version) = 4 Then - Dim TargetFile = Version.PathIndie & "authlib-injector.jar" + If Setup.Get("VersionServerLogin", Version:=Version) = 4 OrElse + (PageLinkHiper.HiperState = LoadState.Finished AndAlso Setup.Get("LoginType") = McLoginType.Legacy) Then 'HiPer 登录转接 + Dim TargetFile = PathAppdata & "authlib-injector.jar" Dim DownloadInfo As JObject = Nothing '获取下载信息 Try Log("[Minecraft] 开始获取 Authlib-Injector 下载信息") DownloadInfo = GetJson(NetGetCodeByDownload({"https://download.mcbbs.net/mirrors/authlib-injector/artifact/latest.json", "https://bmclapi2.bangbang93.com/mirrors/authlib-injector/artifact/latest.json"}, IsJson:=True)) Catch ex As Exception - Log("获取 Authlib-Injector 下载信息失败", LogLevel.Hint) + Log(ex, "获取 Authlib-Injector 下载信息失败") End Try '校验文件 If DownloadInfo IsNot Nothing Then @@ -3804,7 +3817,11 @@ NextEntry: Else Select Case McLoginLoader.Input.Type Case McLoginType.Legacy - Raw = Raw.Replace("{login}", "离线") + If PageLinkHiper.HiperState = LoadState.Finished Then + Raw = Raw.Replace("{login}", "联机离线") + Else + Raw = Raw.Replace("{login}", "离线") + End If Case McLoginType.Mojang Raw = Raw.Replace("{login}", "Mojang 正版") Case McLoginType.Ms diff --git a/Plain Craft Launcher 2/Modules/Minecraft/ModModpack.vb b/Plain Craft Launcher 2/Modules/Minecraft/ModModpack.vb index 81908d9..3780f92 100644 --- a/Plain Craft Launcher 2/Modules/Minecraft/ModModpack.vb +++ b/Plain Craft Launcher 2/Modules/Minecraft/ModModpack.vb @@ -126,7 +126,7 @@ End If '解压文件 Dim RetryCount As Integer = 1 - Dim Encode = Encoding.Default + Dim Encode = Encoding.GetEncoding("GB18030") Try Retry: '完全不知道为啥会出现文件正在被另一进程使用的问题,总之多试试 diff --git a/Plain Craft Launcher 2/Modules/Minecraft/ModWatcher.vb b/Plain Craft Launcher 2/Modules/Minecraft/ModWatcher.vb index 7193328..947aac4 100644 --- a/Plain Craft Launcher 2/Modules/Minecraft/ModWatcher.vb +++ b/Plain Craft Launcher 2/Modules/Minecraft/ModWatcher.vb @@ -94,7 +94,6 @@ Do Until State = MinecraftState.Ended OrElse State = MinecraftState.Crashed OrElse Loader.State = LoadState.Aborted TimerWindow() TimerLog() - If State = MinecraftState.Loading Then ProgressUpdate() '设置窗口标题 For i = 1 To 3 If IsWindowFinished AndAlso WindowTitle <> "" AndAlso State = MinecraftState.Running AndAlso Not GameProcess.HasExited Then @@ -151,6 +150,7 @@ For Each Str As String In Copyed GameLog(Str) Next + If State = MinecraftState.Loading Then ProgressUpdate() '游戏退出检查 If GameProcess.HasExited Then WatcherLog("Minecraft 已退出,返回值:" & GameProcess.ExitCode) @@ -167,7 +167,7 @@ '返回值不为 0 且未结束 WatcherLog("Minecraft 返回值异常,可能已崩溃") Crashed() - Else + ElseIf State <> MinecraftState.Crashed Then '正常关闭 State = MinecraftState.Ended End If @@ -268,8 +268,18 @@ WatcherLog("Minecraft 窗口已加载:" & WindowHandle.ToInt64) IsWindowFinished = True '最大化 - Thread.Sleep(3000) '1.7.10 LiteLoader 不延迟会显示错误 - If Setup.Get("LaunchArgumentWindowType") = 4 Then ShowWindow(WindowHandle, 3) + If Setup.Get("LaunchArgumentWindowType") = 4 Then + RunInNewThread(Sub() + Try + '如果最大化导致屏幕渲染大小不对,那是 MC 的 Bug,不是我的 Bug + '……虽然我很想这样说,但总有人反馈,算了 + Thread.Sleep(1000) + ShowWindow(WindowHandle, 3) + Catch ex As Exception + Log(ex, "最大化 Minecraft 窗口时出现错误") + End Try + End Sub, "MinecraftWindowMaximize") + End If ElseIf Not IsWindowAppeared Then '已找到 FML 窗口 WatcherLog("FML 窗口已加载:" & MinecraftWindows.Keys(0).ToInt64) diff --git a/Plain Craft Launcher 2/My Project/AssemblyInfo.vb b/Plain Craft Launcher 2/My Project/AssemblyInfo.vb index 3f55573..b8bdb0a 100644 --- a/Plain Craft Launcher 2/My Project/AssemblyInfo.vb +++ b/Plain Craft Launcher 2/My Project/AssemblyInfo.vb @@ -51,6 +51,6 @@ Imports System.Runtime.InteropServices ' 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号 ' 方法是按如下所示使用“*” - - + + diff --git a/Plain Craft Launcher 2/My Project/Resources.resx b/Plain Craft Launcher 2/My Project/Resources.resx index fb11c58..66663f3 100644 --- a/Plain Craft Launcher 2/My Project/Resources.resx +++ b/Plain Craft Launcher 2/My Project/Resources.resx @@ -137,7 +137,7 @@ ..\Resources\Newtonsoft.Json.dll;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - ..\Resources\ModData.json;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ..\Resources\ModData.txt;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ..\Resources\NAudio.dll;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 diff --git a/Plain Craft Launcher 2/Pages/PageDownload/ModDownloadLib.vb b/Plain Craft Launcher 2/Pages/PageDownload/ModDownloadLib.vb index 2b710bd..5f0320a 100644 --- a/Plain Craft Launcher 2/Pages/PageDownload/ModDownloadLib.vb +++ b/Plain Craft Launcher 2/Pages/PageDownload/ModDownloadLib.vb @@ -180,7 +180,7 @@ Public Module ModDownloadLib '建立控件 Dim NewItem As New MyListItem With {.Logo = Logo, .SnapsToDevicePixels = True, .Title = Entry("id").ToString, .Height = 42, .Type = MyListItem.CheckType.Clickable, .Tag = Entry, .PaddingRight = 60} If Entry("lore") Is Nothing Then - NewItem.Info = Entry("releaseTime").Value(Of Date).ToString("yyyy/MM/dd") + NewItem.Info = Entry("releaseTime").Value(Of Date).ToString("yyyy/MM/dd HH:mm") Else NewItem.Info = Entry("lore").ToString End If @@ -679,7 +679,9 @@ Public Module ModDownloadLib '建立控件 Dim NewItem As New MyListItem With { .Title = Entry.NameDisplay, .SnapsToDevicePixels = True, .Height = 42, .Type = MyListItem.CheckType.Clickable, .Tag = Entry, .PaddingRight = 60, - .Info = If(Entry.IsPreview, "测试版", "正式版") & If(Entry.ReleaseTime = "", "", ",发布于 " & Entry.ReleaseTime), + .Info = If(Entry.IsPreview, "测试版", "正式版") & + If(Entry.ReleaseTime = "", "", ",发布于 " & Entry.ReleaseTime) & + If(Entry.RequiredForgeVersion = "", "", ",推荐 Forge 版本:" & Entry.RequiredForgeVersion), .Logo = "pack://application:,,,/images/Blocks/GrassPath.png" } AddHandler NewItem.Click, OnClick @@ -1672,6 +1674,7 @@ Public Module ModDownloadLib Dim Loaders As New List(Of LoaderBase) '下载 Json + MinecraftName = MinecraftName.Replace("∞", "infinite") '放在 ID 后面避免影响版本文件夹名称 Loaders.Add(New LoaderTask(Of String, List(Of NetFile))("获取 Fabric 主文件下载地址", Sub(Task As LoaderTask(Of String, List(Of NetFile))) '启动依赖版本的下载 @@ -2083,7 +2086,7 @@ Public Module ModDownloadLib SplitArguments = ArrayNoDouble(SplitArguments) Dim RealArguments As String = Nothing If SplitArguments.Count > 0 Then - RealArguments = "--" & Join(SplitArguments, " --") + RealArguments = If(AllArguments.StartsWith("--"), "--", "") & Join(SplitArguments, " --") End If '合并 OutputJson = MinecraftJson diff --git a/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadCfDetail.xaml.vb b/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadCfDetail.xaml.vb index bc08112..c162eff 100644 --- a/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadCfDetail.xaml.vb +++ b/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadCfDetail.xaml.vb @@ -139,7 +139,7 @@ PanIntro.Children.Insert(0, CfItem) '决定按钮显示 - BtnIntroWiki.Visibility = If(Project.McWikiId = 0, Visibility.Collapsed, Visibility.Visible) + BtnIntroWiki.Visibility = If(Project.WikiId = 0, Visibility.Collapsed, Visibility.Visible) BtnIntroMCBBS.Visibility = If(Project.MCBBS Is Nothing, Visibility.Collapsed, Visibility.Visible) AniControlEnabled -= 1 @@ -165,7 +165,14 @@ Dim Loaders As New List(Of LoaderBase) Dim Target As String = PathMcFolder & "versions\" & VersionName & "\原始整合包.zip" Loaders.Add(New LoaderDownload("下载整合包文件", New List(Of NetFile) From {File.GetDownloadFile(Target, True)}) With {.ProgressWeight = 10, .Block = True}) - Loaders.Add(New LoaderTask(Of Integer, Integer)("准备安装整合包", Sub() ModpackInstall(Target, VersionName)) With {.ProgressWeight = 0.1}) + Loaders.Add(New LoaderTask(Of Integer, Integer)("准备安装整合包", + Sub() + If Not ModpackInstall(Target, VersionName) Then Throw New Exception("整合包安装过程中出现异常!") + If Not Setup.Get("ToolDownloadKeepModpack") Then + Log("[Download] 根据设置要求删除原始整合包文件:" & Target) + IO.File.Delete(Target) + End If + End Sub) With {.ProgressWeight = 0.1}) '启动 Dim Loader As New LoaderCombo(Of String)(LoaderName, Loaders) With {.OnStateChanged = Sub(MyLoader) @@ -252,7 +259,7 @@ OpenWebsite(Project.Website) End Sub Private Sub BtnIntroWiki_Click(sender As Object, e As EventArgs) Handles BtnIntroWiki.Click - OpenWebsite("https://www.mcmod.cn/class/" & Project.McWikiId & ".html") + OpenWebsite("https://www.mcmod.cn/class/" & Project.WikiId & ".html") End Sub Private Sub BtnIntroMCBBS_Click(sender As Object, e As EventArgs) Handles BtnIntroMCBBS.Click OpenWebsite("https://www.mcbbs.net/thread-" & Project.MCBBS & "-1-1.html") diff --git a/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadClient.xaml.vb b/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadClient.xaml.vb index 63cec9a..1601f2b 100644 --- a/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadClient.xaml.vb +++ b/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadClient.xaml.vb @@ -65,11 +65,11 @@ Dim CardInfo As New MyCard With {.Title = "最新版本", .Margin = New Thickness(0, 0, 0, 15), .SwapType = 2} Dim TopestVersions As New List(Of JObject) Dim Release As JObject = Dict("正式版")(0).DeepClone() - Release("lore") = "最新正式版,发布于 " & Release("releaseTime").ToString() + Release("lore") = "最新正式版,发布于 " & Release("releaseTime").Value(Of Date).ToString("yyyy/MM/dd HH:mm") TopestVersions.Add(Release) If Dict("正式版")(0)("releaseTime").Value(Of Date) < Dict("预览版")(0)("releaseTime").Value(Of Date) Then Dim Snapshot As JObject = Dict("预览版")(0).DeepClone() - Snapshot("lore") = "最新预览版,发布于 " & Snapshot("releaseTime").ToString() + Snapshot("lore") = "最新预览版,发布于 " & Snapshot("releaseTime").Value(Of Date).ToString("yyyy/MM/dd HH:mm") TopestVersions.Add(Snapshot) End If Dim PanInfo As New StackPanel With {.Margin = New Thickness(20, MyCard.SwapedHeight, 18, 0), .VerticalAlignment = VerticalAlignment.Top, .RenderTransform = New TranslateTransform(0, 0), .Tag = TopestVersions} diff --git a/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadInstall.xaml.vb b/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadInstall.xaml.vb index 6394977..907beaf 100644 --- a/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadInstall.xaml.vb +++ b/Plain Craft Launcher 2/Pages/PageDownload/PageDownloadInstall.xaml.vb @@ -536,11 +536,11 @@ Dim CardInfo As New MyCard With {.Title = "最新版本", .Margin = New Thickness(0, 15, 0, 15), .SwapType = 2} Dim TopestVersions As New List(Of JObject) Dim Release As JObject = Dict("正式版")(0).DeepClone() - Release("lore") = "最新正式版,发布于 " & Release("releaseTime").ToString() + Release("lore") = "最新正式版,发布于 " & Release("releaseTime").Value(Of Date).ToString("yyyy/MM/dd HH:mm") TopestVersions.Add(Release) If Dict("正式版")(0)("releaseTime").Value(Of Date) < Dict("预览版")(0)("releaseTime").Value(Of Date) Then Dim Snapshot As JObject = Dict("预览版")(0).DeepClone() - Snapshot("lore") = "最新预览版,发布于 " & Snapshot("releaseTime").ToString() + Snapshot("lore") = "最新预览版,发布于 " & Snapshot("releaseTime").Value(Of Date).ToString("yyyy/MM/dd HH:mm") TopestVersions.Add(Snapshot) End If Dim PanInfo As New StackPanel With {.Margin = New Thickness(20, MyCard.SwapedHeight, 18, 0), .VerticalAlignment = VerticalAlignment.Top, .RenderTransform = New TranslateTransform(0, 0), .Tag = TopestVersions} @@ -571,17 +571,39 @@ ''' 获取 OptiFine 的加载异常信息。若正常则返回 Nothing。 ''' Private Function LoadOptiFineGetError() As String - 'If Not SelectedMinecraftId.Contains("1.") Then Return "没有可用版本" If LoadOptiFine.State.LoadingState = MyLoading.MyLoadingState.Run Then Return "正在获取版本列表……" If LoadOptiFine.State.LoadingState = MyLoading.MyLoadingState.Error Then Return "获取版本列表失败:" & CType(LoadOptiFine.State, Object).Error.Message - For Each Version As DlOptiFineListEntry In DlOptiFineListLoader.Output.Value - If Version.NameDisplay.StartsWith(SelectedMinecraftId & " ") Then - 'If SelectedFabric IsNot Nothing Then Return "与 Fabric 不兼容" - If SelectedForge IsNot Nothing AndAlso VersionSortInteger(SelectedMinecraftId, "1.13") >= 0 AndAlso VersionSortInteger("1.14.3", SelectedMinecraftId) >= 0 Then Return "与 Forge 不兼容" + '检查 Forge 1.13 - 1.14.3:全部不兼容 + If SelectedForge IsNot Nothing AndAlso + VersionSortInteger(SelectedMinecraftId, "1.13") >= 0 AndAlso VersionSortInteger("1.14.3", SelectedMinecraftId) >= 0 Then + Return "与 Forge 不兼容" + End If + '检查最低 Forge 版本 + Dim MinimalForgeVersion As String = "9999.9999" + For Each OptiFineVersion As DlOptiFineListEntry In DlOptiFineListLoader.Output.Value + If Not OptiFineVersion.NameDisplay.StartsWith(SelectedMinecraftId & " ") Then Continue For '不是同一个大版本 + If SelectedForge Is Nothing OrElse IsOptiFineSuitForForge(OptiFineVersion, SelectedForge) Then Return Nothing + Else + '设置用于显示的最低 Forge 版本 + MinimalForgeVersion = If(VersionSortBoolean(MinimalForgeVersion, OptiFineVersion.RequiredForgeVersion), + OptiFineVersion.RequiredForgeVersion, MinimalForgeVersion) End If Next - Return "没有可用版本" + If MinimalForgeVersion = "9999.9999" Then + Return "没有可用版本" + Else + Return "需要 Forge " & If(MinimalForgeVersion.Contains("."), "", "#") & MinimalForgeVersion & " 或更高版本" + End If + End Function + + '检查某个 OptiFine 是否与某个 Forge 兼容(最低 Forge 版本是否达到需求) + Private Function IsOptiFineSuitForForge(OptiFine As DlOptiFineListEntry, Forge As DlForgeVersionEntry) + If Forge.Inherit <> OptiFine.Inherit Then Return False '不是同一个大版本 + Return (OptiFine.RequiredForgeVersion.Contains(".") AndAlso 'XX.X.XXX + VersionSortInteger(Forge.Version, OptiFine.RequiredForgeVersion) >= 0) OrElse + (Not OptiFine.RequiredForgeVersion.Contains(".") AndAlso '#XXXX + VersionSortInteger(Forge.Version.Split(".").Last, OptiFine.RequiredForgeVersion) >= 0) End Function '限制展开 @@ -595,9 +617,11 @@ Private Sub OptiFine_Loaded() Handles LoadOptiFine.StateChanged Try If DlOptiFineListLoader.State <> LoadState.Finished Then Exit Sub + '获取版本列表 Dim Versions As New List(Of DlOptiFineListEntry) For Each Version As DlOptiFineListEntry In DlOptiFineListLoader.Output.Value + If SelectedForge IsNot Nothing AndAlso Not IsOptiFineSuitForForge(Version, SelectedForge) Then Continue For If Version.NameDisplay.StartsWith(SelectedMinecraftId & " ") Then Versions.Add(Version) Next If Versions.Count = 0 Then Exit Sub @@ -618,7 +642,9 @@ '选择与清除 Private Sub OptiFine_Selected(sender As MyListItem, e As EventArgs) SelectedOptiFine = sender.Tag + If SelectedForge IsNot Nothing AndAlso Not IsOptiFineSuitForForge(SelectedOptiFine, SelectedForge) Then SelectedForge = Nothing OptiFabric_Loaded() + Forge_Loaded() CardOptiFine.IsSwaped = True SelectReload() End Sub @@ -627,6 +653,7 @@ SelectedOptiFabric = Nothing CardOptiFine.IsSwaped = True e.Handled = True + Forge_Loaded() SelectReload() End Sub @@ -743,6 +770,7 @@ ForgeDownloadListItemPreload(PanForge, Versions, AddressOf Forge_Selected, False) For Each Version In Versions If Version.Category = "universal" OrElse Version.Category = "client" Then Continue For '跳过无法自动安装的版本 + If SelectedOptiFine IsNot Nothing AndAlso Not IsOptiFineSuitForForge(SelectedOptiFine, Version) Then Continue For PanForge.Children.Add(ForgeDownloadListItem(Version, AddressOf Forge_Selected, False)) Next Catch ex As Exception @@ -754,12 +782,15 @@ Private Sub Forge_Selected(sender As MyListItem, e As EventArgs) SelectedForge = sender.Tag CardForge.IsSwaped = True + If SelectedOptiFine IsNot Nothing AndAlso Not IsOptiFineSuitForForge(SelectedOptiFine, SelectedForge) Then SelectedOptiFine = Nothing + OptiFine_Loaded() SelectReload() End Sub Private Sub Forge_Clear(sender As Object, e As MouseButtonEventArgs) Handles BtnForgeClear.MouseLeftButtonUp SelectedForge = Nothing CardForge.IsSwaped = True e.Handled = True + OptiFine_Loaded() SelectReload() End Sub @@ -774,7 +805,7 @@ If LoadFabric.State.LoadingState = MyLoading.MyLoadingState.Run Then Return "正在获取版本列表……" If LoadFabric.State.LoadingState = MyLoading.MyLoadingState.Error Then Return "获取版本列表失败:" & CType(LoadFabric.State, Object).Error.Message For Each Version As JObject In DlFabricListLoader.Output.Value("game") - If Version("version").ToString = SelectedMinecraftId Then + If Version("version").ToString = SelectedMinecraftId.Replace("∞", "infinite") Then If SelectedForge IsNot Nothing Then Return "与 Forge 不兼容" 'If SelectedOptiFine IsNot Nothing Then Return "与 OptiFine 不兼容" Return Nothing diff --git a/Plain Craft Launcher 2/Pages/PageLaunch/MySkin.xaml.vb b/Plain Craft Launcher 2/Pages/PageLaunch/MySkin.xaml.vb index e5c3271..efd17e6 100644 --- a/Plain Craft Launcher 2/Pages/PageLaunch/MySkin.xaml.vb +++ b/Plain Craft Launcher 2/Pages/PageLaunch/MySkin.xaml.vb @@ -224,7 +224,10 @@ Retry: RunInUiWait(Sub() Try Dim CapeNames As New Dictionary(Of String, String) From { - {"Migrator", "迁移者披风"}, {"MapMaker", "Realms 地图制作者披风"}, {"Moderator", "Mojira 管理员披风"}, {"Translator-Chinese", "Crowdin 中文翻译者披风"}, {"Translator", "Crowdin 翻译者披风"} + {"Migrator", "迁移者披风"}, {"MapMaker", "Realms 地图制作者披风"}, {"Moderator", "Mojira 管理员披风"}, + {"Translator-Chinese", "Crowdin 中文翻译者披风"}, {"Translator", "Crowdin 翻译者披风"}, {"Cobalt", "Cobalt 披风"}, + {"Vanilla", "原版披风"}, {"Minecon2011", "Minecon 2011 参与者披风"}, {"Minecon2012", "Minecon 2012 参与者披风"}, + {"Minecon2013", "Minecon 2013 参与者披风"}, {"Minecon2015", "Minecon 2015 参与者披风"}, {"Minecon2016", "Minecon 2016 参与者披风"} } Dim SelectionControl As New List(Of IMyRadio) From {New MyRadioBox With {.Text = "无披风"}} For Each Cape In SkinData("capes") diff --git a/Plain Craft Launcher 2/Pages/PageLaunch/PageLaunchLeft.xaml.vb b/Plain Craft Launcher 2/Pages/PageLaunch/PageLaunchLeft.xaml.vb index f7e8459..0692fc8 100644 --- a/Plain Craft Launcher 2/Pages/PageLaunch/PageLaunchLeft.xaml.vb +++ b/Plain Craft Launcher 2/Pages/PageLaunch/PageLaunchLeft.xaml.vb @@ -711,7 +711,11 @@ ExitRefresh: '修改登陆方式 Select Case Setup.Get("LoginType") Case McLoginType.Legacy - LabLaunchingMethod.Text = "离线登录" + If PageLinkHiper.HiperState = LoadState.Finished Then + LabLaunchingMethod.Text = "联机离线登录" + Else + LabLaunchingMethod.Text = "离线登录" + End If Case McLoginType.Mojang LabLaunchingMethod.Text = "Mojang 正版登录" Case McLoginType.Ms diff --git a/Plain Craft Launcher 2/Pages/PageLaunch/PageLoginLegacy.xaml.vb b/Plain Craft Launcher 2/Pages/PageLaunch/PageLoginLegacy.xaml.vb index e3fec69..b2ed860 100644 --- a/Plain Craft Launcher 2/Pages/PageLaunch/PageLoginLegacy.xaml.vb +++ b/Plain Craft Launcher 2/Pages/PageLaunch/PageLoginLegacy.xaml.vb @@ -32,12 +32,9 @@ ''' ''' 获取当前页面的登录信息。 ''' - Public Shared Function GetLoginData() As McLoginLegacy - If FrmLoginLegacy Is Nothing Then - Return New McLoginLegacy With {.UserName = "", .SkinType = Setup.Get("LaunchSkinType"), .SkinName = Setup.Get("LaunchSkinID")} - Else - Return New McLoginLegacy With {.UserName = FrmLoginLegacy.ComboName.Text.Replace("¨", "").Trim, .SkinType = Setup.Get("LaunchSkinType"), .SkinName = Setup.Get("LaunchSkinID")} - End If + Public Shared Function GetLoginData() As McLoginData + Dim UserName As String = If(FrmLoginLegacy Is Nothing, "", FrmLoginLegacy.ComboName.Text.Replace("¨", "").Trim) + Return New McLoginLegacy With {.UserName = UserName, .SkinType = Setup.Get("LaunchSkinType"), .SkinName = Setup.Get("LaunchSkinID")} End Function ''' ''' 当前页面的登录信息是否有效。 diff --git a/Plain Craft Launcher 2/Pages/PageLink/PageLinkFeedback.xaml b/Plain Craft Launcher 2/Pages/PageLink/PageLinkFeedback.xaml index fe74e5b..72e6dff 100644 --- a/Plain Craft Launcher 2/Pages/PageLink/PageLinkFeedback.xaml +++ b/Plain Craft Launcher 2/Pages/PageLink/PageLinkFeedback.xaml @@ -13,7 +13,7 @@ @@ -230,7 +230,7 @@ - + diff --git a/Plain Craft Launcher 2/Pages/PageLink/PageLinkIoi.xaml b/Plain Craft Launcher 2/Pages/PageLink/PageLinkIoi.xaml index fa912d0..c98aa47 100644 --- a/Plain Craft Launcher 2/Pages/PageLink/PageLinkIoi.xaml +++ b/Plain Craft Launcher 2/Pages/PageLink/PageLinkIoi.xaml @@ -44,7 +44,7 @@ - + diff --git a/Plain Craft Launcher 2/Pages/PageSetup/PageSetupSystem.xaml b/Plain Craft Launcher 2/Pages/PageSetup/PageSetupSystem.xaml index 496cc36..91a3a29 100644 --- a/Plain Craft Launcher 2/Pages/PageSetup/PageSetupSystem.xaml +++ b/Plain Craft Launcher 2/Pages/PageSetup/PageSetupSystem.xaml @@ -23,6 +23,7 @@ + @@ -45,7 +46,9 @@ - + diff --git a/Plain Craft Launcher 2/Pages/PageSetup/PageSetupSystem.xaml.vb b/Plain Craft Launcher 2/Pages/PageSetup/PageSetupSystem.xaml.vb index 60207fa..19dbfc6 100644 --- a/Plain Craft Launcher 2/Pages/PageSetup/PageSetupSystem.xaml.vb +++ b/Plain Craft Launcher 2/Pages/PageSetup/PageSetupSystem.xaml.vb @@ -56,6 +56,7 @@ SliderDownloadSpeed.Value = Setup.Get("ToolDownloadSpeed") ComboDownloadVersion.SelectedIndex = Setup.Get("ToolDownloadVersion") ComboDownloadTranslate.SelectedIndex = Setup.Get("ToolDownloadTranslate") + CheckDownloadKeepModpack.Checked = Setup.Get("ToolDownloadKeepModpack") 'Minecraft 更新提示 CheckUpdateRelease.Checked = Setup.Get("ToolUpdateRelease") @@ -84,6 +85,7 @@ Setup.Reset("ToolDownloadSpeed") Setup.Reset("ToolDownloadVersion") Setup.Reset("ToolDownloadTranslate") + Setup.Reset("ToolDownloadKeepModpack") Setup.Reset("ToolUpdateRelease") Setup.Reset("ToolUpdateSnapshot") Setup.Reset("ToolHelpChinese") @@ -105,7 +107,7 @@ End Sub '将控件改变路由到设置改变 - Private Shared Sub CheckBoxChange(sender As MyCheckBox, e As Object) Handles CheckDebugMode.Change, CheckDebugDelay.Change, CheckDebugSkipCopy.Change, CheckUpdateRelease.Change, CheckUpdateSnapshot.Change, CheckHelpChinese.Change + Private Shared Sub CheckBoxChange(sender As MyCheckBox, e As Object) Handles CheckDebugMode.Change, CheckDebugDelay.Change, CheckDebugSkipCopy.Change, CheckUpdateRelease.Change, CheckUpdateSnapshot.Change, CheckHelpChinese.Change, CheckDownloadKeepModpack.Change If AniControlEnabled = 0 Then Setup.Set(sender.Tag, sender.Checked) End Sub Private Shared Sub SliderChange(sender As MySlider, e As Object) Handles SliderDebugAnim.Change, SliderDownloadThread.Change, SliderDownloadSpeed.Change diff --git a/Plain Craft Launcher 2/Plain Craft Launcher 2.vbproj b/Plain Craft Launcher 2/Plain Craft Launcher 2.vbproj index 53cb7b4..0a7adc8 100644 --- a/Plain Craft Launcher 2/Plain Craft Launcher 2.vbproj +++ b/Plain Craft Launcher 2/Plain Craft Launcher 2.vbproj @@ -736,7 +736,6 @@ - @@ -900,5 +899,8 @@ + + + \ No newline at end of file diff --git a/Plain Craft Launcher 2/Resources/Help.zip b/Plain Craft Launcher 2/Resources/Help.zip index a82592dcf1c64521558855f397b74325654e3034..fbd7361b9971a6248c8dc2601442b6fbf734c0a5 100644 GIT binary patch delta 39580 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%0DJE&s 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 cv3qU^^0a0NHf@&YbV8s>iy~c%+ewRm0