static void Main(string[] args) { #if DEBUG var vmfPath = Path.GetFullPath(@".\..\..\Tests\dev_room.vmf"); var configPath = Path.GetFullPath(@".\..\..\Tests\remotecompile.cfg"); #else var vmfPath = "path.vmf"; var configPath = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location), "remotecompile.cfg"); #endif //TODO: Take parameter of map to compile //TODO: Take parameter of maps root path for instances // Temporarily use vmf location var mapsRoot = Path.GetDirectoryName(vmfPath); //TODO: Take optional parameter of config file path //TODO: Load local config file, if it doesn't exist, create a default one Config config; if (File.Exists(configPath)) { //TODO: Load config } else { #region Create default config config = new Config(new List <IVNode> { new VBlock("RemoteCompileConfig", new List <IVNode> { new VBlock("BuildServer", new List <IVNode> { new VProperty("Address", "127.0.0.1") , new VProperty("Port", "9043") , new VProperty("Username", "") , new VProperty("Password", "") , new VBlock("AuthLock", new List <IVNode> { new VProperty("Token", "") , new VProperty("Expires", "") }) }) , new VProperty("BuildTarget", "Source SDK 2013") //TODO: Add all available VBSP, VVIS, VRAD parameters , new VBlock("VBSP", new List <IVNode> { new VProperty("", "") }) , new VBlock("VVIS", new List <IVNode> { new VProperty("", "") }) , new VBlock("VRAD", new List <IVNode> { new VProperty("", "") }) }) }); File.WriteAllLines(configPath, config.ToVMFStrings()); #endregion } // Load VMF if (!File.Exists(vmfPath)) { // Early exit Console.WriteLine("Map does not exist \"{0}\"", vmfPath); return; } var vmfFileContents = File.ReadAllLines(vmfPath); var vmf = new VMF(vmfFileContents); // Recursively identify and load dependent instances // Track instance dependency tree to recognize instance recursion // Only dig 100 levels deep unless otherwise specified in the config var instanceTree = new Dictionary <int, Tuple <string, List <int> > >(); BuildInstanceTree(instanceTree, 100, 0, vmf, vmfPath, BuildInstanceDictionaryKeyIndex++, mapsRoot); //TODO: Make sure there is no recursion in the instanceTree //TODO: Request hashes of all dependent resources from server. // Compare results to local copies. // Notify user of the comparison //TODO: Send compile request with serialized parameters, and list of incoming resources //TODO: Send copy of vmf and instances to server //TODO: Spin off waiting thread for server to execute OnCompleteBuild commands // This could include: downloading the map, and running the game }
/** * Exports the given NailsMap to a VMF file. Uses the file name passed in when this adapter was constructed. * <author>1upD</author> */ public void Export(NailsMap map) { try { log.Info(string.Format("Exporting Nails map data to VMF file: {0}", this._filename)); // Make a deep copy of the stored VMF to add instances to VMF output_vmf = new VMFParser.VMF(this._vmf.ToVMFStrings()); int i = 0; foreach (NailsCube cube in map.NailsCubes) { int x_pos = cube.X * this._horizontal_scale; int y_pos = cube.Y * this._horizontal_scale; int z_pos = cube.Z * this._vertical_scale; var faces = cube.GetFaces(); if (faces.Contains(NailsCubeFace.Floor)) { instanceData instance = this.MakeInstance("floor", cube.StyleName, 0, i++, x_pos, y_pos, z_pos); insertInstanceIntoVMF(instance, output_vmf); } if (faces.Contains(NailsCubeFace.Front)) { instanceData instance = this.MakeInstance("wall", cube.StyleName, 0, i++, x_pos, y_pos, z_pos); insertInstanceIntoVMF(instance, output_vmf); } if (faces.Contains(NailsCubeFace.Left)) { instanceData instance = this.MakeInstance("wall", cube.StyleName, 90, i++, x_pos, y_pos, z_pos); insertInstanceIntoVMF(instance, output_vmf); } if (faces.Contains(NailsCubeFace.Back)) { instanceData instance = this.MakeInstance("wall", cube.StyleName, 180, i++, x_pos, y_pos, z_pos); insertInstanceIntoVMF(instance, output_vmf); } if (faces.Contains(NailsCubeFace.Right)) { instanceData instance = this.MakeInstance("wall", cube.StyleName, 270, i++, x_pos, y_pos, z_pos); insertInstanceIntoVMF(instance, output_vmf); } if (faces.Contains(NailsCubeFace.Ceiling)) { instanceData instance = this.MakeInstance("ceiling", cube.StyleName, 0, i++, x_pos, y_pos, z_pos); insertInstanceIntoVMF(instance, output_vmf); } } using (StreamWriter sw = new StreamWriter(new FileStream(this._filename, FileMode.Create))) { var vmfStrings = output_vmf.ToVMFStrings(); foreach (string line in vmfStrings) { sw.WriteLine(line); } } log.Info(string.Format("Wrote to VMF file: {0}", this._filename)); } catch (Exception e) { log.Error("VMFAdapter.Export(): Caught exception: ", e); log.Info(string.Format("Failed to write to VMF file: {0}", this._filename)); } }
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; }
static int CollapseInstances(VMF vmf) { #region Identify useable IDs int usableID = vmf.Body.GetHighestID() + 1; #endregion var world = vmf.Body.Where(node => node.Name == "world").Where(node => node is VBlock).Cast<VBlock>().FirstOrDefault(); if (world == null) { Console.WriteLine("Can't find \"world\""); return -1; } int lastEntityLocation = 0; lastEntityLocation = vmf.Body.IndexOf(world) + vmf.Body.Where(node => node.Name == "entity").Count(); int autoInstance = 0; var entities = vmf.Body.Where(item => item.Name == "entity").Select(item => item as VBlock).ToList(); var instances = entities.Where(entity => entity.Body.Where(item => item.Name == "classname" && (item as VProperty).Value == "func_instance").Count() > 0).ToList(); foreach (var instance in instances) { // Get instance targetname string instanceTargetName = ""; var instanceTargetNameProperty = instance.Body.Where(node => node.Name == "targetname" && node.GetType() == typeof(VProperty)).Select(node => node as VProperty).FirstOrDefault(); if ((instanceTargetNameProperty?.Value ?? "") == "") instanceTargetName = String.Format("AutoInstance{0}", autoInstance++); // TODO: Give it a default name if unnamed (or not?). // Load the instance vmf var fileProp = instance.Body.Where(node => node.Name == "file" && node.GetType() == typeof(VProperty)).Select(node => node as VProperty).FirstOrDefault(); if (fileProp == null || string.IsNullOrEmpty(fileProp.Value.Trim())) { // Looks like there is no file property, or its empty continue; } if (!File.Exists(fileProp.Value)) { // TODO: What do you do when the file doesn't exist? Probably should throw up some sort of error. // Just skip it for now. continue; } var instanceVMF = new VMF(File.ReadAllLines(fileProp.Value)); // Clone the important parts // TODO: think about collapsing groups // TODO: only grab visible entities var instanceVisibleEntities = instanceVMF.Body.Where(node => node.Name == "entity").Where(node => node is VBlock).Cast<VBlock>(); var instanceVisibleSolids = instanceVMF.Body.Where(node => node.Name == "world").Where(node => node is VBlock).Cast<VBlock>() .SelectMany(node => node.Body.Where(worldNode => worldNode.Name == "solid").Where(worldNode => worldNode is VBlock).Cast<VBlock>() ); // Update each entity into the map with relative offsets and angles from the instance point, and the instance origin (defaults at 0 0 0) // angles and origin var instanceOriginProperty = instance.Body.Where(node => node.Name == "origin" && node.GetType() == typeof(VProperty)).Select(node => node as VProperty).FirstOrDefault(); var instanceAnglesProperty = instance.Body.Where(node => node.Name == "angles" && node.GetType() == typeof(VProperty)).Select(node => node as VProperty).FirstOrDefault(); var instanceOrigin = new Vector3(instanceOriginProperty?.Value ?? "0 0 0"); var instanceAngles = new Vector3(instanceAnglesProperty?.Value ?? "0 0 0"); var fixupStyle = int.Parse(instance.Body.Where(node => node.Name == "fixup_style" && node.GetType() == typeof(VProperty)).Select(node => node as VProperty).FirstOrDefault()?.Value ?? "0"); foreach (var entity in instanceVisibleEntities) { VBlock collapsedEntity = CollapseEntity(entity, fixupStyle, instanceTargetName, instanceOrigin, instanceAngles, ref usableID); vmf.Body.Insert(lastEntityLocation++, collapsedEntity); } foreach (var solid in instanceVisibleSolids) { VBlock collapsedSolid = CollapseSolid(solid, ref usableID); world.Body.Add(collapsedSolid); } // Rename all internal communication // Link external IO // Replace replaceable parameters // Replace replaceable materials // Insert into actual map // Remove instance from map vmf.Body.Remove(instance); } return 0; }
static void Main(string[] args) { #if DEBUG args = new string[] { "preview.vmf" }; //REMOVE TEST DATA WHEN DEPLOYING :P #endif try { string fileName = args.FirstOrDefault(); vmf = new VMF(File.ReadAllLines(fileName)); if (TagModifications()) File.WriteAllLines(fileName, vmf.ToVMFStrings()); } catch (Exception ex) { File.WriteAllText("errors.txt", ex.ToString()); } }