public override void HandleEvent(object sender, EventArgs e)
        {
            Logging.Logger.GetLogger().Info("Handling update application event!");

            var progress = new InternalNodeProgress("Update Application");
            var progressWindow = new ProgressWindow(progress);
            Task.Run(() =>
            {
                try
                {
                    var message = this.Engine.UpdateManager.FetchLatestVersionAndStartUpdate(progress);
                    this.Engine.UiControl.StartPopupWindow(this.Engine.UiControl.MajorWindow, "Update", message);
                }
                catch (Exception ex)
                {

                    Logging.Logger.GetLogger()
                            .Error(String.Format("Can not update because {0}", ex));
                    this.Engine.UiControl.StartPopupWindow(this.Engine.UiControl.MajorWindow, "Can not launch", String.Format(
                        "Caused by an internal error, we can not update right now. Detail: {0}", ex.Message));
                }
                finally
                {
                    progressWindow.CrossThreadClose();
                }
            });
            progressWindow.ShowDialog();
        }
 public InternalNodeProgress CreateNewInternalSubProgress(string taskName, double taskPercentage)
 {
     taskPercentage = this.CheckPercentage(taskPercentage);
     var progress = new InternalNodeProgress(taskName);
     this.SubProgressesAndPercentage.Add(progress, taskPercentage);
     progress.ProgressChanged += sender => { this.OnProgressChanged(); };
     return progress;
 }
        public override void HandleEvent(object sender, EventArgs e)
        {
            Logging.TerminologyLogger.GetLogger().Info("Handling update application event!");

            try
            {
                if (this.Engine.UpdateManager.GetupdateInfo().UpdateType != UpdateType.Higher)
                {
                    this.Engine.UiControl.MainWindow.PopupNotifyDialog("Update", "No update available. You are using the latest version.");
                    return;
                }

                var updateInfo = this.Engine.UpdateManager.GetupdateInfo();
                var confirm = this.Engine.UiControl.MainWindow.PopupConfirmDialog("Update",
                    $"Do you confirm to update from {this.Engine.UpdateManager.Version.CoreVersion}-{this.Engine.UpdateManager.Version.BuildNumber} to {updateInfo.LatestVersion.CoreVersion}-{updateInfo.LatestVersion.BuildNumber}");
                if (!confirm.Value)
                {
                    return;
                }

                var progress = new InternalNodeProgress("Update Application");
                var progressWindow = this.Engine.UiControl.MainWindow.BeginPopupProgressWindow(progress);
                Task.Run(() =>
                {
                    try
                    {
                        var message = this.Engine.UpdateManager.FetchLatestVersionAndStartUpdate(progress);
                        this.Engine.Exit();
                    }
                    catch (Exception ex)
                    {

                        Logging.TerminologyLogger.GetLogger()
                                .Error($"Cannot update because {ex}");
                        this.Engine.UiControl.MainWindow.PopupNotifyDialog("Cannot launch",
                            $"Caused by an internal error, we cannot update right now. Detail: {ex.Message}");
                    }
                    finally
                    {
                        progressWindow.CrossThreadClose();
                    }
                });
                progressWindow.ShowDialog();

            }
            catch (Exception ex)
            {
                TerminologyLogger.GetLogger()
                    .ErrorFormat($"Cannot update launcher because {ex}");
                this.Engine.UiControl.MainWindow.PopupNotifyDialog("Cannot update",
                    $"Caused by an error, we cannot update launcher right now. Detail: {ex.Message}");

                throw;
            }
        }
        public override void HandleEvent(object sender, EventArgs e)
        {
            Logging.Logger.GetLogger().Info("Handling update instance event!");

            var instance = this.Engine.UiControl.MajorWindow.SelectInstance;
            if (instance == null)
            {
                Logging.Logger.GetLogger().Warn("Did not select any instance. Ignore!");
                return;
            }

            var progress = new InternalNodeProgress(String.Format("Launching instance {0}", instance.InstanceName));
            var progressWindow = new ProgressWindow(progress);
            Task.Run(() =>
            {
                try
                {
                    var message = this.Engine.InstanceManager.UpdateInstance(progress, instance.InstanceName);
                    Logging.Logger.GetLogger().InfoFormat(message);
                    this.Engine.UiControl.StartPopupWindow(this.Engine.UiControl.MajorWindow, "Successful updated", message);

                }
                catch (NoAvailableUpdateException ex)
                {
                    Logging.Logger.GetLogger().Info(ex.Message);
                    this.Engine.UiControl.StartPopupWindow(this.Engine.UiControl.MajorWindow, "No available update",
                        ex.Message);
                }
                catch (WrongStateException ex)
                {
                    Logging.Logger.GetLogger().ErrorFormat("Update instance {0} encountered an error: {1}", instance.InstanceName, ex.Message);
                    this.Engine.UiControl.StartPopupWindow(this.Engine.UiControl.MajorWindow, "Can not update",
                        String.Format(
                            "Encounter an wrong state error. Detail:{0}",
                            ex.Message));

                }
                catch (Exception ex)
                {
                    Logging.Logger.GetLogger().ErrorFormat("Update instance {0} encountered an error:\n{1}", instance.InstanceName, ex);
                    this.Engine.UiControl.StartPopupWindow(this.Engine.UiControl.MajorWindow, "Can not update",
                        String.Format(
                            "Caused by an internal error, we can not update this instance right now.Detail:{0}",
                            ex.Message));

                }
                finally
                {
                    progressWindow.CrossThreadClose();
                }

            });
            progressWindow.ShowDialog();
        }
 public void DownloadText()
 {
     var progress = new InternalNodeProgress("Download text main task");
     progress.ProgressChanged += sender =>
     {
         Console.WriteLine(progress.Percent);
     };
     var content =
         DownloadUtils.GetFileContent(progress.CreateNewLeafSubProgress(100D, String.Format("Downloading Text")), "http://baidu.com");
     // Console.WriteLine(content);
 }
        public void LaunchInstance()
        {
            if (InstanceManager.Config != null)
                InstanceManager.Config.SetConfigString("javaBinPath", "C:\\jdk1.7.0_51\\bin\\");

            var progress = new InternalNodeProgress("");
            progress.ProgressChanged += (i) =>
            {
                Console.WriteLine(progress.Percent);
            };
            InstanceManager.LaunchInstance(progress.CreateNewInternalSubProgress("", 100D), InstanceManager.Instances[0].InstanceName, new PlayerEntity() { PlayerName = "DeckerCHAN" });
        }
        public override void HandleEvent(object sender, EventArgs e)
        {
            Logging.TerminologyLogger.GetLogger().Info("Handling update instance event!");

            var instance = this.Engine.UiControl.MainWindow.SelectInstance;
            if (instance == null)
            {
                Logging.TerminologyLogger.GetLogger().Warn("Did not select any instance. Ignore!");
                return;
            }

            var progress = new InternalNodeProgress($"Updating instance {instance.InstanceName}");
            var progressWindow = this.Engine.UiControl.MainWindow.BeginPopupProgressWindow(progress);
            Task.Run(() =>
            {
                try
                {
                    var message = this.Engine.InstanceManager.UpdateInstance(progress, instance.InstanceName);
                    progressWindow.CrossThreadClose();
                    this.Engine.UiControl.MainWindow.PopupNotifyDialog("Successful updated", message);
                    this.Engine.UiControl.MainWindow.InstanceList = new ObservableCollection<InstanceEntity>(this.Engine.InstanceManager.InstancesWithLocalImageSource);
                }
                catch (NoAvailableUpdateException ex)
                {
                    Logging.TerminologyLogger.GetLogger().Info(ex.Message);
                    this.Engine.UiControl.MainWindow.PopupNotifyDialog("No available update", ex.Message);
                }
                catch (WrongStateException ex)
                {
                    Logging.TerminologyLogger.GetLogger()
                        .ErrorFormat($"Update instance {instance.InstanceName} encountered an error: {ex.Message}");
                    this.Engine.UiControl.MainWindow.PopupNotifyDialog("Cannot update",
                        $"Encounter an wrong state error. Detail:{ex.Message}");

                }
                catch (Exception ex)
                {
                    Logging.TerminologyLogger.GetLogger()
                        .ErrorFormat($"Update instance {instance.InstanceName} encountered an error:\n{ex}");
                    this.Engine.UiControl.MainWindow.PopupNotifyDialog("Cannot update",
                        $"Caused by an internal error, we cannot update this instance right now.Detail:{ex.Message}");

                }
                finally
                {
                    progressWindow.CrossThreadClose();
                }

            });
            progressWindow.ShowDialog();
        }
        public string FetchLatestVersionAndStartUpdate(InternalNodeProgress progress)
        {
            progress.Percent = 0D;

            if (!this.GetupdateInfo().UpdateType.Equals(UpdateType.Higher))
            {
                return TranslationManager.GetManager.Localize("NoUpdateAvailable", "No update available.");
            }

            var update = JsonConverter.Parse<UpdateEntity>(DownloadUtils.GetWebContent(this.Config.GetConfigString("updateCheckingUrl")));

            var updateTempFolder = Path.Combine(FolderUtils.SystemTempFolder.FullName,
                $"TerminologyLauncher-{update.LatestVersion.CoreVersion}-{update.LatestVersion.BuildNumber}");
            var updateBinaryFolder = Path.Combine(updateTempFolder, "Binary");
            var updaterExecutorFile = Path.Combine(
                Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), "Updater.exe");
            var updaterRealExecutorFile = Path.Combine(updateTempFolder, "Updater.exe");

            if (Directory.Exists(updateTempFolder))
            {
                FolderUtils.DeleteDirectory(updateTempFolder);
            }

            progress.Percent = 10D;
            DownloadUtils.DownloadZippedFile(
                progress.CreateNewInternalSubProgress("Fetching update pack", 80D), update.LatestVersion.DownloadLink,
                updateBinaryFolder,
                update.LatestVersion.Md5);
            if (!File.Exists(updaterExecutorFile))
            {
                throw new FileNotFoundException("Cannot find updater.exe. You may have to re-install to resolve!");
            }
            File.Copy("Updater.exe", updaterRealExecutorFile, true);
            var updateProcessInfo = new ProcessStartInfo(updaterRealExecutorFile)
            {
                Arguments =
                    $"{updateBinaryFolder} {Path.GetDirectoryName(Assembly.GetEntryAssembly().Location)} {Assembly.GetEntryAssembly().Location}",
                CreateNoWindow = false,
                UseShellExecute = true
            };
            var updateProcess = new Process { StartInfo = updateProcessInfo };
            updateProcess.Start();

            progress.Percent = 100D;
            return string.Format(TranslationManager.GetManager.Localize("FetchedNewUpdateToVersion", "Updating from {0} to {1}! Close launcher to continue.", 2),
                $"{this.Version.CoreVersion}-{this.Version.BuildNumber}",
                $"{this.Version.CoreVersion}-{this.Version.BuildNumber}");
        }
        public String FetchLatestVersionAndStartUpdate(InternalNodeProgress progress)
        {
            progress.Percent = 0D;

            if (!this.CheckUpdateAvailable())
            {
                return "No newer update available.";
            }

            var update = JsonConverter.Parse<UpdateEntity>(DownloadUtils.GetFileContent(this.Config.GetConfig("updateCheckingUrl")));

            var updateTempFolder = Path.Combine(FolderUtils.SystemTempFolder.FullName,
                String.Format("TerminologyLauncher-{0}", update.LatestVersion.VersionNumber));
            var updateBinaryFolder = Path.Combine(updateTempFolder, "Binary");
            var updaterExecutorFile = Path.Combine(
                Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), "Updater.exe");
            var updaterRealExecutorFile = Path.Combine(updateTempFolder, "Updater.exe");

            if (Directory.Exists(updateTempFolder))
            {
                FolderUtils.DeleteDirectory(updateTempFolder);
            }

            progress.Percent = 10D;
            DownloadUtils.DownloadZippedFile(
                progress.CreateNewInternalSubProgress(80D, "Fetching update pack"), update.LatestVersion.DownloadLink,
                updateBinaryFolder,
                update.LatestVersion.Md5);
            if (!File.Exists(updaterExecutorFile))
            {
                throw new FileNotFoundException("Can not find updater.exe. You may have to re-install to resolve!");
            }
            File.Copy("Updater.exe", updaterRealExecutorFile, true);
            var updateProcessInfo = new ProcessStartInfo(updaterRealExecutorFile)
            {
                Arguments =
                    String.Format("{0} {1} {2}", updateBinaryFolder,
                        Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), Assembly.GetEntryAssembly().Location),
                CreateNoWindow = false,
                UseShellExecute = true
            };
            var updateProcess = new Process { StartInfo = updateProcessInfo };
            updateProcess.Start();

            progress.Percent = 100D;
            return String.Format("Updating from {0} to {1}! Close launcher to continue.", this.Version,
            update.LatestVersion.VersionNumber);
        }
 public void DownloadFileWithProgress()
 {
     var progress = new InternalNodeProgress("Download File Main Task");
     progress.ProgressChanged += sender =>
     {
         Console.WriteLine(progress.Percent);
     };
     var downloadFile = new FileInfo("Test.QQ.exe");
     if (downloadFile.Exists)
     {
         downloadFile.Delete();
     }
     DownloadUtils.DownloadFile(progress.CreateNewLeafSubProgress(100D, "Downloading test file"),
         "http://dldir1.qq.com/qqfile/qq/QQ7.4/15197/QQ7.4.exe", downloadFile.FullName);
     downloadFile.Refresh();
     Assert.IsTrue(downloadFile.Exists);
 }
        public static void LaunchInstance()
        {
            if (InstanceManager.Config != null)
                InstanceManager.Config.SetConfig("javaBinPath", "C:\\jdk1.7.0_51\\bin\\");
            var fileRepo = new FileRepository("Configs/FileRepositoryConfig.json");

            var progress = new InternalNodeProgress("");
            var t = Task.Run(() =>
            {
                while (progress.Percent <= 100D)
                {
                    Console.WriteLine(progress.Percent);
                    Thread.Sleep(1000);
                }

            });
            var process = InstanceManager.LaunchInstance(progress.CreateNewInternalSubProgress(100D, ""), InstanceManager.Instances[0].InstanceName, new PlayerEntity() { PlayerName = "DeckerCHAN" });
            process.WaitForExit();
        }
        public String UpdateInstance(InternalNodeProgress progress, String instanceName)
        {
            Logger.GetLogger().Info(String.Format("Start to update {0}", instanceName));
            var instanceInfo = this.InstanceBank.InstancesInfoList.First(x => (x.Name.Equals(instanceName)));
            if (instanceInfo.InstanceState != InstanceState.Ok)
            {
                throw new WrongStateException("Wrong instance state! Just instance which in OK state could update.");
            }

            var oldInstanceEntity =
                JsonConverter.Parse<InstanceEntity>(
                    File.ReadAllText(instanceInfo.FilePath));

            this.CriticalInstanceFieldCheck(oldInstanceEntity);

            var newInstanceContent = DownloadUtils.GetFileContent(instanceInfo.UpdateUrl);
            var newInstanceEntity = JsonConverter.Parse<InstanceEntity>(newInstanceContent);

            //Check instance is available to update
            if (newInstanceEntity.Version == oldInstanceEntity.Version)
            {
                throw new NoAvailableUpdateException(String.Format("Instance now in latest version:{0}! Ignore update.", newInstanceEntity.Version));
            }

            //TODO:I'll support instance name change at feature version.
            if (!newInstanceEntity.InstanceName.Equals(oldInstanceEntity.InstanceName))
            {
                throw new Exception("Old instance name not equal with new instance name.");
            }

            var instanceRootFolder = this.GetInstanceRootFolder(oldInstanceEntity.InstanceName);

            #region Update files

            #region Entire package
            //Difference entire package will cause whole package target folder been delete

            instanceInfo.InstanceState = InstanceState.Update;

            var newEntirePackages = newInstanceEntity.FileSystem.EntirePackageFiles ?? new List<EntirePackageFileEntity>();
            var oldEntirePackages = oldInstanceEntity.FileSystem.EntirePackageFiles ?? new List<EntirePackageFileEntity>();
            //Delete old entire package
            foreach (var oldEntirePackageFileEntity in oldEntirePackages)
            {
                if (!newEntirePackages.Exists
                        (
                            x => x.Name.Equals(oldEntirePackageFileEntity.Name) &&
                                x.Md5.Equals(oldEntirePackageFileEntity.Md5)
                        )
                    )
                {
                    FolderUtils.DeleteDirectory(Path.Combine(instanceRootFolder.FullName, oldEntirePackageFileEntity.LocalPath));
                }
            }
            //Download new entire package
            foreach (var newEntirePackageFileEntity in newEntirePackages)
            {
                if (!oldEntirePackages.Exists
                    (
                        x =>
                            x.Name.Equals(newEntirePackageFileEntity.Name) &&
                            x.Md5.Equals(newEntirePackageFileEntity.Md5)
                    )
                    )
                {
                    //TODO:Support progress
                    this.ReceiveEntirePackage(new InternalNodeProgress("Ignore"), newInstanceEntity.InstanceName,
                        newEntirePackageFileEntity);
                }
            }
            #endregion
            progress.Percent = 30D;
            #region Official files

            var newOfficialFiles = newInstanceEntity.FileSystem.OfficialFiles ?? new List<OfficialFileEntity>();
            var oldOfficialFiles = newInstanceEntity.FileSystem.OfficialFiles ?? new List<OfficialFileEntity>();
            //Delete old official files
            foreach (var oldOfficialFileEntity in oldOfficialFiles)
            {
                if (!newOfficialFiles.Exists(x => x.ProvideId.Equals(oldOfficialFileEntity.ProvideId)))
                {
                    File.Delete(Path.Combine(instanceRootFolder.FullName, oldOfficialFileEntity.LocalPath));
                }
            }
            //Receive new official files
            foreach (var newOfficialFileEntity in newOfficialFiles)
            {
                if (!oldOfficialFiles.Exists(x => x.ProvideId.Equals(newOfficialFileEntity.ProvideId)))
                {
                    this.ReceiveOfficialFile(new LeafNodeProgress("Ignore"), newInstanceEntity.InstanceName,
                        newOfficialFileEntity, this.UsingFileRepository);
                }
            }
            #endregion

            progress.Percent = 60D;
            #region Custom files

            var newCustomFiles = newInstanceEntity.FileSystem.CustomFiles ?? new List<CustomFileEntity>();
            var oldCustomFiles = oldInstanceEntity.FileSystem.CustomFiles ?? new List<CustomFileEntity>();
            foreach (var oldCustomFileEntity in oldCustomFiles)
            {
                if (
                    !newCustomFiles.Exists(
                        x => x.Name.Equals(oldCustomFileEntity.Name) && x.Md5.Equals(oldCustomFileEntity.Md5)))
                {
                    File.Delete(Path.Combine(instanceRootFolder.FullName, oldCustomFileEntity.LocalPath));
                }
            }
            foreach (var newCustomFileEntity in newCustomFiles)
            {
                if (!oldCustomFiles.Exists(x => x.Name.Equals(newCustomFileEntity.Name) && x.Md5.Equals(newCustomFileEntity.Md5)))
                {
                    this.ReceiveCustomFile(new LeafNodeProgress("Ignore"), newInstanceEntity.InstanceName,
                        newCustomFileEntity);
                }
            }
            #endregion
            progress.Percent = 90D;
            #endregion

            instanceInfo.InstanceState = InstanceState.Ok;
            instanceInfo.UpdateDate = DateTime.Now.ToString("O");
            this.SaveInstancesBankToFile();
            File.WriteAllText(instanceInfo.FilePath, JsonConverter.ConvertToJson(newInstanceEntity));
            progress.Percent = 100D;
            return String.Format("Successful update instance {0} from version {1} to {2}!",
                newInstanceEntity.InstanceName, oldInstanceEntity.Version, newInstanceEntity.Version);
        }
        public Process LaunchInstance(InternalNodeProgress progress, String instanceName, PlayerEntity player)
        {
            Logger.GetLogger().Info(String.Format("Start to launch {0} by player {1}...", instanceName, player.PlayerName));
            var instanceInfo = this.InstanceBank.InstancesInfoList.First(x => (x.Name.Equals(instanceName)));
            var instance =
                JsonConverter.Parse<InstanceEntity>(
                    File.ReadAllText(instanceInfo.FilePath));

            if (!(instanceInfo.InstanceState == InstanceState.Ok || instanceInfo.InstanceState == InstanceState.PerInitialized))
            {
                throw new WrongStateException("Wrong instance state! Just instance which in OK or PerInitialized state could launch.");
            }

            this.CriticalInstanceFieldCheck(instance);

            var instanceRootFolder = this.GetInstanceRootFolder(instance.InstanceName);

            #region Buding environment

            if (instanceInfo.InstanceState == InstanceState.PerInitialized)
            {
                #region entire file.
                if (instance.FileSystem.EntirePackageFiles != null && instance.FileSystem.EntirePackageFiles.Count != 0)
                {
                    var singlePackageDownloadNodeProgress = 30D / instance.FileSystem.EntirePackageFiles.Count;
                    foreach (var entirePackageFile in instance.FileSystem.EntirePackageFiles)
                    {
                        this.ReceiveEntirePackage(progress.CreateNewInternalSubProgress(singlePackageDownloadNodeProgress, String.Format("Receiving entire package {0}", entirePackageFile.Name)),
                        instance.InstanceName, entirePackageFile);
                    }
                }
                #endregion
                progress.Percent = 30D;
                #region official files.
                if (instance.FileSystem.OfficialFiles != null && instance.FileSystem.OfficialFiles.Count != 0)
                {
                    var singleOfficialDownloadNodeProgress = 30D / instance.FileSystem.OfficialFiles.Count;
                    foreach (var officialFileEntity in instance.FileSystem.OfficialFiles)
                    {
                        this.ReceiveOfficialFile(
                            progress.CreateNewLeafSubProgress(singleOfficialDownloadNodeProgress,
                                String.Format("Downloading official file: {0}", officialFileEntity.Name)),
                            instance.InstanceName, officialFileEntity, this.UsingFileRepository);
                    }
                }
                #endregion
                progress.Percent = 60D;
                #region custom files

                if (instance.FileSystem.CustomFiles != null && instance.FileSystem.CustomFiles.Count != 0)
                {
                    var singleCustomDownloadNodeProgress = 30D / instance.FileSystem.CustomFiles.Count;
                    foreach (var customFileEntity in instance.FileSystem.CustomFiles)
                    {
                        this.ReceiveCustomFile(
                           progress.CreateNewLeafSubProgress(singleCustomDownloadNodeProgress,
                               String.Format("Downloading custom file: {0}", customFileEntity.Name)),
                           instance.InstanceName, customFileEntity);
                    }
                }
                #endregion
            }

            #endregion
            progress.Percent = 90D;

            instanceInfo.InstanceState = InstanceState.Ok;
            instanceInfo.UpdateDate = DateTime.Now.ToString("O");
            this.SaveInstancesBankToFile();

            //DONE:Build start argument.
            var startArgument = new StringBuilder();// placer.ReplaceArgument(instance.StartupArguments);
            foreach (var jvmArgument in instance.StartupArguments.JvmArguments)
            {
                startArgument.Append(jvmArgument + " ");
            }

            startArgument.Append(this.Config.GetConfig("extraJvmArguments") ?? String.Empty).Append(" ");

            startArgument.AppendFormat("-Xmx{0}M -Xms{1}M" + " ", Convert.ToInt64(this.Config.GetConfig("maxMemorySizeMega")), instance.StartupArguments.MiniumMemoryMegaSize);

            var nativeFolder = new DirectoryInfo(Path.Combine(instanceRootFolder.FullName, instance.StartupArguments.Nativespath));
            if (nativeFolder.Exists)
            {
                startArgument.AppendFormat("-Djava.library.path=\"{0}\"" + " ", nativeFolder.FullName);

            }
            else
            {
                throw new DirectoryNotFoundException(String.Format("Native folder is not valid!"));
            }

            startArgument.Append("-cp" + " ");

            foreach (var libraryPath in instance.StartupArguments.LibraryPaths)
            {
                var libFile = new FileInfo(Path.Combine(instanceRootFolder.FullName, libraryPath));
                if (libFile.Exists)
                {
                    startArgument.Append("\"" + libFile.FullName + "\"" + ";");
                }
                else
                {
                    throw new FileNotFoundException(String.Format("Instance {0} is missing lib file {1}", instance.InstanceName, libraryPath));
                }
            }

            var mainJarFile =
                new FileInfo(Path.Combine(instanceRootFolder.FullName, instance.StartupArguments.MainJarPath));

            if (mainJarFile.Exists)
            {
                startArgument.Append("\"" + mainJarFile.FullName + "\"" + " ");
            }
            else
            {
                throw new FileNotFoundException(String.Format("Instance {0} is missing main jar file {1}", instance.InstanceName, mainJarFile.Name));
            }

            startArgument.Append(instance.StartupArguments.MainClass + " ");

            startArgument.AppendFormat("--username {0} ", player.PlayerName);
            startArgument.AppendFormat("--version {0} ", instance.StartupArguments.Version);
            startArgument.AppendFormat("--gameDir \"{0}\" ", instanceRootFolder.FullName);

            var assetsDir =
                new DirectoryInfo(Path.Combine(instanceRootFolder.FullName, instance.StartupArguments.AssetsDir));
            if (assetsDir.Exists)
            {
                startArgument.AppendFormat("--assetsDir \"{0}\" ", assetsDir.FullName);
            }
            else
            {
                throw new DirectoryNotFoundException("Assets folder not found!");
            }

            startArgument.AppendFormat("--assetIndex {0} ", instance.StartupArguments.AssetIndex);
            startArgument.AppendFormat("--uuid {0} ", player.PlayerId);
            startArgument.AppendFormat("--accessToken {0} ", player.AccessToken);
            startArgument.AppendFormat("--userProperties {{{0}}} ", instance.StartupArguments.UserProperties);
            startArgument.AppendFormat("--userType {0} ", instance.StartupArguments.UserType);

            foreach (var tweakClass in instance.StartupArguments.TweakClasses)
            {
                startArgument.AppendFormat("--tweakClass {0} ", tweakClass);
            }

            //Launch minecraft
            var instanceStartInfo = new ProcessStartInfo
            {
                FileName = this.JavaRuntime.JavaWPath,
                Arguments = startArgument.ToString(),
                WorkingDirectory = instanceRootFolder.FullName,
                WindowStyle = ProcessWindowStyle.Normal,
                UseShellExecute = false,
                RedirectStandardOutput = true
            };
            var instanceProcess = new Process { StartInfo = instanceStartInfo, EnableRaisingEvents = true };
            instanceProcess.Start();
            progress.Percent = 100D;

            this.CurrentInstanceProcess = instanceProcess;
            Logger.GetLogger().Info(String.Format("Instance {0} launched!", instanceName));

            return this.CurrentInstanceProcess;
        }
        public static void DownloadZippedFile(InternalNodeProgress progress, String url, String path, String md5)
        {
            var tempFileInfo = new FileInfo(Path.Combine(new[] { FolderUtils.SystemTempFolder.FullName, Guid.NewGuid().ToString("N") }));
            DownloadFile(progress.CreateNewLeafSubProgress(90D, String.Format("Downloading zip file {0}", url)), url, tempFileInfo.FullName, md5);

            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }

            new FastZip().ExtractZip(tempFileInfo.FullName, path, null);
            progress.Percent = 100D;
        }
 public void TopLevel()
 {
     var progress = new InternalNodeProgress("Main task");
     progress.ProgressChanged += sender =>
     {
         Console.WriteLine("Woring on {0}:{1}", progress.TaskName, progress.Percent);
     };
     Console.WriteLine(progress.Percent);
     this.MidLevel(progress.CreateNewInternalSubProgress(100D,"MidLevel"));
     Console.WriteLine("All tasks finished!");
 }
        public override void HandleEvent(object sender, EventArgs e)
        {
            Logging.Logger.GetLogger().Info("Handling launch instance event!");

            InstanceEntity instance = this.Engine.UiControl.MajorWindow.SelectInstance;
            var progress = new InternalNodeProgress(String.Format("Launching instance {0}", instance.InstanceName));
            var progressWindow = new ProgressWindow(progress);
            Task.Run(() =>
            {
                try
                {
                    this.Engine.GameProcess = this.Engine.InstanceManager.LaunchInstance(progress, instance.InstanceName,
                        this.Engine.AuthServer.CurrentPlayer);
                    this.Engine.GameProcess.Exited += (s, o) =>
                    {
                        this.Engine.UiControl.ShowMainWindow();
                    };
                    this.Engine.UiControl.HideMainWindow();
                    this.Engine.GameProcess.BeginOutputReadLine();
                    this.Engine.GameProcess.OutputDataReceived += (s, ea) =>
                    {

                        if (!String.IsNullOrEmpty(ea.Data))
                        {
                            Logging.Logger.GetLogger().InfoFormat(">>>GAME<<<: {0}", ea.Data);
                        }
                    };
                }
                catch (WebException ex)
                {
                    var response = ((HttpWebResponse) ex.Response);
                    switch (response.StatusCode)
                    {
                        case HttpStatusCode.NotFound:
                        {
                            Logging.Logger.GetLogger()
                                .ErrorFormat("Can not find file on server when donloading:{0}", response.ResponseUri);
                            this.Engine.UiControl.StartPopupWindow(this.Engine.UiControl.MajorWindow, "Can not launch",
                                String.Format(
                                    "Can not find file on server when donloading:{0}", response.ResponseUri));
                            break;
                        }
                        case HttpStatusCode.Forbidden:
                        {
                            Logging.Logger.GetLogger()
                             .ErrorFormat("You have no right to access this server when downloading: {0}", response.ResponseUri);
                            this.Engine.UiControl.StartPopupWindow(this.Engine.UiControl.MajorWindow, "Can not launch",
                                String.Format(
                                    "You have no right to access this server when downloading: {0}", response.ResponseUri));

                            break;
                        }
                        default:
                        {

                            Logging.Logger.GetLogger()
             .Error(String.Format("Encounter an network error during build environment: {0}", ex));
                            this.Engine.UiControl.StartPopupWindow(this.Engine.UiControl.MajorWindow, "Can not launch", String.Format(
                                "Encounter an network error during build environment: {0}", ex.Message));

                            break;
                        }
                    }
                }
                catch (Exception ex)
                {
                    Logging.Logger.GetLogger()
                        .Error(String.Format("Can not launch this instance because {0}", ex));
                    this.Engine.UiControl.StartPopupWindow(this.Engine.UiControl.MajorWindow, "Can not launch", String.Format(
                        "Caused by an internal error, we can not launch this instance right now. Detail: {0}", ex.Message));
                }
                finally
                {
                    progressWindow.CrossThreadClose();
                }
            });
            progressWindow.ShowDialog();
        }
 private void ReceiveEntirePackage(InternalNodeProgress progress, String instanceName, EntirePackageFileEntity entirePackageFile)
 {
     var downloadLink = entirePackageFile.DownloadLink;
     var downloadTargetPositon = Path.Combine(this.GetInstanceRootFolder(instanceName).FullName, entirePackageFile.LocalPath ?? String.Empty);
     Logger.GetLogger().Info(String.Format("Downloading file:{0} from remote url:{1}.", downloadTargetPositon, downloadLink));
     DownloadUtils.DownloadZippedFile(progress, downloadLink, downloadTargetPositon, entirePackageFile.Md5);
     Logger.GetLogger().Info(String.Format("Successfully downloaded file:{0} then extracted to {1}.", downloadLink, downloadTargetPositon));
 }
        public override void HandleEvent(object sender, EventArgs e)
        {
            Logging.TerminologyLogger.GetLogger().Info("Handling launch instance event!");

            var instance = this.Engine.UiControl.MainWindow.SelectInstance;
            var progress = new InternalNodeProgress($"Launching instance {instance.InstanceName}");
            var progressWindow = this.Engine.UiControl.MainWindow.BeginPopupProgressWindow(progress);
            Task.Run(() =>
            {
                try
                {
                    this.Engine.GameProcess = this.Engine.InstanceManager.LaunchInstance(progress, instance.InstanceName,
                        this.Engine.AuthServer.CurrentPlayer);
                    var usingConsole = this.Engine.CoreConfig.GetConfigObject<bool>("usingConsoleWindow");
                    this.Engine.GameProcess.Exited += (s, o) =>
                    {
                        this.Engine.UiControl.HideConsoleWindow();
                        this.Engine.UiControl.ShowMainWindow();
                    };
                    this.Engine.UiControl.HideMainWindow();
                    if (usingConsole)
                    {
                        this.Engine.UiControl.ConsoleWindow.Process = this.Engine.GameProcess;
                        this.Engine.UiControl.ShowConsoleWindow();

                    }
                }
                catch (WebException ex)
                {
                    var response = ((HttpWebResponse)ex.Response);
                    switch (response.StatusCode)
                    {
                        case HttpStatusCode.NotFound:
                            {
                                Logging.TerminologyLogger.GetLogger()
                                    .ErrorFormat($"Cannot find file on server when donloading:{response.ResponseUri}");
                                this.Engine.UiControl.MainWindow.PopupNotifyDialog("Cannot launch",
                                    $"Cannot find file on server when donloading:{response.ResponseUri}");
                                break;
                            }
                        case HttpStatusCode.Forbidden:
                            {
                                Logging.TerminologyLogger.GetLogger()
                                    .ErrorFormat(
                                        $"You have no right to access this server when downloading: {response.ResponseUri}");
                                this.Engine.UiControl.MainWindow.PopupNotifyDialog("Cannot launch",
                                    $"You have no right to access this server when downloading: {response.ResponseUri}");

                                break;
                            }
                        default:
                            {

                                Logging.TerminologyLogger.GetLogger()
                 .Error($"Encounter an network error during build environment: {ex}");
                                this.Engine.UiControl.MainWindow.PopupNotifyDialog("Cannot launch",
                                    $"Encounter an network error during build environment: {ex.Message}");

                                break;
                            }
                    }
                }
                catch (Exception ex)
                {
                    Logging.TerminologyLogger.GetLogger()
                        .Error($"Cannot launch this instance because {ex}");
                    this.Engine.UiControl.MainWindow.PopupNotifyDialog("Cannot launch",
                        $"Caused by an internal error, we cannot launch this instance right now. Detail: {ex.Message}");
                }
                finally
                {
                    progressWindow.CrossThreadClose();
                }
            });
            progressWindow.ShowDialog();
        }
 public void MidLevel(InternalNodeProgress progress)
 {
     this.BottomLevelA(progress.CreateNewLeafSubProgress(50D, "MidLevel A"));
     this.BottomLevelB(progress.CreateNewLeafSubProgress(50, "MidLevel B"));
 }
        public string UpdateInstance(InternalNodeProgress progress, string instanceName)
        {
            TerminologyLogger.GetLogger().Info($"Start to update {instanceName}");
            var instanceInfo = this.InstanceBank.InstancesInfoList.First(x => (x.Name.Equals(instanceName)));

            var oldInstanceEntity =
                JsonConverter.Parse<InstanceEntity>(
                    File.ReadAllText(this.GetInstnaceFile(instanceInfo.Name)));
            this.CriticalInstanceFieldCheck(oldInstanceEntity);

            var newInstanceContent = DownloadUtils.GetWebContent(progress.CreateNewLeafSubProgress(
                $"Receiving {instanceInfo.Name} instance file", 50D), instanceInfo.UpdateUrl);
            var newInstanceEntity = JsonConverter.Parse<InstanceEntity>(newInstanceContent);
            progress.Percent = 60D;
            //Check instance is available to update
            if (newInstanceEntity.Version.Equals(oldInstanceEntity.Version))
            {
                progress.Percent = 100D;
                TerminologyLogger.GetLogger()
                    .InfoFormat(
                        $"Instacne {oldInstanceEntity.InstanceName} already at latest version {oldInstanceEntity.Version}");
                return (string.Format(TranslationManager.GetManager.Localize("InsatnceAtLatestVersion", "Instance now in latest version:{0}! Ignore update.", 1), newInstanceEntity.Version));
            }
            var updateSuccessfulInfo = TranslationManager.GetManager.Localize("InstanceUpdateToVersion",
                "Successful update instance file {0} from version {1} to {2}!", 3);
            switch (instanceInfo.InstanceState)
            {
                case InstanceState.PerInitialized:
                    {
                        this.RemoveInstance(instanceInfo.Name);
                        this.AddInstance(instanceInfo.UpdateUrl);
                        progress.Percent = 100D;
                        TerminologyLogger.GetLogger()
                            .InfoFormat(
                                $"Successful updated instance file {newInstanceEntity.InstanceName} from {oldInstanceEntity.Version} to {newInstanceEntity.Version}!");
                        return string.Format(updateSuccessfulInfo,
                       newInstanceEntity.InstanceName, oldInstanceEntity.Version, newInstanceEntity.Version);

                    }

                case InstanceState.Ok:
                    {
                        //TODO:I'll support instance name change at future version.
                        if (!newInstanceEntity.InstanceName.Equals(oldInstanceEntity.InstanceName))
                        {
                            throw new Exception("Old instance name not equal with new instance name.");
                        }

                        var instanceRootFolder = this.GetInstanceRootFolder(oldInstanceEntity.InstanceName);

                        #region Update files

                        #region Entire package
                        //Difference entire package will cause whole package target folder been delete

                        var newEntirePackages = newInstanceEntity.FileSystem.EntirePackageFiles ?? new List<EntirePackageFileEntity>();
                        var oldEntirePackages = oldInstanceEntity.FileSystem.EntirePackageFiles ?? new List<EntirePackageFileEntity>();
                        //Delete old entire package
                        foreach (var oldEntirePackageFileEntity in oldEntirePackages)
                        {
                            if (!newEntirePackages.Exists
                                    (
                                        x => x.Name.Equals(oldEntirePackageFileEntity.Name) &&
                                            x.Md5.Equals(oldEntirePackageFileEntity.Md5)
                                    )
                                )
                            {
                                FolderUtils.DeleteDirectory(Path.Combine(instanceRootFolder.FullName, oldEntirePackageFileEntity.LocalPath));
                            }
                        }
                        //Download new entire package
                        foreach (var newEntirePackageFileEntity in newEntirePackages)
                        {
                            if (!oldEntirePackages.Exists
                                (
                                    x =>
                                        x.Name.Equals(newEntirePackageFileEntity.Name) &&
                                        x.Md5.Equals(newEntirePackageFileEntity.Md5)
                                )
                                )
                            {
                                //TODO:Support progress
                                this.ReceiveEntirePackage(new InternalNodeProgress("Ignore"), newInstanceEntity.InstanceName,
                                    newEntirePackageFileEntity);
                            }
                        }
                        #endregion
                        progress.Percent = 80D;
                        #region Official files

                        var newOfficialFiles = newInstanceEntity.FileSystem.OfficialFiles ?? new List<OfficialFileEntity>();
                        var oldOfficialFiles = newInstanceEntity.FileSystem.OfficialFiles ?? new List<OfficialFileEntity>();
                        //Delete old official files
                        foreach (var oldOfficialFileEntity in oldOfficialFiles)
                        {
                            if (!newOfficialFiles.Exists(x => x.ProvideId.Equals(oldOfficialFileEntity.ProvideId)))
                            {
                                File.Delete(Path.Combine(instanceRootFolder.FullName, oldOfficialFileEntity.LocalPath));
                            }
                        }
                        //Receive new official files
                        foreach (var newOfficialFileEntity in newOfficialFiles)
                        {
                            if (!oldOfficialFiles.Exists(x => x.ProvideId.Equals(newOfficialFileEntity.ProvideId)))
                            {
                                this.ReceiveOfficialFile(new LeafNodeProgress("Ignore"), newInstanceEntity.InstanceName,
                                    newOfficialFileEntity, this.UsingFileRepository);
                            }
                        }
                        #endregion

                        progress.Percent = 90D;
                        #region Custom files

                        var newCustomFiles = newInstanceEntity.FileSystem.CustomFiles ?? new List<CustomFileEntity>();
                        var oldCustomFiles = oldInstanceEntity.FileSystem.CustomFiles ?? new List<CustomFileEntity>();
                        foreach (var oldCustomFileEntity in oldCustomFiles)
                        {
                            if (
                                !newCustomFiles.Exists(
                                    x => x.Name.Equals(oldCustomFileEntity.Name) && x.Md5.Equals(oldCustomFileEntity.Md5)))
                            {
                                File.Delete(Path.Combine(instanceRootFolder.FullName, oldCustomFileEntity.LocalPath));
                            }
                        }
                        foreach (var newCustomFileEntity in newCustomFiles)
                        {
                            if (!oldCustomFiles.Exists(x => x.Name.Equals(newCustomFileEntity.Name) && x.Md5.Equals(newCustomFileEntity.Md5)))
                            {
                                this.ReceiveCustomFile(new LeafNodeProgress("Ignore"), newInstanceEntity.InstanceName,
                                    newCustomFileEntity);
                            }
                        }
                        #endregion
                        progress.Percent = 100D;
                        #endregion

                        instanceInfo.UpdateDate = DateTime.Now.ToString("O");
                        this.SaveInstancesBankToFile();
                        File.WriteAllText(this.GetInstnaceFile(instanceInfo.Name), JsonConverter.ConvertToJson(newInstanceEntity));
                        TerminologyLogger.GetLogger()
                            .InfoFormat(
                                $"Successful updated entire instance {newInstanceEntity.InstanceName} from {oldInstanceEntity.Version} to {newInstanceEntity.Version}!");
                        return string.Format(updateSuccessfulInfo,
                            newInstanceEntity.InstanceName, oldInstanceEntity.Version, newInstanceEntity.Version);

                    }
                default:
                    {
                        throw new WrongStateException("Wrong instance state! Just instance which in OK or perinitialized state could update.");
                        break;
                    }

            }
        }