示例#1
0
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();
}
示例#2
0
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();
}
示例#3
0
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();
};
/**
 * 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;
	}
}
示例#5
0
/** 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;
    }
}
示例#6
0
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();
}
示例#7
0
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;
}
示例#9
0
/**
 * 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;
}
示例#10
0
/**
 * 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;
	}
}