功能演示
文章开始之前,仍然是先来个视频,以便用户知道鼠标连点器的基本功能
软件主界面
多功能鼠标连点器
快速点击:
痕即鼠标点击器可以设定每秒点击次数,让您轻松应对高频点击需求。
切换时长,即每次动作之间的间隔时间,最小设置为1毫秒,那么理论上1秒内最多产生1000次动作
定时功能:
您可以预设点击开始和结束时间,做到自动操作。
打开全局配置,如图所示,提供3种定时作业:特定时间、每天定点、周期循环,您根据自己需要选择
多种点击模式:
支持左键、右键、中键点击,满足各种操作需求。
如上图,支持高达9种动作模式,请问谁有这么全,就问你牛不牛,够不够!
自定义点击间隔:
根据不同需求设置点击间隔,精确到毫秒,确保操作准确无误。
如上图,不要选中“随机”,则可以精确指定时间间隔,若选中了“随机”,那么就将在范围内随机生成一个时间间隔,动作之间的最小间隔时间是1毫秒,即1秒内理论上最多1000次动作。
坐标偏移(防外挂):
用于防止鼠标固定在同一个位置重复执行,要不然可能被您使用的系统监控到你可能使用外挂。
此功能坐标偏移 + 切换时长随机,双层结合是为了防止您被您的系统判定为您在使用外挂。
实际案例:temu抢仓库
使用简单,界面友好
就问你这样的操作界面,清不清爽?!牛不牛逼?!
是不是比其它人的一堆看起来头疼的设置,简单易用多了?!
核心代码
/// <summary>/// 开始运行/// </summary>public async Task RunAsync(){if (_loadedForms != null){foreach (var form in _loadedForms){form.Invoke(new System.Action(() =>{((ActionForm)form).SetWindowExStyle();}));}}else{return;}ActionData recordData = _actionData;if (recordData == null || recordData.Actions == null || recordData.Actions.Count == 0){return;}lock (recordData){if (_running){return;}}//keyboardHook.Start();_running = true;int l = 0;_totalCount = 0;this.Start?.Invoke(this, EventArgs.Empty);await Task.Run(() =>{Random random = new Random();while (_running){if (_actionConfig.Loop > 0){if (l >= _actionConfig.Loop){_running = false;this.Stop();this.Complete?.Invoke(this, EventArgs.Empty);MessagingCenter.Send(ActionSheduleCompleteMessageName, this);break;}l++;}_totalCount++;//Debug.WriteLine("循环几次了:" + l);foreach (ActionSegment action in recordData.Actions){OffsetParameter offsetParameter = action.ActionParameter.OffsetParameter;int xOffset = 0;int yOffset = 0;if (offsetParameter != null){xOffset = random.Next(offsetParameter.XOffset.Start, offsetParameter.XOffset.End);yOffset = random.Next(offsetParameter.YOffset.Start, offsetParameter.YOffset.End);}switch (action.Type){case ActionType.MouseClick:if (_running){if (action.ActionParameter.GraphicParameter != null && !string.IsNullOrEmpty(action.ActionParameter.GraphicParameter.FilePath)){//_stopwatch.Restart();var matchPoints = _shapeMatch.Match(action.ActionParameter.GraphicParameter.FilePath);//_stopwatch.Stop();//Debug.WriteLine("耗时毫秒:" + _stopwatch.ElapsedMilliseconds);if (matchPoints == null || matchPoints.Length == 0){break;}ActionForm form = _loadedForms.First(q => q.Action == action);form.BeginInvoke(new System.Action(() =>{form.ChangePosition(new Point { X = matchPoints[0].X - form.Width / 2, Y = matchPoints[0].Y - form.Height / 2 });MouseSimulator.Click(matchPoints[0].X, matchPoints[0].Y);}));}else{Point point1 = new Point(action.ActionParameter.StartPoint.X + xOffset, action.ActionParameter.StartPoint.Y + yOffset);MouseSimulator.Click(point1.X, point1.Y);}}break;case ActionType.MouseDoubleClick:if (_running){if (action.ActionParameter.GraphicParameter != null && !string.IsNullOrEmpty(action.ActionParameter.GraphicParameter.FilePath)){var matchPoints = _shapeMatch.Match(action.ActionParameter.GraphicParameter.FilePath);if (matchPoints == null || matchPoints.Length == 0){break;}ActionForm form = _loadedForms.First(q => q.Action == action);form.BeginInvoke(new System.Action(() =>{form.ChangePosition(new Point { X = matchPoints[0].X - form.Width / 2, Y = matchPoints[0].Y - form.Height / 2 });MouseSimulator.DoubleClick(matchPoints[0].X, matchPoints[0].Y);}));}else{Point point2 = new Point(action.ActionParameter.StartPoint.X + xOffset, action.ActionParameter.StartPoint.Y + yOffset);MouseSimulator.DoubleClick(point2.X, point2.Y);}}break;case ActionType.MouseRightClick:if (_running){if (action.ActionParameter.GraphicParameter != null && !string.IsNullOrEmpty(action.ActionParameter.GraphicParameter.FilePath)){var matchPoints = _shapeMatch.Match(action.ActionParameter.GraphicParameter.FilePath);if (matchPoints == null || matchPoints.Length == 0){break;}ActionForm form = _loadedForms.First(q => q.Action == action);form.BeginInvoke(new System.Action(() =>{form.ChangePosition(new Point { X = matchPoints[0].X - form.Width / 2, Y = matchPoints[0].Y - form.Height / 2 });MouseSimulator.RightClick(matchPoints[0].X, matchPoints[0].Y);}));}else{Point point3 = new Point(action.ActionParameter.StartPoint.X + xOffset, action.ActionParameter.StartPoint.Y + yOffset);MouseSimulator.RightClick(point3.X, point3.Y);}}break;case ActionType.MouseMiddleClick:if (_running){if (action.ActionParameter.GraphicParameter != null && !string.IsNullOrEmpty(action.ActionParameter.GraphicParameter.FilePath)){var matchPoints = _shapeMatch.Match(action.ActionParameter.GraphicParameter.FilePath);if (matchPoints == null || matchPoints.Length == 0){break;}ActionForm form = _loadedForms.First(q => q.Action == action);form.BeginInvoke(new System.Action(() =>{form.ChangePosition(new Point { X = matchPoints[0].X - form.Width / 2, Y = matchPoints[0].Y - form.Height / 2 });MouseSimulator.MiddleClick(matchPoints[0].X, matchPoints[0].Y);}));}else{Point point4 = new Point(action.ActionParameter.StartPoint.X + xOffset, action.ActionParameter.StartPoint.Y + yOffset);MouseSimulator.MiddleClick(point4.X, point4.Y);}}break;case ActionType.MouseDrag:if (_running){if (action.ActionParameter.GraphicParameter != null && !string.IsNullOrEmpty(action.ActionParameter.GraphicParameter.FilePath)){var matchPoints = _shapeMatch.Match(action.ActionParameter.GraphicParameter.FilePath);if (matchPoints == null || matchPoints.Length == 0){break;}ActionForm form = _loadedForms.First(q => q.Action == action);form.BeginInvoke(new System.Action(() =>{form.ChangePosition(new Point { X = matchPoints[0].X - form.Width / 2, Y = matchPoints[0].Y - form.Height / 2 });Point end = new Point(action.ActionParameter.EndPoint.X + xOffset, action.ActionParameter.EndPoint.Y + yOffset);MouseSimulator.Drag(matchPoints[0].X, matchPoints[0].Y, end.X, end.Y);}));}else{Point start = new Point(action.ActionParameter.StartPoint.X + xOffset, action.ActionParameter.StartPoint.Y + yOffset);Point end = new Point(action.ActionParameter.EndPoint.X + xOffset, action.ActionParameter.EndPoint.Y + yOffset);MouseSimulator.Drag(start.X, start.Y, end.X, end.Y);}}break;case ActionType.Sleep:if (_running){//await Task.Delay(Convert.ToInt32(action.Parameter.Value));//用Thread.Sleep比Task.Delay的效果要好很多,特别是在很微小的休眠时间的时候//可能是因为Task.Delay有5ms下限值的原因SleepParameter sleepParameter = action.ActionParameter.Value as SleepParameter;if (sleepParameter == null){sleepParameter = JsonConvert.DeserializeObject<SleepParameter>(action.ActionParameter.Value.ToString());}if (sleepParameter.IsRandom){var interval = random.Next(sleepParameter.Start, sleepParameter.End);Thread.Sleep(interval);}else{Thread.Sleep(sleepParameter.Start);}}break;case ActionType.Content:if (_running){MainForm.Instance.Invoke(new System.Action(() =>{KeyboardSimulator.TextPaste(action.ActionParameter?.Value?.ToString());}));}break;case ActionType.Enter:if (_running){MainForm.Instance.Invoke(new System.Action(() =>{KeyboardSimulator.Enter();}));}break;case ActionType.LongPress:if (_running){if (action.ActionParameter.GraphicParameter != null && !string.IsNullOrEmpty(action.ActionParameter.GraphicParameter.FilePath)){var matchPoints = _shapeMatch.Match(action.ActionParameter.GraphicParameter.FilePath);if (matchPoints == null || matchPoints.Length == 0){break;}ActionForm form = _loadedForms.First(q => q.Action == action);form.BeginInvoke(new System.Action(() =>{form.ChangePosition(new Point { X = matchPoints[0].X - form.Width / 2, Y = matchPoints[0].Y - form.Height / 2 });MouseSimulator.LongPress(matchPoints[0].X, matchPoints[0].Y, Convert.ToInt32(action.ActionParameter.Value));}));}else{Point point6 = new Point(action.ActionParameter.StartPoint.X + xOffset, action.ActionParameter.StartPoint.Y + yOffset);MouseSimulator.LongPress(point6.X, point6.Y, Convert.ToInt32(action.ActionParameter.Value));}}break;default:break;}}}});}
可提供程序生成包,通过主页可见我的介绍方式
祝您用餐愉快。