Compare commits

...
4 Commits
Author SHA1 Message Date
ImgBotApp 112c4c1595 [ImgBot] Optimize images
*Total -- 5,614.07kb -> 4,966.73kb (11.53%)

/src/BD.WTTS.Client.Plugins.GameTools/UI/Assets/movecross_hide.png -- 2.14kb -> 1.12kb (47.68%)
/src/BD.WTTS.Client.Plugins.GameTools/UI/Assets/CounterStrike.png -- 1.59kb -> 0.87kb (45.09%)
/res/avatars/045c57ebb6946fdf7e57a53d5768117dd8543862.gif -- 1,197.84kb -> 867.11kb (27.61%)
/src/BD.WTTS.Client.Avalonia/UI/Assets/Logos/avaloniaui-logo.png -- 1.89kb -> 1.37kb (27.48%)
/src/BD.WTTS.Client.Avalonia.App/Assets.xcassets/AppIcon.appiconset/Icon1024.png -- 43.68kb -> 31.70kb (27.41%)
/res/icons/app/v3/Logo_512.png -- 20.81kb -> 15.62kb (24.96%)
/src/BD.WTTS.Client.Avalonia.App/Assets.xcassets/AppIcon.appiconset/Icon512.png -- 20.81kb -> 15.62kb (24.96%)
/res/icons/app/v3/Logo_256.png -- 9.95kb -> 8.22kb (17.37%)
/src/BD.WTTS.Client.Avalonia.App/Assets.xcassets/AppIcon.appiconset/Icon256.png -- 9.95kb -> 8.22kb (17.37%)
/src/BD.WTTS.Client.Plugins.Accelerator/UI/Assets/defaultBackground.png -- 1,044.18kb -> 871.83kb (16.51%)
/res/brands/steam.jpg -- 9.02kb -> 7.55kb (16.36%)
/src/BD.WTTS.Client.Avalonia.App/Assets.xcassets/AppIcon.appiconset/Icon128.png -- 4.71kb -> 4.41kb (6.25%)
/res/icons/app/v3/Logo_128.png -- 4.71kb -> 4.41kb (6.25%)
/res/avatars/e081bb44f8c79e9b5ae44d1be71aae559d7fcf88.gif -- 2,044.77kb -> 1,941.66kb (5.04%)
/res/icons/app/v3/Logo_96.png -- 3.49kb -> 3.31kb (4.93%)
/src/BD.WTTS.Client.AppHost.Bridge.Package/Images/StoreLogo.scale-400.png -- 15.15kb -> 14.46kb (4.57%)
/res/windows/makepri/images/StoreLogo.scale-400.png -- 15.15kb -> 14.46kb (4.57%)
/res/icons/app/v3/Icon_Logo_Shadow.svg -- 7.48kb -> 7.14kb (4.48%)
/res/icons/app/v3/Icon_Logo_Shadow_512.svg -- 7.60kb -> 7.32kb (3.76%)
/res/icons/app/v3/Icon_Logo_Shadow_1024.svg -- 7.68kb -> 7.40kb (3.71%)
/res/avatars/86c8686ba735c03cc98b815a30034a1a52e68fec.gif -- 42.15kb -> 40.66kb (3.53%)
/res/avatars/11bbadea5154c316c883df0f3f1944395b3715b8.gif -- 23.70kb -> 23.19kb (2.14%)
/res/icons/avalonia.svg -- 1.72kb -> 1.69kb (2.1%)
/res/icons/app/v3/Icon_Logo.svg -- 5.88kb -> 5.80kb (1.33%)
/src/BD.WTTS.Client.Avalonia/UI/Assets/page_bg.jpg -- 126.09kb -> 124.47kb (1.29%)
/res/windows/makepri/images/StoreLogo.scale-200.png -- 6.65kb -> 6.60kb (0.76%)
/src/BD.WTTS.Client.AppHost.Bridge.Package/Images/StoreLogo.scale-200.png -- 6.65kb -> 6.60kb (0.76%)
/res/avatars/ea16deb58fb1582c5ec3acfe5344fdc7b00077de.gif -- 928.63kb -> 923.93kb (0.51%)

Signed-off-by: ImgBotApp <ImgBotHelp@gmail.com>
2024-09-04 10:01:10 +00:00
ff m 7b9ba5e8a0 ➕ BsDiff 2024-09-04 13:30:44 +08:00
k1mlka f27d3c9111 Merge pull request #3469 from luojunyuan/develop
🐛 初次启动时"设置页面-启动页设置项"显示修复
2024-09-02 11:59:32 +08:00
k1mlka 6ab74d449e 🐛 初次启动时"设置页面-启动页设置项"显示修复 2024-09-02 11:54:17 +08:00
32 changed files with 473 additions and 521 deletions
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

After

Width:  |  Height:  |  Size: 867 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 MiB

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 929 KiB

After

Width:  |  Height:  |  Size: 924 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.0 KiB

After

Width:  |  Height:  |  Size: 7.5 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 7.5 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 7.7 KiB

After

Width:  |  Height:  |  Size: 7.4 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.9 KiB

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

