示例#1
0
        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);
        }