예제 #1
0
 public static Tasker SetProgress(this Tasker tasker, long value, long maximum, Tasker.State state, string status)
 {
     tasker.SetProgress(value, maximum);
     tasker.SetState(state);
     tasker.SetStatus(status);
     return(tasker);
 }
예제 #2
0
        public Tasker.Conclusion SyncLocalGames(Tasker tasker, Object syncObject = null)
        {
            // now transfer whatever games are remaining
            Debug.WriteLine("Exporting games: " + Shared.SizeSuffix(stats.TotalSize));
            long     max = transferGameSet.Sum(afi => afi.FileSize);
            long     value = 0;
            DateTime startTime = DateTime.Now, lastTime = DateTime.Now;

            tasker.SetProgress(0, max, Tasker.State.Running, Resources.CopyingGames);
            foreach (var afi in transferGameSet)
            {
                string path = new Uri(exportDirectory + "/" + afi.FilePath).LocalPath;
                string dir  = Path.GetDirectoryName(path);
                if (!Directory.Exists(dir))
                {
                    Directory.CreateDirectory(dir);
                }

                if (!string.IsNullOrEmpty(afi.LocalFilePath))
                {
                    File.Copy(afi.LocalFilePath, path, true);
                }
                else
                {
                    if (afi.FileStream == null || !afi.FileStream.CanRead)
                    {
                        Debug.WriteLine($"\"{afi.FilePath}\": no source data or stream or unreadable");
                    }
                    else
                    {
                        afi.FileStream.Position = 0;
                        using (var f = File.Open(path, FileMode.Create))
                            afi.FileStream.CopyTo(f);
                        File.SetLastWriteTimeUtc(path, afi.ModifiedTime);
                    }
                }
                value += afi.FileSize;

                if (DateTime.Now.Subtract(lastTime).TotalMilliseconds > UpdateFreq)
                {
                    transferForm.SetProgress(value, max, afi.FilePath);
                    lastTime = DateTime.Now;
                }
            }
            Debug.WriteLine("Uploaded " + (int)(max / 1024) + "kb in " + DateTime.Now.Subtract(startTime).TotalSeconds + " seconds");

            // show resulting games directory
            tasker.SetStatus(Resources.PleaseWait);
            var process = new Process()
            {
                StartInfo = new ProcessStartInfo()
                {
                    FileName = exportDirectory
                }
            };

            process.Start();

            return(Tasker.Conclusion.Success);
        }
예제 #3
0
        public static Conclusion WaitForShellCycle(Tasker tasker, Object syncObject = null)
        {
            var hostForm = tasker.GetSpecificViews <Form>().FirstOrDefault();

            if (hostForm == default(Form))
            {
                hostForm = tasker.HostForm;
            }
            if (hostForm.InvokeRequired)
            {
                return((Conclusion)hostForm.Invoke(new Func <Tasker, object, Conclusion>(WaitForShellCycle), new object[] { tasker, syncObject }));
            }

            tasker.SetStatus(Resources.WaitingForDevice);
            tasker.PushState(State.Waiting);
            var result = WaitingShellCycleForm.WaitForDevice(hostForm, MembootWaitDelay);

            tasker.PopState();
            if (result == DialogResult.OK)
            {
                return(Conclusion.Success);
            }

            return(Conclusion.Abort);
        }
예제 #4
0
        public Tasker.Conclusion CalculateRemoteDiff(Tasker tasker, Object syncObject = null)
        {
            // clean up previous directories (separate game storage vs not)
            tasker.SetStatus(Resources.CleaningUp);
            hakchi.Shell.ExecuteSimple("find \"" + (ConfigIni.Instance.UploadToTmp ? remoteTempDirectory : hakchi.RemoteGameSyncPath) + "/\" -maxdepth 1 | tail -n +2 " +
                                       "| grep -" + (ConfigIni.Instance.SeparateGameStorage ? "v" : "") + "Ee '(/hvcj-jpn?|/snes(-usa|-eur|-jpn)?|/nes(-usa|-jpn)?|/)$' " +
                                       "| while read f; do rm -rf \"$f\"; done", 0, true);

            // clean up symbolic links (they will be recreated if needed)
            hakchi.Shell.ExecuteSimple($"find \"{uploadPath}\" -type l | while read f; do rm \"$f\"; done", 0, true);

            // get the remote list of files, timestamps, and sizes
            tasker.SetStatus(Resources.CalculatingDiff);
            string gamesOnDevice = hakchi.Shell.ExecuteSimple($"mkdir -p \"{uploadPath}\"; cd \"{uploadPath}\"; find . -type f -exec sh -c \"stat \\\"{{}}\\\" -c \\\"%n %s %y\\\"\" \\;", 0, true);
            var    remoteGameSet = ApplicationFileInfo.GetApplicationFileInfoFromConsoleOutput(gamesOnDevice);

            // delete any remote files that aren't present locally
            var remoteGamesToDelete = remoteGameSet.Except(localGameSet);

            DeleteRemoteApplicationFiles(remoteGamesToDelete, uploadPath);

            // only keep the local files that aren't matching on the mini
            transferGameSet = localGameSet.Except(remoteGameSet);

            return(Tasker.Conclusion.Success);
        }
