Example #1
0
        public int Merge(MainEntity toMerge, MergerConfiguration conf)
        {
            toMerge.NotNull("mainEntity");

            var oldExpressions = _dataAccess.GetAllExpressions();

            if (conf.ImportStatisticsForOld)
            {
                UpdateStatistics(toMerge.Expressions, oldExpressions);
            }

            MergeExpressionsWithUnknownTranslations(toMerge.Expressions, oldExpressions, conf);

            return(MergeUnknownExpressions(toMerge.Expressions, oldExpressions, conf));
        }
Example #2
0
        /// <summary>
        /// Given an original manga gamer script file, attempts to detect which channel is used for BGM
        /// As input it needs to know the filenames of the BGM music files.
        /// It obtains this from the MergerConfiguration argument (the .toml file)
        /// It also uses the bgm length threshold to determine the difference between a BGM and a sound effect.
        /// </summary>
        /// <param name="mgScriptPath"></param>
        /// <param name="configuration"></param>
        /// <returns></returns>
        public static int?DetectBGMChannel(string mgScriptPath, MergerConfiguration configuration)
        {
            Dictionary <int, int> channelCounter = new Dictionary <int, int>();

            using (StreamReader mgScript = new StreamReader(mgScriptPath, Encoding.UTF8))
            {
                //Count how many times each channel plays a BGM
                //channel is considered to play a BGM if the file being played is longer than the configured length
                string line;
                while ((line = mgScript.ReadLine()) != null)
                {
                    int?maybeBGMChannel = TryGetBGMMusicChannelOnSingleLine(line, searchFolders: configuration.bgm_folders, bgmLengthThresholdSeconds: configuration.music_threshold_seconds);
                    if (maybeBGMChannel != null)
                    {
                        int BGMChannel = (int)maybeBGMChannel;
                        if (channelCounter.ContainsKey(BGMChannel))
                        {
                            channelCounter[BGMChannel] += 1;
                        }
                        else
                        {
                            channelCounter[BGMChannel] = 0;
                        }
                    }
                }

                //TODO: Debug - remove later
                foreach (KeyValuePair <int, int> item in channelCounter)
                {
                    Console.WriteLine($"channel: {item.Key} count: {item.Value}");
                }

                //return the channel which has the max number of BGM plays
                foreach (KeyValuePair <int, int> item in channelCounter.OrderByDescending(key => key.Value))
                {
                    return(item.Key);
                }
            }

            //if no playBGMs were found, return null
            return(null);
        }
Example #3
0
        /// <summary>
        /// Same as DetectBGMChannel() but if bgm channel couldn't be detected, uses user supplied default
        /// </summary>
        /// <returns></returns>
        public static int DetectBGMChannelOrDefault(string mgScriptPath, MergerConfiguration configuration, int defaultChannel, bool PrintOnFoundChannelAndWarnings)
        {
            int?maybeBGMChannel = MGScriptBGMChannelDetector.DetectBGMChannel(mgScriptPath, configuration);

            if (maybeBGMChannel != null)
            {
                if (PrintOnFoundChannelAndWarnings)
                {
                    Console.WriteLine($"Detected channel [{maybeBGMChannel.Value}] as BGM Channel number");
                }
                ;
                return(maybeBGMChannel.Value);
            }
            else
            {
                if (PrintOnFoundChannelAndWarnings)
                {
                    Console.WriteLine($"WARNING: Could not detect bgmChannel. Will use channel {defaultChannel} when inserting PS3 music");
                }
                return(defaultChannel);
            }
        }
        private void Merge(MainEntity source, bool inbackground = true)
        {
            Log.StartTiming("Merge");

            var conf = new MergerConfiguration
            {
                ImportCreationDate     = ImportCreationDate,
                ImportRecentlyUsedDate = ImportRecentlyUsedDate,
                ImportDefinedDate      = ImportDefinedDate,
                ImportStatisticsForNew = ImportStatisticsForNew,
                ImportStatisticsForOld = ImportStatisticsForOld
            };

            if (inbackground)
            {
                WindowService.DoBackgroundTask(
                    () => Merger.Merge(source, conf));
            }
            else
            {
                Merger.Merge(source, conf);
            }
            Log.StopTiming("Merge");
        }
