diff --git a/CommonLibrary/Packer.cs b/CommonLibrary/Packer.cs index b512509..5df14ff 100644 --- a/CommonLibrary/Packer.cs +++ b/CommonLibrary/Packer.cs @@ -1,153 +1,135 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using System.IO; using System.IO.Compression; +using System.Linq; + namespace CommonLibrary { - - internal class ProgressStream : Stream + internal class ProgressStream : Stream + { + private readonly Stream insideStream; + private readonly IProgress insideReadProgress; + private readonly IProgress insideWriteProgress; + + public ProgressStream(Stream stream, IProgress readProgress, IProgress writeProgress) { - private readonly Stream insideStream; - private readonly IProgress insideReadProgress; - private readonly IProgress insideWriteProgress; + insideStream = stream; + insideReadProgress = readProgress; + insideWriteProgress = writeProgress; + } - public ProgressStream(Stream stream, IProgress readProgress, IProgress writeProgress) + public override bool CanRead => insideStream.CanRead; + public override bool CanSeek => insideStream.CanSeek; + public override bool CanWrite => insideStream.CanWrite; + public override long Length => insideStream.Length; + + public override long Position + { + get => insideStream.Position; + set => insideStream.Position = value; + } + + public override void Flush() => insideStream.Flush(); + public override long Seek(long offset, SeekOrigin origin) => insideStream.Seek(offset, origin); + public override void SetLength(long value) => insideStream.SetLength(value); + + public override int Read(byte[] buffer, int offset, int count) + { + int bytesRead = insideStream.Read(buffer, offset, count); + insideReadProgress?.Report(bytesRead); + return bytesRead; + } + + public override void Write(byte[] buffer, int offset, int count) + { + insideStream.Write(buffer, offset, count); + insideWriteProgress?.Report(count); + } + } + + public class ProgressPacker + { + public void Pack(string sourceDirectoryName, string packFileName, IProgress progress) + { + sourceDirectoryName = Path.GetFullPath(sourceDirectoryName); + + FileInfo[] sourceFiles = new DirectoryInfo(sourceDirectoryName).GetFiles("*", SearchOption.AllDirectories); + double totalBytes = sourceFiles.Sum(f => f.Length); + long currentBytes = 0; + + using (ZipArchive zipArchive = ZipFile.Open(packFileName, ZipArchiveMode.Create)) { - insideStream = stream; - insideReadProgress = readProgress; - insideWriteProgress = writeProgress; - } + foreach (FileInfo file in sourceFiles) + { + // 경로 구분자를 '/' 로 통일 (Windows 탐색기 호환) + string entryName = file.FullName.Substring(sourceDirectoryName.Length + 1) + .Replace(Path.DirectorySeparatorChar, '/'); - public override bool CanRead { get { return insideStream.CanRead; } } - public override bool CanSeek { get { return insideStream.CanSeek; } } - public override bool CanWrite { get { return insideStream.CanWrite; } } - public override long Length { get { return insideStream.Length; } } + ZipArchiveEntry entry = zipArchive.CreateEntry(entryName); + entry.LastWriteTime = file.LastWriteTime; - public override long Position - { - get { return insideStream.Position; } - set { insideStream.Position = value; } - } - - public override void Flush() - { - insideStream.Flush(); - } - - public override long Seek(long offset, SeekOrigin origin) - { - return insideStream.Seek(offset, origin); - } - - public override void SetLength(long value) - { - insideStream.SetLength(value); - } - - public override int Read(byte[] buffer, int offset, int count) - { - int bytesRead = insideStream.Read(buffer, offset, count); - - insideReadProgress?.Report(bytesRead); - return bytesRead; - } - - public override void Write(byte[] buffer, int offset, int count) - { - insideStream.Write(buffer, offset, count); - insideWriteProgress?.Report(count); + using (Stream inputStream = file.OpenRead()) + using (Stream outputStream = entry.Open()) + using (Stream progressStream = new ProgressStream(inputStream, + new BasicProgress(i => + { + currentBytes += i; + progress?.Report(currentBytes / totalBytes); + }), null)) + { + // ✅ 방향 수정: inputStream → progressStream → outputStream + progressStream.CopyTo(outputStream); + } + } } } - public class ProgressPacker + public void UnPack(string packFileName, string destinationDirectoryName, IProgress progress) { - public void Pack(string sourceDirectoryName, string packFileName, IProgress progress) + using (ZipArchive zipArchive = ZipFile.OpenRead(packFileName)) { - sourceDirectoryName = Path.GetFullPath(sourceDirectoryName); - - FileInfo[] sourceFiles = new DirectoryInfo(sourceDirectoryName).GetFiles("*", SearchOption.AllDirectories); - double totalBytes = sourceFiles.Sum(f => f.Length); + double totalBytes = zipArchive.Entries.Sum(f => f.Length); long currentBytes = 0; - using (ZipArchive zipArchive = ZipFile.Open(packFileName, ZipArchiveMode.Create)) + foreach (ZipArchiveEntry entry in zipArchive.Entries) { + // 디렉터리 엔트리 건너뜀 + if (string.IsNullOrEmpty(entry.Name)) + continue; - foreach (FileInfo file in sourceFiles) - { - string entryName = file.FullName.Substring(sourceDirectoryName.Length + 1); - ZipArchiveEntry entry = zipArchive.CreateEntry(entryName); + string fileName = Path.Combine(destinationDirectoryName, entry.FullName); + Directory.CreateDirectory(Path.GetDirectoryName(fileName)); - entry.LastWriteTime = file.LastWriteTime; - using (Stream inputStream = file.OpenRead()) + using (Stream inputStream = entry.Open()) + using (Stream outputStream = File.OpenWrite(fileName)) + using (Stream progressStream = new ProgressStream(outputStream, null, + new BasicProgress(i => { - using (Stream outputStream = entry.Open()) - { - Stream progressStream = new ProgressStream(inputStream, - new BasicProgress(i => - { - currentBytes += i; - progress.Report(currentBytes / totalBytes); - }), null); - - progressStream.CopyTo(outputStream); - } - } - } - } - } - - public void UnPack(string packFileName, string destinationDirectoryName, IProgress progress) - { - using (ZipArchive zipArchive = ZipFile.OpenRead(packFileName)) - { - double totalBytes = zipArchive.Entries.Sum(f => f.Length); - long currentBytes = 0; - foreach (ZipArchiveEntry entry in zipArchive.Entries) + currentBytes += i; + progress?.Report(currentBytes / totalBytes); + }))) { - string fileName = Path.Combine(destinationDirectoryName, entry.FullName); - if (entry.Name == "") continue; - Directory.CreateDirectory(Path.GetDirectoryName(fileName)); - using (Stream inputStream = entry.Open()) - { - using (Stream outputStream = File.OpenWrite(fileName)) - { - - Stream progressStream = new ProgressStream(outputStream, null, - new BasicProgress(i => - { - currentBytes += i; - if (progress != null) - { - progress.Report(currentBytes / totalBytes); - } - })); - - inputStream.CopyTo(progressStream); - - } - File.SetLastWriteTime(fileName, entry.LastWriteTime.LocalDateTime); - } + inputStream.CopyTo(progressStream); } + + File.SetLastWriteTime(fileName, entry.LastWriteTime.LocalDateTime); } } } - - public class BasicProgress : IProgress - { - private readonly Action actionHandler; - - public BasicProgress(Action handler) - { - actionHandler = handler; - } - - void IProgress.Report(T value) - { - actionHandler(value); - } - } } + public class BasicProgress : IProgress + { + private readonly Action actionHandler; + + public BasicProgress(Action handler) + { + actionHandler = handler; + } + + public void Report(T value) + { + actionHandler(value); + } + } +} diff --git a/Mitria_Minecraft_Launcher/Updater/GameUpdateManager.cs b/Mitria_Minecraft_Launcher/Updater/GameUpdateManager.cs index afc2d24..92e44d6 100644 --- a/Mitria_Minecraft_Launcher/Updater/GameUpdateManager.cs +++ b/Mitria_Minecraft_Launcher/Updater/GameUpdateManager.cs @@ -27,7 +27,7 @@ namespace Mitria_Minecraft_Launcher.Updater // Version File Download CommonLibrary.Log.INFO("download version file."); - var verionData = downloader.DownloadString(CommonLibrary.Extensions.PathCombineL(Settings.ServerBaseUrl,"Servers", Settings.NowProfile.ServerName, Settings.ServerDataPatchInformationFile)); + var verionData = downloader.DownloadString(CommonLibrary.Extensions.PathCombineL(Settings.ServerBaseUrl, "Servers", Settings.NowProfile.ServerName, Settings.ServerDataPatchInformationFile)); // Versoin File 받기에 실패하였을때 업데이트 전체 실패처리 if (verionData == string.Empty) @@ -74,7 +74,7 @@ namespace Mitria_Minecraft_Launcher.Updater CommonLibrary.Log.INFO("Runtime delete it for update."); // 런타임 폴더 경로 가져오기 - var rootDirectoryInfo = new System.IO.DirectoryInfo(System.IO.Path.GetFullPath(CommonLibrary.Extensions.PathCombineW(Settings.RuntimeLocation,Settings.NowProfile.ServerName))); + var rootDirectoryInfo = new System.IO.DirectoryInfo(System.IO.Path.GetFullPath(CommonLibrary.Extensions.PathCombineW(Settings.RuntimeLocation, Settings.NowProfile.ServerName))); // 런타임 폴더 삭제후 새로만들기 if (!rootDirectoryInfo.Exists) @@ -124,6 +124,7 @@ namespace Mitria_Minecraft_Launcher.Updater CommonLibrary.Log.INFO("[Package] LocalVersion : " + thisVersion); CommonLibrary.Log.INFO("[Package] RemoteVersion : " + remoteVersion); result = remoteVersion.CompareTo(thisVersion); + //TODO: 만약 Major 버전이 바뀌면 전부삭제, 아니면 있는 폴더면 선별후 삭제 // 1 : 리모트가 큼, 0 : 같음, -1 리모트가 적음 if (result == 0) @@ -133,10 +134,21 @@ namespace Mitria_Minecraft_Launcher.Updater else { CommonLibrary.Log - .INFO(string.Format("{0}", result == 1 ? "remote is the upper version" : "remote is the lower version")); - CommonLibrary.Log.INFO("[Package] delete it for update."); + .INFO(string.Format("{0}", result == 1 ? "remote is the upper version" : "remote is the lower version")); - var rootDirectoryInfo = new System.IO.DirectoryInfo(System.IO.Path.GetFullPath(CommonLibrary.Extensions.PathCombineW(Settings.UserLauncherConfig.GameDirectory,Settings.NowProfile.ServerName))); + bool packageInitialization = true; + + if (thisVersion.Major < remoteVersion.Major || + (thisVersion.Major == remoteVersion.Major && thisVersion.Minor < remoteVersion.Minor)) + { + packageInitialization = false; + CommonLibrary.Log.INFO("[Package] update."); + } + else + { + CommonLibrary.Log.INFO("[Package] delete it for update."); + } + var rootDirectoryInfo = new System.IO.DirectoryInfo(System.IO.Path.GetFullPath(CommonLibrary.Extensions.PathCombineW(Settings.UserLauncherConfig.GameDirectory, Settings.NowProfile.ServerName))); if (!rootDirectoryInfo.Exists) { @@ -231,7 +243,7 @@ namespace Mitria_Minecraft_Launcher.Updater { // 제거된 폴더 삭제 var resultDirectorys = new List(); - + foreach (var directory in Settings.UserClientVersion.ComponentDirectorys) { if (!dataPatchInformation.ComponentDirectorys.Contains(directory)) @@ -241,7 +253,7 @@ namespace Mitria_Minecraft_Launcher.Updater } foreach (var directory in resultDirectorys) { - var directoryPath = System.IO.Path.GetFullPath(CommonLibrary.Extensions.PathCombineW(Settings.UserLauncherConfig.GameDirectory,Settings.NowProfile.ServerName, directory)); + var directoryPath = System.IO.Path.GetFullPath(CommonLibrary.Extensions.PathCombineW(Settings.UserLauncherConfig.GameDirectory, Settings.NowProfile.ServerName, directory)); if (System.IO.Directory.Exists(directoryPath)) { @@ -270,7 +282,6 @@ namespace Mitria_Minecraft_Launcher.Updater } } } - } foreach (var directory in dataPatchInformation.ComponentDirectorys) @@ -284,7 +295,6 @@ namespace Mitria_Minecraft_Launcher.Updater } } - var auditFile = new AuditFile(); var localFiles = auditFile.GetLocalFileList(dataPatchInformation.ComponentDirectorys); var removeFiles = auditFile.GetRemoveFiles(localFiles, dataPatchInformation.ComponentList); @@ -294,8 +304,8 @@ namespace Mitria_Minecraft_Launcher.Updater foreach (var fileDetail in removeFiles) { - var filePath = CommonLibrary.Extensions.PathCombineW(Settings.UserLauncherConfig.GameDirectory,Settings.NowProfile.ServerName, fileDetail.Directory, fileDetail.FileName); - FileInfo fileInfo= new FileInfo(filePath); + var filePath = CommonLibrary.Extensions.PathCombineW(Settings.UserLauncherConfig.GameDirectory, Settings.NowProfile.ServerName, fileDetail.Directory, fileDetail.FileName); + FileInfo fileInfo = new FileInfo(filePath); fileInfo.IsReadOnly = false; if (fileInfo.Exists) { @@ -309,7 +319,7 @@ namespace Mitria_Minecraft_Launcher.Updater for (int i = 0; i < needFiles.Count; i++) { var url = CommonLibrary.Extensions.PathCombineL(Settings.ServerBaseUrl, "Servers", Settings.NowProfile.ServerName, dataPatchInformation.ComponentUrl, needFiles[i].Directory, needFiles[i].FileName); - var path = CommonLibrary.Extensions.PathCombineW(Settings.UserLauncherConfig.GameDirectory,Settings.NowProfile.ServerName, needFiles[i].Directory, needFiles[i].FileName); + var path = CommonLibrary.Extensions.PathCombineW(Settings.UserLauncherConfig.GameDirectory, Settings.NowProfile.ServerName, needFiles[i].Directory, needFiles[i].FileName); downloader.DownloadFile(url, path); Log.INFO("[Component] +[F] " + path); } @@ -322,10 +332,11 @@ namespace Mitria_Minecraft_Launcher.Updater // 커스텀 폴더, Config #region CustomData + // 삭제된 파일 찾기 string rootCustomPath = System.IO.Path.GetFullPath(CommonLibrary.Extensions.PathCombineW(Settings.CustomDataDirectory, Settings.NowProfile.ServerName)); - if(!System.IO.Directory.Exists(CommonLibrary.Extensions.PathCombineW(rootCustomPath, "config"))) + if (!System.IO.Directory.Exists(CommonLibrary.Extensions.PathCombineW(rootCustomPath, "config"))) { System.IO.Directory.CreateDirectory(CommonLibrary.Extensions.PathCombineW(rootCustomPath, "config")); } @@ -339,14 +350,12 @@ namespace Mitria_Minecraft_Launcher.Updater for (int i = 0; i < files.Count; i++) { files[i] = files[i].Replace(rootCustomPath + '\\', string.Empty); - } foreach (var file in files) { string sourcePath = CommonLibrary.Extensions.PathCombineW(rootCustomPath, file); - string targetPath = CommonLibrary.Extensions.PathCombineW( Settings.UserLauncherConfig.GameDirectory, Settings.NowProfile.ServerName,file); - + string targetPath = CommonLibrary.Extensions.PathCombineW(Settings.UserLauncherConfig.GameDirectory, Settings.NowProfile.ServerName, file); if (System.IO.File.Exists(targetPath)) { @@ -354,9 +363,8 @@ namespace Mitria_Minecraft_Launcher.Updater System.IO.FileInfo targetFile = new System.IO.FileInfo(targetPath); if (sourceFile.GetFileHashCode() != targetFile.GetFileHashCode()) { - System.IO.File.Copy(sourcePath, targetPath,true); + System.IO.File.Copy(sourcePath, targetPath, true); Log.INFO("[CustomData] +[F] " + targetPath); - } } else @@ -387,33 +395,35 @@ namespace Mitria_Minecraft_Launcher.Updater GameUpdateManagerMessage?.Invoke(this, e); } } +} - public enum GameUpdateStatus +public enum GameUpdateStatus + +{ + Success, + Fail +} + +public enum GameUpdateManagerMessageType +{ + First, + Second, + Message +} + +public class GameUpdateManagerMessageEventArgs : EventArgs +{ + public GameUpdateManagerMessageType MessageType { get; set; } + public long MinValue { get; set; } + public long MaxValue { get; set; } + public string Message { get; set; } + + public GameUpdateManagerMessageEventArgs(GameUpdateManagerMessageType messageType, long minValue, long maxValue, string message) { - Success, - Fail - } - - public enum GameUpdateManagerMessageType - { - First, - Second, - Message - } - - public class GameUpdateManagerMessageEventArgs : EventArgs - { - public GameUpdateManagerMessageType MessageType { get; set; } - public long MinValue { get; set; } - public long MaxValue { get; set; } - public string Message { get; set; } - - public GameUpdateManagerMessageEventArgs(GameUpdateManagerMessageType messageType, long minValue, long maxValue, string message) - { - MessageType = messageType; - MinValue = minValue; - MaxValue = maxValue; - Message = message; - } + MessageType = messageType; + MinValue = minValue; + MaxValue = maxValue; + Message = message; } +} } \ No newline at end of file