op-auto-clicker

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

OP Auto Clicker

OP Auto Clicker

Skill by ara.so — Devtools Skills collection.
OP Auto Clicker is a Windows-based automation tool that provides programmable mouse clicking with customizable intervals (milliseconds to hours), hotkey triggers, click recording/playback, and macro support. Built in C#, it enables automated clicking for gaming, testing, and repetitive task automation.
ara.so提供的技能——开发工具技能合集。
OP Auto Clicker是一款基于Windows的自动化工具,支持可编程的鼠标点击功能,可自定义点击间隔(从毫秒到小时)、快捷键触发、点击录制/回放以及宏支持。它采用C#开发,可用于游戏、测试和重复性任务的自动化点击操作。

Installation

安装

Using Pre-built Release

使用预构建版本

  1. Download from the releases page:
bash
undefined
  1. 从发布页面下载:
bash
undefined

Direct download link

Direct download link


2. Extract `OPClicker.zip` and run the `.exe` file (portable, no installation required)

3. Grant permissions if Windows Defender flags it (common for unsigned automation tools)

2. 解压`OPClicker.zip`并运行`.exe`文件(便携版,无需安装)

3. 如果Windows Defender标记该文件,请授予权限(未签名的自动化工具常出现此情况)

Building from Source

从源码构建

bash
undefined
bash
undefined

Clone the repository

Clone the repository

Open in Visual Studio

Open in Visual Studio

Open the .sln file and build (Ctrl+Shift+B)

Open the .sln file and build (Ctrl+Shift+B)


**Requirements:**
- Windows OS
- .NET Framework (typically pre-installed on Windows)
- Visual Studio 2019+ (for building from source)

**要求:**
- Windows操作系统
- .NET Framework(Windows通常预装)
- Visual Studio 2019+(用于从源码构建)

Core Features

核心功能

Click Automation Types

点击自动化类型

Single/Double/Triple Click
  • Configure click count per automation cycle
  • Set precise intervals between clicks
Mouse Buttons
  • Left click (most common)
  • Right click
  • Middle click (scroll wheel)
Repeat Modes
  • Until stopped (manual termination)
  • Fixed count (stop after N clicks)
Position Targeting
  • Current mouse location
  • Pick specific coordinates
  • Record and playback sequences
单/双/三次点击
  • 配置每个自动化周期的点击次数
  • 设置点击之间的精确间隔
鼠标按钮
  • 左键点击(最常用)
  • 右键点击
  • 中键点击(滚轮)
重复模式
  • 直到手动停止
  • 固定次数(点击N次后停止)
位置定位
  • 当前鼠标位置
  • 指定特定坐标
  • 录制并回放点击序列

C# Integration Examples

C#集成示例

Basic Auto Clicker Implementation

基础自动点击器实现

csharp
using System;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;

namespace AutoClickerCore
{
    public class ClickAutomation
    {
        // Import Windows API functions
        [DllImport("user32.dll")]
        static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint dwData, int dwExtraInfo);
        
        private const uint MOUSEEVENTF_LEFTDOWN = 0x0002;
        private const uint MOUSEEVENTF_LEFTUP = 0x0004;
        private const uint MOUSEEVENTF_RIGHTDOWN = 0x0008;
        private const uint MOUSEEVENTF_RIGHTUP = 0x0010;
        
        private bool isRunning = false;
        private Thread clickThread;
        
        public void StartClicking(int intervalMs, int clickCount = -1)
        {
            isRunning = true;
            clickThread = new Thread(() => ClickLoop(intervalMs, clickCount));
            clickThread.Start();
        }
        
        public void StopClicking()
        {
            isRunning = false;
            clickThread?.Join();
        }
        
        private void ClickLoop(int intervalMs, int maxClicks)
        {
            int clicksPerformed = 0;
            
            while (isRunning && (maxClicks == -1 || clicksPerformed < maxClicks))
            {
                PerformClick();
                clicksPerformed++;
                Thread.Sleep(intervalMs);
            }
        }
        
        private void PerformClick()
        {
            // Simulate left mouse button down and up
            mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
            mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
        }
    }
}
csharp
using System;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;

namespace AutoClickerCore
{
    public class ClickAutomation
    {
        // Import Windows API functions
        [DllImport("user32.dll")]
        static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint dwData, int dwExtraInfo);
        
        private const uint MOUSEEVENTF_LEFTDOWN = 0x0002;
        private const uint MOUSEEVENTF_LEFTUP = 0x0004;
        private const uint MOUSEEVENTF_RIGHTDOWN = 0x0008;
        private const uint MOUSEEVENTF_RIGHTUP = 0x0010;
        
