Ejemplo n.º 1
0
        void Write(AssemblyDefinition assemblyToPatch, NPath assemblyToPatchPath, PatchOptions patchOptions = default)
        {
            // atomic write of file with backup
            // TODO: skip backup if existing file already patched. want the .orig to only be the unpatched file.

            // write to tmp and release the lock
            var tmpPath = assemblyToPatchPath.ChangeExtension(".tmp");

            tmpPath.DeleteIfExists();
            assemblyToPatch.Write(tmpPath); // $$$ , new WriterParameters { WriteSymbols = true }); see https://github.com/jbevain/cecil/issues/421
            assemblyToPatch.Dispose();

            // TODO: peverify obviously won't work with memory written streams. also needs all the dependencies.
            // solution is to create a temp folder, write the patched dll there as well as any of its direct dependencies, and run peverify

            if ((patchOptions & PatchOptions.SkipPeVerify) == 0)
            {
                PeVerify.Verify(tmpPath);
            }

            // move the actual file to backup, and move the tmp to actual
            var backupPath = ElevatedWeaver.GetPatchBackupPathFor(assemblyToPatchPath);

            File.Replace(tmpPath, assemblyToPatchPath, backupPath);
        }
Ejemplo n.º 2
0
 private static VCDiffResult Patch(PatchOptions opt)
 {
     using (var sold = File.OpenRead(opt.OldFile))          // old file
         using (var snew = File.OpenRead(opt.DeltaFile))    // delta file
             using (var sout = File.OpenWrite(opt.NewFile)) // out file
                 return(Decode(sold, snew, sout));
 }
Ejemplo n.º 3
0
        public void GetFilesToPatch(ConcurrentBag <FileToPatch> filesToPatch, PatchOptions patchOptions)
        {
            string msgTmpFile = Path.GetTempFileName();

            _msgService.CreateMsgDat(Path.Combine(_mod.FolderPath, Constants.MsgFolderPath), msgTmpFile);
            filesToPatch.Add(new FileToPatch(Constants.MsgRomPath, msgTmpFile, FilePatchOptions.VariableLength | FilePatchOptions.DeleteSourceWhenDone));
        }
Ejemplo n.º 4
0
 public void GetFilesToPatch(ConcurrentBag <FileToPatch> filesToPatch, PatchOptions patchOptions)
 {
     foreach (var mapFilePath in Directory.GetFiles(Path.Combine(_mod.FolderPath, Constants.MapFolderPath)))
     {
         string mapRomPath = Path.Combine(Constants.MapFolderPath, Path.GetFileName(mapFilePath));
         filesToPatch.Add(new FileToPatch(mapRomPath, mapFilePath, FilePatchOptions.VariableLength));
     }
 }
Ejemplo n.º 5
0
 PatchAttribute(Type type, string typeName, string methodName, Type[] methodParams, PatchOptions options = PatchOptions.None)
 {
     this.type         = type;
     this.typeName     = typeName;
     this.methodName   = methodName;
     this.methodParams = methodParams;
     this.options      = options;
 }
Ejemplo n.º 6
0
        public void RunPatch(PatchOptions options)
        {
            Logger.Info("Running data patch");

            var patcher = InstantiatePatcher(options);

            patcher.Patch();

            Logger.Info("Patch completed successfully");
        }
Ejemplo n.º 7
0
        IDataPatcher InstantiatePatcher(PatchOptions options)
        {
            var type = typeof(IDataPatcher).Assembly.GetType("Catalogue.Toolbox.Patch.DataPatchers." + options.Name);

            if (type == null)
            {
                throw new Exception($"The data patcher '{options.Name}' couldn't be found or does not exist.");
            }

            return((IDataPatcher)Activator.CreateInstance(type));
        }
