TC_GAME_API void LoadM2Cameras(std::string const& dataPath) { sFlyByCameraStore.clear(); TC_LOG_INFO("server.loading", ">> Loading Cinematic Camera files"); boost::filesystem::path camerasPath = boost::filesystem::path(dataPath) / "cameras"; uint32 oldMSTime = getMSTime(); for (CinematicCameraEntry const* cameraEntry : sCinematicCameraStore) { boost::filesystem::path filename = camerasPath / Trinity::StringFormat("FILE%08X.xxx", cameraEntry->ModelFileDataID); // Convert to native format filename.make_preferred(); std::ifstream m2file(filename.string().c_str(), std::ios::in | std::ios::binary); if (!m2file.is_open()) continue; // Get file size m2file.seekg(0, std::ios::end); std::streamoff const fileSize = m2file.tellg(); // Reject if not at least the size of the header if (static_cast<uint32 const>(fileSize) < sizeof(M2Header) + 4) { TC_LOG_ERROR("server.loading", "Camera file %s is damaged. File is smaller than header size", filename.string().c_str()); m2file.close(); continue; } // Read 4 bytes (signature) m2file.seekg(0, std::ios::beg); char fileCheck[5]; m2file.read(fileCheck, 4); fileCheck[4] = '\0'; // Check file has correct magic (MD21) if (strcmp(fileCheck, "MD21")) { TC_LOG_ERROR("server.loading", "Camera file %s is damaged. File identifier not found.", filename.string().c_str()); m2file.close(); continue; } // Now we have a good file, read it all into a vector of char's, then close the file. std::vector<char> buffer(fileSize); m2file.seekg(0, std::ios::beg); if (!m2file.read(buffer.data(), fileSize)) { m2file.close(); continue; } m2file.close(); bool fileValid = true; uint32 m2start = 0; char const* ptr = buffer.data(); while (m2start + 4 < buffer.size() && *reinterpret_cast<uint32 const*>(ptr) != '02DM') { ++m2start; ++ptr; if (m2start + sizeof(M2Header) > buffer.size()) { fileValid = false; break; } } if (!fileValid) { TC_LOG_ERROR("server.loading", "Camera file %s is damaged. File is smaller than header size.", filename.string().c_str()); continue; } // Read header M2Header const* header = reinterpret_cast<M2Header const*>(buffer.data() + m2start); if (m2start + header->ofsCameras + sizeof(M2Camera) > static_cast<uint32 const>(fileSize)) { TC_LOG_ERROR("server.loading", "Camera file %s is damaged. Camera references position beyond file end", filename.string().c_str()); continue; } // Get camera(s) - Main header, then dump them. M2Camera const* cam = reinterpret_cast<M2Camera const*>(buffer.data() + m2start + header->ofsCameras); if (!readCamera(cam, fileSize - m2start, header, cameraEntry)) TC_LOG_ERROR("server.loading", "Camera file %s is damaged. Camera references position beyond file end", filename.string().c_str()); } TC_LOG_INFO("server.loading", ">> Loaded " SZFMTD " cinematic waypoint sets in %u ms", sFlyByCameraStore.size(), GetMSTimeDiffToNow(oldMSTime)); }
void LoadM2Cameras(std::string const& dataPath) { sFlyByCameraStore.clear(); uint32 oldMSTime = WorldTimer::getMSTime(); for (uint32 i = 0; i < sCinematicCameraStore.GetNumRows(); ++i) { if (CinematicCameraEntry const* dbcentry = sCinematicCameraStore.LookupEntry(i)) { std::string filename = dataPath; filename.append(dbcentry->Model); // Replace slashes std::replace(filename.begin(), filename.end(), '\\', '/'); // Replace mdx to .m2 size_t loc = filename.find(".mdx"); if (loc != std::string::npos) filename.replace(loc, 4, ".m2"); std::ifstream m2file(filename.c_str(), std::ios::in | std::ios::binary); if (!m2file.is_open()) continue; // Get file size m2file.seekg(0, std::ios::end); std::streamoff const fileSize = m2file.tellg(); // Reject if not at least the size of the header if (static_cast<uint32 const>(fileSize) < sizeof(M2Header)) { sLog.outError("Camera file %s is damaged. File is smaller than header size", filename.c_str()); m2file.close(); continue; } // Read 4 bytes (signature) m2file.seekg(0, std::ios::beg); char fileCheck[5]; m2file.read(fileCheck, 4); fileCheck[4] = 0; // Check file has correct magic (MD20) if (strcmp(fileCheck, "MD20")) { sLog.outError("Camera file %s is damaged. File identifier not found", filename.c_str()); m2file.close(); continue; } // Now we have a good file, read it all into a vector of char's, then close the file. std::vector<char> buffer(fileSize); m2file.seekg(0, std::ios::beg); if (!m2file.read(buffer.data(), fileSize)) { m2file.close(); continue; } m2file.close(); // Read header M2Header const* header = reinterpret_cast<M2Header const*>(buffer.data()); if (header->ofsCameras + sizeof(M2Camera) > static_cast<uint32 const>(fileSize)) { sLog.outError("Camera file %s is damaged. Camera references position beyond file end (header)", filename.c_str()); continue; } // Get camera(s) - Main header, then dump them. M2Camera const* cam = reinterpret_cast<M2Camera const*>(buffer.data() + header->ofsCameras); if (!readCamera(cam, fileSize, header, dbcentry)) sLog.outError("Camera file %s is damaged. Camera references position beyond file end (camera)", filename.c_str()); } } sLog.outString(">> Loaded %u cinematic waypoint sets in %u ms", static_cast<uint32 const>(sFlyByCameraStore.size()), WorldTimer::getMSTimeDiff(oldMSTime, WorldTimer::getMSTime())); sLog.outString(); }