Пример #1
0
        public string ExtractGame(Game game, EmulatorProfile profile = null, ExecutorLaunchProgressHandler progressHandler = null)
        {
            if (profile == null || profile.EmulatorID != game.ParentEmulator.UID)
            {
                profile = game.GetSelectedProfile();
            }

            lock (syncRoot)
            {
                if (progressHandler != null)
                {
                    progressHandler("Loading archive...", 0);
                }

                if (!loadArchive(game.CurrentDisc.Path))
                {
                    throw new ExtractException("{0} {1}", Translator.Instance.goodmergearchiveerror, game.CurrentDisc.Path);
                }

                using (extractor)
                {
                    List <IArchiveEntry> entries;
                    if (extractor.Entries == null || (entries = extractor.Entries.Where(e => !e.IsDirectory).ToList()).Count < 1)
                    {
                        Logger.LogError("Goodmerge: Archive '{0}' appears to be empty");
                        throw new ExtractException(Translator.Instance.goodmergeempty);
                    }

                    if (progressHandler != null)
                    {
                        progressHandler("Selecting file...", 0);
                    }
                    IArchiveEntry selectedEntry = selectEntry(entries, game.CurrentDisc.LaunchFile, profile.GetGoodmergeTags());
                    Logger.LogDebug("Goodmerge: Selected entry {0}", selectedEntry.FilePath);

                    string cacheKey = string.Format("{0}****{1}", game.CurrentDisc.Path, selectedEntry.FilePath);
                    string extractionPath;
                    if (isInCache(cacheKey, out extractionPath))
                    {
                        Logger.LogDebug("Goodmerge: Using cached file '{0}'", extractionPath);
                        return(extractionPath);
                    }

                    extractionPath = Path.Combine(GoodmergeTempPath, GOODMERGE_FILENAME_PREFIX + game.Filename);
                    string extractedFile = extractFile(extractor, selectedEntry, extractionPath, progressHandler);
                    if (extractedFile != null)
                    {
                        addToCache(cacheKey, extractedFile);
                    }

                    return(extractedFile);
                }
            }
        }
Пример #2
0
        /// <summary>
        /// Launches the specified game using the specified profile. If the specified profile is null
        /// the game's configured profile is used. If isConfig is true then any suspend settings are ignored
        /// and the specified game's playcount and playdate are not updated.
        /// </summary>
        /// <param name="game"></param>
        /// <param name="isConfig">Whether the game is being launched by Configuration. Default false.</param>
        /// <param name="profile">The profile to use when launching the game.</param>
        public void LaunchGame(string path, EmulatorProfile profile, ExecutorLaunchProgressHandler launchProgressChanged = null)
        {
            if (profile == null)
            {
                throw new LaunchException("Profile cannot be null");
            }

            bool isPC     = profile.EmulatorID == -1;
            bool isConfig = Emulators2Settings.Instance.IsConfig;

            ExecutorItem exeItem = new ExecutorItem(isPC);

            exeItem.Arguments = profile.Arguments;
            exeItem.Suspend   = !isConfig && profile.SuspendMP == true;
            if (profile.DelayResume && profile.ResumeDelay > 0)
            {
                exeItem.ResumeDelay = profile.ResumeDelay;
            }

            if (isPC)
            {
                exeItem.Path = path;
                if (!string.IsNullOrEmpty(profile.LaunchedExe))
                {
                    try { exeItem.LaunchedExe = Path.GetFileNameWithoutExtension(profile.LaunchedExe); }
                    catch { exeItem.LaunchedExe = profile.LaunchedExe; }
                }
            }
            else
            {
                exeItem.Path    = profile.EmulatorPath;
                exeItem.RomPath = path;
                exeItem.Mount   = profile.MountImages && DaemonTools.IsImageFile(Path.GetExtension(path));
                exeItem.ShouldReplaceWildcards = !exeItem.Mount;
                exeItem.UseQuotes          = profile.UseQuotes == true;
                exeItem.CheckController    = profile.CheckController;
                exeItem.StopEmulationOnKey = profile.StopEmulationOnKey.HasValue ? profile.StopEmulationOnKey.Value : Options.Instance.GetBoolOption("domap");
                exeItem.EscapeToExit       = profile.EscapeToExit;
            }
            exeItem.PreCommand = new LaunchCommand()
            {
                Command = profile.PreCommand, WaitForExit = profile.PreCommandWaitForExit, ShowWindow = profile.PreCommandShowWindow
            };
            exeItem.PostCommand = new LaunchCommand()
            {
                Command = profile.PostCommand, WaitForExit = profile.PostCommandWaitForExit, ShowWindow = profile.PostCommandShowWindow
            };
            exeItem.Init();

            //stop any media playing
            if (!isConfig && Options.Instance.GetBoolOption("stopmediaplayback") && MediaPortal.Player.g_Player.Playing)
            {
                Logger.LogDebug("Stopping playing media...");
                MediaPortal.Player.g_Player.Stop();
            }

            lock (launchSync)
            {
                launchGame(exeItem, launchProgressChanged);
            }
        }
