static void Main(string[] args) { var oldVMFFilePath = string.Empty; var newVMFFilePath = string.Empty; var p = new OptionSet() { { "o|old=", v => { oldVMFFilePath = v; } } , { "n|new=", v => { newVMFFilePath = v; } } }; var extra = p.Parse(args); #if DEBUG oldVMFFilePath = "../../Test/test_2p.vmf"; newVMFFilePath = "../../Test/test_2p_alt.vmf"; #endif if (!File.Exists(oldVMFFilePath) || !File.Exists(newVMFFilePath)) { //exit return; } var oldVMF = new VMF(File.ReadAllLines(oldVMFFilePath)); var newVMF = new VMF(File.ReadAllLines(newVMFFilePath)); var outVMF = new VMF(); var oldWorld = oldVMF.Body.Where(node => node.Name == "world").Where(node => node is VBlock).Cast <VBlock>().FirstOrDefault(); var newWorld = newVMF.Body.Where(node => node.Name == "world").Where(node => node is VBlock).Cast <VBlock>().FirstOrDefault(); //should totally use a dictionary instead var oldEntitiesList = oldVMF.Body.Where(node => node.Name == "entity").Where(node => node is VBlock).Cast <VBlock>().Select(block => Tuple.Create(block.Body.Where(property => property.Name == "id" && property is VProperty).Cast <VProperty>().FirstOrDefault()?.Value ?? "0", block)).ToList(); var newEntitiesList = newVMF.Body.Where(node => node.Name == "entity").Where(node => node is VBlock).Cast <VBlock>().Select(block => Tuple.Create(block.Body.Where(property => property.Name == "id" && property is VProperty).Cast <VProperty>().FirstOrDefault()?.Value ?? "0", block)).ToList(); //copy oldVMF outVMF = new VMF(oldVMF.ToVMFStrings()); //remove all the entities outVMF = new VMF(outVMF.Body.Where(node => node.Name != "entity").ToList()); //find the world var outWorldIndex = outVMF.Body.IndexOf(outVMF.Body.Where(node => node.Name == "world").Where(node => node is VBlock).Cast <VBlock>().FirstOrDefault()); //make a new one var outNewWorld = (outVMF.Body[outWorldIndex] as VBlock).Body.Where(node => node.Name != "solid").ToList(); //swap it in outVMF.Body[outWorldIndex] = new VBlock("world", outNewWorld); //don't include any duplicate IDs in the diffing process var entitiesNewDuplicateID = newEntitiesList.Where(newEntityTuple1 => newEntitiesList.Where(newEntityTuple2 => newEntityTuple1.Item1 == newEntityTuple2.Item1).Count() > 1).ToList(); var entitiesOldDuplicateID = oldEntitiesList.Where(oldEntityTuple1 => oldEntitiesList.Where(oldEntityTuple2 => oldEntityTuple1.Item1 == oldEntityTuple2.Item1).Count() > 1).ToList(); newEntitiesList.RemoveAll(entityTuple => entitiesNewDuplicateID.Where(duplicate => duplicate == entityTuple).Count() > 0); oldEntitiesList.RemoveAll(entityTuple => entitiesOldDuplicateID.Where(duplicate => duplicate == entityTuple).Count() > 0); var entitiesRemoved = oldEntitiesList.Where(oldEntityTuple => newEntitiesList.Where(newEntityTuple => newEntityTuple.Item1 == oldEntityTuple.Item1).Count() == 0).ToList(); var entitiesAdded = newEntitiesList.Where(newEntityTuple => oldEntitiesList.Where(oldEntityTuple => newEntityTuple.Item1 == oldEntityTuple.Item1).Count() == 0).ToList(); var entitiesOldRemaining = oldEntitiesList.Where(oldEntityTuple => newEntitiesList.Where(newEntityTuple => newEntityTuple.Item1 == oldEntityTuple.Item1).Count() > 0).ToList(); var entitiesNewRemaining = newEntitiesList.Where(newEntityTuple => oldEntitiesList.Where(oldEntityTuple => newEntityTuple.Item1 == oldEntityTuple.Item1).Count() > 0).ToList(); var entitiesNoChange = new List <Tuple <string, VBlock> >(); var entitiesOldChange = new List <Tuple <string, VBlock> >(); var entitiesNewChange = new List <Tuple <string, VBlock> >(); foreach (var oldEntityTuple in entitiesOldRemaining) { var newEntityTuple = entitiesNewRemaining.Where(newEntTuple => newEntTuple.Item1 == oldEntityTuple.Item1).FirstOrDefault(); if (VBlockMatches(oldEntityTuple.Item2, newEntityTuple.Item2)) { entitiesNoChange.Add(oldEntityTuple); } else { entitiesOldChange.Add(oldEntityTuple); entitiesNewChange.Add(newEntityTuple); } } //TODO: Include solids in the above diff checking, and separate them out when generating final VMF //set mapversion to 1 //iterate through world find differences, add to outWorld and visgroups //iterate through the rest of the entities and do the same File.WriteAllLines("diff.vmf", outVMF.ToVMFStrings()); }
static int Main(string[] args) { #if DEBUG //args = new string[] { "-file", "dev_room.vmf" }; args = new string[] { "-file", "1_instance.vmf" }; Utils.DirectoryCopy(@"../../instances", "instances", true, true); #endif #if !DEBUG try { #endif #region Get execution parameters string filePath = null; string gamePath = null; for (int i = 0; i < args.Length; i++) { if (args[i] == "-file" && i + 1 < args.Length && !args[i + 1].StartsWith("-")) { filePath = args[++i]; } else if (args[i] == "-game" && i + 1 < args.Length && !args[i + 1].StartsWith("-")) { gamePath = args[++i]; //does this matter, or should I use the vmfs path to find the instances } // else if // Add additional parameters here } if (filePath == null) { Console.ForegroundColor = ConsoleColor.Red; return(1); } #endregion #region Load VMF Console.Write("Loading file contents from \"" + filePath + "\"..."); string[] fileContents = File.ReadAllLines(filePath); Console.WriteLine("Complete."); Console.Write("Parsing vmf "); VMF vmf = new VMF(fileContents); #endregion CollapseInstances(vmf); #region Save Altered VMF string newFilePath = ""; newFilePath = filePath.EndsWith(".vmf") ? filePath.Insert(filePath.LastIndexOf("."), "_new") : filePath + "_new"; File.WriteAllLines(newFilePath, vmf.ToVMFStrings()); #endregion #if !DEBUG } #region catch - display exception catch (Exception ex) { WriteLine("Exception:", ConsoleColor.Yellow); WriteLine(ex.ToString(), ConsoleColor.Red); return(1); } #endregion #endif return(0); }