Пример #1
0
        /// <summary>
        /// Removes group with specified name
        /// </summary>
        /// <param name="groupToDelete"></param>
        public void RemoveGroup(string groupToDelete)
        {
            // Required group can't be removed
            if (!REQUIRED_GROUP_NAME.Equals(groupToDelete))
            {
                InstallGroup currentGroup = _GetGroup(groupToDelete, _Groups);

                if (currentGroup.exists)
                {
                    _Groups.Remove(currentGroup);

                    // Set instructions to required group
                    InstallGroup requiredGroup = _GetGroup(REQUIRED_GROUP_NAME, _Groups);

                    for (int i = 0; i < _PatchInstructions.Count; i++)
                    {
                        PatchInstruction currentInstruction = _PatchInstructions[i];

                        if (currentInstruction.Group.Equals(currentGroup))
                        {
                            currentInstruction.Group = requiredGroup;
                        }
                    }
                }
            }
        }
Пример #2
0
        /// <summary>
        /// Adds or replace an instruction. If instruction order already exists, corresponding instruction is replaced; else specified instruction is added to the list.
        /// </summary>
        /// <param name="instruction">Instruction to set</param>
        public void SetInstruction(PatchInstruction instruction)
        {
            if (instruction == null || instruction.Order < 1)
            {
                return;
            }

            // Unsupported parameters are removed
            instruction.RemoveUnsupportedParameters();

            if (instruction.Order > PatchInstructions.Count)
            {
                // Add mode
                PatchInstructions.Add(instruction);
            }
            else
            {
                // Replace mode
                for (int i = 0; i < PatchInstructions.Count; i++)
                {
                    PatchInstruction currentInstruction = PatchInstructions[i];

                    if (currentInstruction.Order == instruction.Order)
                    {
                        PatchInstructions[i] = instruction;
                        break;
                    }
                }
            }
        }
Пример #3
0
 public static PatchInstruction Configure(this PatchInstruction patchInstruction, AppInfo context, PatchingManifest manifest, string location, bool enabled = true)
 {
     patchInstruction.IsEnabled = enabled;
     patchInstruction.Patch     = manifest;
     patchInstruction.Location  = location;
     patchInstruction.AppInfo   = context;
     return(patchInstruction);
 }
Пример #4
0
 public static XmlInstruction ToXmlInstruction(this PatchInstruction instruction)
 {
     return(new XmlInstruction
     {
         IsEnabled = instruction.IsEnabled,
         Name = instruction.Patch.PatchInfo.PatchName,
         Location = instruction.Location
     });
 }
Пример #5
0
        /// <summary>
        /// Import specified instruction to current patch
        /// </summary>
        /// <param name="anotherInstruction"></param>
        public void ImportInstruction(PatchInstruction anotherInstruction)
        {
            if (anotherInstruction != null)
            {
                anotherInstruction.Order = PatchInstructions.Count + 1;

                PatchInstructions.Add(anotherInstruction);
            }
        }
Пример #6
0
        /// <summary>
        /// Processes a single instruction
        /// </summary>
        /// <param name="instr">Instruction to execute</param>
        /// <param name="instructionNumber"></param>
        /// <returns></returns>
        private static RunResult _ProcessInstruction(PatchInstruction instr, int instructionNumber)
        {
            // Logger
            if (_PatchLog != null)
            {
                _PatchLog.WriteEvent(string.Format(_MSG_RUNNING_INSTRUCTION, instructionNumber, instr.Group.name, instr.Comment));
            }

            return(instr.Run(_PatchLog));
        }