        private bool isRunning = false;
        private Thread clickThread;
        
        public void StartClicking(int intervalMs, int clickCount = -1)
        {
            isRunning = true;
            clickThread = new Thread(() => ClickLoop(intervalMs, clickCount));
            clickThread.Start();
        }
        
        public void StopClicking()
        {
            isRunning = false;
            clickThread?.Join();
        }
        
        private void ClickLoop(int intervalMs, int maxClicks)
        {
            int clicksPerformed = 0;
            
            while (isRunning && (maxClicks == -1 || clicksPerformed < maxClicks))
            {
                PerformClick();
                clicksPerformed++;
                Thread.Sleep(intervalMs);
            }
        }
        
        private void PerformClick()
        {
            // Simulate left mouse button down and up
            mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
            mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
        }
    }
}

Hotkey Integration

快捷键集成

csharp
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace AutoClickerCore
{
    public class HotkeyManager : Form
    {
        [DllImport("user32.dll")]
        private static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);
        
        [DllImport("user32.dll")]
        private static extern bool UnregisterHotKey(IntPtr hWnd, int id);
        
        private const int HOTKEY_ID = 1;
        private const uint MOD_ALT = 0x0001;
        private const uint MOD_CONTROL = 0x0002;
        private const uint VK_F8 = 0x77; // F8 key
        
        private ClickAutomation automation;
        private bool isActive = false;
        
        public HotkeyManager()
        {
            automation = new ClickAutomation();
            
            // Register F8 as toggle hotkey
            RegisterHotKey(this.Handle, HOTKEY_ID, 0, VK_F8);
        }
        
        protected override void WndProc(ref Message m)
        {
            const int WM_HOTKEY = 0x0312;
            
            if (m.Msg == WM_HOTKEY && m.WParam.ToInt32() == HOTKEY_ID)
            {
                ToggleClicking();
            }
            
            base.WndProc(ref m);
        }
        
        private void ToggleClicking()
        {
            if (isActive)
            {
                automation.StopClicking();
                isActive = false;
                Console.WriteLine("Auto-clicker stopped");
            }
            else
            {
                automation.StartClicking(100); // 100ms interval
                isActive = true;
                Console.WriteLine("Auto-clicker started");
            }
        }
        
        protected override void Dispose(bool disposing)
        {
            UnregisterHotKey(this.Handle, HOTKEY_ID);
            base.Dispose(disposing);
        }
    }
}
csharp
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace AutoClickerCore
{
    public class HotkeyManager : Form
    {
        [DllImport("user32.dll")]
        private static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);
        
        [DllImport("user32.dll")]
        private static extern bool UnregisterHotKey(IntPtr hWnd, int id);
        
        private const int HOTKEY_ID = 1;
        private const uint MOD_ALT = 0x0001;
        private const uint MOD_CONTROL = 0x0002;
        private const uint VK_F8 = 0x77; // F8 key
        
        private ClickAutomation automation;
        private bool isActive = false;
        
        public HotkeyManager()
        {
            automation = new ClickAutomation();
            
            // Register F8 as toggle hotkey
            RegisterHotKey(this.Handle, HOTKEY_ID, 0, VK_F8);
        }
        
        protected override void WndProc(ref Message m)
        {
            const int WM_HOTKEY = 0x0312;
            
            if (m.Msg == WM_HOTKEY && m.WParam.ToInt32() == HOTKEY_ID)
            {
                ToggleClicking();
            }
            
            base.WndProc(ref m);
        }
        
        private void ToggleClicking()
        {
            if (isActive)
            {
                automation.StopClicking();
                isActive = false;
                Console.WriteLine("Auto-clicker stopped");
            }
            else
            {
                automation.StartClicking(100); // 100ms interval
                isActive = true;
                Console.WriteLine("Auto-clicker started");
            }
        }
        
        protected override void Dispose(bool disposing)
        {
            UnregisterHotKey(this.Handle, HOTKEY_ID);
            base.Dispose(disposing);
        }
    }
}

Click Recording and Playback

点击录制与回放

csharp
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Threading;

namespace AutoClickerCore
{
    public class ClickRecorder
    {
        [DllImport("user32.dll")]
        static extern bool SetCursorPos(int x, int y);
        
        [DllImport("user32.dll")]
        static extern bool GetCursorPos(out Point lpPoint);
        
        private List<ClickAction> recordedActions = new List<ClickAction>();
        private bool isRecording = false;
        private DateTime recordingStart;
        