Пример #3
0
        void launchGame(ExecutorItem exeItem, ExecutorLaunchProgressHandler launchProgressChanged)
        {
            Dispose();

            if (exeItem.Mount)
            {
                if (launchProgressChanged != null)
                {
                    launchProgressChanged("Mounting...", 75);
                }
                mountImage(exeItem.RomPath);
            }
            else if (launchProgressChanged != null)
            {
                launchProgressChanged("Launching...", 75);
            }

            List <int> pIds = new List <int>();

            initProc(exeItem, new EventHandler((o, e) => { onExit(exeItem, pIds); }));

            Logger.LogInfo("Launching with arguments '{1} {2}'", exeItem.Path, exeItem.Arguments);
            if (launchProgressChanged != null)
            {
                launchProgressChanged("Launching...", 100);
            }

            if (exeItem.CheckController && !ControllerHandler.CheckControllerState())
            {
                Emulators2Settings.Instance.ShowMPDialog(Translator.Instance.nocontrollerconnected);
            }

            if (exeItem.Suspend)
            {
                suspendMP(true); //suspend MediaPortal rendering
            }
            //run pre-command
            exeItem.PreCommand.Run();

            //if we're a launcher get id of all processes currently running with the same name so they can be excluded when looking for launched process
            if (!string.IsNullOrEmpty(exeItem.LaunchedExe))
            {
                foreach (Process p in Process.GetProcessesByName(exeItem.LaunchedExe))
                {
                    pIds.Add(p.Id);
                }
            }

            //start emulator
            bool result;

            try
            {
                result = proc.Start();
            }
            catch (Exception ex)
            {
                result = false;
                Logger.LogError("Exception starting {0} - {1}", exeItem.Path, ex.Message);
            }

            if (!result)
            {
                Logger.LogWarn("Failed to start {0}", exeItem.Path);
                onExit(exeItem, null, false);
                throw new LaunchException("{0} did not start", exeItem.Path);
            }

            //send status changed event
            if (StatusChanged != null)
            {
                StatusChanged(true);
            }

            //setup keyboard hook if configured and we're not launching a PC Game (they should have their own way of exiting)
            if (exeItem.StopEmulationOnKey)
            {
                setupKeyboardHook(exeItem.EscapeToExit);
            }
        }
Пример #4
0
        string extractFile(IArchive extractor, IArchiveEntry selectedEntry, string extractionPath, ExecutorLaunchProgressHandler progressHandler = null)
        {
            if (progressHandler != null)
            {
                progressHandler("Creating directory...", 0);
            }

            if (!createExtractionDirectory(extractionPath, selectedEntry.FilePath))
            {
                Logger.LogError("Goodmerge: Unable to find alternate extract directory, hard-coded limit has been reached - check '{0}' for any leftover files", GoodmergeTempPath);
                throw new ExtractException(Translator.Instance.goodmergefileerror);
            }

            Logger.LogDebug("Goodmerge: Extracting file '{0}' to directory '{1}'...", selectedEntry.FilePath, extractionPath);
            if (progressHandler != null)
            {
                progressHandler("Extracting...", 0);
                long totalSize = selectedEntry.Size;

                extractor.EntryExtractionBegin += (sender, e) =>
                {
                    Logger.LogDebug("EntryExtractionBegin {0}", e.Item.FilePath);
                };
                extractor.FilePartExtractionBegin += (sender, e) =>
                {
                    Logger.LogDebug("FilePartExtractionBegin {0}, compressed: {1}kb, total: {2}kb", e.Name, e.CompressedSize / 1024, e.Size / 1024);
                };
                extractor.CompressedBytesRead += (sender, e) =>
                {
                    Logger.LogDebug("CompressedBytesRead {0}, current: {1}kb, total: {2}kb", e.CurrentFilePartCompressedBytesRead / 1024, e.CompressedBytesRead / 1024);
                    int perc = (int)((e.CurrentFilePartCompressedBytesRead * 100) / totalSize);
                    progressHandler(string.Format("Extracting ({0}%)...", perc), perc);
                };
                extractor.EntryExtractionEnd += (sender, e) =>
                {
                    Logger.LogDebug("Extraction complete {0}", e.Item.FilePath);
                    progressHandler("Extraction complete...", 100);
                };
            }

            Logger.LogDebug("Extracting {0}, {1}kb", selectedEntry.FilePath, selectedEntry.Size / 1024);
            string outputFile = Path.Combine(extractionPath, selectedEntry.FilePath);

            try
            {
                selectedEntry.WriteToFile(outputFile);
            }
            catch (Exception ex)
            {
                Logger.LogError("Goodmerge: Error extracting to directory '{0}' - {1}", extractionPath, ex.Message);
                throw new ExtractException(Translator.Instance.goodmergeextracterror);
            }
            return(outputFile);
        }