diff --git a/YMCL.Main/App.axaml b/YMCL.Main/App.axaml
index 0b2cf98..e5a62de 100644
--- a/YMCL.Main/App.axaml
+++ b/YMCL.Main/App.axaml
@@ -29,5 +29,6 @@
+
\ No newline at end of file
diff --git a/YMCL.Main/Public/Classes/Sundry.cs b/YMCL.Main/Public/Classes/Sundry.cs
index e8c9180..949d4a5 100644
--- a/YMCL.Main/Public/Classes/Sundry.cs
+++ b/YMCL.Main/Public/Classes/Sundry.cs
@@ -12,6 +12,13 @@
namespace YMCL.Main.Public.Classes;
+public class AggregateSearch()
+{
+ public string Tag { get; set; }
+ public string Type { get; set; }
+ public string Summary { get; set; }
+ public string Text { get; set; }
+}
public class FolderInfo()
{
public string Name { get; set; }
@@ -296,3 +303,65 @@ public class UrlImageDataListEntry()
public string Url { get; set; }
public Bitmap Bitmap { get; set; }
}
+
+public class MojangJavaNews()
+{
+ public class Image
+ {
+ ///
+ ///
+ ///
+ public string url { get; set; }
+ ///
+ ///
+ ///
+ public string title { get; set; }
+ }
+
+ public class EntriesItem
+ {
+ public string BitmapBase64 { get; set; }
+
+ ///
+ ///
+ ///
+ public string title { get; set; }
+ ///
+ ///
+ ///
+ public string type { get; set; }
+ ///
+ ///
+ ///
+ public string version { get; set; }
+ ///
+ ///
+ ///
+ public Image image { get; set; }
+ ///
+ ///
+ ///
+ public string body { get; set; }
+ ///
+ ///
+ ///
+ public string id { get; set; }
+ ///
+ ///
+ ///
+ public string contentPath { get; set; }
+ }
+
+ public class Root
+ {
+ ///
+ ///
+ ///
+ public int version { get; set; }
+ ///
+ ///
+ ///
+ public List entries { get; set; }
+ }
+
+}
\ No newline at end of file
diff --git a/YMCL.Main/Public/Const.cs b/YMCL.Main/Public/Const.cs
index 6e66a74..3598c12 100644
--- a/YMCL.Main/Public/Const.cs
+++ b/YMCL.Main/Public/Const.cs
@@ -34,6 +34,7 @@ public abstract class String
Path.Combine(UserDataRootPath, "YMCL.MinecraftFolder.DaiYu");
public static string JavaDataPath { get; } = Path.Combine(UserDataRootPath, "YMCL.Java.DaiYu");
+ public static string JavaNewsDataPath { get; } = Path.Combine(UserDataRootPath, "YMCL.JavaNews.DaiYu");
public static string AppPathDataPath { get; } = Path.Combine(UserDataRootPath, "YMCL.AppPath.DaiYu");
public static string PlayerDataPath { get; } = Path.Combine(UserDataRootPath, "YMCL.Player.DaiYu");
diff --git a/YMCL.Main/Public/Controls/JavaNewsEntry/JavaNewsEntry.axaml b/YMCL.Main/Public/Controls/JavaNewsEntry/JavaNewsEntry.axaml
new file mode 100644
index 0000000..f4b5553
--- /dev/null
+++ b/YMCL.Main/Public/Controls/JavaNewsEntry/JavaNewsEntry.axaml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/YMCL.Main/Public/Controls/JavaNewsEntry/JavaNewsEntry.axaml.cs b/YMCL.Main/Public/Controls/JavaNewsEntry/JavaNewsEntry.axaml.cs
new file mode 100644
index 0000000..cbe1784
--- /dev/null
+++ b/YMCL.Main/Public/Controls/JavaNewsEntry/JavaNewsEntry.axaml.cs
@@ -0,0 +1,94 @@
+using System;
+using System.Diagnostics;
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Controls.Documents;
+using Avalonia.Markup.Xaml;
+using Avalonia.Media;
+using HtmlAgilityPack;
+
+namespace YMCL.Main.Public.Controls;
+
+public partial class JavaNewsEntry : UserControl
+{
+ public JavaNewsEntry(string img, string text)
+ {
+ InitializeComponent();
+ ImageC.Source = "https://launchercontent.mojang.com" + img;
+
+ var htmlDoc = new HtmlDocument();
+ htmlDoc.LoadHtml(text);
+
+ var wrapPanel = WrapPanelC;
+
+ // 解析并添加段落
+ var paragraphs = htmlDoc.DocumentNode.SelectNodes("//p");
+ if (paragraphs != null)
+ {
+ foreach (var paragraph in paragraphs)
+ {
+ var textBlock = new TextBlock
+ {
+ Text = paragraph.InnerText, FontFamily = (FontFamily)Application.Current.Resources["Font"]!,
+ TextWrapping = TextWrapping.Wrap
+ };
+ wrapPanel.Children.Add(textBlock);
+ }
+ }
+
+ // 解析并添加标题
+ var h1 = htmlDoc.DocumentNode.SelectSingleNode("//h1");
+ if (h1 != null)
+ {
+ var textBlock = new TextBlock
+ {
+ Text = h1.InnerText, FontWeight = FontWeight.Bold,
+ FontFamily = (FontFamily)Application.Current.Resources["Font"]!,
+ TextWrapping = TextWrapping.Wrap
+ };
+ wrapPanel.Children.Add(textBlock);
+ }
+
+ // 解析并添加实验特性
+ var h2 = htmlDoc.DocumentNode.SelectSingleNode("//h2");
+ if (h2 != null)
+ {
+ var textBlock = new TextBlock
+ {
+ Text = h2.InnerText, FontWeight = FontWeight.Bold,
+ FontFamily = (FontFamily)Application.Current.Resources["Font"]!,
+ TextWrapping = TextWrapping.Wrap
+ };
+ wrapPanel.Children.Add(textBlock);
+ }
+
+ // 解析并添加列表项
+ var listItems = htmlDoc.DocumentNode.SelectNodes("//ul/li");
+ if (listItems != null)
+ {
+ foreach (var item in listItems)
+ {
+ var textBlock = new TextBlock
+ { Text = item.InnerText, FontFamily = (FontFamily)Application.Current.Resources["Font"]!,
+ TextWrapping = TextWrapping.Wrap };
+ wrapPanel.Children.Add(textBlock);
+ wrapPanel.Children.Add(new TextBlock { Text = "\n" }); // 添加换行
+ }
+ }
+
+ // 解析并添加超链接
+ var links = htmlDoc.DocumentNode.SelectNodes("//a[@href]");
+ if (links != null)
+ {
+ foreach (var link in links)
+ {
+ var hyperlink = new HyperlinkButton()
+ {
+ Content = link.InnerText, FontFamily = (FontFamily)Application.Current.Resources["Font"]!,
+ NavigateUri = new Uri(link.Attributes["href"].Value)
+ };
+ wrapPanel.Children.Add(hyperlink);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/YMCL.Main/Public/Enum.cs b/YMCL.Main/Public/Enum.cs
index 0527c83..87d228c 100644
--- a/YMCL.Main/Public/Enum.cs
+++ b/YMCL.Main/Public/Enum.cs
@@ -73,7 +73,8 @@ public enum CustomHomePageWay
{
None,
Local,
- Network
+ Network,
+ Presetting_JavaNews
}
public enum DaiYuLoaderType
diff --git a/YMCL.Main/Public/Langs/MainLang.Designer.cs b/YMCL.Main/Public/Langs/MainLang.Designer.cs
index 5c6643f..3917d9a 100644
--- a/YMCL.Main/Public/Langs/MainLang.Designer.cs
+++ b/YMCL.Main/Public/Langs/MainLang.Designer.cs
@@ -194,6 +194,15 @@ public static string AfterLaunchMinimizeAndShowWhenGameExit {
}
}
+ ///
+ /// Looks up a localized string similar to 杈撳叆鍏抽敭璇嶄互鍦╕MCL涓悳绱 .
+ ///
+ public static string AggregateSearchTip {
+ get {
+ return ResourceManager.GetString("AggregateSearchTip", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to 灞呬腑瀵归綈.
///
@@ -509,6 +518,15 @@ public static string CustomHomePageSourceCodeError {
}
}
+ ///
+ /// Looks up a localized string similar to 棰勮-Java鏂伴椈.
+ ///
+ public static string CustomHomePageWay_Presetting_JavaNews {
+ get {
+ return ResourceManager.GetString("CustomHomePageWay_Presetting_JavaNews", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to 鑷畾涔夋洿鏂癠rl.
///
@@ -1565,6 +1583,15 @@ public static string NeedToSelectMinecraftFolder {
}
}
+ ///
+ /// Looks up a localized string similar to 缃戠粶婧.
+ ///
+ public static string NetworkSource {
+ get {
+ return ResourceManager.GetString("NetworkSource", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to 鏃犻檮鍔犲畨瑁.
///
@@ -1610,6 +1637,15 @@ public static string NoCrashInfo {
}
}
+ ///
+ /// Looks up a localized string similar to 鐜颁笉鏀寔.
+ ///
+ public static string NoSupportNow {
+ get {
+ return ResourceManager.GetString("NoSupportNow", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to 鍏抽棴.
///
diff --git a/YMCL.Main/Public/Langs/MainLang.resx b/YMCL.Main/Public/Langs/MainLang.resx
index 8074f8c..6849a3a 100644
--- a/YMCL.Main/Public/Langs/MainLang.resx
+++ b/YMCL.Main/Public/Langs/MainLang.resx
@@ -924,4 +924,16 @@ win10 浠ヤ笅绯荤粺(涓嶅寘鎷10)涓嶆敮鎸佽嚜鍔ㄦ洿鏂
鎵撳紑娴忚鍣
+
+ 棰勮-Java鏂伴椈
+
+
+ 缃戠粶婧
+
+
+ 鐜颁笉鏀寔
+
+
+ 杈撳叆鍏抽敭璇嶄互鍦╕MCL涓悳绱
+
\ No newline at end of file
diff --git a/YMCL.Main/Public/Method.cs b/YMCL.Main/Public/Method.cs
index 0fbf05e..e7d8b00 100644
--- a/YMCL.Main/Public/Method.cs
+++ b/YMCL.Main/Public/Method.cs
@@ -333,7 +333,7 @@ public static void RestartApp()
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36 Edg/91.0.864.54");
var githubApiJson = JArray.Parse(await httpClient.GetStringAsync(Const.String.GithubUpdateApiUrl));
var apiVersion = (string)githubApiJson[0]["name"]!;
- return (true, apiVersion != version, apiVersion, (string)githubApiJson[0]["html_url"]!);
+ return (true, apiVersion != version, apiVersion, (string)githubApiJson[0]["html_url"]!);
}
catch
{
@@ -1612,7 +1612,9 @@ public static async Task LaunchClientUsingMinecraftLaunchAsync(string p_id
}
Launcher launcher = new(gameResolver, config);
-
+ bool _showed = false;
+ string _gameMsg = String.Empty;
+ bool _firstOut = true;
await Task.Run(async () =>
{
try
@@ -1647,6 +1649,12 @@ await Dispatcher.UIThread.InvokeAsync(async () =>
var crashAnalyzer = new GameCrashAnalyzer(gameEntry, l_enableIndependencyCore);
var reports = crashAnalyzer.AnalysisLogs();
var msg = string.Empty;
+ if (_firstOut == true && !setting.ShowGameOutput)
+ {
+ task.UpdateTextProgress(_gameMsg, false);
+ _firstOut = false;
+ }
+
try
{
if (reports == null || reports.Count() == 0)
@@ -1663,26 +1671,32 @@ await Dispatcher.UIThread.InvokeAsync(async () =>
task.UpdateTextProgress(string.Empty, false);
task.UpdateTextProgress($"YMCL -----> {MainLang.MineratCrashed}");
task.isFinish = true;
-
+ task.Show();
var dialogResult = await Ui.ShowDialogAsync(MainLang.MineratCrashed, msg,
b_primary: MainLang.Ok);
task.Destory();
}
});
};
+
watcher.OutputLogReceived += async (_, args) =>
{
Console.WriteLine(args.Log);
- if (setting.ShowGameOutput)
- await Dispatcher.UIThread.InvokeAsync(() =>
- {
- task.UpdateTextProgress(args.Original, false);
- });
- else
- await Dispatcher.UIThread.InvokeAsync(() =>
+ if ((!setting.ShowGameOutput && !_showed))
+ {
+ _gameMsg += args.Log;
+ }
+
+ if (setting.ShowGameOutput || (!setting.ShowGameOutput && _showed))
+ {
+ if (_firstOut)
{
- task.entry.UpdateTextProgress(args.Original, false);
- });
+ task.UpdateTextProgress(_gameMsg, false);
+ _firstOut = false;
+ }
+
+ task.UpdateTextProgress(args.Original, false);
+ }
};
await Dispatcher.UIThread.InvokeAsync(() =>
@@ -1702,6 +1716,11 @@ await Dispatcher.UIThread.InvokeAsync(() =>
Dispatcher.UIThread.Invoke(() =>
{
+ if (!setting.ShowGameOutput)
+ {
+ task.Hide();
+ }
+
switch (setting.LauncherVisibility)
{
case LauncherVisibility.AfterLaunchExitLauncher:
diff --git a/YMCL.Main/Views/Initialize/InitializeWindow.axaml.cs b/YMCL.Main/Views/Initialize/InitializeWindow.axaml.cs
index dca99fb..aa7b09f 100644
--- a/YMCL.Main/Views/Initialize/InitializeWindow.axaml.cs
+++ b/YMCL.Main/Views/Initialize/InitializeWindow.axaml.cs
@@ -80,6 +80,9 @@ private void Init()
if (!File.Exists(Const.String.PluginDataPath))
File.WriteAllText(Const.String.PluginDataPath,
JsonConvert.SerializeObject(new List(), Formatting.Indented));
+ if (!File.Exists(Const.String.JavaNewsDataPath))
+ File.WriteAllText(Const.String.JavaNewsDataPath,
+ "{}");
if (!File.Exists(Const.String.PlayerDataPath))
File.WriteAllText(Const.String.PlayerDataPath,
JsonConvert.SerializeObject(new List(), Formatting.Indented));
diff --git a/YMCL.Main/Views/Main/MainWindow.axaml.cs b/YMCL.Main/Views/Main/MainWindow.axaml.cs
index 410b22c..3e11ba5 100644
--- a/YMCL.Main/Views/Main/MainWindow.axaml.cs
+++ b/YMCL.Main/Views/Main/MainWindow.axaml.cs
@@ -22,6 +22,7 @@
using Newtonsoft.Json;
using YMCL.Main.Public;
using YMCL.Main.Public.Classes;
+using YMCL.Main.Public.Controls;
using YMCL.Main.Public.Controls.WindowTask;
using YMCL.Main.Public.Langs;
using YMCL.Main.Views.Main.Pages.Download;
@@ -224,7 +225,25 @@ public void LoadWindow()
Const.Window.main.Show();
Const.Window.initialize.Close();
- if (setting.CustomHomePage == CustomHomePageWay.Local)
+ _ = FetchJavaNews();
+ _ = LoadCustomHomePage();
+
+ _ = downloadPage.curseForgeFetcherPage.InitModFromCurseForge();
+ Method.Ui.SetWindowBackGroundImg();
+ }
+
+ private async Task FetchJavaNews()
+ {
+ using var client = new HttpClient();
+ var json = await client.GetStringAsync("https://launchercontent.mojang.com/javaPatchNotes.json");
+ await File.WriteAllTextAsync(Const.String.JavaNewsDataPath, json);
+ // _ = LoadCustomHomePage();
+ }
+
+ private async Task LoadCustomHomePage()
+ {
+ if (Const.Data.Setting.CustomHomePage == CustomHomePageWay.Local)
+ {
try
{
var c = (Control)AvaloniaRuntimeXamlLoader.Load(
@@ -235,9 +254,27 @@ public void LoadWindow()
{
Method.Ui.ShowLongException(MainLang.CustomHomePageSourceCodeError, ex);
}
-
- downloadPage.curseForgeFetcherPage.SearchModFromCurseForge();
- Method.Ui.SetWindowBackGroundImg();
+ }
+ else if (Const.Data.Setting.CustomHomePage == CustomHomePageWay.Presetting_JavaNews)
+ {
+ try
+ {
+ var viewer = new ScrollViewer();
+ var container = new StackPanel()
+ {
+ Spacing = 10
+ };
+ viewer.Content = container;
+ launchPage.CustomPageRoot.Child = viewer;
+ var news = JsonConvert.DeserializeObject(
+ await File.ReadAllTextAsync(Const.String.JavaNewsDataPath));
+ news.entries.ForEach(v =>
+ container.Children.Add(new JavaNewsEntry(v.image.url, v.body)));
+ }
+ catch (Exception ex)
+ {
+ }
+ }
}
public async void HandleDrop(object sender, DragEventArgs e)
diff --git a/YMCL.Main/Views/Main/Pages/Download/Pages/CurseForge/CurseForgeFetcher.axaml.cs b/YMCL.Main/Views/Main/Pages/Download/Pages/CurseForge/CurseForgeFetcher.axaml.cs
index 9555bf4..2f1becd 100644
--- a/YMCL.Main/Views/Main/Pages/Download/Pages/CurseForge/CurseForgeFetcher.axaml.cs
+++ b/YMCL.Main/Views/Main/Pages/Download/Pages/CurseForge/CurseForgeFetcher.axaml.cs
@@ -82,6 +82,7 @@ async void OpenDetail()
SearchConsoleRoot.Opacity = 0;
}
+
Loaded += (_, _) =>
{
Method.Ui.PageLoadAnimation((0, 50, 0, -50), (0, 0, 0, 0), TimeSpan.FromSeconds(0.30), Root, true);
@@ -170,7 +171,7 @@ await Task.Run(() =>
index++;
}
});
-
+
ModFileLoading.IsVisible = false;
if (shouldReturn) return;
List mcVersions = new();
@@ -485,7 +486,7 @@ public async void SearchModFromCurseForge()
categoryId: -1, classId: classId);
if (ModNameTextBox.Text != keyword) return;
-
+
mods.Data.ForEach(mod =>
{
var entry = new SearchModListViewItemEntry(mod);
@@ -518,6 +519,71 @@ public async void SearchModFromCurseForge()
}
}
+ public async Task InitModFromCurseForge()
+ {
+ await Task.Run(async () =>
+ {
+ Const.Data.UrlImageDataList.Clear();
+ var keyword = ModNameTextBox.Text;
+ _keyword = keyword;
+ var gameVersion = ModVersionTextBox.Text;
+ _gameVersion = gameVersion;
+ ModLoaderType loaderType;
+
+ if (mapping.TryGetValue((DaiYuLoaderType)LoaderTypeComboBox.SelectedIndex, out var modLoaderType))
+ loaderType = modLoaderType;
+ else
+ loaderType = ModLoaderType.Any;
+
+ _loaderType = loaderType;
+ try
+ {
+ var classId = GetClassIdFromResultTypeComboBoxSelectedIndex(ResultTypeComboBox.SelectedIndex);
+
+ GenericListResponse mods;
+ if (loaderType == ModLoaderType.Any)
+ mods = await cfApiClient.SearchModsAsync(_gameId, gameVersion: gameVersion,
+ searchFilter: keyword, index: _page * 25, pageSize: 25, categoryId: -1, classId: classId);
+ else
+ mods = await cfApiClient.SearchModsAsync(_gameId, gameVersion: gameVersion,
+ searchFilter: keyword, modLoaderType: loaderType, index: _page * 25, pageSize: 25,
+ categoryId: -1, classId: classId);
+
+ if (ModNameTextBox.Text != keyword) return;
+
+ mods.Data.ForEach(mod =>
+ {
+ var entry = new SearchModListViewItemEntry(mod);
+ entry.StringDownloadCount = Method.Value.ConvertToWanOrYi(mod.DownloadCount);
+ var localDateTime = mod.DateReleased.DateTime.ToLocalTime();
+ var formattedDateTime = localDateTime.ToString("yyyy-MM-dd HH:mm", CultureInfo.InvariantCulture);
+ entry.StringDateTime = formattedDateTime;
+ entry.ModSource = ModSource.CurseForge;
+ ModListView.Items.Add(entry);
+ });
+ ModNameTextBox.IsEnabled = true;
+ ModVersionTextBox.IsEnabled = true;
+ SearchBtn.IsEnabled = true;
+ Loading.IsVisible = false;
+ LoadMoreBtn.IsVisible = true;
+ if (mods.Data.Count == 0)
+ {
+ Method.Ui.Toast(MainLang.SearchNoResult);
+ LoadMoreBtn.IsVisible = false;
+ }
+ }
+ catch (Exception ex)
+ {
+ ModNameTextBox.IsEnabled = true;
+ ModVersionTextBox.IsEnabled = true;
+ SearchBtn.IsEnabled = true;
+ Loading.IsVisible = false;
+ LoadMoreBtn.IsVisible = false;
+ Method.Ui.ShowShortException(MainLang.ErrorCallingApi, ex);
+ }
+ });
+ }
+
public class VersionComparer : IComparer
{
public int Compare(string x, string y)
diff --git a/YMCL.Main/Views/Main/Pages/Setting/Pages/Personalize/PersonalizeSettingPage.axaml b/YMCL.Main/Views/Main/Pages/Setting/Pages/Personalize/PersonalizeSettingPage.axaml
index 11caaa0..2ff42ce 100644
--- a/YMCL.Main/Views/Main/Pages/Setting/Pages/Personalize/PersonalizeSettingPage.axaml
+++ b/YMCL.Main/Views/Main/Pages/Setting/Pages/Personalize/PersonalizeSettingPage.axaml
@@ -280,6 +280,8 @@
+
+
diff --git a/YMCL.Main/Views/Main/Pages/Setting/Pages/Personalize/PersonalizeSettingPage.axaml.cs b/YMCL.Main/Views/Main/Pages/Setting/Pages/Personalize/PersonalizeSettingPage.axaml.cs
index 2ae4ea9..3843026 100644
--- a/YMCL.Main/Views/Main/Pages/Setting/Pages/Personalize/PersonalizeSettingPage.axaml.cs
+++ b/YMCL.Main/Views/Main/Pages/Setting/Pages/Personalize/PersonalizeSettingPage.axaml.cs
@@ -58,6 +58,12 @@ private void BindingEvent()
CustomHomePageComboBox.SelectionChanged += (s, e) =>
{
var setting = Const.Data.Setting;
+ if (CustomHomePageComboBox.SelectedIndex == 2)
+ {
+ CustomHomePageComboBox.SelectedIndex = 0;
+ Method.Ui.Toast(MainLang.NoSupportNow);
+ return;
+ }
EditCustomHomePageBtn.IsVisible = CustomHomePageComboBox.SelectedIndex == 1 ? true : false;
if (CustomHomePageComboBox.SelectedIndex != (int)setting.CustomHomePage)
{
diff --git a/YMCL.Main/YMCL.Main.csproj b/YMCL.Main/YMCL.Main.csproj
index f58c45c..2ed45a9 100644
--- a/YMCL.Main/YMCL.Main.csproj
+++ b/YMCL.Main/YMCL.Main.csproj
@@ -46,16 +46,17 @@
-
-
-
+
+
+
+
-
-
-
+
+
+