        public void StartRecording()
        {
            recordedActions.Clear();
            isRecording = true;
            recordingStart = DateTime.Now;
        }
        
        public void RecordClick(MouseButton button)
        {
            if (!isRecording) return;
            
            Point cursorPos;
            GetCursorPos(out cursorPos);
            
            var action = new ClickAction
            {
                Position = cursorPos,
                Button = button,
                TimestampMs = (int)(DateTime.Now - recordingStart).TotalMilliseconds
            };
            
            recordedActions.Add(action);
        }
        
        public void StopRecording()
        {
            isRecording = false;
        }
        
        public void Playback(int repeatCount = 1)
        {
            for (int i = 0; i < repeatCount; i++)
            {
                int lastTimestamp = 0;
                
                foreach (var action in recordedActions)
                {
                    // Wait for the recorded delay
                    int delay = action.TimestampMs - lastTimestamp;
                    if (delay > 0)
                        Thread.Sleep(delay);
                    
                    // Move cursor and click
                    SetCursorPos(action.Position.X, action.Position.Y);
                    PerformClick(action.Button);
                    
                    lastTimestamp = action.TimestampMs;
                }
            }
        }
        
        private void PerformClick(MouseButton button)
        {
            uint downFlag = button == MouseButton.Left ? 0x0002u : 0x0008u;
            uint upFlag = button == MouseButton.Left ? 0x0004u : 0x0010u;
            
            mouse_event(downFlag, 0, 0, 0, 0);
            mouse_event(upFlag, 0, 0, 0, 0);
        }
        
        [DllImport("user32.dll")]
        static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint dwData, int dwExtraInfo);
    }
    
    public class ClickAction
    {
        public Point Position { get; set; }
        public MouseButton Button { get; set; }
        public int TimestampMs { get; set; }
    }
    
    public enum MouseButton
    {
        Left,
        Right,
        Middle
    }
}
csharp
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Threading;

namespace AutoClickerCore
{
    public class ClickRecorder
    {
        [DllImport("user32.dll")]
        static extern bool SetCursorPos(int x, int y);
        
        [DllImport("user32.dll")]
        static extern bool GetCursorPos(out Point lpPoint);
        
        private List<ClickAction> recordedActions = new List<ClickAction>();
        private bool isRecording = false;
        private DateTime recordingStart;
        
        public void StartRecording()
        {
            recordedActions.Clear();
            isRecording = true;
            recordingStart = DateTime.Now;
        }
        
        public void RecordClick(MouseButton button)
        {
            if (!isRecording) return;
            
            Point cursorPos;
            GetCursorPos(out cursorPos);
            
            var action = new ClickAction
            {
                Position = cursorPos,
                Button = button,
                TimestampMs = (int)(DateTime.Now - recordingStart).TotalMilliseconds
            };
            
            recordedActions.Add(action);
        }
        
        public void StopRecording()
        {
            isRecording = false;
        }
        
        public void Playback(int repeatCount = 1)
        {
            for (int i = 0; i < repeatCount; i++)
            {
                int lastTimestamp = 0;
                
                foreach (var action in recordedActions)
                {
                    // Wait for the recorded delay
                    int delay = action.TimestampMs - lastTimestamp;
                    if (delay > 0)
                        Thread.Sleep(delay);
                    
                    // Move cursor and click
                    SetCursorPos(action.Position.X, action.Position.Y);
                    PerformClick(action.Button);
                    
                    lastTimestamp = action.TimestampMs;
                }
            }
        }
        
        private void PerformClick(MouseButton button)
        {
            uint downFlag = button == MouseButton.Left ? 0x0002u : 0x0008u;
            uint upFlag = button == MouseButton.Left ? 0x0004u : 0x0010u;
            
            mouse_event(downFlag, 0, 0, 0, 0);
            mouse_event(upFlag, 0, 0, 0, 0);
        }
        
        [DllImport("user32.dll")]
        static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint dwData, int dwExtraInfo);
    }
    
    public class ClickAction
    {
        public Point Position { get; set; }
        public MouseButton Button { get; set; }
        public int TimestampMs { get; set; }
    }
    
    public enum MouseButton
    {
        Left,
        Right,
        Middle
    }
}

Randomized Clicking Pattern

随机点击模式

csharp
using System;
using System.Threading;

namespace AutoClickerCore
{
    public class RandomizedClicker
    {
        private Random random = new Random();
        private bool isRunning = false;
        