Example #5
0
        private int MergeUnknownExpressions(IEnumerable <ExpressionEntity> toMerge, IEnumerable <ExpressionEntity> oldExpressions, MergerConfiguration conf)
        {
            var unknownExpressions = from ex in toMerge
                                     where !oldExpressions.Any(oex => String.Equals(oex.Expression, ex.Expression, StringComparison.InvariantCultureIgnoreCase))
                                     select ex;

            foreach (var u in unknownExpressions)
            {
                if (!conf.ImportCreationDate)
                {
                    u.CreationDate = _dateTimeProvider.Current;
                }

                var toRemove = new List <TranslationEntity>();
                foreach (var t in u.Translations)
                {
                    if (String.IsNullOrWhiteSpace(t.Translation) && String.IsNullOrWhiteSpace(t.Translation2))
                    {
                        toRemove.Add(t);
                    }
                    else
                    {
                        if (!conf.ImportRecentlyUsedDate)
                        {
                            t.RecentlyUsed = null;
                        }

                        if (!conf.ImportDefinedDate)
                        {
                            t.Defined = _dateTimeProvider.Current;
                        }

                        if (!conf.ImportStatisticsForNew)
                        {
                            ClearStatistics(t);
                        }
                    }
                }

                toRemove.ForEach(t => u.Translations.Remove(t));
            }

            _dataAccess.Save(unknownExpressions);
            return(unknownExpressions.Count());
        }
Example #6
0
        private void MergeTranslations(ExpressionEntity source, ExpressionEntity dest, MergerConfiguration conf)
        {
            foreach (var sourceTran in source.Translations)
            {
                var destTran = dest.Translations.Where(t => t.Language == sourceTran.Language).FirstOrDefault();

                if (destTran == null)
                {
                    if (!conf.ImportStatisticsForNew)
                    {
                        ClearStatistics(sourceTran);
                    }

                    dest.Translations.Add(sourceTran);
                }
                else
                {
                    if (conf.ImportStatisticsForNew)
                    {
                        CopyStatistics(sourceTran, destTran);
                    }
                    else
                    {
                        ClearStatistics(destTran);
                    }

                    destTran.Translation  = sourceTran.Translation;
                    destTran.Translation2 = sourceTran.Translation2;
                }
            }
        }