예제 #5
0
        public Conclusion MembootKexec(Tasker tasker, Object syncObject = null)
        {
            tasker.SetStatus(Resources.Membooting);
            if (!hakchi.Shell.IsOnline)
            {
                return(Conclusion.Abort);
            }

            // load appropriate kernel
            byte[] kernel;
            if (stockKernel != null && stockKernel.Length > 0)
            {
                kernel = stockKernel.ToArray();
            }
            else
            {
                stockKernel = null;
                kernel      = hakchi.Hmod.GetMembootImage().ToArray();
            }

            // memboot using kexec (no way to force clovershell or shell)
            try
            {
                hakchi.Shell.ExecuteSimple("uistop");
                hakchi.Shell.ExecuteSimple("mkdir -p /tmp/kexec/", throwOnNonZero: true);
                hakchi.UploadFile(
                    Path.Combine(Program.BaseDirectoryInternal, "tools", "arm", "kexec.static"),
                    "/tmp/kexec/kexec");
                hakchi.UploadFile(
                    Path.Combine(Program.BaseDirectoryInternal, "tools", "arm", "unpackbootimg.static"),
                    "/tmp/kexec/unpackbootimg");

                TrackableStream kernelStream = new TrackableStream(kernel);
                kernelStream.OnProgress += tasker.OnProgress;
                hakchi.Shell.Execute(
                    command: "cat > /tmp/kexec/boot.img; cd /tmp/kexec/; ./unpackbootimg -i boot.img",
                    stdin: kernelStream,
                    throwOnNonZero: true
                    );

                hakchi.Shell.ExecuteSimple("cd /tmp/kexec/ && ./kexec -l -t zImage boot.img-zImage \"--command-line=$(cat boot.img-cmdline)\" --ramdisk=boot.img-ramdisk.gz --atags", 0, true);
                hakchi.Shell.ExecuteSimple("cd /tmp/; umount -ar", 0);
                try
                {
                    hakchi.Shell.ExecuteSimple("/tmp/kexec/kexec -e", 100);
                }
                catch { } // no-op
            }
            catch
            {
                try
                {
                    hakchi.Shell.ExecuteSimple("uistart");
                }
                catch { } // no-op
                throw;
            }

            return(Conclusion.Success);
        }
예제 #6
0
        public static Conclusion WaitForShellCycle(Tasker tasker, Object syncObject = null, int maxWaitTime = -1, string title = null, string message = null)
        {
            var hostForm = tasker.GetSpecificViews <Form>().FirstOrDefault();

            if (hostForm == default(Form))
            {
                hostForm = tasker.HostForm;
            }
            if (hostForm.InvokeRequired)
            {
                return((Conclusion)hostForm.Invoke(new Func <Tasker, object, int, string, string, Conclusion>(WaitForShellCycle), new object[] { tasker, syncObject, maxWaitTime, title, message }));
            }

            tasker.SetStatus(Resources.WaitingForDevice);
            tasker.PushState(State.Waiting);
            var result = WaitingShellCycleForm.WaitForDevice(hostForm, maxWaitTime == -1 ? MembootWaitDelay : maxWaitTime);

            tasker.PopState();
            if (result == DialogResult.OK)
            {
                return(Conclusion.Success);
            }
            else if (result == DialogResult.No)
            {
                MessageForm.Show(hostForm, title == null ? Resources.WaitingForDevice : title, message == null ? Resources.WaitingForDeviceTakingALongTime : message, Resources.sign_clock);
            }

            return(Conclusion.Abort);
        }
