public void OnNeighborUpdated(int x, int y, int z, Block thisBlock, Block updatedNeighbor) { if (Config.PhysicsFloodProtection && z >= map.WaterLevel) { return; } if ((thisBlock == Block.Water || thisBlock == Block.StillWater) && (updatedNeighbor == Block.Lava || updatedNeighbor == Block.StillLava)) { map.SetBlock(null, x, y, z, LavaPhysics.LavaPlusWater); } else if (thisBlock == Block.Water) { map.PhysicsQueueTick(x, y, z, updatedNeighbor); } else if (thisBlock == Block.StillWater) { if (CanSpreadTo(map.GetBlock(x - 1, y, z)) || CanSpreadTo(map.GetBlock(x + 1, y, z)) || CanSpreadTo(map.GetBlock(x, y - 1, z)) || CanSpreadTo(map.GetBlock(x, y + 1, z)) || CanSpreadTo(map.GetBlock(x, y, z - 1))) { map.SetBlockNoUpdate(x, y, z, Block.Water); map.PhysicsQueueTick(x, y, z, Block.Water); } } }
// die if block is lit, or if block underneath is not stone/gravel/cobblestone void TriggerMushroom(int x, int y, int z) { if (!Config.PhysicsPlants) { return; } Block blockUnder = map.GetBlock(x, y, z - 1); if (blockUnder != Block.Stone && blockUnder != Block.Gravel && blockUnder != Block.Cobble || IsLit(x, y, z)) { map.SetBlock(null, x, y, z, Block.Air); } }
public void Trigger(int x, int y, int z) { // Find where the snow should drop down to (if at all) int dropZ = z; while (dropZ > 0) { if (!LetsSnowThrough(map.GetBlock(x, y, dropZ - 1))) { break; } dropZ--; } // If snow can drop down, start falling... bool snowHasDropped = false; if (dropZ != z) { Block oldBlock = map.GetBlock(x, y, dropZ); map.SetBlockNoNeighborChange(null, x, y, z, Block.Air); if (oldBlock != Block.Snow) { snowHasDropped = true; } z = dropZ; } if (ThisShouldMelt(x, y, z)) { // If we have any hot neighbors, queue melting (2 ticks from now) map.PhysicsQueueTick(x, y, z, Block.Snow); } else if (snowHasDropped) { // Land the dropped snow map.SetBlock(null, x, y, dropZ, Block.Snow); } }
bool ProcessSetBlockPacket() { ResetIdleTimer(); short x = reader.ReadInt16(); short z = reader.ReadInt16(); short y = reader.ReadInt16(); bool isDeleting = (reader.ReadByte() == 0); byte rawType = reader.ReadByte(); // check if block type is valid if (!UsesCustomBlocks && rawType > (byte)Map.MaxLegalBlockType || UsesCustomBlocks && rawType > (byte)Map.MaxCustomBlockType) { KickNow("Hacking detected."); Logger.LogWarning("Player {0} tried to place an invalid block type.", Name); return(false); } if (IsPainting) { isDeleting = false; } Block block = (Block)rawType; if (isDeleting) { block = Block.Air; } // check if coordinates are within map boundaries (don't kick) if (!Map.InBounds(x, y, z)) { return(true); } // check if player is close enough to place if (!IsOp && Config.LimitClickDistance || IsOp && Config.OpLimitClickDistance) { if (Math.Abs(x * 32 - Position.X) > MaxBlockPlacementRange || Math.Abs(y * 32 - Position.Y) > MaxBlockPlacementRange || Math.Abs(z * 32 - Position.Z) > MaxBlockPlacementRange) { KickNow("Hacking detected."); Logger.LogWarning("Player {0} tried to place a block too far away.", Name); return(false); } } // check click rate if (!IsOp && Config.LimitClickRate || IsOp && Config.OpLimitClickRate) { if (DetectBlockSpam()) { KickNow("Hacking detected."); Logger.LogWarning("Player {0} tried to place blocks too quickly.", Name); return(false); } } // apply blocktype mapping if (block == Block.Blue && PlaceWater) { block = Block.Water; } else if (block == Block.Red && PlaceLava) { block = Block.Lava; } else if (block == Block.Stone && PlaceSolid) { block = Block.Admincrete; } else if (block == Block.Dirt && PlaceGrass) { block = Block.Grass; } // check if blocktype is permitted if ((block == Block.Water || block == Block.StillWater) && !CanUseWater || (block == Block.Lava || block == Block.StillLava) && !CanUseLava || (block == Block.Grass) && !CanUseGrass || (block == Block.Admincrete || block == Block.Admincrete) && !CanUseSolid) { KickNow("Hacking detected."); Logger.LogWarning("Player {0} tried to place a restricted block type.", Name); return(false); } // check if deleting admincrete Block oldBlock = Map.GetBlock(x, y, z); if ((oldBlock == Block.Admincrete) && !CanUseSolid) { KickNow("Hacking detected."); Logger.LogWarning("Player {0} tried to delete a restricted block type.", Name); return(false); } // update map Map.SetBlock(this, x, y, z, block); // check if sending back an update is necessary Block placedBlock = Map.GetBlock(x, y, z); if (IsPainting || (!isDeleting && placedBlock != (Block)rawType)) { writer.Write(Packet.MakeSetBlock(x, y, z, placedBlock).Bytes); } return(true); }