bool CGrayInstall::OpenFile( VERFILE_TYPE i ) { CGFile *pFile = GetMulFile(i); if ( !pFile ) return false; if ( pFile->IsFileOpen()) return true; if ( !pFile->GetFilePath().IsEmpty() ) { if ( pFile->Open(pFile->GetFilePath(), OF_READ|OF_SHARE_DENY_WRITE) ) return true; } LPCTSTR pszTitle = GetBaseFileName((VERFILE_TYPE)i); if ( !pszTitle ) return false; return OpenFile(m_File[i], pszTitle, OF_READ|OF_SHARE_DENY_WRITE); }
void CMapDiffCollection::LoadMapDiffs() { // Load mapdif* and stadif* Files ADDTOCALLSTACK("CMapDiffCollection::LoadMapDiffs"); if ( m_bLoaded ) // already loaded return; DWORD dwLength = 0, dwBlockId = 0; DWORD dwOffset = 0, dwRead = 0; CMapDiffBlock * pMapDiffBlock = NULL; for ( int m = 0; m < 256; ++m ) { if ( !g_MapList.IsMapSupported( m ) ) continue; int map = g_MapList.m_mapid[m]; // Load Mapdif Files { CGFile * pFileMapdif = &(g_Install.m_Mapdif[map]); CGFile * pFileMapdifl = &(g_Install.m_Mapdifl[map]); // Check that the relevant dif files are available if ( pFileMapdif->IsFileOpen() && pFileMapdifl->IsFileOpen() ) { // Make sure that we're at the beginning of the files pFileMapdif->SeekToBegin(); pFileMapdifl->SeekToBegin(); dwLength = pFileMapdifl->GetLength(); dwRead = dwOffset = 0; for ( ; dwRead < dwLength; dwOffset += sizeof(CUOMapBlock) ) { dwRead += pFileMapdifl->Read( &dwBlockId, sizeof(dwBlockId) ); pMapDiffBlock = GetNewBlock( dwBlockId, map ); if ( pMapDiffBlock->m_pTerrainBlock ) delete pMapDiffBlock->m_pTerrainBlock; CUOMapBlock * pTerrain = new CUOMapBlock(); if ( pFileMapdif->Seek( dwOffset ) != dwOffset ) { g_Log.EventError("Reading mapdif%d.mul FAILED.\n", map); delete pTerrain; break; } else if ( pFileMapdif->Read( pTerrain, sizeof(CUOMapBlock) ) != sizeof(CUOMapBlock) ) { g_Log.EventError("Reading mapdif%d.mul FAILED. [index=%lu offset=%lu]\n", map, dwBlockId, dwOffset); delete pTerrain; break; } pMapDiffBlock->m_pTerrainBlock = pTerrain; } } } // Mapdif // Load Stadif Files { CGFile * pFileStadif = &(g_Install.m_Stadif[map]); CGFile * pFileStadifl = &(g_Install.m_Stadifl[map]); CGFile * pFileStadifi = &(g_Install.m_Stadifi[map]); // Check that the relevant dif files are available if ( !pFileStadif->IsFileOpen() || !pFileStadifl->IsFileOpen() || !pFileStadifi->IsFileOpen() ) continue; // Make sure that we're at the beginning of the files pFileStadif->SeekToBegin(); pFileStadifl->SeekToBegin(); pFileStadifi->SeekToBegin(); dwLength = pFileStadifl->GetLength(); dwRead = dwOffset = 0; for ( ; dwRead < dwLength; dwOffset += sizeof(CUOIndexRec) ) { dwRead += pFileStadifl->Read( &dwBlockId, sizeof(dwBlockId) ); pMapDiffBlock = GetNewBlock( dwBlockId, map ); if ( pMapDiffBlock->m_pStaticsBlock ) delete[] pMapDiffBlock->m_pStaticsBlock; pMapDiffBlock->m_iStaticsCount = 0; pMapDiffBlock->m_pStaticsBlock = NULL; if ( pFileStadifi->Seek( dwOffset ) != dwOffset ) { g_Log.EventError("Reading stadifi%d.mul FAILED.\n", map); break; } CUOIndexRec index; if ( pFileStadifi->Read( &index, sizeof(CUOIndexRec)) != sizeof(CUOIndexRec) ) { g_Log.EventError("Reading stadifi%d.mul FAILED. [index=%lu offset=%lu]\n", map, dwBlockId, dwOffset); break; } else if ( !index.HasData() ) // This happens if the block has been intentionally patched to remove statics { continue; } else if ((index.GetBlockLength() % sizeof(CUOStaticItemRec)) != 0) // Make sure that the statics block length is valid { g_Log.EventError("Reading stadifi%d.mul FAILED. [index=%lu offset=%lu length=%lu]\n", map, dwBlockId, dwOffset, index.GetBlockLength()); break; } pMapDiffBlock->m_iStaticsCount = index.GetBlockLength()/sizeof(CUOStaticItemRec); pMapDiffBlock->m_pStaticsBlock = new CUOStaticItemRec[pMapDiffBlock->m_iStaticsCount]; if ( !g_Install.ReadMulData(*pFileStadif, index, pMapDiffBlock->m_pStaticsBlock) ) { // This shouldn't happen, if this fails then the block will // be left with no statics pMapDiffBlock->m_iStaticsCount = 0; delete[] pMapDiffBlock->m_pStaticsBlock; pMapDiffBlock->m_pStaticsBlock = NULL; g_Log.EventError("Reading stadif%d.mul FAILED. [index=%lu offset=%lu]\n", map, dwBlockId, dwOffset); break; } } } // Stadif } m_bLoaded = true; }
void CGrayMapBlock::Load( int bx, int by ) { ADDTOCALLSTACK("CGrayMapBlock::Load"); // Read in all the statics data for this block. m_CacheTime.InitCacheTime(); // This is invalid ! ASSERT( bx < (g_MapList.GetX(m_map)/UO_BLOCK_SIZE) ); ASSERT( by < (g_MapList.GetY(m_map)/UO_BLOCK_SIZE) ); if (( m_map < 0 ) || ( m_map >= 255 )) { g_Log.EventError("Unsupported map #%d specified. Auto-fixing that to 0.\n", m_map); m_map = 0; } unsigned long ulBlockIndex = (bx*(g_MapList.GetY(m_map)/UO_BLOCK_SIZE) + by); if ( !g_MapList.m_maps[m_map] ) { memset( &m_Terrain, 0, sizeof( m_Terrain )); throw CGrayError(LOGL_CRIT, 0, "CGrayMapBlock: Map is not supported since MUL files for it not available."); } bool bPatchedTerrain = false, bPatchedStatics = false; if ( g_Cfg.m_fUseMapDiffs && g_MapList.m_pMapDiffCollection ) { // Check to see if the terrain or statics in this block is patched CMapDiffBlock * pDiffBlock = g_MapList.m_pMapDiffCollection->GetAtBlock( ulBlockIndex, g_MapList.m_mapid[m_map] ); if ( pDiffBlock ) { if ( pDiffBlock->m_pTerrainBlock ) { memcpy( &m_Terrain, pDiffBlock->m_pTerrainBlock, sizeof(CUOMapBlock) ); bPatchedTerrain = true; } if ( pDiffBlock->m_iStaticsCount >= 0 ) { m_Statics.LoadStatics( pDiffBlock->m_iStaticsCount, pDiffBlock->m_pStaticsBlock ); bPatchedStatics = true; } } } // Only load terrain if it wasn't patched if ( ! bPatchedTerrain ) { int mapNumber = g_MapList.m_mapnum[m_map]; CGFile * pFile = &(g_Install.m_Maps[mapNumber]); ASSERT(pFile != NULL); ASSERT(pFile->IsFileOpen()); // determine the location in the file where the data needs to be read from CUOIndexRec index; index.SetupIndex( ulBlockIndex * sizeof(CUOMapBlock), sizeof(CUOMapBlock)); unsigned long fileOffset = index.GetFileOffset(); if (g_Install.m_IsMapUopFormat[mapNumber]) { for ( int i = 0; i < 256; i++ ) { MapAddress pMapAddress = g_Install.m_UopMapAddress[mapNumber][i]; if (( ulBlockIndex <= pMapAddress.dwLastBlock ) && ( ulBlockIndex >= pMapAddress.dwFirstBlock )) { fileOffset = static_cast<unsigned long>(pMapAddress.qwAdress + ((ulBlockIndex - pMapAddress.dwFirstBlock)*196)); break; } } /* // when the map is in a UOP container we need to modify the file offset to account for the block header // data. the uop file format splits the map data into smaller 'blocks', each of which has its on header (as // well as an overall file header) // // we must therefore determine which block of data contains the map information we need, and then add // the extra number of bytes to our file offset const unsigned long fileHeaderLength = 40; // length of overall file header const unsigned long blockHeaderLength = 12; // length of the block header const unsigned long firstDataEntryOffset = 3412; // offset of first actual data byte within a block const unsigned long firstBlockDataEntryOffset = fileHeaderLength + blockHeaderLength + firstDataEntryOffset; // offset of first actual data byte for the first entry in the file const unsigned long mapBlockLength = 802816; // maximum size of a block // note: to avoid writing code that parse the UOP format properly we are calculating a new offset based on the // sizes of the blocks as-of client 7.0.24.0. the nature of the UOP format allows the block lengths to differ // and for the data to be compressed, so we should watch out for this in the future (and if this happens we'll // have to handle UOP data properly) unsigned long block = fileOffset / mapBlockLength; fileOffset += firstBlockDataEntryOffset + ((firstDataEntryOffset) * (block / 100)) + (blockHeaderLength * block);*/ } // seek to position in file if ( pFile->Seek( fileOffset, SEEK_SET ) != fileOffset ) { memset( &m_Terrain, 0, sizeof(m_Terrain)); throw CGrayError(LOGL_CRIT, CGFile::GetLastError(), "CGrayMapBlock: Seek Ver"); } // read terrain data if ( pFile->Read( &m_Terrain, sizeof(CUOMapBlock)) <= 0 ) { memset( &m_Terrain, 0, sizeof( m_Terrain )); throw CGrayError(LOGL_CRIT, CGFile::GetLastError(), "CGrayMapBlock: Read"); } } // Only load statics if they weren't patched if ( ! bPatchedStatics ) { m_Statics.LoadStatics( ulBlockIndex, m_map ); } m_CacheTime.HitCacheTime(); // validate. }