+1 -1
View File
@@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1000" height="1000" viewBox="0 0 1000 1000" fill="none"><g opacity="1" transform="translate(0 0) rotate(0)"><mask id="bg-mask-0" fill="white"><use transform="translate(0 0) rotate(0)" xlink:href="#path_0"></use></mask><g mask="url(#bg-mask-0)" ><path id="路径 1" fill-rule="evenodd" style="fill:#8B44AC" opacity="1" d="M458.004,207.814c23.05,-3.91 80.67,-2.15 104.11,2.93c56.64,12.11 104.49,37.3 145.31,76.17c51.17,48.63 82.62,111.33 91.4,181.84c1.18,10.15 1.96,76.95 1.96,174.21v157.82h-154.3v-17.58c0,-9.77 -0.39,-17.58 -0.98,-17.58c-0.58,0 -7.03,2.93 -14.25,6.64c-23.83,11.92 -49.03,19.92 -81.45,25.59c-20.7,3.71 -67.38,4.1 -88.87,0.97c-97.85,-14.06 -181.83,-74.8 -226.17,-163.08c-7.42,-15.04 -19.92,-47.66 -19.92,-52.35c0,-1.36 5.47,-4.88 12.11,-8c31.25,-14.46 50.39,-50.98 44.53,-84.77c-4.49,-25.98 -21.48,-48.83 -44.73,-59.96c-6.64,-3.12 -11.91,-6.84 -11.91,-8.2c0,-4.3 13.48,-39.46 20.7,-53.52c19.34,-38.87 57.42,-83.4 92,-107.81c38.67,-27.34 82.81,-45.51 130.46,-53.32zM474.614,362.114c-53.13,11.32 -94.54,49.41 -110.55,101.75c-5.08,16.6 -5.27,61.53 -0.2,77.93c33.6,108.99 167.58,140.43 244.53,57.42c14.26,-15.42 28.13,-41.01 33.21,-61.13c4.69,-18.75 4.29,-53.51 -0.78,-72.26c-13.48,-48.64 -49.22,-85.16 -98.83,-100.39c-17.58,-5.47 -49.61,-7.04 -67.38,-3.32z"></path><path id="路径 2" fill-rule="evenodd" style="fill:#8B44AC" opacity="1" d="M153.907 541.604C187.107 573.824 242.387 553.514 245.707 508.004C246.877 489.644 242.577 477.344 230.667 465.034C216.407 450.394 192.777 445.114 173.247 451.954C136.917 465.034 126.167 514.454 153.907 541.604Z"></path></g></g><defs><rect id="path_0" x="0" y="0" width="1000.0000000000001" height="1000" /></defs></svg>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1000" height="1000" fill="none" viewBox="0 0 1000 1000"><g opacity="1" transform="translate(0 0) rotate(0)"><mask id="bg-mask-0" fill="#fff"><use transform="translate(0 0) rotate(0)" xlink:href="#path_0"/></mask><g mask="url(#bg-mask-0)"><path id="路径 1" fill-rule="evenodd" style="fill:#8b44ac" d="M458.004,207.814c23.05,-3.91 80.67,-2.15 104.11,2.93c56.64,12.11 104.49,37.3 145.31,76.17c51.17,48.63 82.62,111.33 91.4,181.84c1.18,10.15 1.96,76.95 1.96,174.21v157.82h-154.3v-17.58c0,-9.77 -0.39,-17.58 -0.98,-17.58c-0.58,0 -7.03,2.93 -14.25,6.64c-23.83,11.92 -49.03,19.92 -81.45,25.59c-20.7,3.71 -67.38,4.1 -88.87,0.97c-97.85,-14.06 -181.83,-74.8 -226.17,-163.08c-7.42,-15.04 -19.92,-47.66 -19.92,-52.35c0,-1.36 5.47,-4.88 12.11,-8c31.25,-14.46 50.39,-50.98 44.53,-84.77c-4.49,-25.98 -21.48,-48.83 -44.73,-59.96c-6.64,-3.12 -11.91,-6.84 -11.91,-8.2c0,-4.3 13.48,-39.46 20.7,-53.52c19.34,-38.87 57.42,-83.4 92,-107.81c38.67,-27.34 82.81,-45.51 130.46,-53.32zM474.614,362.114c-53.13,11.32 -94.54,49.41 -110.55,101.75c-5.08,16.6 -5.27,61.53 -0.2,77.93c33.6,108.99 167.58,140.43 244.53,57.42c14.26,-15.42 28.13,-41.01 33.21,-61.13c4.69,-18.75 4.29,-53.51 -0.78,-72.26c-13.48,-48.64 -49.22,-85.16 -98.83,-100.39c-17.58,-5.47 -49.61,-7.04 -67.38,-3.32z" opacity="1"/><path id="路径 2" fill-rule="evenodd" style="fill:#8b44ac" d="M153.907 541.604C187.107 573.824 242.387 553.514 245.707 508.004C246.877 489.644 242.577 477.344 230.667 465.034C216.407 450.394 192.777 445.114 173.247 451.954C136.917 465.034 126.167 514.454 153.907 541.604Z" opacity="1"/></g></g><defs><rect id="path_0" width="1000" height="1000" x="0" y="0"/></defs></svg>

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.9 KiB

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 126 KiB

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 MiB

After

Width:  |  Height:  |  Size: 872 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 894 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