예제 #7
0
        public static Conclusion BootHakchi(Tasker tasker, Object syncObject = null)
        {
            // Continue the hakchi boot process
            tasker.SetStatus(Resources.BootingHakchi);
            MemoryStream hakchiLogStream = new MemoryStream();
            var          splitStream     = new SplitterStream(hakchiLogStream).AddStreams(Program.debugStreams);

            tasker.PushState(State.Waiting);
            try
            {
                hakchi.Shell.Execute("boot", null, splitStream, splitStream, 0, true);
            }
            catch { }
            tasker.PopState();

            hakchiLogStream.Seek(0, SeekOrigin.Begin);
            string hakchiLog;

            using (StreamReader sr = new StreamReader(hakchiLogStream))
            {
                hakchiLog = sr.ReadToEnd();
            }
            foreach (string line in hakchiLog.Split(Convert.ToChar(0x0A)))
            {
                if (line.StartsWith("flash md5 mismatch! "))
                {
                    throw new Exception(line);
                }
            }

            return(Conclusion.Success);
        }
예제 #8
0
        public static Conclusion GetHmods(Tasker tasker, Object modObject)
        {
            if (!(modObject is ModObject))
            {
                return(Conclusion.Error);
            }
            ModObject unboxedObject = (ModObject)modObject;

            unboxedObject.LoadedHmods = new List <Hmod>();
            if (unboxedObject.HmodsToLoad == null)
            {
                return(Conclusion.Error);
            }
            tasker.SetStatus(Properties.Resources.LoadingHmods);
            int progress = 0;

            foreach (string mod in unboxedObject.HmodsToLoad)
            {
                unboxedObject.LoadedHmods.Add(new Hmod(mod, unboxedObject.InstalledHmods));
                progress++;
                tasker.SetProgress(progress, unboxedObject.HmodsToLoad.Count);
            }
            tasker.SetProgress(1, 1);
            return(Conclusion.Success);
        }
예제 #9
0
        public Conclusion WaitForFelOrMembootableShell(Tasker tasker, Object syncObject = null)
        {
            if (tasker.HostForm.InvokeRequired)
            {
                return((Conclusion)tasker.HostForm.Invoke(new Func <Tasker, Object, Conclusion>(WaitForFelOrMembootableShell), new object[] { tasker, syncObject }));
            }

            tasker.SetStatus(Resources.WaitingForDevice);
            if (hakchi.Shell.IsOnline && hakchi.Shell.Execute("[ -f /proc/atags ]") == 0)
            {
                return(Conclusion.Success);
            }

            if (!WaitingFelForm.WaitForDevice(Shared.ClassicUSB.vid, Shared.ClassicUSB.pid, tasker.HostForm))
            {
                return(Conclusion.Abort);
            }

            fel.Fes1Bin = Resources.fes1;
            if (ConfigIni.Instance.MembootUboot == Fel.UbootType.SD)
            {
                fel.UBootBin = Resources.ubootSD;
            }
            else
            {
                fel.UBootBin = Resources.uboot;
            }
            if (!fel.Open(Shared.ClassicUSB.vid, Shared.ClassicUSB.pid))
            {
                throw new FelException("Can't open device");
            }
            tasker.SetStatus(Resources.UploadingFes1);
            fel.InitDram(true);
            return(Conclusion.Success);
        }
예제 #10
0
 public Tasker.Conclusion PrepareRemoteTransfer(Tasker tasker, Object syncObject = null)
 {
     hakchi.ShowSplashScreen();
     hakchi.Shell.ExecuteSimple("hakchi eval 'umount \"$gamepath\"'");
     tasker.AddFinalTask(FinishRemoteTransfer);
     return(Tasker.Conclusion.Success);
 }
예제 #11
0
 public Tasker.Conclusion ShowExportDialog(Tasker tasker, Object syncObject = null)
 {
     if (tasker.HostForm.Disposing)
     {
         return(Tasker.Conclusion.Undefined);
     }
     if (tasker.HostForm.InvokeRequired)
     {
         return((Tasker.Conclusion)tasker.HostForm.Invoke(new Func <Tasker, Object, Tasker.Conclusion>(ShowExportDialog), new object[] { tasker, syncObject }));
     }
     tasker.SetStatus(Resources.SelectDrive);
     try
     {
         using (ExportGamesDialog driveSelectDialog = new ExportGamesDialog())
         {
             tasker.PushState(Tasker.State.Paused);
             var result = driveSelectDialog.ShowDialog() == DialogResult.OK;
             tasker.PopState();
             if (!result)
             {
                 return(Tasker.Conclusion.Abort);
             }
             this.exportLinked    = driveSelectDialog.LinkedExport;
             this.exportDirectory = driveSelectDialog.ExportPath;
             if (!Directory.Exists(driveSelectDialog.ExportPath))
             {
                 Directory.CreateDirectory(driveSelectDialog.ExportPath);
             }
         }
         copyMode = exportLinked ? NesApplication.CopyMode.LinkedExport : NesApplication.CopyMode.Export;
         return(Tasker.Conclusion.Success);
     }
     catch (InvalidOperationException) { }
     return(Tasker.Conclusion.Abort);
 }
