bool CGrayInstall::ReadMulData(CGFile &file, const CUOIndexRec &Index, void * pData) { if ( file.Seek(Index.GetFileOffset(), SEEK_SET) != Index.GetFileOffset() ) return false; DWORD dwLength = Index.GetBlockLength(); if ( file.Read(pData, dwLength) != dwLength ) return false; return true; }
CSphereTerrainInfo::CSphereTerrainInfo( TERRAIN_TYPE id ) { ASSERT( id < TERRAIN_QTY ); VERFILE_TYPE filedata; size_t offset; CUOIndexRec Index; VERFILE_FORMAT format; if ( g_VerData.FindVerDataBlock( VERFILE_TILEDATA, id/UOTILE_BLOCK_QTY, Index )) { filedata = VERFILE_VERDATA; format = VERFORMAT_ORIGINAL; offset = Index.GetFileOffset() + 4 + (sizeof(CUOTerrainTypeRec)*(id%UOTILE_BLOCK_QTY)); ASSERT( Index.GetBlockLength() >= sizeof( CUOTerrainTypeRec )); } else { filedata = VERFILE_TILEDATA; format = g_Install.GetMulFormat(filedata); switch (format) { case VERFORMAT_HIGHSEAS: // high seas format (CUOTerrainTypeRec_HS) offset = (id == 0? 0 : 4) + (( id / UOTILE_BLOCK_QTY ) * 4 ) + ( id * sizeof( CUOTerrainTypeRec_HS )); break; case VERFORMAT_ORIGINAL: // original format (CUOTerrainTypeRec) default: offset = 4 + (( id / UOTILE_BLOCK_QTY ) * 4 ) + ( id * sizeof( CUOTerrainTypeRec )); break; } } if ( g_Install.m_File[filedata].Seek( offset, SEEK_SET ) != offset ) { throw CSError(LOGL_CRIT, CSFile::GetLastError(), "CTileTerrainType.ReadInfo: TileData Seek"); } switch (format) { case VERFORMAT_HIGHSEAS: // high seas format (CUOTerrainTypeRec_HS) if ( g_Install.m_File[filedata].Read(static_cast <CUOTerrainTypeRec_HS *>(this), sizeof(CUOTerrainTypeRec_HS)) <= 0 ) throw CSError(LOGL_CRIT, CSFile::GetLastError(), "CTileTerrainType.ReadInfo: TileData Read"); break; case VERFORMAT_ORIGINAL: // old format (CUOTerrainTypeRec) default: { CUOTerrainTypeRec record; if ( g_Install.m_File[filedata].Read(static_cast <CUOTerrainTypeRec *>(&record), sizeof(CUOTerrainTypeRec)) <= 0 ) throw CSError(LOGL_CRIT, CSFile::GetLastError(), "CTileTerrainType.ReadInfo: TileData Read"); m_flags = record.m_flags; m_unknown = 0; m_index = record.m_index; strcpylen(m_name, record.m_name, CountOf(m_name)); break; } } }
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. }