        public void StartRandomClicking(int minIntervalMs, int maxIntervalMs)
        {
            isRunning = true;
            
            new Thread(() =>
            {
                while (isRunning)
                {
                    PerformClick();
                    
                    // Randomize interval to avoid detection
                    int delay = random.Next(minIntervalMs, maxIntervalMs);
                    Thread.Sleep(delay);
                }
            }).Start();
        }
        
        public void StopClicking()
        {
            isRunning = false;
        }
        
        private void PerformClick()
        {
            mouse_event(0x0002, 0, 0, 0, 0); // Left down
            Thread.Sleep(random.Next(10, 30)); // Randomize click duration
            mouse_event(0x0004, 0, 0, 0, 0); // Left up
        }
        
        [System.Runtime.InteropServices.DllImport("user32.dll")]
        static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint dwData, int dwExtraInfo);
    }
}
csharp
using System;
using System.Threading;

namespace AutoClickerCore
{
    public class RandomizedClicker
    {
        private Random random = new Random();
        private bool isRunning = false;
        
        public void StartRandomClicking(int minIntervalMs, int maxIntervalMs)
        {
            isRunning = true;
            
            new Thread(() =>
            {
                while (isRunning)
                {
                    PerformClick();
                    
                    // Randomize interval to avoid detection
                    int delay = random.Next(minIntervalMs, maxIntervalMs);
                    Thread.Sleep(delay);
                }
            }).Start();
        }
        
        public void StopClicking()
        {
            isRunning = false;
        }
        
        private void PerformClick()
        {
            mouse_event(0x0002, 0, 0, 0, 0); // Left down
            Thread.Sleep(random.Next(10, 30)); // Randomize click duration
            mouse_event(0x0004, 0, 0, 0, 0); // Left up
        }
        
        [System.Runtime.InteropServices.DllImport("user32.dll")]
        static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint dwData, int dwExtraInfo);
    }
}

Configuration Patterns

配置模式

Basic Configuration Class

基础配置类

csharp
namespace AutoClickerCore
{
    public class ClickerConfig
    {
        // Timing
        public int IntervalMilliseconds { get; set; } = 100;
        public bool RandomizeInterval { get; set; } = false;
        public int RandomRangeMs { get; set; } = 50;
        
        // Click settings
        public MouseButton Button { get; set; } = MouseButton.Left;
        public ClickType ClickType { get; set; } = ClickType.Single;
        
        // Repeat mode
        public RepeatMode RepeatMode { get; set; } = RepeatMode.UntilStopped;
        public int ClickCount { get; set; } = 100;
        
        // Position
        public bool UseFixedPosition { get; set; } = false;
        public System.Drawing.Point FixedPosition { get; set; }
        
        // Hotkeys
        public System.Windows.Forms.Keys StartStopKey { get; set; } = System.Windows.Forms.Keys.F8;
    }
    
    public enum ClickType
    {
        Single,
        Double,
        Triple
    }
    
    public enum RepeatMode
    {
        UntilStopped,
        FixedCount
    }
}
csharp
namespace AutoClickerCore
{
    public class ClickerConfig
    {
        // Timing
        public int IntervalMilliseconds { get; set; } = 100;
        public bool RandomizeInterval { get; set; } = false;
        public int RandomRangeMs { get; set; } = 50;
        
        // Click settings
        public MouseButton Button { get; set; } = MouseButton.Left;
        public ClickType ClickType { get; set; } = ClickType.Single;
        
        // Repeat mode
        public RepeatMode RepeatMode { get; set; } = RepeatMode.UntilStopped;
        public int ClickCount { get; set; } = 100;
        
        // Position
        public bool UseFixedPosition { get; set; } = false;
        public System.Drawing.Point FixedPosition { get; set; }
        
        // Hotkeys
        public System.Windows.Forms.Keys StartStopKey { get; set; } = System.Windows.Forms.Keys.F8;
    }
    
    public enum ClickType
    {
        Single,
        Double,
        Triple
    }
    
    public enum RepeatMode
    {
        UntilStopped,
        FixedCount
    }
}

Common Use Cases

常见使用场景

Gaming Automation (Roblox/Minecraft AFK)

游戏自动化(Roblox/Minecraft AFK)

csharp
public class GameAutomation
{
    private ClickAutomation clicker = new ClickAutomation();
    
    public void StartAFKClicking()
    {
        // Click every 5 seconds to prevent AFK kick
        clicker.StartClicking(5000);
    }
    
    public void StartFastMining()
    {
        // Rapid clicking for mining/harvesting
        clicker.StartClicking(50);
    }
}
csharp
public class GameAutomation
{
    private ClickAutomation clicker = new ClickAutomation();
    