Пример #7
0
        /// <summary>
        /// Method to create an instruction from a XML node
        /// </summary>
        /// <param name="node">node to process</param>
        /// <param name="order">instruction order</param>
        /// <returns>Correponding instruction</returns>
        private PatchInstruction _ProcessInstruction(XmlNode node, int order)
        {
            PatchInstruction processedPI = null;

            if (node != null && order > 0)
            {
                // Main attributes
                string instructionType = node.Attributes[_TYPE_ATTRIBUTE].Value;
                string isFailOnError   = Xml2.GetAttributeWithDefaultValue(node, _FAIL_ON_ERROR_ATTRIBUTE, true.ToString());
                string isEnabled       = Xml2.GetAttributeWithDefaultValue(node, _ENABLED_ATTRIBUTE, true.ToString());
                string comment         = Xml2.GetAttributeWithDefaultValue(node, _COMMENT_ATTRIBUTE, "");
                string groupName       = Xml2.GetAttributeWithDefaultValue(node, _GROUP_ATTRIBUTE, REQUIRED_GROUP_NAME);

                processedPI = PatchInstruction.MakeInstruction(instructionType);

                if (processedPI != null)
                {
                    processedPI.FailOnError = bool.Parse(isFailOnError);
                    processedPI.Enabled     = bool.Parse(isEnabled);
                    processedPI.Order       = order;
                    processedPI.Comment     = comment;

                    if (string.IsNullOrEmpty(groupName))
                    {
                        groupName = REQUIRED_GROUP_NAME;
                    }

                    processedPI.Group = GetGroupFromName(groupName);

                    // Instruction parameters
                    XmlNodeList allParameterNodes = node.SelectNodes(_PARAMETER_NODE);

                    if (allParameterNodes != null)
                    {
                        foreach (XmlNode anotherParameterNode in allParameterNodes)
                        {
                            PatchInstructionParameter pip = _ProcessParameter(anotherParameterNode);

                            if (pip == null)
                            {
                                throw new Exception("Invalid parameter: " + anotherParameterNode.Value);
                            }

                            processedPI.Parameters.Add(pip.Name, pip);
                        }
                    }
                }
            }

            return(processedPI);
        }
Пример #8
0
 /// <exception cref="T:PatchworkLauncher.PatchingProcessException">Cannot patch manifest during the patching process</exception>
 public static void TryPatchManifest(this AssemblyPatcher patcher, PatchInstruction patch, PatchGroup patchGroup, ProgressObject patchProgress)
 {
     try
     {
         patcher.PatchManifest(patch.Patch, patchProgress.ToMonitor());
     }
     catch (PatchException patchException)
     {
         throw new PatchingProcessException(patchException)
               {
                   AssociatedInstruction = patch,
                   AssociatedPatchGroup  = patchGroup,
                   Step = PatchProcessingStep.ApplyingSpecificPatch
               };
     }
 }
Пример #9
0
        /// <summary>
        /// Handles single execution
        /// </summary>
        /// <param name="patchToRun">Patch instance to execute</param>
        /// <param name="instructionNumber">Instruction number to execute</param>
        /// <param name="log">Log for message storing</param>
        /// <param name="tduPath">Path for tdu files; can be null = default</param>
        /// <param name="filePath">Path for patch files</param>
        /// <param name="currentCulture"></param>
        /// <returns></returns>
        public static RunResult RunSingleInstruction(PCH patchToRun, int instructionNumber, Log log, string tduPath, string filePath, DB.Culture currentCulture)
        {
            RunResult result = RunResult.NotRun;

            if (patchToRun == null || string.IsNullOrEmpty(filePath))
            {
                return(result);
            }

            _InitializeComponents(patchToRun, filePath, currentCulture, log);

            // Instruction finding
            PatchInstruction instr = patchToRun.GetInstruction(instructionNumber);

            if (instr != null)
            {
                result = _ProcessInstruction(instr, instructionNumber);

                switch (result)
                {
                case RunResult.RunWithWarnings:
                    // Non-critical failure > next instruction
                    _PatchLog.WriteEvent(string.Format(_MSG_INSTRUCTION_END_WARN, instr.Order, 1));
                    break;

                case RunResult.RunWithErrors:
                    _PatchLog.WriteEvent(_MSG_FINISHING_ERR);
                    break;

                default:
                    _PatchLog.WriteEvent(_MSG_FINISHING_OK);
                    break;
                }
            }

            // Displaying collected messages
            _DisplayCollectedMessages();

            // Saving Logger to file
            _PatchLog.SaveToFile(_PatchLog.Name);

            return(result);
        }
