int main(int argc, char**argv){ CREATE_FILE(TEST_FILE, DATA_FOR_FILE, DATASIZE_FOR_FILE); /*unlink*/ REMOVE_EXISTING_FILEPATH(TEST_FILE); CREATE_FILE(TEST_FILE2, DATA_FOR_FILE, DATASIZE_FOR_FILE); int ret; TEST_OPERATION_RESULT( link(TEST_FILE2, TEST_FILE), &ret, ret!=-1); /*now we have 2 hardlinks for a single file*/ /*compare files*/ int fd1, fd2; char *data1, *data2; off_t filesize1, filesize2; MMAP_READONLY_SHARED_FILE(TEST_FILE, 0, &fd1, data1); MMAP_READONLY_SHARED_FILE(TEST_FILE2, 0, &fd2, data2); GET_FILE_SIZE(TEST_FILE, &filesize1); GET_FILE_SIZE(TEST_FILE2, &filesize2); TEST_OPERATION_RESULT( (filesize1==filesize2), &ret, ret==1); CMP_MEM_DATA(data1, data2, filesize1); //check stat data struct stat st1; struct stat st2; TEST_OPERATION_RESULT( stat(TEST_FILE, &st1), &ret, ret==0); TEST_OPERATION_RESULT( stat(TEST_FILE2, &st2), &ret, ret==0); TEST_OPERATION_RESULT( st1.st_nlink==st2.st_nlink, &ret, ret!=0); TEST_OPERATION_RESULT( st1.st_ino==st2.st_ino, &ret, ret!=0); MUNMAP_FILE(data1, filesize1); MUNMAP_FILE(data2, filesize2); CLOSE_FILE(fd1); CLOSE_FILE(fd2); test_zrt_issue_67(TMP_TEST_DIR, TMP_TEST_FILE); test_zrt_issue_67(TMP_TEST_DIR, TMP_TEST_FILE); test_zrt_issue_70(); test_zrt_issue_77(TMP_TEST_DIR, TMP_TEST_FILE); return 0; }
void mmap_test(off_t offset) { int fd; char* data; MMAP_READONLY_SHARED_FILE(MMAP_FILE, offset, &fd, data) fprintf(stderr, "expected data:%s\n", DATA_FOR_MMAP+offset); fprintf(stderr, "mmaped data :%s\n", ((char*)data+offset)); off_t filesize; GET_FILE_SIZE(MMAP_FILE, &filesize); CMP_MEM_DATA( DATA_FOR_MMAP+offset, data+offset, filesize-offset ); MUNMAP_FILE(data, filesize); CLOSE_FILE(fd); }
/* <4f19c7> ../game_shared/bot/nav_file.cpp:947 */ NavErrorType LoadNavigationMap() { // since the navigation map is destroyed on map change, // if it exists it has already been loaded for this map if (!TheNavAreaList.empty()) return NAV_OK; // nav filename is derived from map filename char filename[256]; Q_sprintf(filename, "maps\\%s.nav", STRING(gpGlobals->mapname)); // free previous navigation map data DestroyNavigationMap(); placeDirectory.Reset(); IMPL_CLASS(CNavArea, m_nextID) = 1; SteamFile navFile(filename); if (!navFile.IsValid()) return NAV_CANT_ACCESS_FILE; // check magic number bool result; unsigned int magic; result = navFile.Read(&magic, sizeof(unsigned int)); if (!result || magic != NAV_MAGIC_NUMBER) { CONSOLE_ECHO("ERROR: Invalid navigation file '%s'.\n", filename); return NAV_INVALID_FILE; } // read file version number unsigned int version; result = navFile.Read(&version, sizeof(unsigned int)); if (!result || version > 5) { CONSOLE_ECHO("ERROR: Unknown navigation file version.\n"); return NAV_BAD_FILE_VERSION; } if (version >= 4) { // get size of source bsp file and verify that the bsp hasn't changed unsigned int saveBspSize; navFile.Read(&saveBspSize, sizeof(unsigned int)); // verify size char *bspFilename = GetBspFilename(filename); if (bspFilename == NULL) return NAV_INVALID_FILE; unsigned int bspSize = (unsigned int)GET_FILE_SIZE(bspFilename); if (bspSize != saveBspSize) { // this nav file is out of date for this bsp file char *msg = "*** WARNING ***\nThe AI navigation data is from a different version of this map.\nThe CPU players will likely not perform well.\n"; HintMessageToAllPlayers(msg); CONSOLE_ECHO("\n-----------------\n"); CONSOLE_ECHO(msg); CONSOLE_ECHO("-----------------\n\n"); } } // load Place directory if (version >= 5) { placeDirectory.Load(&navFile); } // get number of areas unsigned int count; result = navFile.Read(&count, sizeof(unsigned int)); Extent extent; extent.lo.x = 9999999999.9f; extent.lo.y = 9999999999.9f; extent.hi.x = -9999999999.9f; extent.hi.y = -9999999999.9f; // load the areas and compute total extent for (unsigned int i = 0; i < count; ++i) { CNavArea *area = new CNavArea; area->Load(&navFile, version); TheNavAreaList.push_back(area); const Extent *areaExtent = area->GetExtent(); // check validity of nav area if (areaExtent->lo.x >= areaExtent->hi.x || areaExtent->lo.y >= areaExtent->hi.y) CONSOLE_ECHO("WARNING: Degenerate Navigation Area #%d at ( %g, %g, %g )\n", area->GetID(), area->m_center.x, area->m_center.y, area->m_center.z); if (areaExtent->lo.x < extent.lo.x) extent.lo.x = areaExtent->lo.x; if (areaExtent->lo.y < extent.lo.y) extent.lo.y = areaExtent->lo.y; if (areaExtent->hi.x > extent.hi.x) extent.hi.x = areaExtent->hi.x; if (areaExtent->hi.y > extent.hi.y) extent.hi.y = areaExtent->hi.y; } // add the areas to the grid TheNavAreaGrid.Initialize(extent.lo.x, extent.hi.x, extent.lo.y, extent.hi.y); NavAreaList::iterator iter; for (iter = TheNavAreaList.begin(); iter != TheNavAreaList.end(); ++iter) TheNavAreaGrid.AddNavArea(*iter); // allow areas to connect to each other, etc for (iter = TheNavAreaList.begin(); iter != TheNavAreaList.end(); ++iter) { CNavArea *area = *iter; area->PostLoad(); } // load legacy location file (Places) if (version < 5) { LoadLocationFile(filename); } // Set up all the ladders BuildLadders(); return NAV_OK; }
/* <4f05c5> ../game_shared/bot/nav_file.cpp:876 */ void SanityCheckNavigationMap(const char *mapName) { if (!mapName) { CONSOLE_ECHO("ERROR: navigation file not specified.\n"); return; } // nav filename is derived from map filename const int BufLen = 4096; char bspFilename[BufLen]; char navFilename[BufLen]; Q_snprintf(bspFilename, BufLen, "maps\\%s.bsp", mapName); Q_snprintf(navFilename, BufLen, "maps\\%s.nav", mapName); SteamFile navFile(navFilename); if (!navFile.IsValid()) { CONSOLE_ECHO("ERROR: navigation file %s does not exist.\n", navFilename); return; } // check magic number bool result; unsigned int magic; result = navFile.Read(&magic, sizeof(unsigned int)); if (!result || magic != NAV_MAGIC_NUMBER) { CONSOLE_ECHO("ERROR: Invalid navigation file '%s'.\n", navFilename); return; } // read file version number unsigned int version; result = navFile.Read(&version, sizeof(unsigned int)); if (!result || version > 5) { CONSOLE_ECHO("ERROR: Unknown version in navigation file %s.\n", navFilename); return; } if (version >= 4) { // get size of source bsp file and verify that the bsp hasn't changed unsigned int saveBspSize; navFile.Read(&saveBspSize, sizeof(unsigned int)); // verify size if (bspFilename == NULL) { CONSOLE_ECHO("ERROR: No map corresponds to navigation file %s.\n", navFilename); return; } unsigned int bspSize = (unsigned int)GET_FILE_SIZE(bspFilename); if (bspSize != saveBspSize) { // this nav file is out of date for this bsp file CONSOLE_ECHO("ERROR: Out-of-date navigation data in navigation file %s.\n", navFilename); return; } } CONSOLE_ECHO("navigation file %s passes the sanity check.\n", navFilename); }
/* <4f3e47> ../game_shared/bot/nav_file.cpp:702 */ bool SaveNavigationMap(const char *filename) { if (filename == NULL) return false; // Store the NAV file COM_FixSlashes(const_cast<char *>(filename)); #ifdef WIN32 int fd = _open(filename, _O_BINARY | _O_CREAT | _O_WRONLY, _S_IREAD | _S_IWRITE); #else int fd = creat(filename, S_IRUSR | S_IWUSR | S_IRGRP); #endif // WIN32 if (fd < 0) return false; // store "magic number" to help identify this kind of file unsigned int magic = NAV_MAGIC_NUMBER; Q_write(fd, &magic, sizeof(unsigned int)); // store version number of file // 1 = hiding spots as plain vector array // 2 = hiding spots as HidingSpot objects // 3 = Encounter spots use HidingSpot ID's instead of storing vector again // 4 = Includes size of source bsp file to verify nav data correlation // ---- Beta Release at V4 ----- // 5 = Added Place info unsigned int version = 5; Q_write(fd, &version, sizeof(unsigned int)); // get size of source bsp file and store it in the nav file // so we can test if the bsp changed since the nav file was made char *bspFilename = GetBspFilename(filename); if (bspFilename == NULL) return false; unsigned int bspSize = (unsigned int)GET_FILE_SIZE(bspFilename); CONSOLE_ECHO("Size of bsp file '%s' is %u bytes.\n", bspFilename, bspSize); Q_write(fd, &bspSize, sizeof(unsigned int)); // Build a directory of the Places in this map placeDirectory.Reset(); NavAreaList::iterator it; for (it = TheNavAreaList.begin(); it != TheNavAreaList.end(); ++it) { CNavArea *area = *it; Place place = area->GetPlace(); if (place) { placeDirectory.AddPlace(place); } } placeDirectory.Save(fd); // Store navigation areas // store number of areas unsigned int count = TheNavAreaList.size(); Q_write(fd, &count, sizeof(unsigned int)); // store each area for (it = TheNavAreaList.begin(); it != TheNavAreaList.end(); ++it) { CNavArea *area = *it; area->Save(fd, version); } Q_close(fd); #ifdef _WIN32 // output a simple Wavefront file to visualize the generated areas in 3DSMax FILE *fp = fopen("c:\\tmp\\nav.obj", "w"); if (fp) { for (NavAreaList::iterator iter = TheNavAreaList.begin(); iter != TheNavAreaList.end(); ++iter) { (*iter)->Save(fp); } fclose(fp); } #endif // _WIN32 return true; }