unsigned int IArchive::GetCrc32(unsigned int fid) { CRC crc; std::vector<std::uint8_t> buffer; if (GetFile(fid, buffer) && !buffer.empty()) crc.Update(&buffer[0], buffer.size()); return crc.GetDigest(); }
unsigned CArchiveBase::GetCrc32(unsigned fid) { CRC crc; std::vector<boost::uint8_t> buffer; if (GetFile(fid, buffer)) crc.Update(&buffer[0], buffer.size()); return crc.GetDigest(); }
void Comm::put(char *buf, int length) { CRC crc = CRC(); crc_t code = crc.encode(buf, length); sendBytes(COMM_HEAD, COMM_HEAD_LEN); send((char *)&code, sizeof(crc_t)); send(buf, length); sendBytes(COMM_TAIL, COMM_TAIL_LEN); }
void doit(int index)//, CycList<zip*>* zipList) { char* qualifiedName = "C:/Users/Ahmad/Downloads/test"; m.lock(); CRC crclib; crclib.partialCompute((uint8_t *)qualifiedName, 0, _strlen(qualifiedName)); uint32_t crc = crclib.GetCRC32(); uint64_t zipCount = zipList.count; uint32_t i; for (i = 0; i < zipCount && zipList[i]->crc != crc; i++); zip* cur; if (i == zipCount) { cur = new zip(true); cur->crc = crc; if (zipList.count == ZIPLISTCAP) delete zipList[zipList.index + 1 % ZIPLISTCAP]; zipList.append(cur); cur->zs->addDirectory(qualifiedName); } else cur = zipList[i]; m.unlock(); std::ostringstream ss; ss << "c:/users/ahmad/desktop/custom/test" << index; std::ofstream outfile(ss.str(), std::ios::binary); cur->m.lock(); cur->zs->buildStream(); cur->m.unlock(); int64_t streamSize = cur->zs->getStreamSize(); uint64_t from = (streamSize / THREADCOUNT + 1) * index; uint64_t to = from + streamSize / THREADCOUNT; if (index == THREADCOUNT - 1) to = streamSize - 1; uint64_t targetLength; for (uint64_t i = from; i <= to; i += targetLength) { targetLength = MIN(10240, to - i + 1); cur->zs->printBytes(i, i + targetLength - 1, outfile.rdbuf()); } //cur->zs->printBytes(from, to, outfile.rdbuf()); outfile.close(); }
void LocalNodeInfo::recomputeConsolidateSubsciptionList (void) { // TODO CHECK: I don't think the includes applies anymore, so I commented it // In fact, even if the includes returns true, // I still need to merge subscriptions in terms of priority, reliability, sequenced, etc CRC * pCRC = new CRC(); pCRC->init(); for (StringHashtable<Subscription>::Iterator iterator = _consolidatedSubscriptions.getIterator(); !iterator.end(); iterator.nextElement()) { pCRC->update ((const char *)iterator.getKey()); pCRC->update32 (iterator.getValue()); } uint16 oldCRC = pCRC->getChecksum(); // Delete the current Consolidate Subscription List and compute a new one _consolidatedSubscriptions.clear(); // For each client for (UInt32Hashtable<SubscriptionList>::Iterator i = _localSubscriptions.getAllElements(); !i.end(); i.nextElement()) { SubscriptionList *pSL = i.getValue(); if (pSL != NULL) { // Get all its subscriptions PtrLList<String> *pSubgroups = pSL->getAllSubscribedGroups(); for (String *pSubGroupName = pSubgroups->getFirst(); pSubGroupName != NULL; pSubGroupName = pSubgroups->getNext()) { // For each group, get the subscription the client has const char *pszGroupName = pSubGroupName->c_str(); Subscription *pClientSub = pSL->getSubscription (pszGroupName); // And the subscription in the consolidate subscription list if any Subscription *pSubInConsolidateList = _consolidatedSubscriptions.getSubscription (pszGroupName); if (pSubInConsolidateList == NULL) { _consolidatedSubscriptions.addSubscription (pszGroupName, pClientSub->clone()); } else { /*if (pClientSub->includes (pSubInConsolidateList)) { _consolidatedSubscriptions.removeGroup (pszGroupName); _consolidatedSubscriptions.addSubscription (pszGroupName, pClientSub->clone()); } else {*/ pClientSub->merge (pSubInConsolidateList); /*}*/ } } } } pCRC->reset(); for (StringHashtable<Subscription>::Iterator iterator = _consolidatedSubscriptions.getIterator(); !iterator.end(); iterator.nextElement()) { pCRC->update ((const char *) iterator.getKey()); pCRC->update32 (iterator.getValue()); } uint16 newCRC = pCRC->getChecksum(); if (oldCRC != newCRC) { ui32SubscriptionStateSeqID++; GroupSubscription *pSubscription = new GroupSubscription(); // Void subscription to respect method interface _notifier.modifiedSubscriptionForPeer (_pszId, pSubscription); } }
/** * Get CRC of the data in the specified archive. * Returns 0 if file could not be opened. */ unsigned int CArchiveScanner::GetCRC(const std::string& arcName) { CRC crc; CArchiveBase* ar; std::list<std::string> files; //! Try to open an archive ar = CArchiveFactory::OpenArchive(arcName); if (!ar) { return 0; // It wasn't an archive } //! Load ignore list. IFileFilter* ignore = CreateIgnoreFilter(ar); for (unsigned fid = 0; fid != ar->NumFiles(); ++fid) { std::string name; int size; ar->FileInfo(fid, name, size); if (ignore->Match(name)) { continue; } StringToLowerInPlace(name); //! case insensitive hash files.push_back(name); } files.sort(); //! Add all files in sorted order for (std::list<std::string>::iterator i = files.begin(); i != files.end(); ++i) { const unsigned int nameCRC = CRC().Update(i->data(), i->size()).GetDigest(); const unsigned fid = ar->FindFile(*i); const unsigned int dataCRC = ar->GetCrc32(fid); crc.Update(nameCRC); crc.Update(dataCRC); } delete ignore; delete ar; unsigned int digest = crc.GetDigest(); //! A value of 0 is used to indicate no crc.. so never return that //! Shouldn't happen all that often if (digest == 0) { return 4711; } else { return digest; } }
int test_main(int, char*[]) { // Test case: // http://lists.gnu.org/archive/html/bug-commoncpp/2002-12/msg00088.html // expected: df1dc234 // Source Message was 'pippo' CRC crc; crc += std::string("pippo"); BOOST_TEST_EQUAL(0x0df1dc234, crc.value()); return EXIT_SUCCESS; }
/** Get CRC of the data in the specified archive. Returns 0 if file could not be opened. */ unsigned int CArchiveScanner::GetCRC(const string& arcName) { CRC crc; CArchiveBase* ar; std::list<string> files; // Try to open an archive ar = CArchiveFactory::OpenArchive(arcName); if (!ar) { return 0; // It wasn't an archive } // Load ignore list. IFileFilter* ignore = CreateIgnoreFilter(ar); string name; int size; // Sort all file paths for deterministic behaviour for (int cur = 0; (cur = ar->FindFiles(cur, &name, &size)); /* no-op */) { if (ignore->Match(name)) { continue; } const string lower = StringToLower(name); // case insensitive hash files.push_back(lower); } files.sort(); // Add all files in sorted order for (std::list<string>::iterator i = files.begin(); i != files.end(); i++ ) { const unsigned int nameCRC = CRC().Update(i->data(), i->size()).GetDigest(); const unsigned int dataCRC = ar->GetCrc32(*i); crc.Update(nameCRC); crc.Update(dataCRC); } delete ignore; delete ar; unsigned int digest = crc.GetDigest(); // A value of 0 is used to indicate no crc.. so never return that // Shouldn't happen all that often if (digest == 0) { return 4711; } else { return digest; } }
int Comm::get() { int size = recv(); if (size < CRC_SIZE) return -1; else { crc_t code; CRC crc = CRC(); code = crc.encode(&m_buf[CRC_SIZE], size - CRC_SIZE); if (code == *((crc_t *)m_buf)) return size; else return -1; } }
// ---------------------------------------------------------------------------- // Type III command: READ-ADDRESS // ---------------------------------------------------------------------------- void MB8877::cmd_readaddr(char cmd) { CRC *crc = new CRC; #ifdef FDC_DEBUG fdcdisplay((char*)"III READ_ADDR"); #endif fdc.cmdtype = cmd; reg[STATUS] |= FDC_ST_BUSY|FDC_ST_HEADENG; // Compute CRC crc->compute(reg[TRACK]); crc->compute(fdc.side); crc->compute(reg[SECTOR]); // 0x02=512 bytes/sector, 0x03=1024 bytes/sector crc->compute(reg[TRACK]<80 ? 0x03 : 0x02); // Send data : send_qx1(reg[TRACK]); // 1- Track Address send_qx1(fdc.side); // 2- Side number send_qx1(reg[SECTOR]); // 3- Sector Address send_qx1((reg[TRACK]<80 ? 0x03 : 0x02)); // 4- Sector length send_qx1(crc->msb()); // 5- CRC1 send_qx1(crc->lsb()); // 6- CRC2 }
unsigned int CArchiveBase::GetCrc32(const std::string& fileName) { CRC crc; unsigned char buffer [65536]; int handle; int maxRead; int total = 0; handle = this->OpenFile(fileName); if (handle == 0) return crc.GetDigest(); do { maxRead = this->ReadFile(handle, &buffer, sizeof(buffer)); crc.Update(buffer, maxRead); total += maxRead; } while (maxRead == sizeof(buffer)); this->CloseFile(handle); return crc.GetDigest(); };
MoveDefHandler::MoveDefHandler(LuaParser* defsParser) { const LuaTable rootTable = defsParser->GetRoot().SubTable("MoveDefs"); if (!rootTable.IsValid()) throw content_error("Error loading movement definitions"); CRC crc; for (int tt = 0; tt < CMapInfo::NUM_TERRAIN_TYPES; ++tt) { const CMapInfo::TerrainType& terrType = mapInfo->terrainTypes[tt]; crc << terrType.tankSpeed << terrType.kbotSpeed; crc << terrType.hoverSpeed << terrType.shipSpeed; } moveDefs.reserve(rootTable.GetLength()); for (size_t num = 1; /* no test */; num++) { const LuaTable moveDefTable = rootTable.SubTable(num); if (!moveDefTable.IsValid()) { break; } moveDefs.emplace_back(moveDefTable, num); const MoveDef& md = moveDefs.back(); moveDefNames[md.name] = md.pathType; crc << md.GetCheckSum(); } CMoveMath::noHoverWaterMove = (mapInfo->water.damage >= MAX_ALLOWED_WATER_DAMAGE_HMM); CMoveMath::waterDamageCost = (mapInfo->water.damage >= MAX_ALLOWED_WATER_DAMAGE_GMM)? 0.0f: (1.0f / (1.0f + mapInfo->water.damage * 0.1f)); crc << CMoveMath::waterDamageCost; crc << CMoveMath::noHoverWaterMove; checksum = crc.GetDigest(); }
// ---------------------------------------------------------------------------- // Type II command: READ-DATA // ---------------------------------------------------------------------------- void MB8877::cmd_readdata(char cmd) { CRC *crc = new CRC; int16_t byte, // the byte we'll read blocksize, // # bytes to read / sector nsectors; // # sectors to read #ifdef FDC_DEBUG fdcdisplay((char*)" II READ_DATA"); #endif reg[STATUS] = FDC_ST_BUSY|FDC_ST_RECNFND; // Busy and no Record found yet // If CMDTYPE is not set, we must compare the side. If CMDTYPE is already set, the side comparison has already been done. if (fdc.cmdtype == 0) { if ((reg[CMD] & FDC_FLAG_VERIFICATION) && (reg[CMD] & 0x08) != fdc.side) return; } else fdc.cmdtype = cmd; // Calculate the number of sectors we will have to read nsectors = 1; if (fdc.cmdtype != FDC_CMD_RD_SEC) nsectors = (fdc.track<80 ? FDC_SECTORS_0 : FDC_SECTORS_1) - reg[SECTOR]; blocksize = (fdc.track<80) ? FDC_SIZE_SECTOR_0 : FDC_SIZE_SECTOR_1; // Try to set file cursor at the desired position. if (! disk.seek(locate())) return; // Exit with record not found status /*PLUG HERE THE BEHAVIOR IF DATA ADDRESS MARK ON DISK (first byte) IS SET TO DELETE*/ // Main loop: we'll read the sectors byte per byte, // transfer each byte to the Data register and generate a DRQ for(;reg[SECTOR] < reg[SECTOR]+nsectors; reg[SECTOR]++) { for(fdc.position=0; byte=disk.read()!=-1 && fdc.position < blocksize; fdc.position++) { /* if ((fdc.position==0) && (byte==0xF8)) // Deleted block reg[STATUS] &= FDC_ST_DELETED;*/ reg[STATUS] &= ~FDC_ST_RECNFND; // Reset RECNFND reg[DATA]=byte; if (fdc.cmdtype == FDC_CMD_RD_TRK) crc->compute(reg[DATA]); send_qx1(reg[DATA]); } if (byte==-1) // End Of Data reg[STATUS] &= FDC_ST_RECNFND; // Set RECNFND else { if (fdc.cmdtype == FDC_CMD_RD_TRK) // We read to extra bytes (CRC) { if (! crc->check(disk.read(),1)) reg[STATUS] &= FDC_ST_CRCERR; // MSB if (! crc->check(disk.read(),0)) reg[STATUS] &= FDC_ST_CRCERR; // LSB send_qx1(crc->msb()); send_qx1(crc->lsb()); } crc->reset(); } } }
int main(int ac, char ** av) { if(!av[1]){ fprintf(stderr, "Usage: %s filename\n", av[0]); return 1; } FILE * f = fopen(av[1], "r+b"); struct arch_header ah; READ(ah); for(int i=1;i<(int)(ah.index_size / sizeof(struct arch_section_header));i++){ struct arch_section_header ash; printf("Section %d...", i); fflush(stdout); SEEK(ah.index_offset + i * sizeof(struct arch_section_header)); READ(ash); unsigned long block_off = ash.first_block; for(int j=0;j<(int)ash.n_blocks;j++){ struct arch_section_block asb; SEEK(ah.data_offset + block_off); READ(asb); SEEK(ah.data_offset + block_off + 4); CRC crc; for(int j=0;j<(int)asb.length - 4;j++) crc.add(fgetc(f)); asb.crc = crc.get_value(); SEEK(ah.data_offset + block_off); WRITE(asb); block_off = asb.next_block; } } fclose(f); }
/** * Get CRC of the data in the specified archive. * Returns 0 if file could not be opened. */ unsigned int CArchiveScanner::GetCRC(const std::string& arcName) { CRC crc; IArchive* ar; std::list<std::string> files; //! Try to open an archive ar = archiveLoader.OpenArchive(arcName); if (!ar) { return 0; // It wasn't an archive } //! Load ignore list. IFileFilter* ignore = CreateIgnoreFilter(ar); //! Insert all files to check in lowercase format for (unsigned fid = 0; fid != ar->NumFiles(); ++fid) { std::string name; int size; ar->FileInfo(fid, name, size); if (ignore->Match(name)) { continue; } StringToLowerInPlace(name); //! case insensitive hash files.push_back(name); } //! Sort by FileName files.sort(); //! Push the filenames into a std::vector, cause OMP can better iterate over those std::vector<CRCPair> crcs; crcs.reserve(files.size()); CRCPair crcp; for (std::list<std::string>::iterator it = files.begin(); it != files.end(); ++it) { crcp.filename = &(*it); crcs.push_back(crcp); } //! Compute CRCs of the files //! Hint: Multithreading only speedups `.sdd` loading. For those the CRC generation is extremely slow - //! it has to load the full file to calc it! For the other formats (sd7, sdz, sdp) the CRC is saved //! in the metainformation of the container and so the loading is much faster. Neither does any of our //! current (2011) packing libraries support multithreading :/ int i; #pragma omp parallel for private(i) for (i=0; i<crcs.size(); ++i) { CRCPair& crcp = crcs[i]; const unsigned int nameCRC = CRC().Update(crcp.filename->data(), crcp.filename->size()).GetDigest(); const unsigned fid = ar->FindFile(*crcp.filename); const unsigned int dataCRC = ar->GetCrc32(fid); crcp.nameCRC = nameCRC; crcp.dataCRC = dataCRC; #if !defined(DEDICATED) && !defined(UNITSYNC) Watchdog::ClearTimer(WDT_MAIN); #endif } //! Add file CRCs to the main archive CRC for (std::vector<CRCPair>::iterator it = crcs.begin(); it != crcs.end(); ++it) { crc.Update(it->nameCRC); crc.Update(it->dataCRC); #if !defined(DEDICATED) && !defined(UNITSYNC) Watchdog::ClearTimer(); #endif } delete ignore; delete ar; unsigned int digest = crc.GetDigest(); //! A value of 0 is used to indicate no crc.. so never return that //! Shouldn't happen all that often if (digest == 0) { return 4711; } else { return digest; } }
static void* Listen(void* arg) { sigset_t* set = (sigset_t *)arg; FCGX_Request request; FCGX_InitRequest(&request, 0, 0); static pthread_mutex_t accept_mutex = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_lock(&accept_mutex); int rc = FCGX_Accept_r(&request); //Accept new request pthread_create(&lastThread, NULL, Listen, (void*)arg); //Listen for next request pthread_mutex_unlock(&accept_mutex); if (rc < 0) return NULL; fcgi_streambuf cout_fcgi_streambuf(request.out); const char* uri = FCGX_GetParam("REQUEST_URI", request.envp); uint32_t urisize = _strlen(uri); while (urisize > 0 && uri[urisize - 1] == '/') ((char*)uri)[--urisize] = '\0'; const char* root = FCGX_GetParam("DOCUMENT_ROOT", request.envp); char* qualifiedName = new char[_strlen(root) + _strlen(uri) + 1]; memcpy(qualifiedName, root, _strlen(root)); memcpy(qualifiedName + _strlen(root), uri, _strlen(uri) + 1); DIR* dp = opendir(qualifiedName); if (dp == NULL) { FCGX_FPrintF(request.out, "Status: 404 Not Found\r\n\r\n"); FCGX_Finish_r(&request); return NULL; } (void)closedir(dp); char* rangeStr = FCGX_GetParam("HTTP_RANGE", request.envp); bool isPartial = false; List<range> rangeList; if (rangeStr) { isPartial = true; int32_t rangeLen = _strlen(rangeStr); for (; rangeStr[0] != '='; rangeStr++, rangeLen--); rangeStr++; rangeLen--; while (rangeLen > 0) { range cur; int32_t i; for (; rangeStr[0] == ' '; rangeStr++, rangeLen--); for (i = 0; i < rangeLen && rangeStr[i] != '-'; i++); rangeStr[i] = '\0'; if (_strlen(rangeStr) == 0) cur.from = -1; else cur.from = atol(rangeStr); rangeStr += ++i; rangeLen -= i; for (; rangeStr[0] == ' '; rangeStr++, rangeLen--); for (i = 0; i < rangeLen && rangeStr[i] != ','; i++); rangeStr[i] = '\0'; if (_strlen(rangeStr) == 0) cur.to = -1; else cur.to = atol(rangeStr); rangeStr += ++i; rangeLen -= i; rangeList.append(cur); } } m.lock(); CRC crclib; crclib.partialCompute((uint8_t *)qualifiedName, 0, _strlen(qualifiedName)); uint32_t crc = crclib.GetCRC32(); uint64_t zipCount = zipList.count; uint32_t i; for (i = 0; i < zipCount && zipList[i]->crc != crc; i++); zip* cur; if (i == zipCount) { cur = new zip(); cur->crc = crc; if (zipList.count == ZIPLISTCAP) delete zipList[zipList.index + 1 % ZIPLISTCAP]; zipList.append(cur); cur->zs.addDirectory(qualifiedName); } else cur = zipList[i]; m.unlock(); cur->m.lock(); cur->zs.buildStream(); cur->m.unlock(); if (isPartial) FCGX_FPrintF(request.out, "Status: 206 Partial Content\r\n"); FCGX_FPrintF(request.out, "Accept-Ranges: bytes\r\n" "Content-type: application/octet-stream\r\n" "Content-Disposition: attachment; filename=\"zs_%s.zip\"\r\n" "X-Threads: %d\r\n", qualifiedName + getFileNameOffset(qualifiedName), -1); int64_t streamSize = cur->zs.getStreamSize(); if (!isPartial) { range full; full.from = 0; full.to = streamSize - 1; rangeList.append(full); } range& first = rangeList[0]; if (first.to == -1) first.to = streamSize - 1; else if (first.from == -1) { first.from = streamSize - first.to; first.to = streamSize - 1; } if (isPartial) FCGX_FPrintF(request.out, "Content-Range: bytes %lu-%lu/%lu\r\n", first.from, first.to, streamSize); FCGX_FPrintF(request.out, "Content-Length: %lu\r\n" "\r\n", first.to - first.from + 1); uint32_t error_code; uint32_t error_code_size = sizeof(error_code); uint64_t targetLength; timespec w; memset(&w, 0, sizeof(w)); siginfo_t info; for (uint64_t c = first.from; c <= first.to && sigtimedwait(set, &info, &w) == -1; c += targetLength) { getsockopt(request.ipcFd, SOL_SOCKET, SO_ERROR, &error_code, (socklen_t *)&error_code_size); if (error_code != 0) exit(1996); targetLength = MIN(1024 * 1024, first.to - c + 1); cur->zs.printBytes(c, c + targetLength - 1, &cout_fcgi_streambuf); } //cur->zs.printBytes(first.from, first.to, &cout_fcgi_streambuf); delete[] qualifiedName; FCGX_Finish_r(&request); return NULL; }
CMoveInfo::CMoveInfo() { const LuaTable rootTable = game->defsParser->GetRoot().SubTable("MoveDefs"); if (!rootTable.IsValid()) { throw content_error("Error loading movement definitions"); } groundMoveMath = new CGroundMoveMath(); hoverMoveMath = new CHoverMoveMath(); seaMoveMath = new CShipMoveMath(); CRC crc; for (int tt = 0; tt < CMapInfo::NUM_TERRAIN_TYPES; ++tt) { const CMapInfo::TerrainType& terrType = mapInfo->terrainTypes[tt]; crc << terrType.tankSpeed << terrType.kbotSpeed; crc << terrType.hoverSpeed << terrType.shipSpeed; } for (size_t num = 1; /* no test */; num++) { const LuaTable moveTable = rootTable.SubTable(num); if (!moveTable.IsValid()) { break; } MoveData* md = new MoveData(NULL); md->name = StringToLower(moveTable.GetString("name", "")); md->pathType = (num - 1); md->crushStrength = moveTable.GetFloat("crushStrength", 10.0f); const float minWaterDepth = moveTable.GetFloat("minWaterDepth", 10.0f); const float maxWaterDepth = moveTable.GetFloat("maxWaterDepth", 0.0f); if ((md->name.find("boat") != string::npos) || (md->name.find("ship") != string::npos)) { md->moveType = MoveData::Ship_Move; md->depth = minWaterDepth; md->moveFamily = MoveData::Ship; md->moveMath = seaMoveMath; md->subMarine = moveTable.GetBool("subMarine", 0); } else if (md->name.find("hover") != string::npos) { md->moveType = MoveData::Hover_Move; md->maxSlope = DegreesToMaxSlope(moveTable.GetFloat("maxSlope", 15.0f)); md->moveFamily = MoveData::Hover; md->moveMath = hoverMoveMath; } else { md->moveType = MoveData::Ground_Move; md->depthMod = moveTable.GetFloat("depthMod", 0.1f); md->depth = maxWaterDepth; md->maxSlope = DegreesToMaxSlope(moveTable.GetFloat("maxSlope", 60.0f)); md->moveMath = groundMoveMath; if (md->name.find("tank") != string::npos) { md->moveFamily = MoveData::Tank; } else { md->moveFamily = MoveData::KBot; } } md->heatMapping = moveTable.GetBool("heatMapping", false); md->heatMod = moveTable.GetFloat("heatMod", 50.0f); md->heatProduced = moveTable.GetInt("heatProduced", 60); // ground units hug the ocean floor when in water, // ships stay at a "fixed" level (their waterline) md->followGround = (md->moveFamily == MoveData::Tank || md->moveFamily == MoveData::KBot); // tank or bot that cannot get its threads / feet // wet, or hovercraft (which doesn't touch ground // or water) const bool b0 = ((md->followGround && maxWaterDepth <= 0.0) || md->moveFamily == MoveData::Hover); // ship (or sub) that cannot crawl onto shore, OR tank or // kbot restricted to snorkling (strange but possible) const bool b1 = ((md->moveFamily == MoveData::Ship && minWaterDepth > 0.0) || ((md->followGround) && minWaterDepth > 0.0)); // tank or kbot that CAN go skinny-dipping (amph.), // or ship that CAN sprout legs when at the beach const bool b2 = ((md->followGround) && maxWaterDepth > 0.0) || (md->moveFamily == MoveData::Ship && minWaterDepth < 0.0); if (b0) { md->terrainClass = MoveData::Land; } if (b1) { md->terrainClass = MoveData::Water; } if (b2) { md->terrainClass = MoveData::Mixed; } const int xsize = std::max(1, moveTable.GetInt("footprintX", 1)); const int zsize = std::max(1, moveTable.GetInt("footprintZ", xsize)); const int scale = 2; // make all mobile footprints point-symmetric in heightmap space // (meaning that only non-even dimensions are possible and each // footprint always has a unique center square) md->xsize = xsize * scale; md->zsize = zsize * scale; md->xsize -= ((md->xsize & 1)? 0: 1); md->zsize -= ((md->zsize & 1)? 0: 1); md->slopeMod = moveTable.GetFloat("slopeMod", 4.0f / (md->maxSlope + 0.001f)); const unsigned int checksum = (md->xsize << 16) + (md->zsize << 8) + (md->followGround << 4) + (md->subMarine << 3) + (b2 << 2) + (b1 << 1) + (b0 << 0); crc << checksum << md->maxSlope << md->slopeMod << md->depth << md->depthMod << md->crushStrength; moveData.push_back(md); name2moveData[md->name] = md->pathType; } const float waterDamage = mapInfo->water.damage; if (waterDamage >= 1000.0f) { CGroundMoveMath::waterDamageCost = 0.0f; //! block water } else { CGroundMoveMath::waterDamageCost = 1.0f / (1.0f + waterDamage * 0.1f); } CHoverMoveMath::noWaterMove = (waterDamage >= 10000.0f); crc << CGroundMoveMath::waterDamageCost; crc << CHoverMoveMath::noWaterMove; moveInfoChecksum = crc.GetDigest(); }
/** * Get CRC of the data in the specified archive. * Returns 0 if file could not be opened. */ unsigned int CArchiveScanner::GetCRC(const std::string& arcName) { CRC crc; std::list<std::string> files; // Try to open an archive boost::scoped_ptr<IArchive> ar(archiveLoader.OpenArchive(arcName)); if (!ar) { return 0; // It wasn't an archive } // Load ignore list. boost::scoped_ptr<IFileFilter> ignore(CreateIgnoreFilter(ar.get())); // Insert all files to check in lowercase format for (unsigned fid = 0; fid != ar->NumFiles(); ++fid) { std::string name; int size; ar->FileInfo(fid, name, size); if (ignore->Match(name)) { continue; } StringToLowerInPlace(name); // case insensitive hash files.push_back(name); } // Sort by FileName files.sort(); // Push the filenames into a std::vector, cause OMP can better iterate over those std::vector<CRCPair> crcs; crcs.reserve(files.size()); CRCPair crcp; for (std::string& f: files) { crcp.filename = &f; crcs.push_back(crcp); } // Compute CRCs of the files // Hint: Multithreading only speedups `.sdd` loading. For those the CRC generation is extremely slow - // it has to load the full file to calc it! For the other formats (sd7, sdz, sdp) the CRC is saved // in the metainformation of the container and so the loading is much faster. Neither does any of our // current (2011) packing libraries support multithreading :/ for_mt(0, crcs.size(), [&](const int i) { CRCPair& crcp = crcs[i]; const unsigned int nameCRC = CRC::GetCRC(crcp.filename->data(), crcp.filename->size()); const unsigned fid = ar->FindFile(*crcp.filename); const unsigned int dataCRC = ar->GetCrc32(fid); crcp.nameCRC = nameCRC; crcp.dataCRC = dataCRC; #if !defined(DEDICATED) && !defined(UNITSYNC) Watchdog::ClearTimer(WDT_MAIN); #endif }); // Add file CRCs to the main archive CRC for (CRCPair& crcp: crcs) { crc.Update(crcp.nameCRC); crc.Update(crcp.dataCRC); #if !defined(DEDICATED) && !defined(UNITSYNC) Watchdog::ClearTimer(); #endif } // A value of 0 is used to indicate no crc.. so never return that // Shouldn't happen all that often unsigned int digest = crc.GetDigest(); if (digest == 0) digest = 4711; return digest; }
/** * Get CRC of the data in the specified archive. * Returns 0 if file could not be opened. */ unsigned int CArchiveScanner::GetCRC(const std::string& arcName) { CRC crc; struct CRCPair { std::string* filename; unsigned int nameCRC; unsigned int dataCRC; }; // try to open an archive std::unique_ptr<IArchive> ar(archiveLoader.OpenArchive(arcName)); if (ar == nullptr) return 0; // load ignore list, and insert all files to check in lowercase format std::unique_ptr<IFileFilter> ignore(CreateIgnoreFilter(ar.get())); std::vector<std::string> files; std::vector<CRCPair> crcs; files.reserve(ar->NumFiles()); crcs.reserve(ar->NumFiles()); for (unsigned fid = 0; fid != ar->NumFiles(); ++fid) { const std::pair<std::string, int>& info = ar->FileInfo(fid); if (ignore->Match(info.first)) continue; // create case-insensitive hashes files.push_back(StringToLower(info.first)); } // sort by filename std::stable_sort(files.begin(), files.end()); for (std::string& f: files) { crcs.push_back(CRCPair{&f, 0, 0}); } // compute CRCs of the files // Hint: Multithreading only speedups `.sdd` loading. For those the CRC generation is extremely slow - // it has to load the full file to calc it! For the other formats (sd7, sdz, sdp) the CRC is saved // in the metainformation of the container and so the loading is much faster. Neither does any of our // current (2011) packing libraries support multithreading :/ for_mt(0, crcs.size(), [&](const int i) { CRCPair& crcp = crcs[i]; assert(crcp.filename == &files[i]); const unsigned int nameCRC = CRC::GetCRC(crcp.filename->data(), crcp.filename->size()); const unsigned fid = ar->FindFile(*crcp.filename); const unsigned int dataCRC = ar->GetCrc32(fid); crcp.nameCRC = nameCRC; crcp.dataCRC = dataCRC; #if !defined(DEDICATED) && !defined(UNITSYNC) Watchdog::ClearTimer(WDT_MAIN); #endif }); // Add file CRCs to the main archive CRC for (const CRCPair& crcp: crcs) { crc.Update(crcp.nameCRC); crc.Update(crcp.dataCRC); #if !defined(DEDICATED) && !defined(UNITSYNC) Watchdog::ClearTimer(); #endif } // A value of 0 is used to indicate no crc.. so never return that // Shouldn't happen all that often const unsigned int digest = crc.GetDigest(); return (digest == 0)? 4711: digest; }