예제 #12
0
        public static DialogResult SelectFile(Tasker tasker, string[] files)
        {
            if (tasker.HostForm.Disposing)
            {
                return(DialogResult.Cancel);
            }
            if (tasker.HostForm.InvokeRequired)
            {
                return((DialogResult)tasker.HostForm.Invoke(new Func <Tasker, string[], DialogResult>(SelectFile), new object[] { tasker, files }));
            }
            try
            {
                using (var form = new SelectFileForm(files))
                {
                    tasker.PushState(Tasker.State.Paused);
                    var result = form.ShowDialog();
                    tasker.PopState();
                    selectedFile = form.listBoxFiles.SelectedItem != null?form.listBoxFiles.SelectedItem.ToString() : null;

                    return(result);
                }
            }
            catch (InvalidOperationException) { }
            return(DialogResult.Cancel);
        }
예제 #13
0
        // --- update listview ui element
        public Tasker.Conclusion UpdateListView(Tasker tasker, Object syncObject = null)
        {
            if (ListViewGames.Disposing)
            {
                return(Tasker.Conclusion.Undefined);
            }
            if (ListViewGames.InvokeRequired)
            {
                return((Tasker.Conclusion)ListViewGames.Invoke(new Func <Tasker, Object, Tasker.Conclusion>(UpdateListView), new object[] { tasker, syncObject }));
            }

            var sync = (LoadGamesSyncObject)syncObject;

            try
            {
                ListViewGames.BeginUpdate();
                ListViewGames.Groups.Clear();
                ListViewGames.Items.Clear();
                ListViewGames.Groups.AddRange(sync.groups);
                ListViewGames.Items.AddRange(sync.items);
            }
            catch (InvalidOperationException) { }
            finally
            {
                ListViewGames.EndUpdate();
            }
            return(Tasker.Conclusion.Success);
        }
예제 #14
0
        public Tasker.Conclusion ResetROMHeaders(Tasker tasker, Object SyncObject = null)
        {
            tasker.SetTitle(Resources.ResettingHeaders);
            tasker.SetStatusImage(Resources.sign_database);
            tasker.SetProgress(-1, -1, Tasker.State.Running, Resources.ResettingHeaders);

            int i = 0;

            foreach (NesApplication game in Games)
            {
                if (game is SnesGame && !(game as SnesGame).IsOriginalGame)
                {
                    tasker.SetStatus(string.Format(Resources.ResettingHeader, game.Name));
                    bool wasCompressed = game.DecompressPossible().Length > 0;
                    if (wasCompressed)
                    {
                        game.Decompress();
                    }
                    SfromToolWrapper.ResetSFROM(game.GameFilePath);
                    if (wasCompressed)
                    {
                        game.Compress();
                    }
                }
                else
                {
                    tasker.SetStatus(string.Format(Resources.Skipping, game.Name));
                    Thread.Sleep(1);
                }

                tasker.SetProgress(++i, Games.Count);
            }

            return(Tasker.Conclusion.Success);
        }
예제 #15
0
        private void buttonAccept_Click(object sender, EventArgs e)
        {
            using (var tasker = new Tasks.Tasker(this))
            {
                tasker.AttachView(new Tasks.TaskerTaskbar());
                tasker.AttachView(new Tasks.TaskerForm());
                var task = new Tasks.GameTask();
                for (int i = 0; i < listViewGames.Items.Count; ++i)
                {
                    var gameItem = listViewGames.Items[i];
                    if (gameItem.SubItems[4].Text != Resources.DefaultNoChange)
                    {
                        var game = gameItem.Tag as NesApplication;
                        foreach (var coverMatch in game.CoverArtMatches)
                        {
                            if (Path.GetFileName(coverMatch) == gameItem.SubItems[4].Text)
                            {
                                task.GamesChanged[game] = coverMatch;
                                break;
                            }
                        }
                    }
                }
                tasker.AddTask(task.SetCoverArtForMultipleGames);
                var conclusion = tasker.Start();
            }

            DialogResult = DialogResult.OK;
            Close();
        }