Ejemplo n.º 8
0
        public static void DrawOptions(Listing_Standard listing)
        {
            var left  = listing.GetRect(Text.LineHeight * 11); // the average height of this is ~226, which is 10.2 * Text.LineHeight
            var right = left.RightPart(0.48f);

            left = left.LeftPart(0.48f);

            PatchOptions.DrawPatches(left);
            PatchOptions.DrawUnPatches(right);

            DubGUI.CenterText(() => listing.Label("Utilites"));
        }
Ejemplo n.º 9
0
    private void PrepareForPatch()
    {
        string       romPath      = "romPath";
        PatchOptions patchOptions = 0;

        _dialogService.Setup(i => i.CommitToRom(It.IsAny <ModInfo>(), out romPath, out patchOptions)).Returns(true);
        string failReason = "failreason";

        _patchingService.Setup(i => i.CanPatch(It.IsAny <ModInfo>(), romPath, patchOptions, out failReason)).Returns(true);

        _dialogService.Setup(i => i.ProgressDialog(It.IsAny <Action <IProgress <ProgressInfo> > >(), It.IsAny <bool>()))
        .Callback((Action <IProgress <ProgressInfo> > action, bool opt) => action(null));
    }
Ejemplo n.º 10
0
        public bool CanPatch(ModInfo modInfo, string romPath, PatchOptions patchOptions, out string reasonCannotPatch)
        {
            if (patchOptions.HasFlag(PatchOptions.IncludeSprites))
            {
                if (!_fallbackSpriteProvider.IsDefaultsPopulated)
                {
                    reasonCannotPatch = "Cannot patch sprites unless 'Populate Graphics Defaults' has been run";
                    return(false);
                }
            }

            reasonCannotPatch = "";
            return(true);
        }
Ejemplo n.º 11
0
        public void GetFilesToPatch(ConcurrentBag <FileToPatch> filesToPatch, PatchOptions patchOptions)
        {
            if (!patchOptions.HasFlag(PatchOptions.IncludeSprites))
            {
                return;
            }

            if (!_fallbackSpriteProvider.IsDefaultsPopulated)
            {
                throw new Exception("Cannot patch sprites unless 'Populate Graphics Defaults' has been run");
            }

            Parallel.ForEach(GraphicsInfoResource.All, gInfo =>
            {
                foreach (var builder in _builders)
                {
                    builder.GetFilesToPatch(filesToPatch, gInfo);
                }
            });
        }
