/// <summary> /// Repopulates the plan list with the plan files that are listed in the world REQ and mode MRQs. /// </summary> private void PopulatePlanList() { try { worldPlans.Clear(); // Get the existing pln files that are listed in the world req and merge the returned dictionary with the worldPlans dictionary ReqChunk basePlnChunk = ReqParser.ParseChunk(worldReqFilePath, "congraph"); var resolvedBasePlanFiles = basePlnChunk.ResolveContentsAsFiles(worldDirectory, ".pln", true); resolvedBasePlanFiles.ToList().ForEach(x => worldPlans[x.Key] = x.Value); // Get a list of all the existing pln files in each game mode mrq foreach (string modeFilePath in worldModes.Values) { if (modeFilePath != DROPDOWN_MODES_BASE) { ReqChunk modePlnChunk = ReqParser.ParseChunk(modeFilePath, "congraph"); // Get the mrq's existing pln files and merge the returned dictionary with the worldPlans dictionary var resolvedModePlanFiles = modePlnChunk.ResolveContentsAsFiles(worldDirectory, ".pln", true); resolvedModePlanFiles.ToList().ForEach(x => worldPlans[x.Key] = x.Value); } } // Add the pln files to the dropdown dd_PlanFile.Items.Clear(); dd_PlanFile.Items.AddRange(worldPlans.Keys.ToArray()); } catch (ArgumentNullException ex) { Trace.WriteLine(ex.Message); throw; } catch (FileNotFoundException ex) { Trace.WriteLine(ex.Message); throw; } catch (IOException ex) { Trace.WriteLine(ex.Message); throw; } catch (OutOfMemoryException ex) { Trace.WriteLine(ex.Message); throw; } ResetSelectedPlan(); }
/// <summary> /// Returns a list of file paths for files of the specified extensions from the specified world REQ file and mode MRQ. /// </summary> /// <param name="reqFile">Path of REQ file to parse.</param> /// <param name="mrqFile">Path of MRQ file to parse.</param> /// <param name="extensions">Array of file extensions to check for. (ex: ".rgn")</param> /// <returns></returns> private List <string> GetWorldChunkFilePaths(string reqFile, string mrqFile, string[] extensions) { List <string> filePaths = new List <string>(); bool mrq = (mrqFile != "" && mrqFile != DROPDOWN_MODES_BASE); try { // Retrieve the "world" REQN chunks ReqChunk baseWorldChunk = ReqParser.ParseChunk(reqFile, "world"); ReqChunk modeWorldChunk = new ReqChunk(); if (mrq) { modeWorldChunk = ReqParser.ParseChunk(mrqFile, "world"); } // Resolve the file paths for each extension foreach (string extension in extensions) { filePaths.AddRange(baseWorldChunk.ResolveContentsAsFiles(worldDirectory, extension).Values); if (mrq) { filePaths.AddRange(modeWorldChunk.ResolveContentsAsFiles(worldDirectory, extension).Values); } } } catch (FileNotFoundException ex) { Trace.WriteLine(ex.Message); throw; } catch (IOException ex) { Trace.WriteLine(ex.Message); throw; } catch (OutOfMemoryException ex) { Trace.WriteLine(ex.Message); throw; } return(filePaths); }
/// <summary> /// Repopulates the mode list with the modes that are listed in world REQ. /// </summary> private void PopulateModeList() { try { try { ReqChunk reqChunk = ReqParser.ParseChunk(worldReqFilePath, "lvl"); // Add the "[Base]" mode to the list worldModes.Clear(); worldModes.Add(DROPDOWN_MODES_BASE, DROPDOWN_MODES_BASE); // Get the existing mrq files and merge the returned dictionary with the worldModes dictionary var resolvedFiles = reqChunk.ResolveContentsAsFiles(worldDirectory, ".mrq", true); resolvedFiles.ToList().ForEach(x => worldModes[x.Key] = x.Value); // Add the modes to the dropdown dd_ModeMrq.Items.Clear(); dd_ModeMrq.Items.AddRange(worldModes.Keys.ToArray()); } catch (FileNotFoundException ex) { Trace.WriteLine(ex.Message); throw; } catch (IOException ex) { Trace.WriteLine(ex.Message); throw; } catch (OutOfMemoryException ex) { Trace.WriteLine(ex.Message); throw; } } catch (ArgumentNullException ex) { Trace.WriteLine(ex.Message); throw; } ResetSelectedMode(); }
/// <summary> /// Returns the contents of a given chunk name in a REQ (or MRQ) file. /// </summary> /// <param name="reqFilePath">File path of file to parse chunk from.</param> /// <param name="reqChunkName">Name of REQN chunk to parse.</param> /// <returns>Contents of parsed REQN chunk.</returns> /// <exception cref="FileNotFoundException"></exception> /// <exception cref="IOException"></exception> /// <exception cref="OutOfMemoryException"></exception> public static ReqChunk ParseChunk(string reqFilePath, string reqChunkName) { string ParseLine(string line) { if (line.Contains("\"")) { // TODO: should probably refactor this to use the Trim method // Get the contents in the quotation marks return(line.Substring(line.IndexOf("\"") + 1, line.LastIndexOf("\"") - line.IndexOf("\"") - 1)); } else { return(line); } } bool CheckLine(string line, string match) { if (line.ToLower().Contains(match.ToLower())) { //Debug.WriteLine("match: " + match.ToLower()); } return(line.ToLower().Contains(match.ToLower())); } ReqChunk reqChunk = new ReqChunk(); reqChunk.Contents = new List <string>(); if (!File.Exists(reqFilePath)) { var message = "ERROR! File does not exist at " + reqFilePath; Trace.WriteLine(message); return(reqChunk); } FileInfo fileInfo = new FileInfo(reqFilePath); if (fileInfo.Extension.ToLower() != ".req" && fileInfo.Extension.ToLower() != ".mrq") { var message = "ERROR! File extension is " + fileInfo.Extension; Trace.WriteLine(message); return(reqChunk); } string curLine; int numChunks = 0; int curChunkIdx = 0; bool foundChunk = false; ReqChunkParseState curState = ReqChunkParseState.CheckBegin; try { StreamReader file = new StreamReader(reqFilePath); // Count the number of REQ chunks in the file while ((curLine = file.ReadLine()) != null) { //Debug.WriteLine("curLine: " + curLine); if (CheckLine(curLine, "REQN")) { numChunks++; } } Debug.WriteLine("numChunks: " + numChunks); // Scan the file line by line and extract the segments from the given REQ chunk Debug.WriteLine("Looking for chunk: " + reqChunkName); file = new StreamReader(reqFilePath); if (numChunks > 0) { while ((curLine = file.ReadLine()) != null) { var parsedLine = ParseLine(curLine); //Debug.WriteLine("curLine: " + curLine); // File Header if (CheckLine(parsedLine, "ucft") && curState == ReqChunkParseState.CheckBegin) { curState = ReqChunkParseState.FileHeader; } // File Begin - opening bracket if (CheckLine(parsedLine, "{") && curState == ReqChunkParseState.FileHeader) { curState = ReqChunkParseState.FileBegin; } // Chunk Header if (CheckLine(parsedLine, "REQN")) { curState = ReqChunkParseState.ChunkHeader; curChunkIdx++; } // Chunk Begin - opening bracket if (CheckLine(parsedLine, "{") && curState == ReqChunkParseState.ChunkHeader) { curState = ReqChunkParseState.ChunkBegin; } // Chunk Name - declaration of chunk type, e.g. "lvl", "class", "config", etc. if (!parsedLine.Contains("{") && curState == ReqChunkParseState.ChunkBegin) { curState = ReqChunkParseState.ChunkName; //Debug.WriteLine("Current chunk: " + parsedLine); if (parsedLine == reqChunkName) { Debug.WriteLine("Found chunk: " + parsedLine); Debug.WriteLine("Adding Name: " + parsedLine); reqChunk.Name = parsedLine; foundChunk = true; } else { Debug.WriteLine("Wrong chunk: " + parsedLine); foundChunk = false; } } // Start processing and storing the different chunk segments if we have the right chunk if (foundChunk && reqChunk.Name != null) { // Chunk Align - chunk header byte align value, pretty much almost always "align=2048" if (CheckLine(parsedLine, "align=") && (curState == ReqChunkParseState.ChunkName || curState == ReqChunkParseState.ChunkPlatform)) { curState = ReqChunkParseState.ChunkAlign; Debug.WriteLine("Adding Align: " + parsedLine); reqChunk.Align = parsedLine; } // Chunk Platform - platform designation for the chunk, always "platform=" followed by "pc", "ps2" or "xbox", e.g. "platform=pc" if ((curState == ReqChunkParseState.ChunkName || curState == ReqChunkParseState.ChunkAlign) && CheckLine(parsedLine, "platform=")) { curState = ReqChunkParseState.ChunkPlatform; Debug.WriteLine("Adding Platform: " + parsedLine); reqChunk.Platform = parsedLine; } // Chunk Contents - list of files within the chunk if (!CheckLine(parsedLine, "align=") && !CheckLine(parsedLine, "platform=") && !CheckLine(parsedLine, reqChunk.Name) && !CheckLine(parsedLine, "}") && (curState == ReqChunkParseState.ChunkContents || curState == ReqChunkParseState.ChunkName || curState == ReqChunkParseState.ChunkAlign || curState == ReqChunkParseState.ChunkPlatform)) { curState = ReqChunkParseState.ChunkContents; // Don't add blank lines! if (curLine.Contains("\"")) { Debug.WriteLine("Adding Contents: " + parsedLine.ToLower()); reqChunk.AddContents(parsedLine.ToLower()); } } } // Chunk End - closing bracket if (CheckLine(parsedLine, "}") && ((curState == ReqChunkParseState.ChunkContents) || (curState == ReqChunkParseState.ChunkName && !foundChunk))) { curState = ReqChunkParseState.ChunkEnd; } // File End - closing bracket if (CheckLine(parsedLine, "}") && curState == ReqChunkParseState.ChunkEnd && curChunkIdx == numChunks) { Debug.WriteLine("END OF FILE"); curState = ReqChunkParseState.FileEnd; } } } else { Trace.WriteLine("ERROR! There are no chunks in the REQ file @ " + @reqFilePath); } file.Close(); } catch (FileNotFoundException ex) { throw new FileNotFoundException(ex.Message, reqFilePath, ex); } catch (IOException ex) { throw new IOException(ex.Message, ex); } catch (OutOfMemoryException ex) { throw new OutOfMemoryException(ex.Message, ex); } return(reqChunk); }