예제 #16
0
        public Tasker.Conclusion DeleteGames(Tasker tasker, Object SyncObject = null)
        {
            tasker.SetTitle(Resources.RemovingGames);
            tasker.SetStatusImage(Resources.sign_trashcan);
            tasker.SetProgress(-1, -1, Tasker.State.Running, Resources.RemovingGames);

            int i = 0;

            foreach (NesApplication game in Games)
            {
                if (!game.IsOriginalGame)
                {
                    tasker.SetStatus(string.Format(Resources.Removing, game.Name));
                    game.IsDeleting = true;
                    Directory.Delete(game.BasePath, true);
                    tasker.SetProgress(++i, Games.Count);
                }
                else
                {
                    tasker.SetStatus(string.Format(Resources.Skipping, game.Name));
                    Thread.Sleep(1);
                }
            }

            return(Tasker.Conclusion.Success);
        }
예제 #17
0
        public Tasker.Conclusion DecompressGames(Tasker tasker, Object SyncObject = null)
        {
            tasker.SetTitle(Resources.DecompressingGames);
            tasker.SetStatusImage(Resources.sign_cogs);
            tasker.SetProgress(-1, -1, Tasker.State.Running, Resources.DecompressingGames);

            int i = 0;

            foreach (NesApplication game in Games)
            {
                if (!game.IsOriginalGame)
                {
                    tasker.SetStatus(string.Format(Resources.Decompressing, game.Name));
                    game.Decompress();
                    tasker.SetProgress(++i, Games.Count);
                }
                else
                {
                    tasker.SetStatus(string.Format(Resources.Skipping, game.Name));
                    Thread.Sleep(1);
                }
            }

            return(Tasker.Conclusion.Success);
        }
예제 #18
0
        public Conclusion FlashKernel(Tasker tasker, Object syncObject = null)
        {
            tasker.SetStatus(Resources.UploadingKernel);
            if (stockKernel == null || stockKernel.Length == 0)
            {
                return(Conclusion.Error);
            }

            stockKernel.Seek(0, SeekOrigin.Begin);
            hakchi.Shell.Execute("cat > /kernel.img", stockKernel, null, null, 0, true);

            if (hakchi.Shell.Execute("sntool check /kernel.img") != 0)
            {
                throw new Exception(Resources.KernelCheckFailed);
            }

            hakchi.Shell.Execute("sntool kernel /kernel.img", null, null, null, 0, true);

            if (hakchi.Shell.Execute("hakchi flashBoot2 /kernel.img") != 0)
            {
                throw new Exception(Resources.VerifyFailed);
            }

            return(Conclusion.Success);
        }
예제 #19
0
        public Tasker.Conclusion ExportGames(Tasker tasker, Object syncObject = null)
        {
            // get specialized view
            transferForm = tasker.GetSpecificViews <TaskerTransferForm>().First();

            // set up progress bar
            tasker.SetTitle(Resources.ExportGames);
            tasker.SetState(Tasker.State.Starting);
            tasker.SetStatusImage(Resources.sign_up);

            // safeguard
            if (Games == null || Games.Count == 0)
            {
                return(Tasker.Conclusion.Error);
            }

            // add sub-tasks
            tasker.AddTask(ShowExportDialog, 0);
            tasker.AddTask(BuildMenu, 0);
            tasker.AddTask(BuildFiles, 1);
            tasker.AddTask(CheckLocalStorageRequirements, 1);
            tasker.AddTask(CalculateLocalDiff, 1);
            tasker.AddTask(SyncLocalGames, 12);

            return(Tasker.Conclusion.Success);
        }
