public bool SetBlockNoNeighborChange([CanBeNull] Player except, int x, int y, int z, Block newBlock) { Block oldBlock = GetBlock(x, y, z); if (oldBlock == newBlock || oldBlock == Block.Undefined) { return(false); } // water at map edges if ((x == 0 || y == 0 || x == Width - 1 || y == Length - 1) && (z >= WaterLevel - 2 && z < WaterLevel) && (newBlock == Block.Air)) { newBlock = Block.Water; // stair stacking } else if (newBlock == Block.Slab && GetBlock(x, y, z - 1) == Block.Slab) { SetBlock(null, x, y, z, Block.Air); SetBlock(null, x, y, z - 1, Block.DoubleSlab); return(true); } else if (newBlock == Block.CobbleSlab && GetBlock(x, y, z - 1) == Block.CobbleSlab) { SetBlock(null, x, y, z, Block.Air); SetBlock(null, x, y, z - 1, Block.Cobble); return(true); } Blocks[Index(x, y, z)] = (byte)newBlock; ChangedSinceSave = true; PhysicsOnRemoved(x, y, z, oldBlock); PhysicsOnPlaced(x, y, z, newBlock); if (IsActive) { Server.Players.Send(except, Packet.MakeSetBlock(x, y, z, GetBlock(x, y, z))); } return(true); }
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); }