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; }
bool CGrayInstall::ReadMulIndex(CGFile &file, DWORD id, CUOIndexRec &Index) { LONG lOffset = id * sizeof(CUOIndexRec); if ( file.Seek(lOffset, SEEK_SET) != lOffset ) return false; if ( file.Read((void *)&Index, sizeof(CUOIndexRec)) != sizeof(CUOIndexRec) ) return false; return Index.HasData(); }
int CWebPageDef::ServPageRequest( CClient * pClient, LPCTSTR pszURLArgs, CGTime * pdateIfModifiedSince ) { ADDTOCALLSTACK("CWebPageDef::ServPageRequest"); UNREFERENCED_PARAMETER(pszURLArgs); // Got a web page request from the client. // ARGS: // pszURLArgs = args on the URL line ex. http://www.hostname.com/dir?args // RETURN: // HTTP error code = 0=200 page was served. ASSERT(pClient); if ( HasTrigger(WTRIG_Load)) { CResourceLock s; if ( ResourceLock(s)) { if (CScriptObj::OnTriggerScript( s, sm_szTrigName[WTRIG_Load], pClient, NULL ) == TRIGRET_RET_TRUE) return( 0 ); // Block further action. } } if ( m_privlevel ) { if ( !pClient->m_pAccount ) return 401; // Authorization required if ( pClient->GetPrivLevel() < m_privlevel ) return 403; // Forbidden } CGTime datetime = CGTime::GetCurrentTime(); LPCTSTR pszName; bool fGenerate = false; if ( m_type == WEBPAGE_TEMPLATE ) // my version of cgi { pszName = GetDstName(); if ( pszName[0] == '\0' ) { pszName = "temppage.htm"; fGenerate = true; } else { fGenerate = ! m_iUpdatePeriod; } // The page must be generated on demand. if ( ! WebPageUpdate( fGenerate, pszName, pClient )) return 500; } else { pszName = GetName(); } // Get proper Last-Modified: time. time_t dateChange; DWORD dwSize; if ( ! CFileList::ReadFileInfo( pszName, dateChange, dwSize )) { return 500; } const char *sDate = datetime.FormatGmt(NULL); // current date. if ( !fGenerate && !pdateIfModifiedSince && (pdateIfModifiedSince->IsTimeValid() && pdateIfModifiedSince->GetTime() > dateChange) ) { TCHAR *pszTemp = Str_GetTemp(); sprintf(pszTemp, "HTTP/1.1 304 Not Modified\r\nDate: %s\r\nServer: " GRAY_TITLE " V " GRAY_VERSION "\r\nContent-Length: 0\r\n\r\n", sDate); new PacketWeb(pClient, (BYTE*)pszTemp, strlen(pszTemp)); return 0; } // Now serve up the page. CGFile FileRead; if ( ! FileRead.Open( pszName, OF_READ|OF_BINARY )) return 500; // Send the header first. TCHAR szTmp[8*1024]; size_t iLen = sprintf(szTmp, "HTTP/1.1 200 OK\r\n" // 100 Continue "Date: %s\r\n" "Server: " GRAY_TITLE " V " GRAY_VERSION "\r\n" "Accept-Ranges: bytes\r\n" "Content-Type: %s\r\n", static_cast<LPCTSTR>(sDate), static_cast<LPCTSTR>(sm_szPageType[m_type]) // type of the file. image/gif, image/x-xbitmap, image/jpeg ); if ( m_type == WEBPAGE_TEMPLATE ) iLen += sprintf(szTmp + iLen, "Expires: 0\r\n"); else iLen += sprintf(szTmp + iLen, "Last-Modified: %s\r\n", CGTime(dateChange).FormatGmt(NULL)); iLen += sprintf( szTmp + iLen, "Content-Length: %lu\r\n" "\r\n", dwSize ); PacketWeb packet; packet.setData((BYTE*)szTmp, iLen); packet.send(pClient); for (;;) { iLen = FileRead.Read( szTmp, sizeof( szTmp ) ); if ( iLen <= 0 ) break; packet.setData((BYTE*)szTmp, iLen); packet.send(pClient); //dwSize -= iLen; if ( iLen < sizeof( szTmp ) ) { // memset( szTmp+iLen, 0, sizeof(szTmp)-iLen ); break; } } return 0; }
bool CClient::OnRxAxis( const BYTE * pData, size_t iLen ) { ADDTOCALLSTACK("CClient::OnRxAxis"); if ( !iLen || ( GetConnectType() != CONNECT_AXIS )) return false; while ( iLen -- ) { int iRet = OnConsoleKey( m_Targ_Text, *pData++, GetAccount() != NULL ); if ( ! iRet ) return( false ); if ( iRet == 2 ) { if ( GetAccount() == NULL ) { if ( !m_zLogin[0] ) { if ( static_cast<unsigned int>(m_Targ_Text.GetLength()) <= (COUNTOF(m_zLogin) - 1) ) strcpy(m_zLogin, m_Targ_Text); m_Targ_Text.Empty(); } else { CGString sMsg; CAccountRef pAccount = g_Accounts.Account_Find(m_zLogin); if (( pAccount == NULL ) || ( pAccount->GetPrivLevel() < PLEVEL_Counsel )) { SysMessagef("\"MSG:%s\"", g_Cfg.GetDefaultMsg(DEFMSG_AXIS_NOT_PRIV)); m_Targ_Text.Empty(); return false; } if ( LogIn(m_zLogin, m_Targ_Text, sMsg ) == PacketLoginError::Success ) { m_Targ_Text.Empty(); if ( GetPrivLevel() < PLEVEL_Counsel ) { SysMessagef("\"MSG:%s\"", g_Cfg.GetDefaultMsg(DEFMSG_AXIS_NOT_PRIV)); return false; } if (GetPeer().IsValidAddr()) { CScriptTriggerArgs Args; Args.m_VarsLocal.SetStrNew("Account",GetName()); Args.m_VarsLocal.SetStrNew("IP",GetPeer().GetAddrStr()); TRIGRET_TYPE tRet = TRIGRET_RET_DEFAULT; r_Call("f_axis_preload", this, &Args, NULL, &tRet); if ( tRet == TRIGRET_RET_FALSE ) return false; if ( tRet == TRIGRET_RET_TRUE ) { SysMessagef("\"MSG:%s\"", g_Cfg.GetDefaultMsg(DEFMSG_AXIS_DENIED)); return false; } time_t dateChange; DWORD dwSize; if ( ! CFileList::ReadFileInfo( "Axis.db", dateChange, dwSize )) { SysMessagef("\"MSG:%s\"", g_Cfg.GetDefaultMsg(DEFMSG_AXIS_INFO_ERROR)); return false; } CGFile FileRead; if ( ! FileRead.Open( "Axis.db", OF_READ|OF_BINARY )) { SysMessagef("\"MSG:%s\"", g_Cfg.GetDefaultMsg(DEFMSG_AXIS_FILE_ERROR)); return false; } TCHAR szTmp[8*1024]; PacketWeb packet; for (;;) { size_t iLength = FileRead.Read( szTmp, sizeof( szTmp ) ); if ( iLength <= 0 ) break; packet.setData((BYTE*)szTmp, iLength); packet.send(this); dwSize -= iLength; if ( dwSize <= 0 ) break; } return true; } return false; } else if ( ! sMsg.IsEmpty()) { SysMessagef("\"MSG:%s\"", (LPCTSTR)sMsg); return false; } m_Targ_Text.Empty(); } return true; } } } return true; }
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. }