예제 #20
0
        public Tasker.Conclusion ScanCovers(Tasker tasker, Object SyncObject = null)
        {
            tasker.SetTitle(Resources.ScanningCovers);
            tasker.SetStatusImage(Resources.sign_file_picture);
            tasker.SetProgress(-1, -1, Tasker.State.Running, Resources.ScanningCovers);
            var unknownApps = new List <NesApplication>();
            int i           = 0;

            foreach (NesApplication game in Games)
            {
                tasker.SetStatus(string.Format(Resources.ScanningCover, game.Name));
                try
                {
                    uint   crc32    = game.Metadata.OriginalCrc32;
                    string gameFile = game.GameFilePath;
                    if (crc32 == 0 && !game.IsOriginalGame && gameFile != null && File.Exists(gameFile))
                    {
                        using (var stream = game.GameFileStream)
                        {
                            if (stream != null)
                            {
                                stream.Position             = 0;
                                crc32                       = Shared.CRC32(stream);
                                game.Metadata.OriginalCrc32 = crc32;
                                game.SaveMetadata();
                            }
                        }
                    }
                    else
                    {
                        gameFile = game.BasePath;
                    }
                    game.FindCover(game.Metadata.OriginalFilename ?? Path.GetFileName(gameFile), crc32, game.Name);
                    if (!game.CoverArtMatchSuccess && game.CoverArtMatches.Any())
                    {
                        unknownApps.Add(game);
                    }
                }
                catch (Exception ex)
                {
                    Debug.WriteLine("Error trying to finding cover art for game " + game.Name);
                    Debug.WriteLine(ex.Message + ex.StackTrace);
                }
                tasker.SetProgress(++i, Games.Count);
            }

            if (unknownApps.Count > 0)
            {
                tasker.HostForm.Invoke(new Action(() => {
                    using (SelectCoverDialog selectCoverDialog = new SelectCoverDialog())
                    {
                        selectCoverDialog.Games.AddRange(unknownApps);
                        selectCoverDialog.ShowDialog(tasker.HostForm);
                    }
                }));
            }

            return(Tasker.Conclusion.Success);
        }
예제 #21
0
        internal Tasker.Conclusion ArchiveGames(Tasker tasker, object syncObject)
        {
            long counter   = 0;
            long gameCount = Games.Count;

            tasker.SetTitle(gameCount > 1 ? Resources.ArchivingGames : Resources.ArchivingGame);

            string directory = null;

            if (gameCount > 1)
            {
                using (var fbd = new FolderBrowserDialog()
                {
                    SelectedPath = Program.BaseDirectoryExternal
                })
                {
                    if (fbd.ShowDialog() == DialogResult.OK)
                    {
                        directory = fbd.SelectedPath;
                    }
                    else
                    {
                        return(Tasker.Conclusion.Abort);
                    }
                }
            }

            foreach (var game in Games)
            {
                tasker.SetStatus(String.Format(Resources.Archiving, game.Name));
                var fileName = Shared.ReplaceInvalidFilenameCharacters($"{game.Code} - {game.Name}.clvg");

                if (directory == null)
                {
                    using (var sfd = new SaveFileDialog()
                    {
                        Filter = Resources.GameArchive + "(*.clvg)|*.clvg", FileName = fileName
                    })
                    {
                        if (sfd.ShowDialog() == DialogResult.OK)
                        {
                            game.Archive(sfd.FileName);
                        }
                    }
                }
                else
                {
                    var archivePath = Path.Combine(directory, fileName);
                    if (File.Exists(archivePath) && tasker.ShowMessage(Resources.ReplaceFileQ, String.Format(Resources.ReplaceFollowingFileQ, archivePath), Resources.sign_question, new MessageForm.Button[] { MessageForm.Button.Yes, MessageForm.Button.No }) == MessageForm.Button.No)
                    {
                        continue;
                    }
                    game.Archive(archivePath);
                }
                counter++;
                tasker.SetProgress(counter, gameCount);
            }
            return(Tasker.Conclusion.Success);
        }
예제 #22
0
 public Tasker.Conclusion RemoteCleanup(Tasker tasker, Object syncObject = null)
 {
     // delete any empty directories we may have left during the differential sync
     tasker.SetStatus(Resources.CleaningUp);
     hakchi.Shell.ExecuteSimple($"for f in $(find \"{uploadPath}\" -type d -mindepth 1 -maxdepth 2); do {{ find \"$f\" -type f -mindepth 1 | grep -v pixelart | grep -v autoplay " +
                                "| wc -l | { read wc; test $wc -eq 0 && rm -rf \"$f\"; } } ; done", 0);
     return(Tasker.Conclusion.Success);
 }