Ejemplo n.º 12
0
        public void AddPatch(string patchName, PatchOptions Options = null)
        {
            if (string.IsNullOrWhiteSpace(patchName))
            {
                throw new ApplicationException("Patch Name required");
            }
            else
            {
                var cfgWriter = new BuildConfigurationWriter(_configFileName, _configLocalFileName);
                var cfg       = cfgWriter.Read();

                // load options
                //DatabaseOptions dbopt = LoadDatabaseOptions(cfg);

                //create unique id prefix to avoid collisions
                string prefix = $"{DateTime.Now:yyyyMMddHHmm}-{_rand.Next(0, 9999):0000}";

                // patch names are limited to 50 char total at present, but this could be a property of the plugin
                string finalId = $"{prefix}-{patchName.Trim()}";
                finalId = finalId.Substring(0, Math.Min(50, finalId.Length));

                string patchPath = _io.Path.Combine(cfg.PatchFolder, finalId);

                if (!_io.Directory.Exists(patchPath))
                {
                    _io.Directory.CreateDirectory(patchPath);

                    // when adding a patch, make it dependent on all patches
                    // that don't already have a dependency.
                    // need to guard against circular dependencies
                    var openPatches = cfg.GetOpenPatches();
                    cfg.patches.Add(new Patch(finalId, openPatches));
                    cfgWriter.Write(cfg);
                }
                else
                {
                    // create custom exception
                    throw new ApplicationException($"A folder named '{finalId}' already exists");
                }
            }
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Patch kubernetes object.
        /// </summary>
        /// <typeparam name="T">the object type</typeparam>
        /// <param name="name"> the name</param>
        /// <param name="obj"> the object</param>
        /// <param name="patchOptions">the patch options</param>
        /// <param name="cancellationToken">the token </param>
        /// <returns>the kubernetes object</returns>
        public async Task <T> PatchAsync <T>(string name, object obj, PatchOptions patchOptions, CancellationToken cancellationToken = default)
            where T : class, IKubernetesObject <V1ObjectMeta>
        {
            if (obj == null)
            {
                throw new ArgumentNullException(nameof(obj));
            }

            if (patchOptions == null)
            {
                throw new ArgumentNullException(nameof(patchOptions));
            }

            if (string.IsNullOrEmpty(name))
            {
                throw new ArgumentNullException(nameof(name));
            }

            var resp = await _client.PatchClusterCustomObjectWithHttpMessagesAsync(body : obj, group : _apiGroup, version : _apiVersion, plural : _resourcePlural, name : name, dryRun : patchOptions.DryRun,
                                                                                   fieldManager : patchOptions.FieldManager, force : patchOptions.Force, cancellationToken : cancellationToken).ConfigureAwait(false);

            return(KubernetesJson.Deserialize <T>(resp.Body.ToString()));
        }
Ejemplo n.º 14
0
    public bool CommitToRom(ModInfo info, out string romPath, out PatchOptions patchOptions)
    {
        var vm = new ModCommitViewModel(this, info, _recentCommitRomSetting.Value)
        {
            IncludeSprites = _patchSpritesSetting.Value
        };

        var dialog = new Dialogs.ModCommitDialog
        {
            Owner       = Application.Current.MainWindow,
            DataContext = vm,
        };

        bool?proceed = dialog.ShowDialog();

        if (proceed == true)
        {
            romPath = vm.File;
            _recentCommitRomSetting.Value = vm.File;
            _patchSpritesSetting.Value    = vm.IncludeSprites;
            _settingService.Save();
            patchOptions = 0;

            if (vm.IncludeSprites)
            {
                patchOptions |= PatchOptions.IncludeSprites;
            }

            return(true);
        }
        else
        {
            romPath      = null;
            patchOptions = 0;
            return(false);
        }
    }
Ejemplo n.º 15
0
        public void GetFilesToPatch(ConcurrentBag <FileToPatch> filesToPatch, PatchOptions patchOptions)
        {
            List <string> dataRomPaths = new List <string>()
            {
                Constants.MoveRomPath,
                Constants.AbilityRomPath,
                Constants.WarriorSkillRomPath,
                Constants.GimmickRomPath,
                Constants.BuildingRomPath,
                Constants.ItemRomPath,
                Constants.KingdomRomPath,
                Constants.MoveRangeRomPath,
                Constants.EventSpeakerRomPath,
                Constants.MaxLinkRomPath,
                Constants.BaseBushouRomPath,
                Constants.BattleConfigRomPath,
                Constants.GimmickRangeRomPath,
                Constants.MoveAnimationRomPath,
                Constants.GimmickObjectRomPath,
                Constants.EpisodeRomPath
            };

            foreach (var i in EnumUtil.GetValues <ScenarioId>())
            {
                dataRomPaths.Add(Constants.ScenarioPokemonPathFromId((int)i));
                dataRomPaths.Add(Constants.ScenarioWarriorPathFromId((int)i));
                dataRomPaths.Add(Constants.ScenarioAppearPokemonPathFromId((int)i));
                dataRomPaths.Add(Constants.ScenarioKingdomPathFromId((int)i));
            }

            filesToPatch.Add(new FileToPatch(Constants.PokemonRomPath, Path.Combine(_mod.FolderPath, Constants.PokemonRomPath), FilePatchOptions.VariableLength));
            foreach (string drp in dataRomPaths)
            {
                filesToPatch.Add(new FileToPatch(drp, Path.Combine(_mod.FolderPath, drp), FilePatchOptions.None));
            }
        }
Ejemplo n.º 16
0
Archivo: App.cs Proyecto: tuanva/RawCMS
 private int RunPatchOptionsCode(PatchOptions opts)
 {
     throw new NotImplementedException();
 }
        public static IReadOnlyCollection <PatchResult> PatchAllDependentAssemblies(NPath testAssemblyPath, PatchOptions patchOptions)
        {
            // TODO: ensure we do not have any assemblies that we want to patch already loaded
            // (this will require the separate in-memory patching ability)

            // this dll has types we're going to be injecting, so ensure it is in the same folder
            //var targetWeaverDll

            var toProcess = new List <NPath> {
                testAssemblyPath.FileMustExist()
            };
            var patchResults = new Dictionary <string, PatchResult>(StringComparer.OrdinalIgnoreCase);
            var mockInjector = new MockInjector(testAssemblyPath.Parent.Combine("NSubstitute.Elevated"));

            for (var toProcessIndex = 0; toProcessIndex < toProcess.Count; ++toProcessIndex)
            {
                var assemblyToPatchPath = toProcess[toProcessIndex];

                // as we accumulate dependencies recursively, we will probably get some duplicates we can early-out on
                if (patchResults.ContainsKey(assemblyToPatchPath))
                {
                    continue;
                }

                using (var assemblyToPatch = AssemblyDefinition.ReadAssembly(assemblyToPatchPath))
                {
                    GatherReferences(assemblyToPatchPath, assemblyToPatch);

                    var patchResult = TryPatch(assemblyToPatchPath, assemblyToPatch);
                    patchResults.Add(assemblyToPatchPath, patchResult);
                }
            }

            void GatherReferences(NPath assemblyToPatchPath, AssemblyDefinition assemblyToPatch)
            {
                foreach (var referencedAssembly in assemblyToPatch.Modules.SelectMany(m => m.AssemblyReferences))
                {
                    // only patch dll's we "own", that are in the same folder as the test assembly
                    var referencedAssemblyPath = assemblyToPatchPath.Parent.Combine(referencedAssembly.Name + ".dll");

                    if (referencedAssemblyPath.FileExists())
                    {
                        toProcess.Add(referencedAssemblyPath);
                    }
                    else if (!patchResults.ContainsKey(referencedAssembly.Name))
                    {
                        patchResults.Add(referencedAssembly.Name, new PatchResult(referencedAssembly.Name, null, PatchState.IgnoredForeignAssembly));
                    }
                }
            }

            PatchResult TryPatch(NPath assemblyToPatchPath, AssemblyDefinition assemblyToPatch)
            {
                var alreadyPatched = mockInjector.IsPatched(assemblyToPatch);
                var cannotPatch    = assemblyToPatch.Name.HasPublicKey;

                if (assemblyToPatchPath == testAssemblyPath && (patchOptions & PatchOptions.PatchTestAssembly) == 0)
                {
                    if (alreadyPatched)
                    {
                        throw new Exception("Unexpected already-patched test assembly, yet we want PatchTestAssembly.No");
                    }
                    if (cannotPatch)
                    {
                        throw new Exception("Cannot patch an assembly with a strong name");
                    }
                    return(new PatchResult(assemblyToPatchPath, null, PatchState.IgnoredTestAssembly));
                }

                if (alreadyPatched)
                {
                    return(new PatchResult(assemblyToPatchPath, null, PatchState.AlreadyPatched));
                }
                if (cannotPatch)
                {
                    return(new PatchResult(assemblyToPatchPath, null, PatchState.IgnoredForeignAssembly));
                }

                return(Patch(assemblyToPatchPath, assemblyToPatch));
            }

            PatchResult Patch(NPath assemblyToPatchPath, AssemblyDefinition assemblyToPatch)
            {
                mockInjector.Patch(assemblyToPatch);

                // atomic write of file with backup
                // TODO: skip backup if existing file already patched. want the .orig to only be the unpatched file.

                // write to tmp and release the lock
                var tmpPath = assemblyToPatchPath.ChangeExtension(".tmp");

                tmpPath.DeleteIfExists();
                assemblyToPatch.Write(tmpPath); // $$$ , new WriterParameters { WriteSymbols = true }); see https://github.com/jbevain/cecil/issues/421
                assemblyToPatch.Dispose();

                if ((patchOptions & PatchOptions.SkipPeVerify) == 0)
                {
                    PeVerify.Verify(tmpPath);
                }

                // move the actual file to backup, and move the tmp to actual
                var backupPath = GetPatchBackupPathFor(assemblyToPatchPath);

                File.Replace(tmpPath, assemblyToPatchPath, backupPath);

                // TODO: move pdb file too

                return(new PatchResult(assemblyToPatchPath, backupPath, PatchState.Patched));
            }

            return(patchResults.Values);
        }
Ejemplo n.º 18
0
        public void Patch(ModInfo modInfo, string romPath, PatchOptions patchOptions, IProgress <ProgressInfo> progress = null)
        {
            progress?.Report(new ProgressInfo(statusText: "Preparing to patch...", isIndeterminate: true));

            ConcurrentBag <FileToPatch> filesToPatch = new ConcurrentBag <FileToPatch>();
            Exception exception = null;

            try
            {
                var services = _modServiceGetterFactory.Create(modInfo);
                var patchers = services.Get <IEnumerable <IPatchBuilder> >();
                GetFilesToPatch(patchers, filesToPatch, patchOptions);

#if PATCHER_BUG_FIXING
                string debugOut = FileUtil.MakeUniquePath(Path.Combine(FileUtil.DesktopDirectory, "patch_debug_dump"));
                Directory.CreateDirectory(debugOut);
                foreach (var file in filesToPatch)
                {
                    string dest = Path.Combine(debugOut, file.GamePath.Replace(Path.DirectorySeparatorChar, '~'));
                    if (file.Options.HasFlag(FilePatchOptions.DeleteSourceWhenDone))
                    {
                        File.Move(file.FileSystemPath, dest);
                    }
                    else
                    {
                        File.Copy(file.FileSystemPath, dest);
                    }
                }
                return;
#endif

                progress?.Report(new ProgressInfo(isIndeterminate: false, maxProgress: filesToPatch.Count, statusText: "Patching..."));
                int count = 0;
                using (var nds = _ndsFactory(romPath))
                {
                    foreach (var file in filesToPatch)
                    {
                        if (file.Options.HasFlag(FilePatchOptions.VariableLength))
                        {
                            nds.InsertVariableLengthFile(file.GamePath, file.FileSystemPath);
                        }
                        else
                        {
                            nds.InsertFixedLengthFile(file.GamePath, file.FileSystemPath);
                        }
                        progress?.Report(new ProgressInfo(progress: ++count));
                    }
                }
            }
            catch (Exception e)
            {
                exception = e;
            }
            finally
            {
                progress?.Report(new ProgressInfo(statusText: "Cleaning up temporary files...", isIndeterminate: true));

                foreach (var file in filesToPatch)
                {
                    if (file.Options.HasFlag(FilePatchOptions.DeleteSourceWhenDone))
                    {
                        File.Delete(file.FileSystemPath);
                    }
                }
            }

            if (exception != null)
            {
                throw exception;
            }

            progress?.Report(new ProgressInfo(statusText: "Done!", isIndeterminate: false));
        }
Ejemplo n.º 19
0
 private void GetFilesToPatch(IEnumerable <IPatchBuilder> patchBuilders, ConcurrentBag <FileToPatch> filesToPatch, PatchOptions patchOptions)
 {
     Parallel.ForEach(patchBuilders, builder =>
     {
         builder.GetFilesToPatch(filesToPatch, patchOptions);
     });
 }
Ejemplo n.º 20
0
 public PatchAttribute(PatchOptions options) :
     this(null, null, null, null, options)
 {
 }