void Grass::randomTick(const Block &block, World &world, BlockIterator blockIterator, WorldLockManager &lock_manager) const { BlockIterator bi = blockIterator; bi.moveBy(VectorI(0, 1, 0)); Block b = bi.get(lock_manager); if((b.lighting.toFloat(world.getLighting(bi.position().d)) >= 4.0f / 15 || b.lighting.indirectSkylight >= 4) && b.descriptor->lightProperties.isTotallyTransparent()) return; world.setBlock(blockIterator, lock_manager, Block(Dirt::descriptor())); }
//======================================================================== template <class Scalar> inline Vector<Scalar> Vector<Scalar> ::getNonConstBlock(const BlockIterator<Scalar>& b) { /* Check that the block iterator is valid */ TEUCHOS_TEST_FOR_EXCEPTION(b.atEnd(), RuntimeError, "Attempt to use a block iterator that's run off end"); return this->getNonConstBlock(b.blockIndex()); }
void Dirt::randomTick(const Block &block, World &world, BlockIterator blockIterator, WorldLockManager &lock_manager) const { BlockIterator bi = blockIterator; bi.moveBy(VectorI(0, 1, 0)); Block b = bi.get(lock_manager); if(!b.good()) return; if(b.lighting.toFloat(world.getLighting(bi.position().d)) < 4.0f / 15 || !b.descriptor->lightProperties.isTotallyTransparent()) return; for(int dx = -1; dx <= 1; dx++) { for(int dy = -3; dy <= 1; dy++) { for(int dz = -1; dz <= 1; dz++) { bi = blockIterator; bi.moveBy(VectorI(dx, dy, dz)); b = bi.get(lock_manager); if(b.descriptor != Grass::descriptor()) continue; bi.moveBy(VectorI(0, 1, 0)); Block b = bi.get(lock_manager); if(b.lighting.toFloat(world.getLighting(bi.position().d)) < 9.0f / 15) continue; world.setBlock(blockIterator, lock_manager, Block(Grass::descriptor())); return; } } } }
int main () { vector<double> data (300, 0.0); unsigned block_size = 23; unsigned data_size = 5; unsigned current = 0; double value = 1.0; unsigned count = 0; unsigned total = 0; while (current < data.size()) { data[current] = value; current ++; value ++; count ++; total ++; if (count == data_size) { current += block_size - data_size; count = 0; } } BlockIterator<double> iterator ( &(data[0]) ); iterator.set_data_size (data_size); iterator.set_block_size (block_size); value = 1.0; for (count=0; count < total; count++) { if (value != *iterator) { cerr << "BlockIterator fail" << endl; cerr << "expected=" << value << " got=" << *iterator << endl; return -1; } value ++; ++ iterator; } cerr << "BlockIterator passes simple test" << endl; return 0; }
void Torch::onReplace(World &world, Block b, BlockIterator bi, WorldLockManager &lock_manager) const { ItemDescriptor::addToWorld(world, lock_manager, ItemStack(Item(Items::builtin::Torch::descriptor())), bi.position() + VectorF(0.5)); }
template <class Scalar> inline bool BlockIterator<Scalar> ::operator<(const BlockIterator<Scalar>& other) const { if (debug()) { Out::os() << "comparing (<): LHS=" << *this << ", RHS=" << other << std::endl; } TEUCHOS_TEST_FOR_EXCEPTION(this->space() != other.space(), RuntimeError, "Attempt to compare block iterators attached to " "two different spaces"); if (!this->atEnd_ && other.atEnd_) return true; if (this->atEnd_ && !other.atEnd_) return false; if (this->atEnd_ && other.atEnd_) return false; int d = std::min(this->index_.size(), other.index_.size()); for (int i=0; i<d; i++) { if (this->index_[i] < other.index_[i]) return true; if (this->index_[i] > other.index_[i]) return false; } return false; }
void CorDisasm::dumpInstruction(const BlockIterator &BIter) const { assert(BIter.isDecoded() && "Cannot print before Decode"); uint64_t InstSize = BIter.InstrSize; string buffer; raw_string_ostream OS(buffer); OS << format("%8llx: ", BIter.Addr); dumpBytes(ArrayRef<uint8_t>(BIter.Ptr, InstSize), OS); if ((TheTargetArch == Target_X86) || (TheTargetArch == Target_X64)) { // For architectures with a variable size instruction, we pad the // byte dump with space up to 7 bytes. Some instructions might be longer, // but ... const char *Padding[] = {"", " ", " ", " ", " ", " ", " "}; OS << (Padding[(InstSize < 7) ? (7 - InstSize) : 0]); } IP->printInst(&BIter.Inst, OS, "", *STI); Print->Dump(OS.str().c_str()); }
int TestNet3Chain::nextWorkRequired(BlockIterator blk) const { const int64_t nTargetTimespan = 14 * 24 * 60 * 60; // two weeks const int64_t nTargetSpacing = 10 * 60; const int64_t nInterval = nTargetTimespan / nTargetSpacing; // Genesis block int h = blk.height(); if (h == 0) // trick to test that it is asking for the genesis block return proofOfWorkLimit().GetCompact(); // Only change once per interval if ((h + 1) % nInterval != 0) { // Return the last non-special-min-difficulty-rules-block while (blk.height() % nInterval != 0 && blk->bits == proofOfWorkLimit().GetCompact()) blk--; return blk->bits; } // Go back by what we want to be 14 days worth of blocks BlockIterator former = blk - (nInterval-1); // Limit adjustment step int nActualTimespan = blk->time - former->time; log_debug(" nActualTimespan = %"PRI64d" before bounds", nActualTimespan); if (nActualTimespan < nTargetTimespan/4) nActualTimespan = nTargetTimespan/4; if (nActualTimespan > nTargetTimespan*4) nActualTimespan = nTargetTimespan*4; // Retarget CBigNum bnNew; bnNew.SetCompact(blk->bits); bnNew *= nActualTimespan; bnNew /= nTargetTimespan; if (bnNew > proofOfWorkLimit()) bnNew = proofOfWorkLimit(); /// debug print log_info("GetNextWorkRequired RETARGET"); log_info("\tnTargetTimespan = %"PRI64d" nActualTimespan = %"PRI64d"", nTargetTimespan, nActualTimespan); log_info("\tBefore: %08x %s", blk->bits, CBigNum().SetCompact(blk->bits).getuint256().toString().c_str()); log_info("\tAfter: %08x %s", bnNew.GetCompact(), bnNew.getuint256().toString().c_str()); return bnNew.GetCompact(); }
void Grass::onBreak( World &world, Block b, BlockIterator bi, WorldLockManager &lock_manager, Item &tool) const { ItemDescriptor::addToWorld(world, lock_manager, ItemStack(Item(Items::builtin::Dirt::descriptor())), bi.position() + VectorF(0.5)); handleToolDamage(tool); }
void Torch::generateParticles(World &world, Block b, BlockIterator bi, WorldLockManager &lock_manager, double currentTime, double deltaTime) const { const double generateSmokePerSecond = 1.0; double nextTime = currentTime + deltaTime; std::uint32_t v = std::hash<PositionI>()(bi.position()); v *= 21793497; float timeOffset = (float)v / 6127846.0f; double currentSmokeCount = std::floor(currentTime * generateSmokePerSecond + timeOffset); double nextSmokeCount = std::floor(nextTime * generateSmokePerSecond + timeOffset); int generateSmokeCount = limit<int>((int)(nextSmokeCount - currentSmokeCount), 0, 10); for(int i = 0; i < generateSmokeCount; i++) { Entities::builtin::particles::Smoke::addToWorld( world, lock_manager, bi.position() + headPosition); } }
void Torch::onDisattach(World &world, const Block &block, BlockIterator blockIterator, WorldLockManager &lock_manager, BlockUpdateKind blockUpdateKind) const { ItemDescriptor::addToWorld(world, lock_manager, ItemStack(Item(Items::builtin::Torch::descriptor())), blockIterator.position() + VectorF(0.5)); world.setBlock(blockIterator, lock_manager, Block(Air::descriptor(), block.lighting)); }
void DiamondOre::onBreak( World &world, Block b, BlockIterator bi, WorldLockManager &lock_manager, Item &tool) const { if(isMatchingTool(tool)) { ItemDescriptor::addToWorld(world, lock_manager, ItemStack(Item(Items::builtin::Diamond::descriptor())), bi.position() + VectorF(0.5)); } handleToolDamage(tool); }
Value GetBlock::operator()(const Array& params, bool fHelp) { if (fHelp || params.size() != 1) throw RPC::error(RPC::invalid_params, "getblock <hash>\n" "Returns details of a block with given block-hash."); std::string strHash = params[0].get_str(); uint256 hash(strHash); BlockIterator blk = _node.blockChain().iterator(hash); Block block; _node.blockChain().getBlock(hash, block); if (block.isNull()) throw RPC::error(RPC::invalid_request, "Block not found"); Object result; result.push_back(Pair("hash", blk->hash.GetHex())); result.push_back(Pair("blockcount", blk.height())); result.push_back(Pair("version", block.getVersion())); result.push_back(Pair("merkleroot", block.getMerkleRoot().GetHex())); result.push_back(Pair("time", (boost::int64_t)block.getBlockTime())); result.push_back(Pair("nonce", (boost::uint64_t)block.getNonce())); result.push_back(Pair("difficulty", _node.blockChain().getDifficulty(blk))); Array txhashes; BOOST_FOREACH (const Transaction&tx, block.getTransactions()) txhashes.push_back(tx.getHash().GetHex()); result.push_back(Pair("tx", txhashes)); BlockIterator prev = blk + 1; BlockIterator next = blk - 1; if (!!prev) result.push_back(Pair("hashprevious", prev->hash.GetHex())); if (!!next ) result.push_back(Pair("hashnext", next->hash.GetHex())); return result; }
void LapisLazuliOre::onBreak( World &world, Block b, BlockIterator bi, WorldLockManager &lock_manager, Item &tool) const { if(isMatchingTool(tool)) { int dropCount = std::uniform_int_distribution<int>(4, 8)(world.getRandomGenerator()); for(int i = 0; i < dropCount; i++) ItemDescriptor::addToWorld(world, lock_manager, ItemStack(Item(Items::builtin::LapisLazuli::descriptor())), bi.position() + VectorF(0.5)); } handleToolDamage(tool); }
int LitecoinChain::nextWorkRequired(BlockIterator blk) const { const int64_t nTargetTimespan = 3.5 * 24 * 60 * 60; // two weeks const int64_t nTargetSpacing = 2.5 * 60; const int64_t nInterval = nTargetTimespan / nTargetSpacing; // Genesis block int h = blk.height(); if (h == 0) // trick to test that it is asking for the genesis block return _genesisBlock.getBits(); // proofOfWorkLimit().GetCompact(); Actually not for the genesisblock - here it is 0x1e0ffff0, not 0x1e0fffff // Only change once per interval if ((h + 1) % nInterval != 0) return blk->bits; // Litecoin: This fixes an issue where a 51% attack can change difficulty at will. // Go back the full period unless it's the first retarget after genesis. Code courtesy of Art Forz int blockstogoback = nInterval-1; if ((h + 1) != nInterval) blockstogoback = nInterval; // Go back by what we want to be 3.5 days worth of blocks BlockIterator former = blk - blockstogoback; // Limit adjustment step int nActualTimespan = blk->time - former->time; log_debug(" nActualTimespan = %"PRI64d" before bounds", nActualTimespan); if (nActualTimespan < nTargetTimespan/4) nActualTimespan = nTargetTimespan/4; if (nActualTimespan > nTargetTimespan*4) nActualTimespan = nTargetTimespan*4; // Retarget CBigNum bnNew; bnNew.SetCompact(blk->bits); bnNew *= nActualTimespan; bnNew /= nTargetTimespan; if (bnNew > proofOfWorkLimit()) bnNew = proofOfWorkLimit(); /// debug print log_info("GetNextWorkRequired RETARGET"); log_info("\tnTargetTimespan = %"PRI64d" nActualTimespan = %"PRI64d"", nTargetTimespan, nActualTimespan); log_info("\tBefore: %08x %s", blk->bits, CBigNum().SetCompact(blk->bits).getuint256().toString().c_str()); log_info("\tAfter: %08x %s", bnNew.GetCompact(), bnNew.getuint256().toString().c_str()); return bnNew.GetCompact(); }
uint64_t CorDisasm::disasmInstruction(BlockIterator &BIter, bool DumpAsm) const { uint64_t TotalSize = 0; bool ContinueDisasm; // On X86, LLVM disassembler does not handle instruction prefixes // correctly -- please see LLVM bug 7709. // The disassembler reports instruction prefixes separate from the // actual instruction. In order to work-around this problem, we // continue decoding past the prefix bytes. do { if (!decodeInstruction(BIter)) { return 0; } uint64_t Size = BIter.InstrSize; TotalSize += Size; if (DumpAsm) { dumpInstruction(BIter); } ContinueDisasm = false; if ((TheTargetArch == Target_X86) || (TheTargetArch == Target_X64)) { // Check if the decoded instruction is a prefix byte, and if so, // continue decoding. if (Size == 1) { for (uint8_t Pfx = 0; Pfx < X86NumPrefixes; Pfx++) { if (BIter.Ptr[0] == X86Prefix[Pfx].MachineOpcode) { ContinueDisasm = true; BIter.advance(); break; } } } } } while (ContinueDisasm); return TotalSize; }
int TerracoinChain::nextWorkRequired(BlockIterator blk) const { const int64_t nTargetTimespan = 60 * 60; // one hour weeks const int64_t nTargetSpacing = 2 * 60; // new block every two minutes const int64_t nInterval = nTargetTimespan / nTargetSpacing; // Genesis block int h = blk.height(); if (h == 0) // trick to test that it is asking for the genesis block return proofOfWorkLimit().GetCompact(); // Only change once per interval if ((h + 1) % nInterval != 0) return blk->bits; // Go back by what we want to be 14 days worth of blocks BlockIterator former = blk - (nInterval-1); // Limit adjustment step int nActualTimespan = blk->time - former->time; log_debug(" nActualTimespan = %"PRI64d" before bounds", nActualTimespan); if (nActualTimespan < nTargetTimespan/4) nActualTimespan = nTargetTimespan/4; if (nActualTimespan > nTargetTimespan*4) nActualTimespan = nTargetTimespan*4; // Retarget CBigNum bnNew; bnNew.SetCompact(blk->bits); bnNew *= nActualTimespan; bnNew /= nTargetTimespan; if (bnNew > proofOfWorkLimit()) bnNew = proofOfWorkLimit(); /// debug print log_info("GetNextWorkRequired RETARGET"); log_info("nTargetTimespan = %"PRI64d" nActualTimespan = %"PRI64d"", nTargetTimespan, nActualTimespan); log_info("Before: %08x %s", blk->bits, CBigNum().SetCompact(blk->bits).getuint256().toString().c_str()); log_info("After: %08x %s", bnNew.GetCompact(), bnNew.getuint256().toString().c_str()); return bnNew.GetCompact(); }
void EntityPlayer::onMove(EntityData & data, shared_ptr<World> world, float deltaTimeIn) const { getEntity(data, world); assert(data.extraData); auto eData = dynamic_pointer_cast<ExtraData>(data.extraData); assert(eData); data.deltaAcceleration = VectorF(0); data.acceleration = gravityVector; if(eData->flying) data.acceleration = VectorF(0); int count = iceil(deltaTimeIn * abs(data.velocity) / 0.5 + 1); BlockIterator bi = world->get((PositionI)data.position); data.entity->acceleration = data.acceleration; data.entity->deltaAcceleration = data.deltaAcceleration; auto pphysicsObject = make_shared<PhysicsBox>((VectorF)data.position + physicsOffset(), physicsExtents(), data.velocity, data.entity->acceleration, data.entity->deltaAcceleration, data.position.d, physicsProperties(), -physicsOffset()); PhysicsBox & physicsObject = *pphysicsObject; for(int step = 0; step < count; step++) { float deltaTime = deltaTimeIn / count; data.entity->age += deltaTime; int zeroCount = 0; while(deltaTime * deltaTime * absSquared(data.velocity) > eps * eps) { bool supported = false; PhysicsCollision firstCollision(data.position + deltaTime * data.velocity + deltaTime * deltaTime * 0.5f * data.entity->acceleration + deltaTime * deltaTime * deltaTime * (1 / 6.0f) * data.entity->deltaAcceleration, data.velocity + deltaTime * data.entity->acceleration + deltaTime * deltaTime * 0.5f * data.entity->deltaAcceleration, VectorF(0), deltaTime); physicsObject.reInit((VectorF)data.position + physicsOffset(), physicsExtents(), data.velocity, data.entity->acceleration, data.entity->deltaAcceleration); for(int dx = -1; dx <= 1; dx++) { for(int dy = -2; dy <= 2; dy++) { for(int dz = -1; dz <= 1; dz++) { BlockIterator curBI = bi; curBI += VectorI(dx, dy, dz); shared_ptr<PhysicsObject> otherObject; if(curBI.get().good()) otherObject = curBI.get().desc->getPhysicsObject(curBI.position()); else otherObject = static_pointer_cast<PhysicsObject>(make_shared<PhysicsBox>((VectorI)curBI.position() + VectorF(0.5), VectorF(0.5), VectorF(0), VectorF(0), VectorF(0), curBI.position().d, PhysicsProperties(PhysicsProperties::INFINITE_MASS, 1, 0))); assert(otherObject); { bool filled = false; float newY; switch(otherObject->type()) { case PhysicsObject::Type::Box: { const PhysicsBox * pbox = dynamic_cast<const PhysicsBox *>(otherObject.get()); VectorF min = pbox->center - pbox->extents; VectorF max = pbox->center + pbox->extents; if(min.x <= curBI.position().x && max.x >= curBI.position().x + 1 && min.y <= curBI.position().y && max.y >= curBI.position().y + 1 && min.z <= curBI.position().z && max.z >= curBI.position().z + 1) { newY = max.y + physicsObject.extents.y - physicsOffset().y; filled = true; } VectorF temp; if(isBoxCollision(pbox->center, pbox->extents, physicsObject.center - VectorF(0, eps * 10, 0) + physicsOffset(), physicsObject.extents, temp) && !isBoxCollision(pbox->center, pbox->extents, physicsObject.center + physicsOffset(), physicsObject.extents, temp)) { supported = true; } break; } case PhysicsObject::Type::None: break; } if(filled && zeroCount >= 2 && dx == 0 && dy == 0 && dz == 0) { firstCollision.time = 0; firstCollision.newPosition = data.position; firstCollision.newPosition.y = newY; firstCollision.newVelocity = VectorF(0); firstCollision.collisionNormal = VectorF(0, 1, 0); break; } } PhysicsCollision collision = physicsObject.collide(otherObject, deltaTime); if(collision.valid) { if(collision.time < eps) { if(zeroCount > 25) collision.valid = false; else zeroCount++; } else zeroCount = 0; } if(collision.valid && collision.time < firstCollision.time) firstCollision = collision; } } } deltaTime -= firstCollision.time; data.setPosition(firstCollision.newPosition + eps * (2 + abs(firstCollision.newVelocity)) * firstCollision.collisionNormal); data.setVelocity(firstCollision.newVelocity); data.setAcceleration(data.entity->acceleration + data.entity->deltaAcceleration * firstCollision.time); } } if(eData->pclient == nullptr || !isClientValid(*eData->pclient)) { data.clear(); return; } }
void Gravel::onBreak(World &world, Block b, BlockIterator bi, WorldLockManager &lock_manager, Item &tool) const { if(isMatchingTool(tool)) { if(std::uniform_int_distribution<int>(0, 9)(world.getRandomGenerator()) <= 0) ItemDescriptor::addToWorld(world, lock_manager, ItemStack(Item(Items::builtin::Flint::descriptor())), bi.position() + VectorF(0.5)); else ItemDescriptor::addToWorld(world, lock_manager, ItemStack(Item(Items::builtin::Gravel::descriptor())), bi.position() + VectorF(0.5)); } handleToolDamage(tool); }
status_t MatroskaSource::read( MediaBuffer **out, const ReadOptions *options) { *out = NULL; int64_t seekTimeUs; ReadOptions::SeekMode mode; if (options && options->getSeekTo(&seekTimeUs, &mode)) { mBlockIter.seek(seekTimeUs); } if (mBlockIter.eos()) { return ERROR_END_OF_STREAM; } const mkvparser::Block *block = mBlockIter.block(); size_t size = block->GetSize(); int64_t timeUs = mBlockIter.blockTimeUs(); MediaBuffer *buffer = new MediaBuffer(size + 2); buffer->meta_data()->setInt64(kKeyTime, timeUs); buffer->meta_data()->setInt32(kKeyIsSyncFrame, block->IsKey()); long res = block->Read( mExtractor->mReader, (unsigned char *)buffer->data() + 2); if (res != 0) { return ERROR_END_OF_STREAM; } buffer->set_range(2, size); if (mType == AVC) { CHECK(size >= 2); uint8_t *data = (uint8_t *)buffer->data(); unsigned NALsize = data[2] << 8 | data[3]; CHECK_EQ(size, NALsize + 2); memcpy(data, "\x00\x00\x00\x01", 4); buffer->set_range(0, size + 2); } else if (mType == AAC) { // There's strange junk at the beginning... const uint8_t *data = (const uint8_t *)buffer->data() + 2; size_t offset = 0; while (offset < size && data[offset] != 0x21) { ++offset; } buffer->set_range(2 + offset, size - offset); } *out = buffer; #if 0 hexdump((const uint8_t *)buffer->data() + buffer->range_offset(), buffer->range_length()); #endif mBlockIter.advance(); return OK; }
status_t MatroskaSource::start(MetaData *params) { mBlockIter.reset(); return OK; }