Пример #10
0
        /// <summary>
        /// Imports instruction(s) according to provided bribe
        /// </summary>
        /// <param name="bribe">Instructions XML bribe</param>
        public void ImportInstruction(string bribe)
        {
            if (!string.IsNullOrEmpty(bribe))
            {
                XmlDocument doc = new XmlDocument();

                doc.LoadXml(bribe);

                try
                {
                    XmlNode instructionsNode = doc.DocumentElement;

                    if (instructionsNode != null)
                    {
                        XmlNodeList allInstructionNodes = instructionsNode.SelectNodes(_SINGLE_INSTRUCTION_NODE);
                        int         order = _PatchInstructions.Count + 1;

                        if (allInstructionNodes != null)
                        {
                            foreach (XmlNode anotherInstructionNode in allInstructionNodes)
                            {
                                PatchInstruction pi = _ProcessInstruction(anotherInstructionNode, order);

                                if (pi == null)
                                {
                                    Log.Warning("Invalid instruction - can't be imported.");
                                }
                                else
                                {
                                    _PatchInstructions.Add(pi);
                                    order++;
                                }
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    // Current instruction won't be added
                    Exception2.PrintStackTrace(ex);
                }
            }
        }
Пример #11
0
        /// <summary>
        /// Displays help about specified instruction
        /// </summary>
        /// <param name="instruction"></param>
        public void ShowHelp(PatchInstruction instruction)
        {
            string nameLabel        = "";
            string descriptionLabel = "";

            if (instruction != null)
            {
                nameLabel        = instruction.Name;
                descriptionLabel = instruction.Description;
            }

            nameGroupBox.Text = nameLabel;
            instructionDescriptionHelpTextBox.Text = descriptionLabel;

            // Displays if needed
            if (!Visible)
            {
                Show(_ParentForm);
            }
        }
Пример #12
0
        /// <summary>
        /// Swaps 2 instructions according to their order
        /// </summary>
        /// <param name="order">Order of first instruction</param>
        /// <param name="anotherOrder">Order of second instruction</param>
        public void SwitchInstructions(int order, int anotherOrder)
        {
            if (order == anotherOrder ||
                order < 1 ||
                anotherOrder < 1 ||
                order > PatchInstructions.Count ||
                anotherOrder > PatchInstructions.Count)
            {
                return;
            }

            PatchInstruction instr1 = GetInstruction(order);
            PatchInstruction instr2 = GetInstruction(anotherOrder);

            if (instr1 != null && instr2 != null)
            {
                instr1.Order = anotherOrder;
                instr2.Order = order;

                _PatchInstructions[order - 1]        = instr2;
                _PatchInstructions[anotherOrder - 1] = instr1;
            }
        }
Пример #13
0
        /// <summary>
        /// Handles XML writing of specified instruction
        /// </summary>
        /// <param name="instr">Instruction to write</param>
        /// <param name="doc">Main XML document</param>
        /// <param name="instructionsElement">Instruction collection node. If null, written element becomes document element</param>
        private static void _SaveInstruction(PatchInstruction instr, XmlDocument doc, XmlNode instructionsElement)
        {
            if (instr != null && doc != null)
            {
                XmlElement currentInstructionElement = doc.CreateElement(_SINGLE_INSTRUCTION_NODE);

                if (instructionsElement == null)
                {
                    doc.AppendChild(currentInstructionElement);
                }
                else
                {
                    instructionsElement.AppendChild(currentInstructionElement);
                }

                // Instruction attributes
                currentInstructionElement.SetAttribute(_TYPE_ATTRIBUTE, instr.Name);
                currentInstructionElement.SetAttribute(_FAIL_ON_ERROR_ATTRIBUTE, instr.FailOnError.ToString());
                currentInstructionElement.SetAttribute(_ENABLED_ATTRIBUTE, instr.Enabled.ToString());
                currentInstructionElement.SetAttribute(_COMMENT_ATTRIBUTE, instr.Comment);

                string groupName = instr.Group.name;

                if (string.IsNullOrEmpty(groupName))
                {
                    groupName = REQUIRED_GROUP_NAME;
                }

                currentInstructionElement.SetAttribute(_GROUP_ATTRIBUTE, groupName);

                // Parameters
                foreach (KeyValuePair <string, PatchInstructionParameter> pair in instr.Parameters)
                {
                    _SaveParameter(pair.Value, doc, currentInstructionElement);
                }
            }
        }
Пример #14
0
        /// <summary>
        /// Deletes an instruction at specified order
        /// </summary>
        /// <param name="order">Instruction order</param>
        public void DeleteInstructionAt(int order)
        {
            if (order > PatchInstructions.Count)
            {
                return;
            }

            // Retrieving instruction & deletion
            PatchInstruction instructionToDelete = GetInstruction(order);

            if (instructionToDelete != null)
            {
                PatchInstructions.Remove(instructionToDelete);

                // Updating order of following instructions
                foreach (PatchInstruction anotherInstruction in _PatchInstructions)
                {
                    if (anotherInstruction.Order > order)
                    {
                        anotherInstruction.Order--;
                    }
                }
            }
        }
Пример #15
0
        /// <summary>
        /// Utility method converting specified installer patch to uninstaller one
        /// </summary>
        /// <param name="installerPatch"></param>
        /// <param name="uninstallerPatchFileName"></param>
        public static void ConvertInstallerToUninstaller(PCH installerPatch, string uninstallerPatchFileName)
        {
            if (installerPatch == null)
            {
                throw new Exception("Invalid installer patch specified.");
            }

            PCH uninstallerPatch = TduFile.GetFile(uninstallerPatchFileName) as PCH;

            if (uninstallerPatch == null)
            {
                throw new Exception("Unable to create specified uninstaller patch.");
            }

            // Cloning properties
            installerPatch.DuplicateProperties(uninstallerPatch);

            // Browsing instructions
            int ignoredCount = 0;

            foreach (PatchInstruction patchInstruction in installerPatch.PatchInstructions)
            {
                PatchInstruction correspondingInstruction = patchInstruction.Clone() as PatchInstruction;

                // checkPatch instruction is not used in uninstaller
                if (correspondingInstruction == null ||
                    PatchInstruction.InstructionName.checkPatch.ToString().Equals(correspondingInstruction.Name) ||
                    PatchInstruction.InstructionName.nothing.ToString().Equals(correspondingInstruction.Name))
                {
                    ignoredCount++;
                    continue;
                }

                // installFile instruction must be converted into uninstallFile, keeping parameter values
                if (PatchInstruction.InstructionName.installFile.ToString().Equals(correspondingInstruction.Name))
                {
                    correspondingInstruction =
                        PatchInstruction.ChangeInstruction(correspondingInstruction,
                                                           PatchInstruction.InstructionName.uninstallFile);
                }

                // bnkRemap instruction must be converted into bnkUnmap, keeping parameter values
                if (PatchInstruction.InstructionName.bnkRemap.ToString().Equals(correspondingInstruction.Name))
                {
                    correspondingInstruction =
                        PatchInstruction.ChangeInstruction(correspondingInstruction,
                                                           PatchInstruction.InstructionName.bnkUnmap);
                }

                // installPackedFile instruction must be converted into uninstallPackedFile, keeping parameter values
                if (PatchInstruction.InstructionName.installPackedFile.ToString().Equals(correspondingInstruction.Name))
                {
                    correspondingInstruction =
                        PatchInstruction.ChangeInstruction(correspondingInstruction,
                                                           PatchInstruction.InstructionName.uninstallPackedFile);
                }

                // Updates instruction index
                patchInstruction.Order -= ignoredCount;

                // Adding instruction to uninstaller
                uninstallerPatch.SetInstruction(correspondingInstruction);
            }

            // Saving
            uninstallerPatch.Save();
        }
Пример #16
0
        /// <summary>
        /// Reads patch from a PCH (XML format) file
        /// </summary>
        protected override sealed void _ReadData()
        {
            XmlDocument doc = new XmlDocument();

            try
            {
                doc.Load(FileName);

                // Properties
                XmlElement docElement = doc.DocumentElement;

                if (docElement != null)
                {
                    XmlNode propNode = docElement.SelectSingleNode(_PROPERTIES_NODE);

                    _Name              = propNode.Attributes[_NAME_ATTRIBUTE].Value;
                    _Version           = propNode.Attributes[_VERSION_ATTRIBUTE].Value;
                    _Author            = propNode.Attributes[_AUTHOR_ATTRIBUTE].Value;
                    _Date              = propNode.Attributes[_DATE_ATTRIBUTE].Value;
                    _Free              = Xml2.GetAttributeWithDefaultValue(propNode, _FREE_ATTRIBUTE, "");
                    _InstallerFileName = Xml2.GetAttributeWithDefaultValue(propNode, _INSTALLER_FILE_NAME_ATTRIBUTE,
                                                                           INSTALLER_FILE_NAME);

                    // EVO_131: roles
                    _RetrieveRoles(propNode);

                    // EVO_134: groups
                    _RetrieveGroups(propNode);

                    // New attributes
                    _SlotRef = Xml2.GetAttributeWithDefaultValue(propNode, _SLOT_REF_ATTRIBUTE, "");
                    InfoURL  = Xml2.GetAttributeWithDefaultValue(propNode, _INFO_URL_ATTRIBUTE, "");

                    // Instructions
                    XmlNode     instrNode           = docElement.SelectSingleNode(_INSTRUCTIONS_NODE);
                    XmlNodeList allInstructionNodes = instrNode.SelectNodes(_SINGLE_INSTRUCTION_NODE);
                    int         order = 1;

                    if (allInstructionNodes != null)
                    {
                        foreach (XmlNode anotherInstructionNode in allInstructionNodes)
                        {
                            try
                            {
                                PatchInstruction pi = _ProcessInstruction(anotherInstructionNode, order);

                                if (pi == null)
                                {
                                    throw new Exception();
                                }
                                _PatchInstructions.Add(pi);

                                // Groups update
                                if (!_Groups.Contains(pi.Group))
                                {
                                    _Groups.Add(pi.Group);
                                }

                                order++;
                            }
                            catch (Exception ex)
                            {
                                // Current instruction won't be added
                                Exception2.PrintStackTrace(new Exception("Invalid instruction.", ex));
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                // Silent exception
                Exception2.PrintStackTrace(new Exception(_ERROR_LOADING_PATCH, ex));
            }

            // EVO_65: Properties
            Property.ComputeValueDelegate instructionCountDelegate = () => PatchInstructions.Count.ToString();
            Property.ComputeValueDelegate nameDelegate             = () => Name;
            Property.ComputeValueDelegate authorDelegate           = () => Author;
            Property.ComputeValueDelegate dateDelegate             = () => Date;
            Property.ComputeValueDelegate versionDelegate          = () => Version;
            Property.ComputeValueDelegate slotDelegate             = () => SlotRef;
            Property.ComputeValueDelegate groupCountDelegate       = () => Groups.Count.ToString();
            Property.ComputeValueDelegate installerDelegate        = () => InstallerFileName;
            Property.ComputeValueDelegate urlDelegate = () => InfoURL;

            Properties.Add(new Property("Patch name", "Patch", nameDelegate));
            Properties.Add(new Property("Author", "Patch", authorDelegate));
            Properties.Add(new Property("Date", "Patch", dateDelegate));
            Properties.Add(new Property("Version", "Patch", versionDelegate));
            Properties.Add(new Property("Group count", "Patch", groupCountDelegate));
            Properties.Add(new Property("Instruction count", "Patch", instructionCountDelegate));
            Properties.Add(new Property("Slot reference", "Patch", slotDelegate));
            Properties.Add(new Property("Installer file name", "Patch", installerDelegate));
            Properties.Add(new Property("Information URL", "Patch", urlDelegate));
        }
Пример #17
0
 public static XmlPatchHistory FromInstruction(PatchInstruction instr)
 {
     return(new XmlPatchHistory(instr.PatchLocation));
 }
Пример #18
0
        /// <summary>
        /// Parse un Statement suivi de son block.
        /// En général, on obtient :
        /// Statement + Operand + BlockGroup.
        /// Le statement if pouvant être composé différemment (avec else et elsif), il n'est pas traité
        /// dans cette fonction.
        /// </summary>
        /// <param name="tokens"></param>
        /// <returns></returns>
        public static Instruction ParseBlockStatement(TokenList tokens, GlobalContext mainContext)
        {
            // Patch
            if (tokens.Count == 4 && tokens.First().Type == TokenType.Statement)
            {
                PatchInstruction patchInstruction = new PatchInstruction();

                InfoToken itoken = (InfoToken)tokens.First();
                if (itoken.Content != "patch")
                {
                    throw new Exception("Invalid statement format");
                }
                patchInstruction.FuncName = ((InfoToken)((OperandToken)tokens[1]).Tokens[0]).Content;
                InfoToken keyToken = (InfoToken)((OperandToken)(((PrefixedOperatorToken)tokens[2]).Operand)).Tokens.First();
                patchInstruction.Key          = keyToken.Content;
                patchInstruction.Instructions = ParseBlock(((BlockGroupToken)tokens[3]).Tokens).Instructions;
                return(patchInstruction);
            }

            if (tokens.Count != 3)
            {
                throw new Exception("Invalid instruction format.");
            }

            // On récupère les jetons.
            InfoToken       statementToken = tokens[0] as InfoToken;
            Token           exprToken      = tokens[1];
            BlockGroupToken blockToken     = tokens[2] as BlockGroupToken;

            if (statementToken == null || blockToken == null || statementToken.Type != TokenType.Statement)
            {
                throw new Exception("Invalid instruction format.");
            }

            Block block = ParseBlock(blockToken.Tokens, mainContext);

            switch (statementToken.Content)
            {
            case "return":
                throw new Exception();

            case "function":
                throw new Exception();

                /*TokenList exprTokens = ((OperandToken)exprToken).Tokens;
                 * FunctionDeclarationInstruction declaration = new FunctionDeclarationInstruction();
                 * TokenList nameTokens = ((ParenthesisGroupToken)exprTokens[1]).Tokens;
                 *
                 * // Ici on parcours les jetons de exprToken (qui doit être un OperandToken)
                 * // afin de trouver les noms des arguments.
                 *
                 * // Liste contenant les noms des arguments
                 * List<string> argsNamesLists = new List<string>();
                 * string funName = ((InfoToken)(exprTokens[0])).Content;
                 *
                 * // Indique si le prochain jeton doit être une virgule
                 * bool needComa = false;
                 * foreach (Token tok in nameTokens)
                 * {
                 *  if (needComa && tok.Type != TokenType.Separator)
                 *      throw new Exception("Expected ',' token in function declaration");
                 *  else
                 *      needComa = false;
                 *  // Si c'est un nom :
                 *  if (tok.Type == TokenType.OperandTokens && ((OperandToken)tok).Tokens.First().Type == TokenType.Noun)
                 *  {
                 *      argsNamesLists.Add(((InfoToken)((OperandToken)tok).Tokens.First()).Content);
                 *      needComa = true;
                 *  }
                 * }
                 * // Setup de la déclaration de fonction.
                 * declaration.Function = new Function();
                 * declaration.Function.ArgumentNames = argsNamesLists;
                 * declaration.Function.Body = block;
                 * declaration.FunctionName = funName;
                 *
                 * return declaration;*/
                break;

            case "while":
                IGettable expr = ParseExpression(exprToken, mainContext);
                block = ParseBlock(blockToken.Tokens, mainContext);
                WhileStatement statement = new WhileStatement();
                statement.Block     = block;
                statement.Condition = expr;
                return(statement);

            case "for":
                // Dans le cas d'une boucle for, expr est une opérande, contenant
                // une instruction, une expression, et une autre instruction.
                // (bizarre, certes)
                TokenList initializationInstruction = new TokenList();
                TokenList stepInstruction           = new TokenList();
                TokenList conditionExpr             = new TokenList();
                int       step = 0;
                foreach (Token tok in ((OperandToken)exprToken).Tokens)
                {
                    if (tok.Type == TokenType.EndOfInstruction)
                    {
                        step++;
                    }
                    else
                    {
                        switch (step)
                        {
                        case 0:
                            initializationInstruction.Add(tok);
                            break;

                        case 1:
                            conditionExpr.Add(tok);
                            break;

                        case 2:
                            stepInstruction.Add(tok);
                            break;
                        }
                    }
                }
                // On vérifie qu'on ait bien le bon nombre.
                if (step != 2)
                {
                    throw new Exception("Incorrect for statement.");
                }

                // On crée et on retourne le for.
                ForStatement forStatement = new ForStatement();
                forStatement.Initialisation = ParseInstruction(initializationInstruction, mainContext);
                forStatement.Condition      = ParseExpression(new OperandToken(conditionExpr), mainContext);
                forStatement.Update         = ParseInstruction(stepInstruction, mainContext);
                forStatement.Block          = block;

                return(forStatement);

            default:
                throw new NotImplementedException("Not implemented statement");
            }
        }