功能演示
文章开始之前,仍然是先来个视频,以便用户知道鼠标连点器的基本功能
软件主界面
多功能鼠标连点器
快速点击:
痕即鼠标点击器可以设定每秒点击次数,让您轻松应对高频点击需求。
切换时长,即每次动作之间的间隔时间,最小设置为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;
}
}
}
});
}
可提供程序生成包,通过主页可见我的介绍方式
祝您用餐愉快。