From 4548c9b0aaa07dcc06d4a5fe0557e19d1c7fbd8a Mon Sep 17 00:00:00 2001
From: nya-a-cat <188900516+nya-a-cat@users.noreply.github.com>
Date: Fri, 14 Aug 2026 12:02:06 +0800
Subject: [PATCH 1/4] =?UTF-8?q?feat(resource):=20=E6=94=AF=E6=8C=81?=
=?UTF-8?q?=E4=BB=8E=E5=85=B6=E4=BB=96=E5=AE=9E=E4=BE=8B=E5=AF=BC=E5=85=A5?=
=?UTF-8?q?=E8=B5=84=E6=BA=90?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../App/Localization/Languages/en-US.xaml | 6 +-
.../App/Localization/Languages/zh-CN.xaml | 6 +-
.../PageInstanceCompResource.xaml | 4 +-
.../PageInstanceCompResource.xaml.cs | 55 +++++++++++++++++++
4 files changed, 68 insertions(+), 3 deletions(-)
diff --git a/PCL.Core/App/Localization/Languages/en-US.xaml b/PCL.Core/App/Localization/Languages/en-US.xaml
index c090e7a13e..6e793f79a5 100644
--- a/PCL.Core/App/Localization/Languages/en-US.xaml
+++ b/PCL.Core/App/Localization/Languages/en-US.xaml
@@ -1069,6 +1069,10 @@
Export info
Export detailed version info for resources
Favorite
+ {0} file(s) available
+ No other instance contains files available for import
+ Select source instance
+ Import from another instance
Install from files
Loading resource list
Loading resource list
@@ -3570,4 +3574,4 @@
Minecraft window loaded: {0} ({1})
Minecraft window maximized: {0}
-
\ No newline at end of file
+
diff --git a/PCL.Core/App/Localization/Languages/zh-CN.xaml b/PCL.Core/App/Localization/Languages/zh-CN.xaml
index 9bae29f93c..eeda141ff3 100644
--- a/PCL.Core/App/Localization/Languages/zh-CN.xaml
+++ b/PCL.Core/App/Localization/Languages/zh-CN.xaml
@@ -1069,6 +1069,10 @@
导出信息
导出详细的资源的版本信息
收藏
+ {0} 个可导入文件
+ 没有找到包含可导入文件的其他实例
+ 选择来源实例
+ 从其他实例导入
从文件安装
正在加载资源列表
正在加载资源列表
@@ -3570,4 +3574,4 @@
Minecraft 窗口已加载:{0}({1})
已最大化 Minecraft 窗口:{0}
-
\ No newline at end of file
+
diff --git a/Plain Craft Launcher 2/Pages/PageInstance/PageInstanceCompResource.xaml b/Plain Craft Launcher 2/Pages/PageInstance/PageInstanceCompResource.xaml
index 185ead92ab..1dbd6e10d4 100644
--- a/Plain Craft Launcher 2/Pages/PageInstance/PageInstanceCompResource.xaml
+++ b/Plain Craft Launcher 2/Pages/PageInstance/PageInstanceCompResource.xaml
@@ -20,6 +20,8 @@
+
-
\ No newline at end of file
+
diff --git a/Plain Craft Launcher 2/Pages/PageInstance/PageInstanceCompResource.xaml.cs b/Plain Craft Launcher 2/Pages/PageInstance/PageInstanceCompResource.xaml.cs
index 00ac8ee7d1..80422aeaf1 100644
--- a/Plain Craft Launcher 2/Pages/PageInstance/PageInstanceCompResource.xaml.cs
+++ b/Plain Craft Launcher 2/Pages/PageInstance/PageInstanceCompResource.xaml.cs
@@ -40,6 +40,7 @@ public PageInstanceCompResource()
BtnHintOpen.Click += BtnManageOpen_Click;
BtnManageSelectAll.Click += BtnManageSelectAll_Click;
BtnManageInstall.Click += BtnManageInstall_Click;
+ BtnManageImport.Click += BtnManageImport_Click;
BtnHintInstall.Click += BtnManageInstall_Click;
BtnManageInfoExport.Click += BtnManageInfoExport_Click;
BtnManageDownload.Click += BtnManageDownload_Click;
@@ -117,6 +118,9 @@ public PageInstanceCompResource(ModComp.CompType loadCompType)
BtnSelectDisable.Visibility = Visibility.Collapsed;
}
+ if (new[] { ModComp.CompType.Shader, ModComp.CompType.ResourcePack }.Contains(currentCompType))
+ BtnManageImport.Visibility = Visibility.Visible;
+
// 投影文件管理页隐藏下载按钮
if (currentCompType == ModComp.CompType.Schematic)
{
@@ -136,6 +140,7 @@ public PageInstanceCompResource(ModComp.CompType loadCompType)
BtnHintOpen.Click += BtnManageOpen_Click;
BtnManageSelectAll.Click += BtnManageSelectAll_Click;
BtnManageInstall.Click += BtnManageInstall_Click;
+ BtnManageImport.Click += BtnManageImport_Click;
BtnHintInstall.Click += BtnManageInstall_Click;
BtnManageDownload.Click += BtnManageDownload_Click;
BtnHintDownload.Click += BtnManageDownload_Click;
@@ -1021,6 +1026,56 @@ private void BtnManageInstall_Click(object sender, MouseButtonEventArgs e)
InstallCompFiles(fileList, currentCompType, CurrentFolderPath);
}
+ ///
+ /// 从其他实例导入资源包或光影包。
+ ///
+ private void BtnManageImport_Click(object sender, MouseButtonEventArgs e)
+ {
+ var folderName = currentCompType switch
+ {
+ ModComp.CompType.ResourcePack => "resourcepacks",
+ ModComp.CompType.Shader => "shaderpacks",
+ _ => null
+ };
+ if (folderName is null) return;
+
+ var targetFolder = Path.GetFullPath(Path.Combine(PageInstanceLeft.McInstance.PathIndie, folderName));
+ var sources = ModInstanceList.mcInstanceList.Values.SelectMany(list => list)
+ .Where(instance => instance.state != McInstanceState.Error &&
+ !instance.Equals(PageInstanceLeft.McInstance))
+ .Select(instance =>
+ {
+ var sourceFolder = Path.GetFullPath(Path.Combine(instance.PathIndie, folderName));
+ var files = Directory.Exists(sourceFolder)
+ ? Directory.GetFiles(sourceFolder, "*.zip", SearchOption.TopDirectoryOnly)
+ : [];
+ return (Instance: instance, Folder: sourceFolder, Files: files);
+ })
+ .Where(source => !source.Folder.Equals(targetFolder, StringComparison.OrdinalIgnoreCase) &&
+ source.Files.Length > 0)
+ .OrderBy(source => source.Instance.Name)
+ .ToList();
+
+ if (sources.Count == 0)
+ {
+ HintService.Hint(Lang.Text("Instance.Resource.Import.NoAvailableInstance"));
+ return;
+ }
+
+ var selection = sources.Select(source => (IMyRadio)new MyListItem
+ {
+ Title = source.Instance.Name,
+ Info = Lang.Text("Instance.Resource.Import.FileCount", source.Files.Length),
+ Type = MyListItem.CheckType.RadioBox
+ }).ToList();
+ var selectedIndex = ModMain.MyMsgBoxSelect(selection,
+ Lang.Text("Instance.Resource.Import.SelectInstance"),
+ Lang.Text("Common.Action.Confirm"), Lang.Text("Common.Action.Cancel"));
+ if (selectedIndex is null) return;
+
+ InstallCompFiles(sources[selectedIndex.Value].Files, currentCompType, CurrentFolderPath);
+ }
+
///
/// 尝试安装 Mod。
/// 返回输入的文件是否为一个 Mod 文件,仅用于判断拖拽行为。
From 94898521cab419c189bc1faa914ab03cf2e2a349 Mon Sep 17 00:00:00 2001
From: nya-a-cat <188900516+nya-a-cat@users.noreply.github.com>
Date: Fri, 14 Aug 2026 12:18:29 +0800
Subject: [PATCH 2/4] =?UTF-8?q?fix(resource):=20=E8=A1=A5=E5=85=A8?=
=?UTF-8?q?=E7=A9=BA=E5=88=97=E8=A1=A8=E5=AF=BC=E5=85=A5=E5=85=A5=E5=8F=A3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../PageInstanceCompResource.xaml | 2 ++
.../PageInstanceCompResource.xaml.cs | 24 ++++++++++++++++---
2 files changed, 23 insertions(+), 3 deletions(-)
diff --git a/Plain Craft Launcher 2/Pages/PageInstance/PageInstanceCompResource.xaml b/Plain Craft Launcher 2/Pages/PageInstance/PageInstanceCompResource.xaml
index 1dbd6e10d4..4d6572ed75 100644
--- a/Plain Craft Launcher 2/Pages/PageInstance/PageInstanceCompResource.xaml
+++ b/Plain Craft Launcher 2/Pages/PageInstance/PageInstanceCompResource.xaml
@@ -73,6 +73,8 @@
Padding="12,0" Visibility="Collapsed" />
+
{
var sourceFolder = Path.GetFullPath(Path.Combine(instance.PathIndie, folderName));
- var files = Directory.Exists(sourceFolder)
- ? Directory.GetFiles(sourceFolder, "*.zip", SearchOption.TopDirectoryOnly)
- : [];
+ var files = GetImportFiles(instance, sourceFolder);
return (Instance: instance, Folder: sourceFolder, Files: files);
})
.Where(source => !source.Folder.Equals(targetFolder, StringComparison.OrdinalIgnoreCase) &&
@@ -1076,6 +1079,21 @@ private void BtnManageImport_Click(object sender, MouseButtonEventArgs e)
InstallCompFiles(sources[selectedIndex.Value].Files, currentCompType, CurrentFolderPath);
}
+ private static string[] GetImportFiles(McInstance instance, string sourceFolder)
+ {
+ try
+ {
+ return Directory.Exists(sourceFolder)
+ ? Directory.GetFiles(sourceFolder, "*.zip", SearchOption.TopDirectoryOnly)
+ : [];
+ }
+ catch (Exception ex)
+ {
+ ModBase.Log(ex, $"读取实例 {instance.Name} 的资源文件失败");
+ return [];
+ }
+ }
+
///
/// 尝试安装 Mod。
/// 返回输入的文件是否为一个 Mod 文件,仅用于判断拖拽行为。
From a0ce7dfc2943480c8abf664338b4caed6100a4ff Mon Sep 17 00:00:00 2001
From: nya-a-cat <188900516+nya-a-cat@users.noreply.github.com>
Date: Fri, 14 Aug 2026 12:57:32 +0800
Subject: [PATCH 3/4] =?UTF-8?q?style(resource):=20=E8=A7=84=E8=8C=83?=
=?UTF-8?q?=E7=A7=81=E6=9C=89=E8=BE=85=E5=8A=A9=E6=96=B9=E6=B3=95=E5=91=BD?=
=?UTF-8?q?=E5=90=8D?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../Pages/PageInstance/PageInstanceCompResource.xaml.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Plain Craft Launcher 2/Pages/PageInstance/PageInstanceCompResource.xaml.cs b/Plain Craft Launcher 2/Pages/PageInstance/PageInstanceCompResource.xaml.cs
index afdcb3a7d9..432f3468c9 100644
--- a/Plain Craft Launcher 2/Pages/PageInstance/PageInstanceCompResource.xaml.cs
+++ b/Plain Craft Launcher 2/Pages/PageInstance/PageInstanceCompResource.xaml.cs
@@ -1051,7 +1051,7 @@ private void BtnManageImport_Click(object sender, MouseButtonEventArgs e)
.Select(instance =>
{
var sourceFolder = Path.GetFullPath(Path.Combine(instance.PathIndie, folderName));
- var files = GetImportFiles(instance, sourceFolder);
+ var files = _GetImportFiles(instance, sourceFolder);
return (Instance: instance, Folder: sourceFolder, Files: files);
})
.Where(source => !source.Folder.Equals(targetFolder, StringComparison.OrdinalIgnoreCase) &&
@@ -1079,7 +1079,7 @@ private void BtnManageImport_Click(object sender, MouseButtonEventArgs e)
InstallCompFiles(sources[selectedIndex.Value].Files, currentCompType, CurrentFolderPath);
}
- private static string[] GetImportFiles(McInstance instance, string sourceFolder)
+ private static string[] _GetImportFiles(McInstance instance, string sourceFolder)
{
try
{
From 0db2ec4028a45fdd189c77163356c209af562d9d Mon Sep 17 00:00:00 2001
From: nya-a-cat <188900516+nya-a-cat@users.noreply.github.com>
Date: Fri, 14 Aug 2026 17:57:51 +0800
Subject: [PATCH 4/4] =?UTF-8?q?fix(resource):=20=E7=9B=B4=E6=8E=A5?=
=?UTF-8?q?=E5=A4=8D=E5=88=B6=E5=85=B6=E4=BB=96=E5=AE=9E=E4=BE=8B=E8=B5=84?=
=?UTF-8?q?=E6=BA=90?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../App/Localization/Languages/en-US.xaml | 7 +-
.../App/Localization/Languages/zh-CN.xaml | 7 +-
.../PageInstanceCompResource.xaml.cs | 92 +++++++++++++++++--
3 files changed, 95 insertions(+), 11 deletions(-)
diff --git a/PCL.Core/App/Localization/Languages/en-US.xaml b/PCL.Core/App/Localization/Languages/en-US.xaml
index 6e793f79a5..d43ace93a5 100644
--- a/PCL.Core/App/Localization/Languages/en-US.xaml
+++ b/PCL.Core/App/Localization/Languages/en-US.xaml
@@ -1069,9 +1069,12 @@
Export info
Export detailed version info for resources
Favorite
- {0} file(s) available
- No other instance contains files available for import
+ {0} resource item(s) available
+ No other instance contains resources available for import
+ A resource named {0} already exists. Overwrite it?
+ Confirm resource overwrite
Select source instance
+ Imported {0} resource item(s)
Import from another instance
Install from files
Loading resource list
diff --git a/PCL.Core/App/Localization/Languages/zh-CN.xaml b/PCL.Core/App/Localization/Languages/zh-CN.xaml
index eeda141ff3..c78a5a4925 100644
--- a/PCL.Core/App/Localization/Languages/zh-CN.xaml
+++ b/PCL.Core/App/Localization/Languages/zh-CN.xaml
@@ -1069,9 +1069,12 @@
导出信息
导出详细的资源的版本信息
收藏
- {0} 个可导入文件
- 没有找到包含可导入文件的其他实例
+ {0} 个可导入资源
+ 没有找到包含可导入资源的其他实例
+ 已存在同名资源:{0},是否覆盖?
+ 资源覆盖确认
选择来源实例
+ 已导入 {0} 个资源
从其他实例导入
从文件安装
正在加载资源列表
diff --git a/Plain Craft Launcher 2/Pages/PageInstance/PageInstanceCompResource.xaml.cs b/Plain Craft Launcher 2/Pages/PageInstance/PageInstanceCompResource.xaml.cs
index 432f3468c9..06869c3e48 100644
--- a/Plain Craft Launcher 2/Pages/PageInstance/PageInstanceCompResource.xaml.cs
+++ b/Plain Craft Launcher 2/Pages/PageInstance/PageInstanceCompResource.xaml.cs
@@ -1051,11 +1051,11 @@ private void BtnManageImport_Click(object sender, MouseButtonEventArgs e)
.Select(instance =>
{
var sourceFolder = Path.GetFullPath(Path.Combine(instance.PathIndie, folderName));
- var files = _GetImportFiles(instance, sourceFolder);
- return (Instance: instance, Folder: sourceFolder, Files: files);
+ var entries = _GetImportEntries(instance, sourceFolder);
+ return (Instance: instance, Folder: sourceFolder, Entries: entries);
})
.Where(source => !source.Folder.Equals(targetFolder, StringComparison.OrdinalIgnoreCase) &&
- source.Files.Length > 0)
+ source.Entries.Length > 0)
.OrderBy(source => source.Instance.Name)
.ToList();
@@ -1068,7 +1068,7 @@ private void BtnManageImport_Click(object sender, MouseButtonEventArgs e)
var selection = sources.Select(source => (IMyRadio)new MyListItem
{
Title = source.Instance.Name,
- Info = Lang.Text("Instance.Resource.Import.FileCount", source.Files.Length),
+ Info = Lang.Text("Instance.Resource.Import.ItemCount", source.Entries.Length),
Type = MyListItem.CheckType.RadioBox
}).ToList();
var selectedIndex = ModMain.MyMsgBoxSelect(selection,
@@ -1076,15 +1076,20 @@ private void BtnManageImport_Click(object sender, MouseButtonEventArgs e)
Lang.Text("Common.Action.Confirm"), Lang.Text("Common.Action.Cancel"));
if (selectedIndex is null) return;
- InstallCompFiles(sources[selectedIndex.Value].Files, currentCompType, CurrentFolderPath);
+ _ImportEntries(sources[selectedIndex.Value].Entries, targetFolder);
}
- private static string[] _GetImportFiles(McInstance instance, string sourceFolder)
+ private static string[] _GetImportEntries(McInstance instance, string sourceFolder)
{
try
{
return Directory.Exists(sourceFolder)
- ? Directory.GetFiles(sourceFolder, "*.zip", SearchOption.TopDirectoryOnly)
+ ? Directory.EnumerateFileSystemEntries(sourceFolder, "*", new EnumerationOptions
+ {
+ RecurseSubdirectories = false,
+ IgnoreInaccessible = false,
+ AttributesToSkip = FileAttributes.ReparsePoint
+ }).ToArray()
: [];
}
catch (Exception ex)
@@ -1094,6 +1099,79 @@ private static string[] _GetImportFiles(McInstance instance, string sourceFolder
}
}
+ private void _ImportEntries(IEnumerable entries, string targetFolder)
+ {
+ try
+ {
+ Directory.CreateDirectory(targetFolder);
+ var importedCount = 0;
+ foreach (var sourceEntry in entries)
+ {
+ var entryName = Path.GetFileName(Path.TrimEndingDirectorySeparator(sourceEntry));
+ var targetEntry = Path.Combine(targetFolder, entryName);
+ if (File.Exists(targetEntry) || Directory.Exists(targetEntry))
+ {
+ if (ModMain.MyMsgBox(
+ Lang.Text("Instance.Resource.Import.OverwriteConfirm.Message", entryName),
+ Lang.Text("Instance.Resource.Import.OverwriteConfirm.Title"),
+ Lang.Text("Common.Action.Overwrite"), Lang.Text("Common.Action.Cancel")) != 1)
+ continue;
+ _DeleteImportTarget(targetEntry);
+ }
+
+ if (File.Exists(sourceEntry))
+ ModBase.CopyFile(sourceEntry, targetEntry);
+ else if (Directory.Exists(sourceEntry))
+ _CopyImportDirectory(sourceEntry, targetEntry);
+ else
+ continue;
+ importedCount += 1;
+ }
+
+ if (importedCount > 0)
+ {
+ HintService.Hint(Lang.Text("Instance.Resource.Import.Success", importedCount), HintType.Success);
+ ReloadCompFileList(true);
+ }
+ }
+ catch (Exception ex)
+ {
+ ModBase.Log(ex, "从其他实例复制资源失败", ModBase.LogLevel.Msgbox,
+ userSummary: Lang.Text("Instance.Resource.Error.OperationFailed"));
+ }
+ }
+
+ private static void _DeleteImportTarget(string targetEntry)
+ {
+ if (File.Exists(targetEntry))
+ {
+ File.Delete(targetEntry);
+ return;
+ }
+
+ if (!Directory.Exists(targetEntry)) return;
+ if (File.GetAttributes(targetEntry).HasFlag(FileAttributes.ReparsePoint))
+ Directory.Delete(targetEntry);
+ else
+ ModBase.DeleteDirectory(targetEntry);
+ }
+
+ private static void _CopyImportDirectory(string sourceFolder, string targetFolder)
+ {
+ Directory.CreateDirectory(targetFolder);
+ var options = new EnumerationOptions
+ {
+ RecurseSubdirectories = true,
+ IgnoreInaccessible = false,
+ AttributesToSkip = FileAttributes.ReparsePoint
+ };
+ foreach (var sourceFile in Directory.EnumerateFiles(sourceFolder, "*", options))
+ {
+ var targetFile = Path.Combine(targetFolder, Path.GetRelativePath(sourceFolder, sourceFile));
+ ModBase.CopyFile(sourceFile, targetFile);
+ }
+ }
+
///
/// 尝试安装 Mod。
/// 返回输入的文件是否为一个 Mod 文件,仅用于判断拖拽行为。