Example #7
0
        private void MergeExpressionsWithUnknownTranslations(IEnumerable <ExpressionEntity> toMerge, IEnumerable <ExpressionEntity> oldExpressions, MergerConfiguration conf)
        {
            var withUnknownTranslation = from ex in toMerge
                                         where
                                         oldExpressions.Any(oldEx => String.Equals(oldEx.Expression, ex.Expression, StringComparison.InvariantCultureIgnoreCase))
                                         &&
                                         !oldExpressions.Contains(ex)
                                         select ex;

            foreach (var ex in withUnknownTranslation)
            {
                var res = oldExpressions.Where(oldEx => String.Equals(ex.Expression, oldEx.Expression, StringComparison.InvariantCultureIgnoreCase));

                foreach (var oldEx in res)
                {
                    MergeTranslations(ex, oldEx, conf);
                }

                _dataAccess.Save(res);
            }
        }
        public static void InsertMGLinesUsingPS3XML(string mergedMGScriptPath, string outputPath, MergerConfiguration configuration, Counter counter)
        {
            const bool USE_OLD_METHOD_FOR_INSERT_BGM = false;

            Console.WriteLine($"--------- Begin Applying Postprocessing Stage 1 to {mergedMGScriptPath} ------");

            //Detect the BGM channel of the original Manga Gamer script. This is used for BGM insertion and FadeOut insertion
            int bgmChannelNumber = MGScriptBGMChannelDetector.DetectBGMChannelOrDefault(mergedMGScriptPath, configuration, defaultChannel: 2, PrintOnFoundChannelAndWarnings: true);


            // --------- Perform stage 1 - this converts the raw merged script into a list of MangaGamerInstructions ---------
            //Iterate over the the Manga Gamer chunks and the PS3 XML Instructions Chunks of the merged script
            int debug_i = 0;
            List <InstructionAssociation> workingInstructionAssociations = new List <InstructionAssociation>();

            List <MangaGamerInstruction> newChunk = new List <MangaGamerInstruction>();

            foreach (var chunk in PS3XMLChunkFinder.GetAllChunksFromMergedScript(mergedMGScriptPath))
            {
                if (chunk.isPS3Chunk)
                {
                    //PS3 XML reader doesn't care about newlines, so just join each line directly to next line
                    HandlePS3Chunk(String.Join("", chunk.lines), newChunk, bgmChannelNumber);

                    HandleChunk(workingInstructionAssociations, newChunk);
                    newChunk = new List <MangaGamerInstruction>();
                }
                else
                {
                    //handle a mangagamer chunk
                    foreach (string mgScriptLine in chunk.lines)
                    {
                        newChunk.Add(ParseMangaGamerInstruction(mgScriptLine, false));
                    }
                }
            }

            //If there are any leftovers (probably just mangagamer original instructions), just add them to the output.
            HandleChunk(workingInstructionAssociations, newChunk);

            // Extract BGM associations of mgBGM -> ps3BGM
            ExtractBGMAssociations(workingInstructionAssociations, counter);

            // Convert the instruction associations to regular mangagamer instructions for stage 2
            List <MangaGamerInstruction> outputStage1 = new List <MangaGamerInstruction>();

            foreach (var instructionAssociation in workingInstructionAssociations)
            {
                outputStage1.Add(instructionAssociation.mgOriginalInstruction);

                //check for a "failed" section. If failed section, just insert the whole section.
                bool failed = false;
                foreach (var inst in instructionAssociation.associatedPS3Instructions)
                {
                    if (inst is FailInstruction)
                    {
                        failed = true;
                    }
                }

                if (failed)
                {
                    outputStage1.AddRange(instructionAssociation.associatedPS3Instructions);
                    continue;
                }


                foreach (var ps3Inst in instructionAssociation.associatedPS3Instructions)
                {
                    MangaGamerInstruction outputInstruction = ps3Inst;

                    switch (ps3Inst)
                    {
                    case MGPlayBGM ps3MGPlayBGM:
                        if (instructionAssociation.mgOriginalInstruction is MGPlayBGM)
                        {
                            MGPlayBGM mgPlayBGM = (MGPlayBGM)instructionAssociation.mgOriginalInstruction;
                            outputInstruction = mgPlayBGM.CloneWithFilename(ps3MGPlayBGM.bgmFileName, ps3MGPlayBGM.IsPS3());
                        }
                        break;

                    case MGPlaySE ps3MGPlaySE:
                        if (instructionAssociation.mgOriginalInstruction is MGPlaySE)
                        {
                            MGPlaySE mgPlaySE = (MGPlaySE)instructionAssociation.mgOriginalInstruction;
                            outputInstruction = mgPlaySE.CloneWithFilename(ps3MGPlaySE.filename, ps3MGPlaySE.IsPS3());
                        }
                        break;
                    }

                    outputStage1.Add(outputInstruction);
                }
            }

            // --------- Perform stage 2 filtering to 'tidy up' the script ---------
            //This section runs filters after all the other filters have run.
            //This stage converts the list of MangaGamerInstructions to a list of strings
            List <string> outputStage2 = new List <string>();

            foreach (MangaGamerInstruction inst in outputStage1)
            {
                //TODO: correctly interpret mangagamer instructions instead of using regexes to determine the line typ
                if (inst.IsPS3())
                {
                    //Disable PS3 fade instructions for now
                    if (!(inst is MGFadeOutBGM))
                    {
                        //wrap all ps3-origin instructions in GAltBGMflow
                        outputStage2.Add($"\tif (GetGlobalFlag(GAltBGMflow) == 1) {{ {inst.GetInstruction()} }}");
                    }
                }
                else if (//fadeOutBGMMusicRegex.IsMatch(inst.GetInstruction()) ||
                    playBGMMusicRegex.IsMatch(inst.GetInstruction()) ||
                    playSERegex.IsMatch(inst.GetInstruction()))
                {
                    //wrap only the above types of MG-origin instructions in GAltBGMflow
                    outputStage2.Add($"\tif (GetGlobalFlag(GAltBGMflow) == 0) {{ {inst.GetInstruction()} }}");
                }
                else
                {
                    //all other MG-origin instructions are output as-is
                    outputStage2.Add(inst.GetInstructionStandalone());
                }
            }

            // --------- Finally, write the output to file. ---------
            File.WriteAllLines(outputPath, outputStage2);
        }