예제 #23
0
        public Tasker.Conclusion SyncRemoteGamesShell(Tasker tasker, Object syncObject = null)
        {
            // transfer games
            tasker.SetProgress(0, 100, Tasker.State.Running, Resources.UploadingGames);
            bool uploadSuccessful = false;

            if (!transferGameSet.Any())
            {
                Trace.WriteLine("No file to upload");
                uploadSuccessful = true;
            }
            else
            {
                Trace.WriteLine("Uploading through tar file");
                using (var gamesTar = new TarStream(transferGameSet, "."))
                {
                    Trace.WriteLine($"Upload size: " + Shared.SizeSuffix(gamesTar.Length));
                    if (gamesTar.Length > 0)
                    {
                        DateTime startTime = DateTime.Now, lastTime = DateTime.Now;
                        bool     done = false;
                        gamesTar.OnAdvancedReadProgress += delegate(long pos, long len, string filename)
                        {
                            if (done)
                            {
                                return;
                            }
                            if (DateTime.Now.Subtract(lastTime).TotalMilliseconds >= UpdateFreq)
                            {
                                transferForm.SetAdvancedProgress(pos, len, filename);
                                lastTime = DateTime.Now;
                            }
                        };
                        hakchi.Shell.Execute($"tar -xvC \"{uploadPath}\"", gamesTar, null, null, 0, true);
                        Trace.WriteLine("Uploaded " + (int)(gamesTar.Length / 1024) + "kb in " + DateTime.Now.Subtract(startTime).TotalSeconds + " seconds");

                        uploadSuccessful = true;
                        done             = true;
#if VERY_DEBUG
                        File.Delete(Program.BaseDirectoryExternal + "\\DebugSyncOutput.tar");
                        gamesTar.Position = 0;
                        gamesTar.CopyTo(File.OpenWrite(Program.BaseDirectoryExternal + "\\DebugSyncOutput.tar"));
#endif
                    }
                    transferForm.SetAdvancedProgress(gamesTar.Length, gamesTar.Length, "");
                }
            }

            // don't continue if upload wasn't successful
            if (!uploadSuccessful)
            {
                Trace.WriteLine("Something happened during transfer, cancelling");
                return(Tasker.Conclusion.Error);
            }

            return(Tasker.Conclusion.Success);
        }
예제 #24
0
        public static Conclusion Memboot(Tasker tasker, Object syncObject = null)
        {
            tasker.SetStatus(Resources.Membooting);
            if (!hakchi.Shell.IsOnline)
            {
                return(Conclusion.Abort);
            }

            // get kernel image (only custom kernel with this method)
            byte[] kernel = hakchi.Hmod.GetMembootImage().ToArray();

            // override arguments
            string addedArgs = "";

            if (ConfigIni.Instance.ForceClovershell)
            {
                addedArgs = " hakchi-clovershell";
            }
            else if (ConfigIni.Instance.ForceNetwork)
            {
                addedArgs = " hakchi-shell";
            }

            // use detached-fallback script and up-to-date boot.img
            try
            {
                hakchi.Shell.ExecuteSimple("uistop");
                hakchi.Shell.ExecuteSimple("mkdir -p /tmp/kexec/", throwOnNonZero: true);
                hakchi.UploadFile(
                    Path.Combine(Program.BaseDirectoryInternal, "tools", "arm", "kexec.static"),
                    "/tmp/kexec/kexec");
                hakchi.UploadFile(
                    Path.Combine(Program.BaseDirectoryInternal, "tools", "arm", "detached-fallback"),
                    "/tmp/kexec/detached-fallback");

                TrackableStream kernelStream = new TrackableStream(kernel);
                kernelStream.OnProgress += tasker.OnProgress;
                hakchi.UploadFile(kernelStream, "/tmp/kexec/boot.img", false);

                try
                {
                    hakchi.Shell.ExecuteSimple("cd /tmp/kexec/; /bin/sh /tmp/kexec/detached-fallback recovery /tmp/kexec/boot.img" + addedArgs, 100);
                }
                catch { } // no-op
            }
            catch
            {
                try
                {
                    hakchi.Shell.ExecuteSimple("uistart");
                }
                catch { } // no-op
                throw;
            }

            return(Conclusion.Success);
        }