@@ -122,7 +122,7 @@
<PackageReference Include="Squid-Box.SevenZipSharp.Lite" />
<PackageReference Include="SharpZipLib" />
<PackageReference Include="ZstdNet" />
<!--<PackageReference Include="BsDiff" />-->
<PackageReference Include="BsDiff" />
<PackageReference Include="7-Zip.NativeAssets.Win32" />
<PackageReference Include="Portable.BouncyCastle" />
<PackageReference Include="System.Security.Cryptography.ProtectedData" />
@@ -1,492 +1,492 @@
//using BsDiff;
//using JsonSerializer = System.Text.Json.JsonSerializer;
//using BD.WTTS.Models;
using BsDiff;
using JsonSerializer = System.Text.Json.JsonSerializer;
using BD.WTTS.Models;
//namespace BD.WTTS.Client.Tools.Publish.Commands;
namespace BD.WTTS.Client.Tools.Publish.Commands;
//interface IGenerateBsPatch : ICommand
//{
// const string commandName = "bs";
// const string BaseUrl =
//#if DEBUG
// "https://localhost:9881";
interface IGenerateBsPatch : ICommand
{
const string commandName = "bs";
const string BaseUrl =
#if DEBUG
"https://localhost:9881";
//#else
// "http://192.168.2.16:19001";
//#endif
#else
"http://192.168.2.16:19001";
#endif
// static Command ICommand.GetCommand()
// {
// var type = new Option<int>("--type", "type 0:Create 1:Apply 2:UploadFile 3:传入版本号生成补丁");
// //旧文件
// var oldFile = new Option<string>("--old", "old file");
// //新文件
// var newFile = new Option<string>("--new", "new file");
// //保存路径
// var patchFile = new Option<string>("--path", "new file");
// //程序版本号
// var clientPlatform = new Option<ClientPlatform>("--platform", "ClientPlatform");
static Command ICommand.GetCommand()
{
var type = new Option<int>("--type", "type 0:Create 1:Apply 2:UploadFile 3:传入版本号生成补丁");
//旧文件
var oldFile = new Option<string>("--old", "old file");
//新文件
var newFile = new Option<string>("--new", "new file");
//保存路径
var patchFile = new Option<string>("--path", "new file");
//程序版本号
var clientPlatform = new Option<ClientPlatform>("--platform", "ClientPlatform");
// var command = new Command(commandName, "Bridge csproj xml generate")
// {
// type, oldFile, newFile, patchFile, clientPlatform
// };
// command.SetHandler(Handler, type, oldFile, newFile, patchFile, clientPlatform);
// return command;
// }
var command = new Command(commandName, "Bridge csproj xml generate")
{
type, oldFile, newFile, patchFile, clientPlatform
};
command.SetHandler(Handler, type, oldFile, newFile, patchFile, clientPlatform);
return command;
}
// internal static void Handler(int type, string oldFile, string newFile, string patchFile, ClientPlatform platform = ClientPlatform.Win32X64)
// {
// if (type < 2)
// {
// if (!File.Exists(oldFile))
// {
// Console.WriteLine("old file not exists");
// return;
// }
// if (!File.Exists(newFile))
// {
// Console.WriteLine("new file not exists");
// return;
// }
// if (string.IsNullOrWhiteSpace(patchFile))
// {
// Console.WriteLine("The patch file path cannot be empty");
// return;
// }
// }
// switch (type)
// {
// case 0:
// using (var output = new FileStream(patchFile, FileMode.Create))
// GenerateBsPatch(File.ReadAllBytes(oldFile), File.ReadAllBytes(newFile), output);
// break;
// case 1:
// using (var input = new FileStream(oldFile, FileMode.Open, FileAccess.Read, FileShare.Read))
// using (var output = new FileStream(newFile, FileMode.Create))
// BinaryPatch.Apply(input, () => new FileStream(patchFile, FileMode.Open, FileAccess.Read, FileShare.Read), output);
// break;
// case 2:
// UploadFiles(oldFile).Wait();
// break;
// case 3:
// GenerateAppPublishPatchBundleInfo(oldFile, newFile, platform, patchFile).Wait();
// break;
// case 4:
// UploadAppVer(oldFile, newFile, platform).Wait();
// break;
// case 5:
// ApplyPatch(oldFile, newFile, patchFile).Wait();
// break;
internal static void Handler(int type, string oldFile, string newFile, string patchFile, ClientPlatform platform = ClientPlatform.Win32X64)
{
if (type < 2)
{
if (!File.Exists(oldFile))
{
Console.WriteLine("old file not exists");
return;
}
if (!File.Exists(newFile))
{
Console.WriteLine("new file not exists");
return;
}
if (string.IsNullOrWhiteSpace(patchFile))
{
Console.WriteLine("The patch file path cannot be empty");
return;
}
}
switch (type)
{
case 0:
using (var output = new FileStream(patchFile, FileMode.Create))
GenerateBsPatch(File.ReadAllBytes(oldFile), File.ReadAllBytes(newFile), output);
break;
case 1:
using (var input = new FileStream(oldFile, FileMode.Open, FileAccess.Read, FileShare.Read))
using (var output = new FileStream(newFile, FileMode.Create))
BinaryPatch.Apply(input, () => new FileStream(patchFile, FileMode.Open, FileAccess.Read, FileShare.Read), output);
break;
case 2:
UploadFiles(oldFile).Wait();
break;
case 3:
GenerateAppPublishPatchBundleInfo(oldFile, newFile, platform, patchFile).Wait();
break;
case 4:
UploadAppVer(oldFile, newFile, platform).Wait();
break;
case 5:
ApplyPatch(oldFile, newFile, patchFile).Wait();
break;
// }
// Console.WriteLine("end");
// }
}
Console.WriteLine("end");
}
// /// <summary>
// /// 应用补丁
// /// </summary>
// /// <param name="applyPath"></param>
// /// <param name="saveFilePath"></param>
// /// <param name="patchPath"></param>
// /// <returns></returns>
// internal static async ThreadTask ApplyPatch(string applyPath, string saveFilePath, string patchPath)
// {
// if (!File.Exists(patchPath))
// {
// Console.WriteLine("PatchPath not exists");
// return;
// }
/// <summary>
/// 应用补丁
/// </summary>
/// <param name="applyPath"></param>
/// <param name="saveFilePath"></param>
/// <param name="patchPath"></param>
/// <returns></returns>
internal static async ThreadTask ApplyPatch(string applyPath, string saveFilePath, string patchPath)
{
if (!File.Exists(patchPath))
{
Console.WriteLine("PatchPath not exists");
return;
}
// if (!Directory.Exists(applyPath))
// {
// Console.WriteLine("ApplyPath not exists");
// return;
// }
// var fileStream = File.OpenRead(patchPath);
// var jsonData = new BrotliStream(fileStream, CompressionMode.Decompress);
// var dic = await MemoryPackSerializer.DeserializeAsync<Dictionary<string, PatchBundleInfo?>>(jsonData);
// if (dic is null)
// {
// Console.WriteLine("Patch Error");
// return;
// }
// if (!Directory.Exists(saveFilePath))
// {
// Directory.CreateDirectory(saveFilePath);
// }
// else
// {
// Directory.Delete(saveFilePath);
// }
// CopyDirectory(applyPath, saveFilePath);
// FileInfo? fileInfo = null;
// foreach (var item in dic.Where(x => x.Value is not null))
// {
// PatchBundleInfo info = item.Value!;
// if (info.PatchData is not null)
// {
// fileInfo = new FileInfo(Path.Combine(saveFilePath, item.Key));
// if (!(fileInfo.Directory?.Exists ?? false))
// fileInfo.Directory?.Create();
// if (info.IsFullOrPatch)
// {
// File.WriteAllBytes(Path.Combine(saveFilePath, item.Key), info.PatchData);
// }
// else
// {
// using var oldFile = File.OpenRead(Path.Combine(applyPath, item.Key));
// var newFile = Path.Combine(saveFilePath, item.Key);
// using var saveFile = File.Exists(newFile) ? File.Create(newFile) : File.OpenWrite(newFile);
// BinaryPatch.Apply(oldFile, () => new MemoryStream(info.PatchData), saveFile);
// }
// }
// }
// Console.WriteLine("ApplyPatch OK");
// }
if (!Directory.Exists(applyPath))
{
Console.WriteLine("ApplyPath not exists");
return;
}
var fileStream = File.OpenRead(patchPath);
var jsonData = new BrotliStream(fileStream, CompressionMode.Decompress);
var dic = await MemoryPackSerializer.DeserializeAsync<Dictionary<string, PatchBundleInfo?>>(jsonData);
if (dic is null)
{
Console.WriteLine("Patch Error");
return;
}
if (!Directory.Exists(saveFilePath))
{
Directory.CreateDirectory(saveFilePath);
}
else
{
Directory.Delete(saveFilePath);
}
CopyDirectory(applyPath, saveFilePath);
FileInfo? fileInfo = null;
foreach (var item in dic.Where(x => x.Value is not null))
{
PatchBundleInfo info = item.Value!;
if (info.PatchData is not null)
{
fileInfo = new FileInfo(Path.Combine(saveFilePath, item.Key));
if (!(fileInfo.Directory?.Exists ?? false))
fileInfo.Directory?.Create();
if (info.IsFullOrPatch)
{
File.WriteAllBytes(Path.Combine(saveFilePath, item.Key), info.PatchData);
}
else
{
using var oldFile = File.OpenRead(Path.Combine(applyPath, item.Key));
var newFile = Path.Combine(saveFilePath, item.Key);
using var saveFile = File.Exists(newFile) ? File.Create(newFile) : File.OpenWrite(newFile);
BinaryPatch.Apply(oldFile, () => new MemoryStream(info.PatchData), saveFile);
}
}
}
Console.WriteLine("ApplyPatch OK");
}
// /// <summary>
// /// 复制目录下的文件
// /// </summary>
// /// <param name="sourceDir"></param>
// /// <param name="targetDir"></param>
// /// <exception cref="DirectoryNotFoundException"></exception>
// public static void CopyDirectory(string sourceDir, string targetDir)
// {
// DirectoryInfo dir = new DirectoryInfo(sourceDir);
// DirectoryInfo[] dirs = dir.GetDirectories();
/// <summary>
/// 复制目录下的文件
/// </summary>
/// <param name="sourceDir"></param>
/// <param name="targetDir"></param>
/// <exception cref="DirectoryNotFoundException"></exception>
public static void CopyDirectory(string sourceDir, string targetDir)
{
DirectoryInfo dir = new DirectoryInfo(sourceDir);
DirectoryInfo[] dirs = dir.GetDirectories();
// // If the source directory does not exist, throw an exception.
// if (!dir.Exists)
// {
// throw new DirectoryNotFoundException($"Source directory does not exist or could not be found: {sourceDir}");
// }
// If the source directory does not exist, throw an exception.
if (!dir.Exists)
{
throw new DirectoryNotFoundException($"Source directory does not exist or could not be found: {sourceDir}");
}
// // If the destination directory does not exist, create it.
// if (!Directory.Exists(targetDir))
// {
// Directory.CreateDirectory(targetDir);
// }
// If the destination directory does not exist, create it.
if (!Directory.Exists(targetDir))
{
Directory.CreateDirectory(targetDir);
}
// // Get the files in the directory and copy them to the new location.
// FileInfo[] files = dir.GetFiles();
// foreach (FileInfo file in files)
// {
// string tempPath = Path.Combine(targetDir, file.Name);
// file.CopyTo(tempPath, false);
// }
// Get the files in the directory and copy them to the new location.
FileInfo[] files = dir.GetFiles();
foreach (FileInfo file in files)
{
string tempPath = Path.Combine(targetDir, file.Name);
file.CopyTo(tempPath, false);
}
// // If copying subdirectories, copy them and their contents to the new location.
// foreach (DirectoryInfo subdir in dirs)
// {
// string tempPath = Path.Combine(targetDir, subdir.Name);
// CopyDirectory(subdir.FullName, tempPath);
// }
// }
// If copying subdirectories, copy them and their contents to the new location.
foreach (DirectoryInfo subdir in dirs)
{
string tempPath = Path.Combine(targetDir, subdir.Name);
CopyDirectory(subdir.FullName, tempPath);
}
}
// /// <summary>
// /// 根据 2个 文件生成补丁
// /// </summary>
// /// <param name="oldByte"></param>
// /// <param name="newByte"></param>
// /// <param name="output"></param>
// internal static void GenerateBsPatch(byte[] oldByte, byte[] newByte, Stream output)
// {
// BinaryPatch.Create(oldByte, newByte, output);
// }
/// <summary>
/// 根据 2个 文件生成补丁
/// </summary>
/// <param name="oldByte"></param>
/// <param name="newByte"></param>
/// <param name="output"></param>
internal static void GenerateBsPatch(byte[] oldByte, byte[] newByte, Stream output)
{
BinaryPatch.Create(oldByte, newByte, output);
}
// /// <summary>
// /// 上传版本信息 加 FileList
// /// </summary>
// /// <param name="appVer"></param>
// /// <param name="jsonPath">发布工具生成的 Json</param>
// /// <param name="platform"></param>
// /// <returns></returns>
// internal static async ThreadTask UploadAppVer(string appVer, string jsonPath, ClientPlatform platform)
// {
// if (string.IsNullOrWhiteSpace(appVer))
// {
// Console.WriteLine("AppVer not exists");
// return;
// }
// if (string.IsNullOrWhiteSpace(jsonPath))
// {
// Console.WriteLine("jsonPath not exists");
// return;
// }
// if (!File.Exists(jsonPath))
// {
// Console.WriteLine("jsonPath not Find");
// return;
// }
/// <summary>
/// 上传版本信息 加 FileList
/// </summary>
/// <param name="appVer"></param>
/// <param name="jsonPath">发布工具生成的 Json</param>
/// <param name="platform"></param>
/// <returns></returns>
internal static async ThreadTask UploadAppVer(string appVer, string jsonPath, ClientPlatform platform)
{
if (string.IsNullOrWhiteSpace(appVer))
{
Console.WriteLine("AppVer not exists");
return;
}
if (string.IsNullOrWhiteSpace(jsonPath))
{
Console.WriteLine("jsonPath not exists");
return;
}
if (!File.Exists(jsonPath))
{
Console.WriteLine("jsonPath not Find");
return;
}
// var fileListRaw = File.ReadAllBytes(jsonPath);
// var appver = await GetAppVer(appVer);
// if (appver is not null)
// {
// var thisFileList = appver.FileList?.FirstOrDefault(x => x.Platform == platform);
// if (thisFileList is not null)
// {
// if (Hashs.String.SHA384(thisFileList.FileListRaw) != Hashs.String.SHA384(fileListRaw))
// {
// thisFileList.FileListRaw = fileListRaw;
// }
// }
// else
// {
// if (appver.FileList is null)
// {
// appver.FileList = new List<AppVerFileList>
// {
// new AppVerFileList
// {
// Platform = platform,
// FileListRaw = fileListRaw
// }
// };
// }
// else
// {
// appver.FileList.Add(new AppVerFileList
// {
// Platform = platform,
// FileListRaw = fileListRaw
// });
// }
// }
// await UploadAppVer(appver);
// }
// else
// {
// appver = new AppVer
// {
// Platform = platform,
// Ver = appVer,
// Published = DateTimeOffset.Now,
// FileList = new List<AppVerFileList>
// {
// new AppVerFileList
// {
// Platform = platform,
// FileListRaw = fileListRaw
// }
// }
// };
// await UploadAppVer(appver);
// }
// }
var fileListRaw = File.ReadAllBytes(jsonPath);
var appver = await GetAppVer(appVer);
if (appver is not null)
{
var thisFileList = appver.FileList?.FirstOrDefault(x => x.Platform == platform);
if (thisFileList is not null)
{
if (Hashs.String.SHA384(thisFileList.FileListRaw) != Hashs.String.SHA384(fileListRaw))
{
thisFileList.FileListRaw = fileListRaw;
}
}
else
{
if (appver.FileList is null)
{
appver.FileList = new List<AppVerFileList>
{
new AppVerFileList
{
Platform = platform,
FileListRaw = fileListRaw
}
};
}
else
{
appver.FileList.Add(new AppVerFileList
{
Platform = platform,
FileListRaw = fileListRaw
});
}
}
await UploadAppVer(appver);
}
else
{
appver = new AppVer
{
Platform = platform,
Ver = appVer,
Published = DateTimeOffset.Now,
FileList = new List<AppVerFileList>
{
new AppVerFileList
{
Platform = platform,
FileListRaw = fileListRaw
}
}
};
await UploadAppVer(appver);
}
}
// /// <summary>
// /// 上传版本信息
// /// </summary>
// /// <param name="appVer"></param>
// /// <returns></returns>
// internal static async ThreadTask UploadAppVer(AppVer appVer)
// {
// using var httpClient = new HttpClient();
// var content = JsonContent.Create(appVer);
// var response = await httpClient.PostAsync($"{BaseUrl}/appver/", content);
// }
/// <summary>
/// 上传版本信息
/// </summary>
/// <param name="appVer"></param>
/// <returns></returns>
internal static async ThreadTask UploadAppVer(AppVer appVer)
{
using var httpClient = new HttpClient();
var content = JsonContent.Create(appVer);
var response = await httpClient.PostAsync($"{BaseUrl}/appver/", content);
}
// /// <summary>
// /// 传入 2 个版本号生成补丁
// /// </summary>
// /// <param name="oldVer"></param>
// /// <param name="newVer"></param>
// /// <param name="platform"></param>
// /// <param name="patchFilePath"></param>
// /// <returns></returns>
// internal static async ThreadTask GenerateAppPublishPatchBundleInfo(string oldVer, string newVer, ClientPlatform platform, string patchFilePath)
// {
// var oldAppVer = await GetAppVer(oldVer);
// var newAppVer = await GetAppVer(newVer);
// if (oldAppVer is null || newAppVer is null)
// {
// Console.WriteLine("AppVer not exists");
// return;
// }
// var oldFileList = await GetAppPublishInfo(oldAppVer.Id, platform);
// var newFileList = await GetAppPublishInfo(newAppVer.Id, platform);
// if (oldFileList is null || newFileList is null)
// {
// Console.WriteLine("AppPublishInfo not exists");
// return;
// }
// var oldAppVerFileList = JsonSerializer.Deserialize<AppPublishInfo>(oldFileList.FileListRaw);
// var newAppVerFileList = JsonSerializer.Deserialize<AppPublishInfo>(newFileList.FileListRaw);
// if (oldAppVerFileList is null || newAppVerFileList is null)
// {
// Console.WriteLine("AppPublishInfo not exists");
// return;
// }
// var pathSavePath = Path.Combine(patchFilePath, oldVer, $"{newVer}.dat");
// var pathFileInfo = new FileInfo(pathSavePath);
// if (!(pathFileInfo.Directory?.Exists ?? false))
// {
// pathFileInfo.Directory?.Create();
// }
// Console.WriteLine($"开始生成: {oldVer} -> {newVer} platform:{platform}");
// await ContrastVersion(oldAppVerFileList, newAppVerFileList, pathSavePath);
/// <summary>
/// 传入 2 个版本号生成补丁
/// </summary>
/// <param name="oldVer"></param>
/// <param name="newVer"></param>
/// <param name="platform"></param>
/// <param name="patchFilePath"></param>
/// <returns></returns>
internal static async ThreadTask GenerateAppPublishPatchBundleInfo(string oldVer, string newVer, ClientPlatform platform, string patchFilePath)
{
var oldAppVer = await GetAppVer(oldVer);
var newAppVer = await GetAppVer(newVer);
if (oldAppVer is null || newAppVer is null)
{
Console.WriteLine("AppVer not exists");
return;
}
var oldFileList = await GetAppPublishInfo(oldAppVer.Id, platform);
var newFileList = await GetAppPublishInfo(newAppVer.Id, platform);
if (oldFileList is null || newFileList is null)
{
Console.WriteLine("AppPublishInfo not exists");
return;
}
var oldAppVerFileList = JsonSerializer.Deserialize<AppPublishInfo>(oldFileList.FileListRaw);
var newAppVerFileList = JsonSerializer.Deserialize<AppPublishInfo>(newFileList.FileListRaw);
if (oldAppVerFileList is null || newAppVerFileList is null)
{
Console.WriteLine("AppPublishInfo not exists");
return;
}
var pathSavePath = Path.Combine(patchFilePath, oldVer, $"{newVer}.dat");
var pathFileInfo = new FileInfo(pathSavePath);
if (!(pathFileInfo.Directory?.Exists ?? false))
{
pathFileInfo.Directory?.Create();
}
Console.WriteLine($"开始生成: {oldVer} -> {newVer} platform:{platform}");
await ContrastVersion(oldAppVerFileList, newAppVerFileList, pathSavePath);
// }
}
// /// <summary>
// /// 获取版本号信息
// /// </summary>
// /// <param name="ver"></param>
// /// <returns></returns>
// public static async Task<AppVer?> GetAppVer(string ver)
// {
// using var httpClient = new HttpClient();
// var response = await httpClient.GetAsync($"{BaseUrl}/appver/{ver}");
// var data = JsonSerializer.Deserialize<ApiRsp<AppVer?>>(await response.Content.ReadAsStringAsync(), new JsonSerializerOptions
// {
// PropertyNameCaseInsensitive = true
// });
// return data?.Content;
// }
/// <summary>
/// 获取版本号信息
/// </summary>
/// <param name="ver"></param>
/// <returns></returns>
public static async Task<AppVer?> GetAppVer(string ver)
{
using var httpClient = new HttpClient();
var response = await httpClient.GetAsync($"{BaseUrl}/appver/{ver}");
var data = JsonSerializer.Deserialize<ApiRsp<AppVer?>>(await response.Content.ReadAsStringAsync(), new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
});
return data?.Content;
}
// /// <summary>
// /// 更具 APP 版本 ID 获取发布信息
// /// </summary>
// /// <param name="appVerId">版本号</param>
// /// <param name="platform">平台</param>
// /// <returns></returns>
// public static async Task<AppVerFileList?> GetAppPublishInfo(Guid appVerId, ClientPlatform platform)
// {
// using var httpClient = new HttpClient();
// var response = await httpClient.GetAsync($"{BaseUrl}/appver/file/{appVerId}/{platform}/list");
// var data = JsonSerializer.Deserialize<ApiRsp<AppVerFileList?>>(await response.Content.ReadAsStringAsync(), new JsonSerializerOptions
// {
// PropertyNameCaseInsensitive = true
// });
// return data?.Content;
// }
/// <summary>
/// 更具 APP 版本 ID 获取发布信息
/// </summary>
/// <param name="appVerId">版本号</param>
/// <param name="platform">平台</param>
/// <returns></returns>
public static async Task<AppVerFileList?> GetAppPublishInfo(Guid appVerId, ClientPlatform platform)
{
using var httpClient = new HttpClient();
var response = await httpClient.GetAsync($"{BaseUrl}/appver/file/{appVerId}/{platform}/list");
var data = JsonSerializer.Deserialize<ApiRsp<AppVerFileList?>>(await response.Content.ReadAsStringAsync(), new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
});
return data?.Content;
}
// /// <summary>
// /// 根据 2 个版本的文件列表生成补丁
// /// </summary>
// /// <param name="oldFileList"></param>
// /// <param name="newFileList"></param>
// /// <param name="patchFilePath"></param>
// /// <returns></returns>
// public static async ThreadTask ContrastVersion(AppPublishInfo oldFileList, AppPublishInfo newFileList, string patchFilePath)
// {
// var oldFiles = oldFileList.Files.Where(x => !x.RelativePath.StartsWith("dotnet\\"));
// var newFiles = newFileList.Files.Where(x => !x.RelativePath.StartsWith("dotnet\\"));
// Console.WriteLine($"旧版本文件数:{oldFiles.Count()}");
// Console.WriteLine($"新版本文件数:{newFiles.Count()}");
// var changeList = new Dictionary<string, PatchBundleInfo?>();
/// <summary>
/// 根据 2 个版本的文件列表生成补丁
/// </summary>
/// <param name="oldFileList"></param>
/// <param name="newFileList"></param>
/// <param name="patchFilePath"></param>
/// <returns></returns>
public static async ThreadTask ContrastVersion(AppPublishInfo oldFileList, AppPublishInfo newFileList, string patchFilePath)
{
var oldFiles = oldFileList.Files.Where(x => !x.RelativePath.StartsWith("dotnet\\"));
var newFiles = newFileList.Files.Where(x => !x.RelativePath.StartsWith("dotnet\\"));
Console.WriteLine($"旧版本文件数:{oldFiles.Count()}");
Console.WriteLine($"新版本文件数:{newFiles.Count()}");
var changeList = new Dictionary<string, PatchBundleInfo?>();
// var removeFiles = oldFiles.Select(x => x.RelativePath).Except(newFiles.Select(x => x.RelativePath));
// //文件删除
// foreach (var item in removeFiles)
// {
// changeList.Add(item, null);
// }
// Console.WriteLine($"需要删除的文件数:{changeList.Count}");
// foreach (var item in newFiles)
// {
// var oldFile = oldFiles.FirstOrDefault(x => x.RelativePath.Equals(item.RelativePath));
// //文件新增
// if (oldFile == null)
// {
// var newFileRaw = string.IsNullOrWhiteSpace(item.SignatureSHA384) ? await GetFileRaw(item.SHA384) : await GetFileRaw(item.SignatureSHA384);
// if (newFileRaw is null)
// {
// Console.WriteLine("new file not exists");
// return;
// }
// changeList.Add(item.RelativePath, new PatchBundleInfo
// {
// SHA384 = item.SHA384,
// IsFullOrPatch = true,
// PatchData = newFileRaw.DataRaw
// });
// }
// else
// {
// //文件修改
// if (oldFile.SHA384 != item.SHA384)
// {
// var oldFileRaw = string.IsNullOrWhiteSpace(oldFile.SignatureSHA384) ? await GetFileRaw(oldFile.SHA384) : await GetFileRaw(oldFile.SignatureSHA384);
// if (oldFileRaw is null)
// {
// Console.WriteLine("old file not exists");
// return;
// }
// var newFileRaw = string.IsNullOrWhiteSpace(item.SignatureSHA384) ? await GetFileRaw(item.SHA384) : await GetFileRaw(item.SignatureSHA384); // await GetFileRaw(item.SignatureSHA384);
// if (newFileRaw is null)
// {
// Console.WriteLine("new file not exists");
// return;
// }
// using (var output = new MemoryStream())
// {
// //BinaryPatch.Create(oldFileRaw.DataRaw, File.ReadAllBytes(item.RelativePath), output);
// BinaryPatch.Create(oldFileRaw.DataRaw, newFileRaw.DataRaw, output);
// changeList.Add(item.RelativePath, new PatchBundleInfo
// {
// SHA384 = item.SHA384,
// IsFullOrPatch = false,
// PatchData = output.ToArray()
// });
// }
// }
// }
// }
// if (File.Exists(patchFilePath))
// File.Delete(patchFilePath);
var removeFiles = oldFiles.Select(x => x.RelativePath).Except(newFiles.Select(x => x.RelativePath));
//文件删除
foreach (var item in removeFiles)
{
changeList.Add(item, null);
}
Console.WriteLine($"需要删除的文件数:{changeList.Count}");
foreach (var item in newFiles)
{
var oldFile = oldFiles.FirstOrDefault(x => x.RelativePath.Equals(item.RelativePath));
//文件新增
if (oldFile == null)
{
var newFileRaw = string.IsNullOrWhiteSpace(item.SignatureSHA384) ? await GetFileRaw(item.SHA384) : await GetFileRaw(item.SignatureSHA384);
if (newFileRaw is null)
{
Console.WriteLine("new file not exists");
return;
}
changeList.Add(item.RelativePath, new PatchBundleInfo
{
SHA384 = item.SHA384,
IsFullOrPatch = true,
PatchData = newFileRaw.DataRaw
});
}
else
{
//文件修改
if (oldFile.SHA384 != item.SHA384)
{
var oldFileRaw = string.IsNullOrWhiteSpace(oldFile.SignatureSHA384) ? await GetFileRaw(oldFile.SHA384) : await GetFileRaw(oldFile.SignatureSHA384);
if (oldFileRaw is null)
{
Console.WriteLine("old file not exists");
return;
}
var newFileRaw = string.IsNullOrWhiteSpace(item.SignatureSHA384) ? await GetFileRaw(item.SHA384) : await GetFileRaw(item.SignatureSHA384); // await GetFileRaw(item.SignatureSHA384);
if (newFileRaw is null)
{
Console.WriteLine("new file not exists");
return;
}
using (var output = new MemoryStream())
{
//BinaryPatch.Create(oldFileRaw.DataRaw, File.ReadAllBytes(item.RelativePath), output);
BinaryPatch.Create(oldFileRaw.DataRaw, newFileRaw.DataRaw, output);
changeList.Add(item.RelativePath, new PatchBundleInfo
{
SHA384 = item.SHA384,
IsFullOrPatch = false,
PatchData = output.ToArray()
});
}
}
}
}
if (File.Exists(patchFilePath))
File.Delete(patchFilePath);
// Console.WriteLine($"变动文件数量:{changeList.Count}");
// using var fileStream = File.OpenWrite(patchFilePath);
// using var brSave = new BrotliStream(fileStream, CompressionLevel.SmallestSize);
// Console.WriteLine($"开始压缩");
// await MemoryPackSerializer.SerializeAsync(typeof(Dictionary<string, PatchBundleInfo?>), brSave, changeList);
// //fileStream.Flush();
// Console.WriteLine($"结束");
// }
Console.WriteLine($"变动文件数量:{changeList.Count}");
using var fileStream = File.OpenWrite(patchFilePath);
using var brSave = new BrotliStream(fileStream, CompressionLevel.SmallestSize);
Console.WriteLine($"开始压缩");
await MemoryPackSerializer.SerializeAsync(typeof(Dictionary<string, PatchBundleInfo?>), brSave, changeList);
//fileStream.Flush();
Console.WriteLine($"结束");
}
// /// <summary>
// /// Hash 384 获取源文件数据
// /// </summary>
// /// <param name="sha384"></param>
// /// <returns></returns>
// public static async Task<AppVerFile?> GetFileRaw(string sha384)
// {
// using var httpClient = new HttpClient();
// var response = await httpClient.GetAsync($"{BaseUrl}/appver/file/{sha384}");
// var data = JsonSerializer.Deserialize<ApiRsp<AppVerFile?>>(await response.Content.ReadAsStringAsync(), new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
// return data?.Content;
// }
/// <summary>
/// Hash 384 获取源文件数据
/// </summary>
/// <param name="sha384"></param>
/// <returns></returns>
public static async Task<AppVerFile?> GetFileRaw(string sha384)
{
using var httpClient = new HttpClient();
var response = await httpClient.GetAsync($"{BaseUrl}/appver/file/{sha384}");
var data = JsonSerializer.Deserialize<ApiRsp<AppVerFile?>>(await response.Content.ReadAsStringAsync(), new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
return data?.Content;
}
// /// <summary>
// /// 上传指定文件到服务器
// /// </summary>
// /// <param name="directoryPath">需要上传的目录</param>
// internal static async ThreadTask UploadFiles(string directoryPath)
// {
// DirectoryInfo directoryInfo = new(directoryPath);
// if (directoryInfo.Exists)
// {
// using var httpClient = new HttpClient();
// var fileList = new List<AppPublishFileInfo>();
// IScanPublicDirectoryCommand.ScanPathCore(directoryPath, fileList, null, null);
// using var form = new MultipartFormDataContent();
// fileList.ForEach(file =>
// {
// var fileStream = file.FileInfo!.OpenRead();
// form.Add(new StreamContent(fileStream), file.FileInfo!.Name, file.FileInfo!.Name);
// });
// if (form.Count() > 0)
// {
// var response = await httpClient.PostAsync($"{BaseUrl}/appver/file/upload", form);
// Console.WriteLine(response);
// }
// }
// else
// {
// Console.WriteLine("文件夹不存在");
// }
// }
//}
/// <summary>
/// 上传指定文件到服务器
/// </summary>
/// <param name="directoryPath">需要上传的目录</param>
internal static async ThreadTask UploadFiles(string directoryPath)
{
DirectoryInfo directoryInfo = new(directoryPath);
if (directoryInfo.Exists)
{
using var httpClient = new HttpClient();
var fileList = new List<AppPublishFileInfo>();
IScanPublicDirectoryCommand.ScanPathCore(directoryPath, fileList, null, null);
using var form = new MultipartFormDataContent();
fileList.ForEach(file =>
{
var fileStream = file.FileInfo!.OpenRead();
form.Add(new StreamContent(fileStream), file.FileInfo!.Name, file.FileInfo!.Name);
});
if (form.Count() > 0)
{
var response = await httpClient.PostAsync($"{BaseUrl}/appver/file/upload", form);
Console.WriteLine(response);
}
}
else
{
Console.WriteLine("文件夹不存在");
}
}
}
@@ -39,7 +39,7 @@ public sealed partial class SettingsPageViewModel : TabItemViewModel
{
if (string.IsNullOrEmpty(UISettings.StartDefaultPageName.Value))
{
return s.Id == "Welcome";
return s.Id == "Watt Toolkit-Welcome";
}
return s.Id == UISettings.StartDefaultPageName.Value;
});