SubDirectory.cpp 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. //
  2. // Created by Иван_Архипов on 07.11.2017.
  3. //
  4. #include "SubDirectory.h"
  5. #include "DatFile.h"
  6. #include "DatException.h"
  7. #include "Subfile.h"
  8. #include "BinaryData.h"
  9. LOTRO_DAT::SubDirectory::SubDirectory() {
  10. offset_ = 0;
  11. }
  12. LOTRO_DAT::SubDirectory::SubDirectory(long long offset, DatFile *dat, long long max_subdirs) :
  13. offset_(offset), dat_(dat), max_subdirs_(max_subdirs) {
  14. try {
  15. MakeSubDirectories();
  16. } catch (...) {
  17. fprintf(stderr, "Unable to initialize directory at offset %lld. Initializing it as empty directory...\n", offset);
  18. subdirs_.clear();
  19. subfiles_.clear();
  20. return;
  21. }
  22. try {
  23. MakeSubFiles();
  24. } catch (...) {
  25. fprintf(stderr, "Unable to initialize directory at offset %lld. Initializing it as empty directory...\n", offset);
  26. subdirs_.clear();
  27. subfiles_.clear();
  28. return;
  29. }
  30. }
  31. void LOTRO_DAT::SubDirectory::MakeSubDirectories() {
  32. BinaryData data(1024);
  33. dat_->ReadData(data, 63 * 8, offset_);
  34. if (data.ToNumber<4>(0) != 0 || data.ToNumber<4>(4) != 0) {
  35. std::string err =
  36. std::string("Bad SubDirectory::MakeSubDirectories - first 8 bytes are not equal to 0 at offset ")
  37. + std::to_string(offset_);
  38. throw DatException(err.c_str(), SUBDIR_EXCEPTION);
  39. }
  40. for (unsigned int i = 8; i < 63 * 8; i += 8) {
  41. if (data.ToNumber<4>(i) == 0 || data.ToNumber<4>(i + 4) == 0)
  42. break;
  43. try {
  44. subdirs_.emplace_back(
  45. SubDirectory(
  46. data.ToNumber<4>(i + 4),
  47. dat_
  48. )
  49. );
  50. } catch (...) {
  51. fprintf(stderr, "Making SubDirectory at offset %lld failed, continuing\n", data.ToNumber<4>(i + 4));
  52. }
  53. }
  54. }
  55. void LOTRO_DAT::SubDirectory::MakeSubFiles() {
  56. BinaryData data(64 * 32);
  57. dat_->ReadData(data, 64 * 32, offset_ + 63 * 8);
  58. for (unsigned int i = 0; i < 61 * 32; i += 32) {
  59. if (data.ToNumber<4>(i + 8) < 0x32 || data.ToNumber<4>(i + 12) < 0x32)
  60. continue;
  61. subfiles_.emplace_back(
  62. Subfile(
  63. dat_,
  64. data.ToNumber<4>(i), // fragments_count
  65. data.ToNumber<4>(i + 4), // unknown1
  66. data.ToNumber<4>(i + 8), // file_id
  67. data.ToNumber<4>(i + 12), // file_offset
  68. data.ToNumber<4>(i + 16), // block_size
  69. data.ToNumber<4>(i + 20), // timestamp
  70. data.ToNumber<4>(i + 24), // version
  71. data.ToNumber<4>(i + 28) // block_size
  72. )
  73. );
  74. }
  75. }
  76. void LOTRO_DAT::SubDirectory::MakeDictionary(std::unordered_map<long long, Subfile *> &dict) {
  77. for (Subfile &i : subfiles_) {
  78. if (i.file_id() == 621002463)
  79. fprintf(stderr, "YAY!!!! offset = %lld\n", i.file_offset());
  80. if (dict.count(i.file_id()) == 0 || dict[i.file_id()]->timestamp() < i.timestamp())
  81. dict[i.file_id()] = &i;
  82. }
  83. for (SubDirectory &i : subdirs_)
  84. i.MakeDictionary(dict);
  85. }