    public void StartAFKClicking()
    {
        // Click every 5 seconds to prevent AFK kick
        clicker.StartClicking(5000);
    }
    
    public void StartFastMining()
    {
        // Rapid clicking for mining/harvesting
        clicker.StartClicking(50);
    }
}

UI Testing Automation

UI测试自动化

csharp
public class UITestClicker
{
    private ClickRecorder recorder = new ClickRecorder();
    
    public void RecordTestSequence()
    {
        recorder.StartRecording();
        // User performs manual clicks
        Thread.Sleep(10000);
        recorder.StopRecording();
    }
    
    public void RunTest(int iterations)
    {
        recorder.Playback(iterations);
    }
}
csharp
public class UITestClicker
{
    private ClickRecorder recorder = new ClickRecorder();
    
    public void RecordTestSequence()
    {
        recorder.StartRecording();
        // User performs manual clicks
        Thread.Sleep(10000);
        recorder.StopRecording();
    }
    
    public void RunTest(int iterations)
    {
        recorder.Playback(iterations);
    }
}

Troubleshooting

故障排除

Windows Defender False Positive

Windows Defender误报

Issue: Windows flags the executable as malware Solution:
  • This is common for automation tools using low-level Windows APIs
  • Add exception in Windows Defender: Settings > Update & Security > Windows Security > Virus & threat protection > Manage settings > Exclusions
  • Or build from source to verify code integrity
问题: Windows将可执行文件标记为恶意软件 解决方案:
  • 这是使用底层Windows API的自动化工具常见情况
  • 在Windows Defender中添加例外:设置 > 更新和安全 > Windows安全中心 > 病毒和威胁防护 > 管理设置 > 排除项
  • 或从源码构建以验证代码完整性

Clicks Not Registering

点击未被识别

Issue: Application doesn't detect clicks Solution:
csharp
// Run with elevated privileges
[System.Security.Principal.WindowsPrincipal]
bool isAdmin = new System.Security.Principal.WindowsPrincipal(
    System.Security.Principal.WindowsIdentity.GetCurrent()
).IsInRole(System.Security.Principal.WindowsBuiltInRole.Administrator);

if (!isAdmin)
{
    Console.WriteLine("Run as Administrator for full functionality");
}
问题: 应用程序无法检测到点击 解决方案:
csharp
// Run with elevated privileges
[System.Security.Principal.WindowsPrincipal]
bool isAdmin = new System.Security.Principal.WindowsPrincipal(
    System.Security.Principal.WindowsIdentity.GetCurrent()
).IsInRole(System.Security.Principal.WindowsBuiltInRole.Administrator);

if (!isAdmin)
{
    Console.WriteLine("Run as Administrator for full functionality");
}

Hotkey Not Working

快捷键无效

Issue: Hotkey doesn't trigger Solution:
  • Ensure the hotkey isn't already registered by another application
  • Use
    UnregisterHotKey
    before re-registering
  • Check that the form handle is properly initialized
问题: 快捷键无法触发 解决方案:
  • 确保该快捷键未被其他应用程序注册
  • 重新注册前先调用
    UnregisterHotKey
  • 检查窗体句柄是否已正确初始化

Game Anti-Cheat Detection

游戏反作弊检测

Issue: Getting banned for "inhuman" clicking patterns Solution:
csharp
// Use randomized intervals
var randomClicker = new RandomizedClicker();
randomClicker.StartRandomClicking(80, 150); // 80-150ms variance
问题: 因“非人类”点击模式被封禁 解决方案:
csharp
// Use randomized intervals
var randomClicker = new RandomizedClicker();
randomClicker.StartRandomClicking(80, 150); // 80-150ms variance

Best Practices

最佳实践

  1. Always provide a stop mechanism (hotkey or timeout)
  2. Use randomization for gaming to avoid detection
  3. Test with low intervals before increasing speed
  4. Run as Administrator when automating other applications
  5. Respect game ToS — some games prohibit automation
  6. Add delays between clicks to avoid system overload
  1. 始终提供停止机制(快捷键或超时)
  2. 游戏场景使用随机化以避免被检测
  3. 先测试低间隔再提高速度
  4. 自动化其他应用时以管理员身份运行
  5. 遵守游戏服务条款——部分游戏禁止自动化
  6. 点击之间添加延迟以避免系统过载

License

许可证

MIT License — Free to use, modify, and distribute.
MIT许可证——可免费使用、修改和分发。