390 lines
18 KiB
C#
390 lines
18 KiB
C#
using CommonLibrary;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
|
|
namespace Mitria_Minecraft_Launcher.Updater
|
|
{
|
|
public class GameUpdateManager
|
|
{
|
|
public delegate void GameUpdateManagerMessageHandler(object sender, GameUpdateManagerMessageEventArgs downloaderProgressChangedEventArgs);
|
|
|
|
public event GameUpdateManagerMessageHandler GameUpdateManagerMessage;
|
|
|
|
public GameUpdateManager()
|
|
{
|
|
}
|
|
|
|
public GameUpdateStatus Start()
|
|
{
|
|
GameUpdateManagerMessage(this, new GameUpdateManagerMessageEventArgs(GameUpdateManagerMessageType.Message, 0, 0, "[0/9] GameUpdatStart"));
|
|
CommonLibrary.Log.INFO("Game Update Start");
|
|
|
|
// Downloader 선언
|
|
var downloader = new Downloader();
|
|
downloader.DownloaderProgressChangedEvent += Downloader_DownloaderProgressChangedEvent;
|
|
|
|
// Version File Download
|
|
CommonLibrary.Log.INFO("download version file.");
|
|
var verionData = downloader.DownloadString(Settings.ServerBaseUrl + Settings.ServerDataPatchInformationFile);
|
|
|
|
// Versoin File 받기에 실패하였을때 업데이트 전체 실패처리
|
|
if (verionData == string.Empty)
|
|
{
|
|
GameUpdateManagerMessage(this, new GameUpdateManagerMessageEventArgs(GameUpdateManagerMessageType.Message, 0, 0, "★★ Update Fail ★★"));
|
|
CommonLibrary.Log.FATAL("Failed to download version file");
|
|
return GameUpdateStatus.Fail;
|
|
}
|
|
|
|
// Version File Xml 형태로 변환
|
|
var dataPatchInformation = CommonLibrary.XMLSystem.LoadFromData<DataPatchInformation>(verionData);
|
|
|
|
// 임시 폴더 생성
|
|
var tempDirectory = System.IO.Path.GetFullPath("temp");
|
|
if (!System.IO.Directory.Exists(tempDirectory))
|
|
{
|
|
System.IO.Directory.CreateDirectory(tempDirectory);
|
|
Log.INFO("[GameUpdateManager] +[F] " + tempDirectory);
|
|
}
|
|
|
|
// 런타임 업데이트
|
|
|
|
#region Runtime Update
|
|
|
|
GameUpdateManagerMessage(this, new GameUpdateManagerMessageEventArgs(GameUpdateManagerMessageType.First, 1, 9, "[1/9] Runtime Version Check"));
|
|
Log.INFO("[Runtime] Version Check");
|
|
|
|
// 버전 비교
|
|
var thisVersion = Version.Parse(Settings.UserLauncherConfig.RuntimeVersion);
|
|
var remoteVersion = Version.Parse(dataPatchInformation.RuntimeVersion);
|
|
CommonLibrary.Log.INFO("[Runtime] LocalVersion : " + thisVersion);
|
|
CommonLibrary.Log.INFO("[Runtime] RemoteVersion : " + remoteVersion);
|
|
var result = remoteVersion.CompareTo(thisVersion);
|
|
|
|
// 1 : 리모트가 큼, 0 : 같음, -1 리모트가 적음
|
|
if (result == 0)
|
|
{
|
|
CommonLibrary.Log.INFO("[Runtime] Version Same");
|
|
}
|
|
else
|
|
{
|
|
CommonLibrary.Log
|
|
.INFO(string.Format("{0}", result == 1 ? "remote is the upper version" : "remote is the lower version"));
|
|
CommonLibrary.Log.INFO("Runtime delete it for update.");
|
|
|
|
// 런타임 폴더 경로 가져오기
|
|
var rootDirectoryInfo = new System.IO.DirectoryInfo(System.IO.Path.GetFullPath(Settings.RuntimeLocation));
|
|
|
|
// 런타임 폴더 삭제후 새로만들기
|
|
if (!rootDirectoryInfo.Exists)
|
|
{
|
|
rootDirectoryInfo.Create();
|
|
Log.INFO("[Runtime] +[D] " + rootDirectoryInfo.FullName);
|
|
}
|
|
else
|
|
{
|
|
rootDirectoryInfo.Delete(true);
|
|
Log.INFO("[Runtime] -[D] " + rootDirectoryInfo.FullName);
|
|
rootDirectoryInfo.Create();
|
|
Log.INFO("[Runtime] +[D] " + rootDirectoryInfo.FullName);
|
|
}
|
|
|
|
// 런타임 다운로드 시작
|
|
GameUpdateManagerMessage(this, new GameUpdateManagerMessageEventArgs(GameUpdateManagerMessageType.First, 2, 9, "[2/9] Runtime Download"));
|
|
Log.INFO("[Runtime] Data Download Start");
|
|
var downloadUrl = CommonLibrary.Extensions.PathCombineL(Settings.ServerBaseUrl, dataPatchInformation.RuntimeUrl, dataPatchInformation.RuntimeFileName);
|
|
var targetPath = System.IO.Path.Combine(tempDirectory, dataPatchInformation.RuntimeFileName); // 임시폴더에 다운로드
|
|
downloader.DownloadFile(downloadUrl, targetPath);
|
|
Log.INFO("[Runtime] Data Download End");
|
|
// 런타임 다운로드 완료
|
|
|
|
// 런타임 언패킹 작업
|
|
var progressPacker = new ProgressPacker();
|
|
var unpackPath = System.IO.Path.GetFullPath(Settings.RuntimeLocation);
|
|
GameUpdateManagerMessage(this, new GameUpdateManagerMessageEventArgs(GameUpdateManagerMessageType.First, 3, 9, "[3/9] Runtime Unpack"));
|
|
Log.INFO("[Runtime] Unpack Start");
|
|
progressPacker.UnPack(targetPath, unpackPath, new BasicProgress<double>(p => Change(p)));
|
|
Settings.UserLauncherConfig.RuntimeVersion = remoteVersion.ToString();
|
|
|
|
//임시폴더 삭제
|
|
System.IO.File.Delete(targetPath);
|
|
Log.INFO("[Runtime] -[F] " + targetPath);
|
|
Log.INFO("[Runtime] Unpack End");
|
|
}
|
|
|
|
#endregion Runtime Update
|
|
|
|
#region Package Update
|
|
|
|
GameUpdateManagerMessage(this, new GameUpdateManagerMessageEventArgs(GameUpdateManagerMessageType.First, 4, 9, "[4/9] Package Version Check"));
|
|
Log.INFO("[Package] Version Check");
|
|
thisVersion = Version.Parse(Settings.UserClientVersion.PackageVersion);
|
|
remoteVersion = Version.Parse(dataPatchInformation.PackageVersion);
|
|
CommonLibrary.Log.INFO("[Package] LocalVersion : " + thisVersion);
|
|
CommonLibrary.Log.INFO("[Package] RemoteVersion : " + remoteVersion);
|
|
result = remoteVersion.CompareTo(thisVersion);
|
|
|
|
// 1 : 리모트가 큼, 0 : 같음, -1 리모트가 적음
|
|
if (result == 0)
|
|
{
|
|
CommonLibrary.Log.INFO("[Package] Version Same");
|
|
}
|
|
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.");
|
|
|
|
var rootDirectoryInfo = new System.IO.DirectoryInfo(System.IO.Path.GetFullPath(Settings.UserLauncherConfig.GameDirectory));
|
|
|
|
if (!rootDirectoryInfo.Exists)
|
|
{
|
|
rootDirectoryInfo.Create();
|
|
Log.INFO("[Package] +[D] " + rootDirectoryInfo.FullName);
|
|
}
|
|
else
|
|
{
|
|
// 비우기 전에 스크린샷폴더 보존 /screenshots
|
|
string oldScreenshotsDirectory = CommonLibrary.Extensions.PathCombineW(Settings.UserLauncherConfig.GameDirectory, "screenshots");
|
|
string newScreenshotsDirectory = CommonLibrary.Extensions.PathCombineW("screenshots " + DateTime.Now.ToString());
|
|
if (System.IO.Directory.Exists(oldScreenshotsDirectory) && System.IO.Directory.GetFiles(oldScreenshotsDirectory, "*", System.IO.SearchOption.AllDirectories).Length > 0)
|
|
{
|
|
Log.INFO("[Package] Screenshots Directory Backup : " + newScreenshotsDirectory);
|
|
System.IO.Directory.Move(oldScreenshotsDirectory, newScreenshotsDirectory);
|
|
}
|
|
|
|
Extensions.EmptyDirectory(rootDirectoryInfo.FullName);
|
|
Log.INFO("[Package] Empty GameDirectory");
|
|
}
|
|
|
|
var downloadUrl = CommonLibrary.Extensions.PathCombineL(Settings.ServerBaseUrl, dataPatchInformation.PackageUrl, dataPatchInformation.PackageFileName);
|
|
var targetPath = System.IO.Path.Combine(tempDirectory, dataPatchInformation.PackageFileName);
|
|
GameUpdateManagerMessage(this, new GameUpdateManagerMessageEventArgs(GameUpdateManagerMessageType.First, 5, 9, "[5/9] Package Download"));
|
|
Log.INFO("[Package] Download Start");
|
|
downloader.DownloadFile(downloadUrl, targetPath);
|
|
Log.INFO("[Package] Download End");
|
|
|
|
if (Settings.UserClientVersion.PackageDirectorys != null)
|
|
{
|
|
foreach (var item in Settings.UserClientVersion.PackageDirectorys)
|
|
{
|
|
var directoryInfo = new System.IO.DirectoryInfo(System.IO.Path.GetFullPath(item));
|
|
|
|
if (directoryInfo.Exists)
|
|
{
|
|
directoryInfo.Delete(true);
|
|
Log.INFO("[Package] -[D] " + directoryInfo.FullName);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (dataPatchInformation.PackageDirectorys != null)
|
|
{
|
|
foreach (var item in dataPatchInformation.PackageDirectorys)
|
|
{
|
|
var directoryInfo = new System.IO.DirectoryInfo(System.IO.Path.GetFullPath(item));
|
|
|
|
if (directoryInfo.Exists)
|
|
{
|
|
directoryInfo.Delete(true);
|
|
Log.INFO("[Package] -[D] " + directoryInfo.FullName);
|
|
}
|
|
}
|
|
}
|
|
|
|
// 패키지 언팩
|
|
var progressPacker = new ProgressPacker();
|
|
var unpackPath = System.IO.Path.GetFullPath(rootDirectoryInfo.FullName);
|
|
GameUpdateManagerMessage(this, new GameUpdateManagerMessageEventArgs(GameUpdateManagerMessageType.First, 6, 9, "[6/9] Package Unpack"));
|
|
Log.INFO("[Package] Unpack Start");
|
|
progressPacker.UnPack(targetPath, unpackPath, new BasicProgress<double>(p => Change(p)));
|
|
Settings.UserClientVersion.PackageVersion = remoteVersion.ToString();
|
|
|
|
//임시파일 삭제
|
|
System.IO.File.Delete(targetPath);
|
|
Log.INFO("[Package] -[F] " + targetPath);
|
|
Log.INFO("[Package] Unpack End");
|
|
}
|
|
|
|
#endregion Package Update
|
|
|
|
#region Coomponent Update
|
|
|
|
GameUpdateManagerMessage(this, new GameUpdateManagerMessageEventArgs(GameUpdateManagerMessageType.First, 7, 9, "[7/9] Component Version Check"));
|
|
Log.INFO("[Component] Version Check");
|
|
|
|
thisVersion = Version.Parse(Settings.UserClientVersion.ComponentVersion);
|
|
remoteVersion = Version.Parse(dataPatchInformation.ComponentVersion);
|
|
CommonLibrary.Log.INFO("[Component] LocalVersion : " + thisVersion);
|
|
CommonLibrary.Log.INFO("[Component] RemoteVersion : " + remoteVersion);
|
|
result = remoteVersion.CompareTo(thisVersion);
|
|
|
|
if (result == 0)
|
|
{
|
|
CommonLibrary.Log.INFO("[Component] Version Same");
|
|
}
|
|
else
|
|
{
|
|
var resultDirectorys = new List<string>();
|
|
|
|
foreach (var directory in Settings.UserClientVersion.ComponentDirectorys)
|
|
{
|
|
if (!dataPatchInformation.ComponentDirectorys.Contains(directory))
|
|
{
|
|
resultDirectorys.Add(directory);
|
|
}
|
|
}
|
|
|
|
foreach (var directory in resultDirectorys)
|
|
{
|
|
var directoryPath = System.IO.Path.GetFullPath(CommonLibrary.Extensions.PathCombineW(Settings.UserLauncherConfig.GameDirectory, directory));
|
|
|
|
if (System.IO.Directory.Exists(directoryPath))
|
|
{
|
|
System.IO.Directory.Delete(directoryPath, true);
|
|
Log.INFO("[Component] -[D] " + directoryPath);
|
|
}
|
|
}
|
|
|
|
foreach (var directory in dataPatchInformation.ComponentDirectorys)
|
|
{
|
|
var directoryPath = System.IO.Path.GetFullPath(CommonLibrary.Extensions.PathCombineW(Settings.UserLauncherConfig.GameDirectory, directory));
|
|
|
|
if (!System.IO.Directory.Exists(directoryPath))
|
|
{
|
|
System.IO.Directory.CreateDirectory(directoryPath);
|
|
Log.INFO("[Component] +[D] " + directoryPath);
|
|
}
|
|
}
|
|
|
|
var auditFile = new AuditFile();
|
|
var localFiles = auditFile.GetLocalFileList(dataPatchInformation.ComponentDirectorys);
|
|
var removeFiles = auditFile.GetRemoveFiles(localFiles, dataPatchInformation.ComponentList);
|
|
|
|
var needFiles = auditFile.GetNeedFiles(localFiles, dataPatchInformation.ComponentList);
|
|
//var customFiles =
|
|
|
|
foreach (var fileDetail in removeFiles)
|
|
{
|
|
var filePath = CommonLibrary.Extensions.PathCombineW(Settings.UserLauncherConfig.GameDirectory, fileDetail.Directory, fileDetail.FileName);
|
|
if (System.IO.File.Exists(filePath))
|
|
{
|
|
Log.INFO("[Component] -[F] " + filePath);
|
|
System.IO.File.Delete(filePath);
|
|
}
|
|
}
|
|
// 디렉토리 삭제
|
|
GameUpdateManagerMessage(this, new GameUpdateManagerMessageEventArgs(GameUpdateManagerMessageType.First, 8, 9, "[8/9] Component Download"));
|
|
Log.INFO("[Component] Download Start");
|
|
for (int i = 0; i < needFiles.Count; i++)
|
|
{
|
|
var url = CommonLibrary.Extensions.PathCombineL(Settings.ServerBaseUrl, dataPatchInformation.ComponentUrl, needFiles[i].Directory, needFiles[i].FileName);
|
|
var path = CommonLibrary.Extensions.PathCombineW(Settings.UserLauncherConfig.GameDirectory, needFiles[i].Directory, needFiles[i].FileName);
|
|
downloader.DownloadFile(url, path);
|
|
Log.INFO("[Component] +[F] " + path);
|
|
}
|
|
Log.INFO("[Component] Download End");
|
|
Settings.UserClientVersion.ComponentVersion = remoteVersion.ToString();
|
|
Settings.UserClientVersion.ComponentDirectorys = dataPatchInformation.ComponentDirectorys;
|
|
|
|
#endregion Coomponent Update
|
|
}
|
|
// 커스텀 폴더, Config
|
|
|
|
#region CustomData
|
|
// 삭제된 파일 찾기
|
|
|
|
string rootCustomPath = System.IO.Path.GetFullPath(Settings.CustomDataDirectory);
|
|
List<string> files = new List<string>();
|
|
files.AddRange(System.IO.Directory.GetFiles(CommonLibrary.Extensions.PathCombineW(rootCustomPath, "config")));
|
|
files.AddRange(System.IO.Directory.GetFiles(CommonLibrary.Extensions.PathCombineW(rootCustomPath, "mods")));
|
|
for (int i = 0; i < files.Count; i++)
|
|
{
|
|
files[i] = files[i].Replace(rootCustomPath + '\\', string.Empty);
|
|
|
|
}
|
|
|
|
for (int i = 0; i < Settings.UserLauncherConfig.CustomData.Count; i++)
|
|
{
|
|
if (!files.Contains(Settings.UserLauncherConfig.CustomData[i]))
|
|
{
|
|
|
|
string filePath = CommonLibrary.Extensions.PathCombineW(Settings.UserLauncherConfig.GameDirectory, Settings.UserLauncherConfig.CustomData[i]);
|
|
System.IO.File.Delete(filePath);
|
|
Log.INFO("[CustomData] -[F] " + filePath);
|
|
}
|
|
}
|
|
foreach (var file in files)
|
|
{
|
|
string sourcePath = CommonLibrary.Extensions.PathCombineW(rootCustomPath, file);
|
|
string targetPath = CommonLibrary.Extensions.PathCombineW(Settings.UserLauncherConfig.GameDirectory, file);
|
|
|
|
|
|
if (System.IO.File.Exists(targetPath))
|
|
{
|
|
System.IO.FileInfo sourceFile = new System.IO.FileInfo(sourcePath);
|
|
System.IO.FileInfo targetFile = new System.IO.FileInfo(targetPath);
|
|
if (sourceFile.GetFileHashCode() != targetFile.GetFileHashCode())
|
|
{
|
|
System.IO.File.Copy(sourcePath, targetPath,true);
|
|
Log.INFO("[CustomData] +[F] " + targetPath);
|
|
|
|
}
|
|
}
|
|
else
|
|
{
|
|
System.IO.File.Copy(sourcePath, targetPath);
|
|
Log.INFO("[CustomData] +[F] " + targetPath);
|
|
}
|
|
Settings.UserLauncherConfig.CustomData = files;
|
|
Settings.SaveUserLauncherConfig();
|
|
}
|
|
|
|
#endregion CustomData
|
|
|
|
GameUpdateManagerMessage(this, new GameUpdateManagerMessageEventArgs(GameUpdateManagerMessageType.First, 9, 9, "[9/9] Update Complete"));
|
|
Log.INFO("GameUpdate All Success");
|
|
return GameUpdateStatus.Success;
|
|
}
|
|
|
|
private void Change(double value)
|
|
{
|
|
var e = new GameUpdateManagerMessageEventArgs(GameUpdateManagerMessageType.Second, (long)(value * 100), 100, string.Empty);
|
|
GameUpdateManagerMessage?.Invoke(this, e);
|
|
}
|
|
|
|
private void Downloader_DownloaderProgressChangedEvent(object sender, DownloaderProgressChangedEventArgs downloaderProgressChangedEventArgs)
|
|
{
|
|
var e = new GameUpdateManagerMessageEventArgs(GameUpdateManagerMessageType.Second, downloaderProgressChangedEventArgs.ProcessedByte, downloaderProgressChangedEventArgs.FileSize, string.Empty);
|
|
GameUpdateManagerMessage?.Invoke(this, e);
|
|
}
|
|
}
|
|
|
|
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)
|
|
{
|
|
MessageType = messageType;
|
|
MinValue = minValue;
|
|
MaxValue = maxValue;
|
|
Message = message;
|
|
}
|
|
}
|
|
} |