예제 #25
0
        public Conclusion MembootFel(Tasker tasker, Object syncObject = null)
        {
            tasker.SetStatus(Resources.Membooting);
            if (hakchi.Shell.IsOnline)
                return Conclusion.Abort;

            // check and adjust kernel size
            byte[] kernel = hakchi.GetMembootImage().ToArray();
            var size = Shared.CalcKernelSize(kernel);
            if (size > kernel.Length || size > Fel.transfer_max_size)
                throw new Exception(Resources.InvalidKernelSize + " " + size);
            size = (size + Fel.sector_size - 1) / Fel.sector_size;
            size = size * Fel.sector_size;
            if (kernel.Length != size)
            {
                var newK = new byte[size];
                Array.Copy(kernel, newK, kernel.Length);
                kernel = newK;
            }

            // clovershell override "hex-edit" boot.img
            if (ConfigIni.Instance.ForceClovershell || ConfigIni.Instance.ForceNetwork)
            {
                kernel.InPlaceStringEdit(64, 512, 0, (string str) => {
                    str.Replace("hakchi-shell", "").Replace("hakchi-clovershell", "");
                    if (ConfigIni.Instance.ForceClovershell)
                        str += " hakchi-clovershell";
                    else if (ConfigIni.Instance.ForceNetwork)
                        str += " hakchi-shell";
                    return str;
                });
            }

            // upload kernel through fel
            int progress = 0;
            int maxProgress = (int)((double)kernel.Length / (double)67000 + 50);
            fel.WriteMemory(Fel.transfer_base_m, kernel,
                delegate (Fel.CurrentAction action, string command)
                {
                    switch (action)
                    {
                        case Fel.CurrentAction.WritingMemory:
                            tasker.SetStatus(Resources.UploadingKernel);
                            break;
                    }
                    progress++;
                    tasker.SetProgress(progress, maxProgress);
                }
            );

            var bootCommand = string.Format("boota {0:x}", Fel.transfer_base_m);
            tasker.SetStatus(Resources.ExecutingCommand + " " + bootCommand);
            fel.RunUbootCmd(bootCommand, true);

            return Conclusion.Success;
        }
예제 #26
0
        public static Conclusion Reboot(Tasker tasker = null, Object syncObject = null)
        {
            tasker?.SetStatus(Resources.Rebooting);
            try
            {
                hakchi.Shell.ExecuteSimple("sync; umount -ar; reboot -f", 100);
            } catch { }

            return(Conclusion.Success);
        }
예제 #27
0
        public static Conclusion Shutdown(Tasker tasker = null, Object syncObject = null)
        {
            tasker?.SetStatus(Resources.PoweringOff);
            try
            {
                hakchi.Shell.ExecuteSimple("sync; umount -ar; poweroff -f", 100);
            }
            catch { }

            return(Conclusion.Success);
        }
예제 #28
0
 public Conclusion BootBackup2(Tasker tasker, object syncObject)
 {
     tasker.SetStatus(Resources.Membooting);
     try
     {
         hakchi.Shell.Execute("hakchi bootBackup2");
     } catch {
         // no-op
     }
     return(Conclusion.Success);
 }
예제 #29
0
        public Tasker.Conclusion DownloadCovers(Tasker tasker, Object SyncObject = null)
        {
            tasker.SetTitle(Resources.DownloadAllCoversTitle);
            tasker.SetStatusImage(Resources.sign_globe);
            tasker.SetProgress(-1, -1, Tasker.State.Running, Resources.DownloadAllCoversTitle);
            int i = 0;

            foreach (NesApplication game in Games)
            {
                tasker.SetStatus(Resources.GooglingFor.Trim() + " " + game.Name + "...");
                string[] urls = null;
                for (int tries = 0; tries < 5; tries++)
                {
                    if (urls == null)
                    {
                        try
                        {
                            urls = ImageGooglerForm.GetImageUrls(game);
                            break;
                        }
                        catch (Exception ex)
                        {
                            tasker.SetStatus(Resources.Error + ": " + ex.Message);
                            Thread.Sleep(1500);
                            continue;
                        }
                    }
                }
                if (urls != null && urls.Length == 0)
                {
                    tasker.SetStatus(Resources.NotFound + " " + game.Name);
                }
                for (int tries = 0; urls != null && tries < 5 && tries < urls.Length; tries++)
                {
                    try
                    {
                        var cover = ImageGooglerForm.DownloadImage(urls[tries]);
                        game.Image = cover;
                        break;
                    }
                    catch (Exception ex)
                    {
                        tasker.SetStatus(Resources.Error + ": " + ex.Message);
                        Thread.Sleep(1500);
                        continue;
                    }
                }
                tasker.SetProgress(++i, Games.Count);
                Thread.Sleep(500); // not so fast, Google don't like it
            }
            return(Tasker.Conclusion.Success);
        }
예제 #30
0
 private void TaskerTransferForm_FormClosing(object sender, FormClosingEventArgs e)
 {
     if (!isClosing && e.CloseReason == CloseReason.UserClosing)
     {
         // make more checks to bypass question when appropriate
         if (Tasker.ShowMessage(Resources.AreYouSure, Resources.DoYouWantCancel, Resources.sign_warning, new MessageForm.Button[] { MessageForm.Button.Yes, MessageForm.Button.No }, MessageForm.DefaultButton.Button2) == MessageForm.Button.Yes)
         {
             Tasker.Abort();
             return;
         }
         e.Cancel = true;
     }
 }