Search.cs 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.IO;
  5. using System.Linq;
  6. namespace OpenVIII.Search
  7. {
  8. public class Search
  9. {
  10. #region Fields
  11. public List<Tuple<string, string, long>> results = new List<Tuple<string, string, long>>();
  12. private static readonly Memory.Archive[] ArchiveList = new Memory.Archive[]
  13. {
  14. //Memory.Archives.A_MENU,
  15. //Memory.Archives.A_MAIN,
  16. //Memory.Archives.A_FIELD, // need support for file in two archives.
  17. //Memory.Archives.A_MAGIC,
  18. //Memory.Archives.A_WORLD,
  19. //Memory.Archives.A_BATTLE,
  20. };
  21. private static readonly string[] Files = new string[]
  22. {
  23. Path.Combine(Memory.FF8DIR,"FF8_EN.exe"),
  24. //Path.Combine(Memory.FF8DIR,"AF3DN.P"),
  25. //Path.Combine(Memory.FF8DIR,"AF4DN.P")
  26. };
  27. private byte[] s;
  28. private string[] skipext = new string[]
  29. {
  30. ".tim",
  31. ".tex",
  32. ".obj"
  33. };
  34. #endregion Fields
  35. #region Constructors
  36. public Search(FF8String searchstring)
  37. {
  38. s = searchstring;
  39. foreach (Memory.Archive a in ArchiveList)
  40. {
  41. ArchiveWorker aw = new ArchiveWorker(a);
  42. string[] lof = aw.GetListOfFiles();
  43. foreach (string f in lof)
  44. {
  45. string ext = Path.GetExtension(f);
  46. if (skipext.Where(x => x.IndexOf(ext, StringComparison.OrdinalIgnoreCase) >= 0).Count() > 0) continue;
  47. Debug.WriteLine($"Searching {f}, in {a} for {searchstring}");
  48. //byte[] bf = aw.GetBinaryFile(f);
  49. //SearchBin(bf, a.ToString(), f);
  50. using (BinaryReader br = new BinaryReader(new MemoryStream(aw.GetBinaryFile(f))))
  51. {
  52. SearchBin(br, a.ToString(), f);
  53. }
  54. }
  55. }
  56. foreach (string a in Files)
  57. {
  58. Debug.WriteLine($"Searching {a}, for {searchstring}");
  59. using (BinaryReader br = new BinaryReader(File.OpenRead(a))) //new FileStream(a, FileMode.Open, FileAccess.Read, FileShare.None, 65536)))//
  60. {
  61. br.BaseStream.Seek(0, SeekOrigin.Begin);
  62. //byte[] bf = br.ReadBytes((int)br.BaseStream.Length);
  63. //SearchBin(bf, a, "");
  64. SearchBin(br, a, "");
  65. }
  66. }
  67. }
  68. #endregion Constructors
  69. #region Methods
  70. /// <summary>
  71. /// Less Slow search.
  72. /// </summary>
  73. /// <param name="bf">buffer</param>
  74. /// <param name="a">file/archive it's searching</param>
  75. /// <param name="f">sub file</param>
  76. public void SearchBin(BinaryReader br, string a, string f)
  77. {
  78. long offset;
  79. while ((offset = br.BaseStream.Position) < br.BaseStream.Length)
  80. {
  81. int pos = 0;
  82. foreach (byte i in s)
  83. {
  84. if (br.ReadByte() == i)
  85. {
  86. pos++;
  87. }
  88. else break;
  89. }
  90. if (pos == s.Length)
  91. {
  92. Debug.WriteLine(string.Format("Found a match at: offset {0:X}", offset));
  93. results.Add(new Tuple<string, string, long>(a, f, offset));
  94. }
  95. }
  96. }
  97. /// <summary>
  98. /// Slow AF search.
  99. /// </summary>
  100. /// <param name="bf">buffer</param>
  101. /// <param name="a">file/archive it's searching</param>
  102. /// <param name="f">sub file</param>
  103. public void SearchBin(byte[] bf, string a, string f)
  104. {
  105. int i = 0;
  106. do
  107. {
  108. i = Array.FindIndex(bf, i, bf.Length - i, x => x == s[0]);
  109. if (i >= 0 && bf != null)
  110. {
  111. byte[] full = bf.Skip(i).Take(s.Length).ToArray();
  112. if (full.SequenceEqual(s))
  113. {
  114. Debug.WriteLine(string.Format("Found a match at: offset {0:X}", i));
  115. results.Add(new Tuple<string, string, long>(a, f, i));
  116. }
  117. i++;
  118. }
  119. }
  120. while (i > 0);
  121. //bf = bf.Reverse().ToArray();
  122. //i = 0;
  123. //do
  124. //{
  125. // i = Array.FindIndex(bf, i, bf.Length - i, x => x == s[0]);
  126. // if (i >= 0 && bf != null)
  127. // {
  128. // var full = bf.Skip(i).Take(s.Length).ToArray();
  129. // if (full.SequenceEqual(s))
  130. // {
  131. // results.Add(new Tuple<string, string, long>(a, f, i));
  132. // }
  133. // i++;
  134. // }
  135. //}
  136. //while (i > 0);
  137. //string decodedarchive = Memory.DirtyEncoding.GetString(aw.GetBinaryFile(f));
  138. //Regex r = new Regex(searchstring, RegexOptions.IgnoreCase);
  139. //Match m = r.Match(f);
  140. //if(m.Success)
  141. //{
  142. // results.Add(new Tuple<string, string, long>(a, f, m.Index));
  143. //}
  144. }
  145. #endregion Methods
  146. }
  147. }