SubDirectory.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  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) :
  13. offset_(offset), dat_(dat) {
  14. try {
  15. MakeSubDirectories();
  16. } catch (...) {
  17. fprintf(stderr, "Unable to initialize directory at offset %lld. Initializing 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 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)
  42. break;
  43. try {
  44. subdirs_.emplace_back(
  45. SubDirectory(
  46. data.ToNumber<4>(i + 4),
  47. dat_
  48. )
  49. );
  50. } catch (DatException &e) {
  51. fprintf(stderr, "Making SubDirectory at offset %lld failed, continuing\n", data.ToNumber<4>(i + 4));
  52. // TODO - do something here....
  53. }
  54. }
  55. }
  56. void LOTRO_DAT::SubDirectory::MakeSubFiles() {
  57. BinaryData data(2048);
  58. dat_->ReadData(data, 61 * 32, offset_ + (63 * 8));
  59. for (unsigned int i = 0; i < 61 * 32; i += 32) {
  60. if (data.ToNumber<4>(i + 8) < 0x32 || data.ToNumber<4>(i + 12) < 0x32)
  61. continue;
  62. subfiles_.emplace_back(
  63. Subfile(
  64. dat_,
  65. data.ToNumber<4>(i), // unknown0
  66. data.ToNumber<4>(i + 4), // unknown1
  67. data.ToNumber<4>(i + 8), // file_id
  68. data.ToNumber<4>(i + 12), // file_offset
  69. data.ToNumber<4>(i + 16), // size1
  70. data.ToNumber<4>(i + 20), // timestamp
  71. data.ToNumber<4>(i + 24), // version
  72. data.ToNumber<4>(i + 28) // size2
  73. )
  74. );
  75. }
  76. }
  77. void LOTRO_DAT::SubDirectory::MakeDictionary(std::unordered_map<long long, Subfile *> &dict) {
  78. for (Subfile &i : subfiles_)
  79. dict[i.file_id()] = &i;
  80. for (SubDirectory &i : subdirs_)
  81. i.MakeDictionary(dict);
  82. }