using System; using System.Collections.Generic; using System.Reflection; using System.Text; using CLAP; using CLAP.Interception; using CLAP.Validation; namespace xmlTools { // Define a class to receive parsed values class ParametersParser { private static string globalFileName = ""; private static string globalElement = ""; private static string globalParentElement = ""; private static bool globalNoBackups = false; [Verb] public static void addValue( [Parameter(Required = true, Description = "Values to add to Element. Separated multiple by spaces.")] string value ) { initialChecks(); XmlTools myTools = new XmlTools(globalElement, globalParentElement, globalNoBackups); List filesToProcess = getFilesToProcess(globalFileName); foreach (string currentFile in filesToProcess) { myTools.addValues(currentFile, value); } printProcessedMessage(filesToProcess.Count, MethodBase.GetCurrentMethod().Name); } [Verb] public static void removeValue( [Parameter(Required = true, Description = "Values to remove of Element. Separated multiple by spaces.")] string value ) { initialChecks(); XmlTools myTools = new XmlTools(globalElement, globalParentElement, globalNoBackups); List filesToProcess = getFilesToProcess(globalFileName); foreach (string currentFile in filesToProcess) { myTools.removeValues(currentFile, value); } printProcessedMessage(filesToProcess.Count, MethodBase.GetCurrentMethod().Name); } [Verb] public static void updateChainValues( [Parameter(Required = true, Description = "The new first value of the chain. All the chain will be updated based on this value")] string newValue, [Parameter(Description = "Value which have some kind of relation with -newVal \n Together with -newVal updates all the values based on the" + "-newvalue and another position specified on -valrelation parameter (basically starts with (newvalue-valrelation) ) Is especially useful when" + "updating multiple related chains (on different files), like multiple objects from one position to another. Don't use with -filename, because" + "it will only update one file. \nExample: xmlTools.exe updatechainvalues -filename:OBANheli_body_center.xml -newvalue:\"1 1 1\" -valrelation:\"4 4 4\" -element:Translation -parelement:" + "OBANKeyFrame")] string valRelation, [Parameter(Description = "Only update specific positions. Positions starts with 0, separted multiple positions with space. Example: valpositions=\"0 1 4\"")] [MoreThan(-1)] string valPositions ) { initialChecks(); XmlTools myTools = new XmlTools(globalElement, globalParentElement, globalNoBackups); List filesToProcess = getFilesToProcess(globalFileName); foreach (string currentFile in filesToProcess) { myTools.changeValue(currentFile, newValue, valRelation, valPositions); } printProcessedMessage(filesToProcess.Count, MethodBase.GetCurrentMethod().Name); } [Verb(Description = "Inverts a chain (like an OBAN animation). Example: xmlTools.exe -filename OBANheli_rotorblades08.xml -invert -valElement Translation -valParentElement OBANKeyFrame (inverts translation chain)")] public static void Invert() { initialChecks(); XmlTools myTools = new XmlTools(globalElement, globalParentElement, globalNoBackups); List filesToProcess = getFilesToProcess(globalFileName); foreach (string currentFile in filesToProcess) { myTools.invert(currentFile); //Inverting the element order } printProcessedMessage(filesToProcess.Count, MethodBase.GetCurrentMethod().Name); } [Verb] public static void replaceValue( [Parameter(Required = true, Description = "Old value to replace in Element.")] string oldValue, [Parameter(Required = true, Description = "New value to replace in Element.")] string newValue ) { XmlTools myTools = new XmlTools(globalElement, globalParentElement, globalNoBackups); List filesToProcess = getFilesToProcess(globalFileName); foreach (string currentFile in filesToProcess) { myTools.replaceValue(currentFile, oldValue, newValue); } printProcessedMessage(filesToProcess.Count, MethodBase.GetCurrentMethod().Name); } [Verb] public static void replaceAll( [Parameter(Required = true, Description = "Value to replace in Element. Replace all values of a element by another value.")] string value, [Parameter(Description = "Only replace specific positions. Positions starts with 0, separted multiple positions with space. Example: valPositions=0 1 4")] [MoreThan(-1)] string valPositions ) { initialChecks(); XmlTools myTools = new XmlTools(globalElement, globalParentElement, globalNoBackups); List filesToProcess = getFilesToProcess(globalFileName); foreach (string currentFile in filesToProcess) { if (!String.IsNullOrEmpty(valPositions)) { myTools.replaceAll(currentFile, value, valPositions); } else { myTools.replaceAll(currentFile, value); } } printProcessedMessage(filesToProcess.Count, MethodBase.GetCurrentMethod().Name); } /// /// Patch in files can be used with wildcard or empty filename instead /// /// [Verb] public static void patchFile( [Parameter(Description = "Force the specified patch to run in specified files")] string forceInFiles ) { XmlPatch myPatch; if (!String.IsNullOrEmpty(forceInFiles)) { myPatch = new XmlPatch(globalFileName, forceInFiles, globalNoBackups); } else { myPatch = new XmlPatch(globalFileName, globalNoBackups); } myPatch.startPatch(); } [Verb(Description = "Displays current XmlTools version.")] public static void version() { Console.WriteLine("xmlTools v" + Program.XmlToolsVersion); Console.WriteLine("\nWritten by s10k"); } [Verb(Description = "Displays extra informations about XmlTools.")] public static void about() { version(); Console.WriteLine(); Console.WriteLine("For extra XmlTools support check it page at: http://wiki.oni2.net/XmlTools"); Console.WriteLine(); Console.WriteLine("This program uses the following free libraries: "); Console.WriteLine("-CLAP: for parameter parsing. (http://adrianaisemberg.github.io/CLAP/)"); Console.WriteLine("-IronJS: for custom javascript code execution. (https://github.com/fholm/IronJS)"); Console.WriteLine(); Console.WriteLine("A big thanks to all the oni.bungie.org community!"); } [Verb] public static void showErrTypes() { Array values = Enum.GetValues(typeof(Program.appErrors)); foreach (Program.appErrors val in values) { Console.WriteLine(Enum.GetName(typeof(Program.appErrors),val) + " : " + (int)val); } } // Global Parameters [Global(Description = "Filename to apply the operations (with patchFile specifies the patch filename). Wildcards accepted for multiple files. No filename = search all .xml files in current path.")] public static void fileName( [Parameter(Required = true)] string filename // xml filename. Wildcards accepted. ) { globalFileName = filename; } [Global(Description = "Element to apply the operation.")] public static void element( [Parameter(Required = true)] string element ) { globalElement = element; } [Global(Description = "Parent of the Element to apply the operation.")] public static void parElement( [Parameter(Required = true)] string parentElement ) { globalParentElement = parentElement; } [Global(Description = "Don't make backup of the files modified. Improves the overall program processing performance.")] public static void noBackups() { globalNoBackups = true; } // Private functions private static List getFilesToProcess(String filename) { List filesToProccess = new List(); if (String.IsNullOrEmpty(filename)) // No filename? Process everything xml file found. { List allXmlFiles = Util.getAllXmlFiles(); foreach (String file in allXmlFiles) { filesToProccess.Add(file); } } else if (Util.containsWildcard(filename)) // Contains wildcards? Get all files that match it. { List matchingWildcardFiles = Util.getXmlFilesWildcard(filename); foreach (String file in matchingWildcardFiles) { filesToProccess.Add(file); } } else // Add the file specified { if (System.IO.File.Exists(filename)) { filesToProccess.Add(filename); } else { Program.printAppError(Program.appErrors.FILE_NOT_FOUND, "The file specified: " + filename + " doesn't exists.", true); } } return filesToProccess; } private static void printProcessedMessage(int count, string methodName) { Console.WriteLine(count + " files processed with " + methodName + " command."); } private static void initialChecks() { if (String.IsNullOrEmpty(globalElement.Trim())) { Program.printAppError(Program.appErrors.ELEMENT_NOT_FOUND, "You must specify the element parameter where the operations will be processed.", true); } } } }