BrawlBuilder.BrawlBuilder.Analyze C# (CSharp) Method

Analyze() private method

private Analyze ( ) : bool
return bool
		private bool Analyze()
		{
			SetStatus("Analyzing...");

			if (File.Exists(_basePath + @"\Resources\CodePatches.txt"))
			{
				// First we'll read the patches we are going to make
				string[] actions = { "REMOVE", "PATCH", "TO", "IF", "ENDIF", "REMOVE_EN" };
				string action = "";
				bool doActions = true;

				string bytesString = "";
				string patchBytesString = "";

				int removes = 0;
				int successfulRemoves = 0;

				int patches = 0;
				int successfulPatches = 0;

				// Load GCT into memory
				byte[] gctBytes = File.ReadAllBytes(gctFile.Text);

				foreach (string s in File.ReadLines(_basePath + @"\Resources\CodePatches.txt"))
				{
					string line = s.Trim().Substring(0, s.IndexOf('#') < 0 ? s.Length : s.IndexOf('#')); // Trim whitespace, ignore comments

					if (actions.Contains(line))
					{
						// Handle one-liner statements. These don't affect action
						if (line == "ENDIF")
						{
							doActions = true; // 'IF' statement is over, start doing actions again (if they were ever stopped)
							continue;
						}
						else if (line == "REMOVE_EN" && doActions)
						{
							_remove_en = true;
							continue;
						}

						action = line;

						continue;
					}

					if (!doActions)
						continue; // If we aren't doing actions just keep looping until the 'ENDIF'

					// Handle multi-line statements
					switch (action)
					{
						case "IF":
							if (line == "") // Blank line means end of codes block, so we can handle the 'IF' statement now.
							{
								action = "";

								if (bytesString.Length > 0)
								{
									byte[] bytes = Enumerable.Range(0, bytesString.Length).Where(x => x % 2 == 0).Select(x => Convert.ToByte(bytesString.Substring(x, 2), 16)).ToArray();
									if (SearchBytes(gctBytes, bytes) < 1)
										doActions = false; // If code wasn't found, stop doing actions until the 'ENDIF' statement
								}

								bytesString = "";
							}
							else
								bytesString += line.Replace(" ", "");
							break;
						case "REMOVE":
							if (line == "")
							{
								action = "";

								if (bytesString.Length > 0)
								{
									removes++;
									byte[] bytes = Enumerable.Range(0, bytesString.Length).Where(x => x % 2 == 0).Select(x => Convert.ToByte(bytesString.Substring(x, 2), 16)).ToArray();
									int index = SearchBytes(gctBytes, bytes);
									if (index >= 0)
									{
										IEnumerable<byte> before = gctBytes.Take(index);
										IEnumerable<byte> after = gctBytes.Skip(index + bytes.Length);

										gctBytes = before.Concat(after).ToArray();
										successfulRemoves++;
									}

									bytesString = "";
								}
							}
							else
								bytesString += line.Replace(" ", "");
							break;
						case "PATCH":
							if (line == "")
								action = ""; // Patch is done after next 'TO'
							else
								patchBytesString += line.Replace(" ", "");
							break;
						case "TO":
							if (line == "")
							{
								action = "";

								if (bytesString.Length > 0 && patchBytesString.Length > 0)
								{
									patches++;
									byte[] patchBytes = Enumerable.Range(0, patchBytesString.Length).Where(x => x % 2 == 0).Select(x => Convert.ToByte(patchBytesString.Substring(x, 2), 16)).ToArray();
									byte[] bytes = Enumerable.Range(0, bytesString.Length).Where(x => x % 2 == 0).Select(x => Convert.ToByte(bytesString.Substring(x, 2), 16)).ToArray();
									int index = SearchBytes(gctBytes, patchBytes);
									if (index >= 0)
									{
										IEnumerable<byte> before = gctBytes.Take(index);
										IEnumerable<byte> after = gctBytes.Skip(index + patchBytes.Length);

										gctBytes = before.Concat(bytes.Concat(after)).ToArray();

										successfulPatches++;
									}

									bytesString = "";
									patchBytesString = "";
								}
							}
							else
								bytesString += line.Replace(" ", "");
							break;
					}
				}

				if (Environment.GetCommandLineArgs().Contains("--notify-gct-patch"))
					MessageBox.Show("Removed codes: " + successfulRemoves + "/" + removes + "\nPatched Codes: " + successfulPatches + "/" + patches + "\nRemove '_en': " + _remove_en, "Notice", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);

				File.WriteAllBytes(_basePath + @"\Resources\temp.gct", gctBytes);
			}
			else
			{
				DialogResult result = MessageBox.Show("CodePatches.txt not found. Do you want to continue without GCT patching? The output ISO may not work without this.", "Notice", MessageBoxButtons.YesNo, MessageBoxIcon.Question);

				if (result == DialogResult.No)
					buildWorker.CancelAsync();
			}

			if (buildWorker.CancellationPending)
				return false;

			return true;
		}