コード例 #1
0
        public async ValueTask <CaptchaImage> Captcha(string type, BaseCaptchaOptions options)
        {
            var captcha = _factory.Create(type);

            if (captcha == null)
            {
                return(default);
コード例 #2
0
        public virtual bool AllowValidate(CaptchaValidateContext context, BaseCaptchaOptions options = null)
        {
            var result = context.GetResult();

            if (!result.AllowValidate)
            {
                return(result.AllowValidate);
            }
            result.AllowValidate = options == null? result.Count < Options?.Validate_Max: result.Count < options.Validate_Max;
            return(result.AllowValidate);
        }
コード例 #3
0
 public abstract ValueTask <CaptchaImage> CaptchaCreate(BaseCaptchaOptions options = null);
コード例 #4
0
 public ValueTask <CaptchaImage> Captcha(BaseCaptchaOptions options = null)
 {
     return(CaptchaCreate(options));
 }
コード例 #5
0
        ValueTask <CaptchaImage> ICaptchaManager.Captcha <T>(BaseCaptchaOptions options)
        {
            var type = typeof(T).Name;

            return(Captcha(type, options));
        }
コード例 #6
0
        public async ValueTask <ValidateResult> Validate(string captcha, CaptchaValidateContext context, BaseCaptchaOptions options)
        {
            var validator = _validatorFactory.Create(captcha);

            if (validator == null)
            {
                return(ValidateResult.Failed);
            }
            if (!validator.AllowValidate(context, options))
            {
                return(context.GetResult().NotAllow());
            }

            var handlers = _validateHandlerFactory?.Create(captcha);

            if (handlers?.Any() ?? false)
            {
                handlers.Handing(async(handler, context) => await handler.Validating(context, options), context);
                if (!context.GetResult().AllowValidate)
                {
                    return(context.GetResult().NotAllow());
                }
            }

            await validator.Validate(context, options);

            var result = context.GetResult();

            if (result.Token == null && result.Succeed)
            {
                result.Token = _token.Create();
            }
            if (!result.Succeed)
            {
                result.Token = null;
            }
            if (result.AllowValidate)
            {
                result.AllowValidate = validator.AllowValidate(context, options);
            }
            handlers?.Reverse().Handing(async(handler, context) => await handler.Validated(context, options), context);
            return(result);
        }
コード例 #7
0
        public ValueTask <ValidateResult> Validate <T>(CaptchaValidateContext context, BaseCaptchaOptions options) where T : ICaptcha, new()
        {
            var type = typeof(T).Name;

            return(Validate(type, context, options));
        }
コード例 #8
0
        public override async ValueTask <CaptchaImage> CaptchaCreate(BaseCaptchaOptions options)
        {
            var path = _imageProvider.SliderRoot;

            using Image <Rgba32> image = await _imageProvider.LoadBackground();

            using var alpha = await _imageProvider.LoadAlpha(path);

            using var border = await _imageProvider.LoadBorder(path);

            using var slider = await _imageProvider.LoadSlider(path);

            var fullImage = image.Clone();
            var option    = options ?? _options;
            int col       = option.Col;
            int row       = option.Row;
            int rotate    = rd.Next(0, 2);
            var point     = RandPoint(image, alpha);

            _driver.CopyNoAlpha(image, new Point(point.X, point.Y), alpha);
            alpha.Mutate(x =>
            {
                x.DrawImage(border, 1);
                if (rotate > 0)
                {
                    rotate = rd.Next(0, 2);
                    x.RotateFlip(RotateMode.Rotate180, rotate == 1?FlipMode.Horizontal:FlipMode.Vertical);
                    rotate = rotate == 0 ? 180 : -180;
                }
            });
            image.Mutate(x =>
            {
                x.DrawImage(slider, new Point(point.X, point.Y), 1);
                if (option?.Safelevel != SafelevelEnum.None)
                {
                    var level = (int)option.Safelevel + 1;
                    for (int i = 0; i < level; i++)
                    {
                        using var safe = slider.Clone();
                        var rePoint    = RandPoint(image, slider);
                        if ((i & 1) == 1)
                        {
                            rePoint.Y = point.Y;
                        }
                        var xpos  = Math.Abs(point.X - rePoint.X);
                        var ypost = Math.Abs(point.Y - rePoint.Y);
                        if (xpos <= (slider.Width >> 1))
                        {
                            xpos       = rd.Next(slider.Width - xpos, slider.Width);
                            rePoint.X += (i & 1) == 1 ? -xpos : xpos;
                        }
                        if (ypost <= (slider.Height >> 1))
                        {
                            ypost      = rd.Next(0, slider.Height >> 1);
                            rePoint.Y += (i & 1) == 1 ? ypost : -ypost;
                        }
                        safe.Mutate(x => x.Rotate(rd.Next(30, 60)));
                        x.DrawImage(safe, rePoint.Point, 0.7f);
                    }
                }
            });

            var randData = _driver.RandImagesBy(image, ref col, ref row);

            _captchaImageBuilder.AddBackground(fullImage)
            .AddGap(alpha.Clone())
            .AddRandData(randData)
            .AddGapBackground(_driver.ImageByRandImages(image, randData, col))
            .AddIndex(randData.Select(x => x.Index).ToArray())
            .AddChange(randData.Where(x => x.Change).Select(x => x.Index).ToArray())
            .AddColumn(col).AddRow(row)
            .AddType(Type).AddName(Name)
            .AddTips("向右拖动滑块填充拼图")
            .AddPoints(new List <CaptchaPoint>(1)
            {
                point
            })
            .AddExtension(new SliderExtension(point.Y, rotate))
            .AddOptions(option);
            return(_captchaImageBuilder.Build());
        }
コード例 #9
0
        public override ValueTask <ValidateResult> Validate(CaptchaValidateContext context, BaseCaptchaOptions options)
        {
            var model = context.GetResult();

            model.IsValidate = true;
            model.Count++;
            model.Succeed = false;
            var sourcePoints = context.Source.Points;
            var points       = context.Validate.Points;

            if (!points?.Any() ?? true || points.Count != sourcePoints?.Count)
            {
                return(new ValueTask <ValidateResult>(model));
            }

            var offset = options?.Offset ?? _options.Offset;

            model.Succeed = true;
            for (int i = 0; i < points.Count; i++)
            {
                var pitem = points[i];
                var oldp  = sourcePoints[i];
                if (pitem.X >= oldp.X - offset && //验证左边范围
                    pitem.X <= oldp.X + oldp.Width + offset &&    //验证 右边范围
                    pitem.Y >= oldp.Y - offset &&     //验证高度上的范围
                    pitem.Y <= oldp.Y + oldp.Height + offset       //验证高度 下的范围
                    )
                {
                    continue;
                }
                model.Succeed = false;
                break;
            }
            model.AllowValidate = !model.Succeed;
            return(new ValueTask <ValidateResult>(model));
        }
コード例 #10
0
        public override ValueTask <ValidateResult> Validate(CaptchaValidateContext context, BaseCaptchaOptions options)
        {
            var model = context.GetResult();

            model.IsValidate = true;
            model.Count++;
            model.Succeed = false;

            if (context.Validate?.Points?.Count != 1)
            {
                return(new ValueTask <ValidateResult>(model));
            }
            var targetPoint = context.Validate.Points[0];
            var vPoint      = context.Source.Points[0];

            var x     = Math.Abs(vPoint.X - targetPoint.X);
            var y     = Math.Abs(vPoint.Y - targetPoint.Y);
            var range = options?.Offset ?? _options.Offset;

            if (x >= 0 && x <= range && y >= 0 && y <= range)
            {
                model.Succeed       = true;
                model.AllowValidate = false;
            }

            return(new ValueTask <ValidateResult>(model));
        }
コード例 #11
0
 public override Task Validating(CaptchaValidateContext context, BaseCaptchaOptions options = null)
 {
     return(Task.CompletedTask);
 }
コード例 #12
0
 public abstract ValueTask <ValidateResult> Validate(CaptchaValidateContext context, BaseCaptchaOptions options = null);
コード例 #13
0
        public override async ValueTask <CaptchaImage> CaptchaCreate(BaseCaptchaOptions options = null)
        {
            var path = _imageProvider.SliderRoot;

            using Image <Rgba32> image = await _imageProvider.LoadBackground();

            var fullImage = image.Clone();
            var option    = options ?? _options;
            int col       = option.Col;
            int row       = option.Row;
            var lumps     = await _imageProvider.LoadRandImages(_imageProvider.LumpRoot);

            var count    = Math.Min((int)option.Safelevel + 1, lumps.Count);
            var points   = new List <CaptchaPoint>(lumps.Count);
            var rdPoints = RandPoints(image, lumps.ToArray());

            image.Mutate(x =>
            {
                foreach (var lump in lumps)
                {
                    var point = RandPoint(rdPoints);
                    if (point != null)
                    {
                        x.DrawImage(lump, new Point(point.X, point.Y), 1);
                        points.Add(point);
                    }
                }
            });
            rdPoints.Clear();
            var randData  = _driver.RandImagesBy(image, ref col, ref row);
            var randImage = _driver.ImageByRandImages(image, randData, col);
            var xpos      = 0;
            var ypos      = randImage.Height + 2;
            var height    = lumps.Max(x => x.Height) + 2;

            var pointRandImage = new Image <Rgba32>(randImage.Width, randImage.Height + height);

            _driver.Copy(randImage.CloneAs <Rgba32>(), Point.Empty, pointRandImage);
            pointRandImage.Mutate(x =>
            {
                for (int i = 0; i < lumps.Count; i++)
                {
                    using var lump = lumps[i].Clone();
                    lump.Mutate(x => x.Invert());
                    x.DrawImage(lump, new Point(xpos, ypos), 1);
                    xpos += lump.Width + 5;
                    lumps[i].Dispose();
                }
            });
            _captchaImageBuilder.AddBackground(fullImage)
            .AddRandData(randData)
            .AddGapBackground(pointRandImage)
            .AddIndex(randData.Select(x => x.Index).ToArray())
            .AddChange(randData.Where(x => x.Change).Select(x => x.Index).ToArray())
            .AddColumn(col).AddRow(row)
            .AddType(Type).AddName(Name)
            .AddTips("请依次点击")
            .AddExtension(new PointExtension(height, xpos))
            .AddPoints(points).AddOptions(option);
            return(_captchaImageBuilder.Build());
        }
コード例 #14
0
 public CaptchaContext(CaptchaImage captcha = null, BaseCaptchaOptions options = null)
 {
     this.Captcha = captcha;
     this.Options = options;
 }
コード例 #15
0
 public CaptchaImageBuilder AddOptions(BaseCaptchaOptions options)
 {
     Captcha.Value.Options = options.Clone() as BaseCaptchaOptions;
     return(this);
 }
コード例 #16
0
 public virtual Task Validated(CaptchaValidateContext context, BaseCaptchaOptions options = null)
 {
     return(Task.CompletedTask);
 }