arduino针对python的键盘映射实现

本项目使用arduino对python进行了键盘映射,可以实现python传按键信息给开发板,开发板输入真实键盘信息到电脑中。

应用场景:现在市面上的养成类PC电脑游戏中玩家都会需要脚本来解决一些复杂繁琐的事情,例如:角色打怪练级,完成每日任务,跑图等等。而现如今的游戏都有针对模拟按键脚本的检测机制,普通的模拟按键脚本根本无法绕过检测机制运行,而真实键盘的按键信息可以完美的解决容易被游戏系统检测的问题。使用本项目的键盘信息输入方式可以绕过绝大多数游戏的键盘按键脚本的检测机制。

项目需求:
1、一个开发板,作者使用的是树莓派PICO RP2040
2、pycharm IDE
3、python3.8环境

教程:
首先去官网下载安装Arduino IDE
进入IDE,打开key_attack.ino

key_attack.ino代码

#define OSX 0
#define WINDOWS 1
#define UBUNTU 2
#include "Keyboard.h"
#include "Mouse.h"
#include <FastLED.h>

#define LED_PIN     18 //GP18
#define NUM_LEDS    3

CRGB leds[NUM_LEDS];


// change this to match your platform:
int platform = WINDOWS;

char **split(const char *source, char flag)
{
    char **pt;
    int j, n = 0;
    int count = 1;
    int len = strlen(source);
    // 动态分配一个 *tmp,静态的话,变量len无法用于下标
    char *tmp = (char*)malloc((len + 1) * sizeof(char));
    tmp[0] = '\0';

    for (int i = 0; i < len; ++i)
    {
        if (source[i] == flag && source[i+1] == '\0')
            continue;
        else if (source[i] == flag && source[i+1] != flag)
            count++;
    }
    // 多分配一个char*,是为了设置结束标志
    pt = (char**)malloc((count+1) * sizeof(char*));

    count = 0;
    for (int i = 0; i < len; ++i)
    {
        if (i == len - 1 && source[i] != flag)
        {
            tmp[n++] = source[i];
            tmp[n] = '\0';  // 字符串末尾添加空字符
            j = strlen(tmp) + 1;
            pt[count] = (char*)malloc(j * sizeof(char));
            strcpy(pt[count++], tmp);
        }
        else if (source[i] == flag)
        {
            j = strlen(tmp);
            if (j != 0)
            {
                tmp[n] = '\0';  // 字符串末尾添加空字符
                pt[count] = (char*)malloc((j+1) * sizeof(char));
                strcpy(pt[count++], tmp);
                // 重置tmp
                n = 0;
                tmp[0] = '\0';
            }
        }
        else
            tmp[n++] = source[i];
    }
    
    // 释放tmp
	  free(tmp);
	
    // 设置结束标志
    pt[count] = NULL;

    return pt;
}

void setup() {
  // make pin 2 an input and turn on the pull-up resistor so it goes high unless
  // connected to ground:
  Serial.begin(9600);
  Keyboard.begin();
  Mouse.begin();
}

void cue_light_gp25() {
  digitalWrite(25,HIGH);
  delay(20);
  digitalWrite(25,LOW);
  delay(20);
}

void loop() {
  
  if (Serial.available() > 0) {
    String comdata = "";
    while (Serial.available() > 0) {
      comdata += char(Serial.read());
    }
    if (comdata[0] == '0') {
      if (comdata == "0_KEY_LEFT_ARROW") {
        Keyboard.release(KEY_LEFT_ARROW);
      } else if (comdata == "0_KEY_RIGHT_ARROW") {
        Keyboard.release(KEY_RIGHT_ARROW);
      } else if (comdata == "0_KEY_LEFT_CTRL") {
        Keyboard.release(KEY_LEFT_CTRL);
      } else if (comdata == "0_KEY_LEFT_SHIFT") {
        Keyboard.release(KEY_LEFT_SHIFT);
      } else if (comdata == "0_KEY_LEFT_ALT") {
        Keyboard.release(KEY_LEFT_ALT);
      } else if (comdata == "0_KEY_UP_ARROW") {
        Keyboard.release(KEY_UP_ARROW);
      } else if (comdata == "0_KEY_DOWN_ARROW") {
        Keyboard.release(KEY_DOWN_ARROW);
      } else if (comdata == "0_KEY_BACKSPACE") {
        Keyboard.release(KEY_BACKSPACE);
      } else if (comdata == "0_KEY_TAB") {
        Keyboard.release(KEY_TAB);
      } else if (comdata == "0_KEY_ESC") {
        Keyboard.release(KEY_ESC);
      } else if (comdata == "0_KEY_INSERT") {
        Keyboard.release(KEY_INSERT);
      } else if (comdata == "0_KEY_DELETE") {
        Keyboard.release(KEY_DELETE);
      } else if (comdata == "0_KEY_PAGE_UP") {
        Keyboard.release(KEY_PAGE_UP);
      } else if (comdata == "0_KEY_PAGE_DOWN") {
        Keyboard.release(KEY_PAGE_DOWN);
      } else if (comdata == "0_KEY_HOME") {
        Keyboard.release(KEY_HOME);
      } else if (comdata == "0_KEY_END") {
        Keyboard.release(KEY_END);
      } else if (comdata == "0_KEY_CAPS_LOCK") {
        Keyboard.release(KEY_CAPS_LOCK);
      } else if (comdata == "0_KEY_KP_ENTER") {
        Keyboard.release(KEY_KP_ENTER);
      } else if (comdata == "0_KEY_F1") {
        Keyboard.release(KEY_F1);
      } else if (comdata == "0_KEY_F2") {
        Keyboard.release(KEY_F2);
      } else if (comdata == "0_KEY_F3") {
        Keyboard.release(KEY_F3);
      } else if (comdata == "0_KEY_F4") {
        Keyboard.release(KEY_F4);
      } else if (comdata == "0_KEY_F5") {
        Keyboard.release(KEY_F5);
      } else if (comdata == "0_KEY_F6") {
        Keyboard.release(KEY_F6);
      } else if (comdata == "0_KEY_F7") {
        Keyboard.release(KEY_F7);
      } else if (comdata == "0_KEY_F8") {
        Keyboard.release(KEY_F8);
      } else if (comdata == "0_KEY_F9") {
        Keyboard.release(KEY_F9);
      } else if (comdata == "0_KEY_F10") {
        Keyboard.release(KEY_F10);
      } else if (comdata == "0_KEY_F11") {
        Keyboard.release(KEY_F11);
      } else if (comdata == "0_KEY_F12") {
        Keyboard.release(KEY_F12);
      } else if (comdata == "0_ALL") {
        Keyboard.releaseAll();
      } else if (comdata.length() == 3) {
        Keyboard.release(comdata[2]);
      }
    } else if (comdata[0] == '1') {
      if (comdata == "1_KEY_LEFT_ARROW") {
        Keyboard.press(KEY_LEFT_ARROW);
      } else if (comdata == "1_KEY_RIGHT_ARROW") {
        Keyboard.press(KEY_RIGHT_ARROW);
      } else if (comdata == "1_KEY_LEFT_CTRL") {
        Keyboard.press(KEY_LEFT_CTRL);
      } else if (comdata == "1_KEY_LEFT_SHIFT") {
        Keyboard.press(KEY_LEFT_SHIFT);
      } else if (comdata == "1_KEY_LEFT_ALT") {
        Keyboard.press(KEY_LEFT_ALT);
      } else if (comdata == "1_KEY_UP_ARROW") {
        Keyboard.press(KEY_UP_ARROW);
      } else if (comdata == "1_KEY_DOWN_ARROW") {
        Keyboard.press(KEY_DOWN_ARROW);
      } else if (comdata == "1_KEY_BACKSPACE") {
        Keyboard.press(KEY_BACKSPACE);
      } else if (comdata == "1_KEY_TAB") {
        Keyboard.press(KEY_TAB);
      } else if (comdata == "1_KEY_ESC") {
        Keyboard.press(KEY_ESC);
      } else if (comdata == "1_KEY_INSERT") {
        Keyboard.press(KEY_INSERT);
      } else if (comdata == "1_KEY_DELETE") {
        Keyboard.press(KEY_DELETE);
      } else if (comdata == "1_KEY_PAGE_UP") {
        Keyboard.press(KEY_PAGE_UP);
      } else if (comdata == "1_KEY_PAGE_DOWN") {
        Keyboard.press(KEY_PAGE_DOWN);
      } else if (comdata == "1_KEY_HOME") {
        Keyboard.press(KEY_HOME);
      } else if (comdata == "1_KEY_END") {
        Keyboard.press(KEY_END);
      } else if (comdata == "1_KEY_CAPS_LOCK") {
        Keyboard.press(KEY_CAPS_LOCK);
      } else if (comdata == "1_KEY_KP_ENTER") {
        Keyboard.press(KEY_KP_ENTER);
      } else if (comdata == "1_KEY_F1") {
        Keyboard.press(KEY_F1);
      } else if (comdata == "1_KEY_F2") {
        Keyboard.press(KEY_F2);
      } else if (comdata == "1_KEY_F3") {
        Keyboard.press(KEY_F3);
      } else if (comdata == "1_KEY_F4") {
        Keyboard.press(KEY_F4);
      } else if (comdata == "1_KEY_F5") {
        Keyboard.press(KEY_F5);
      } else if (comdata == "1_KEY_F6") {
        Keyboard.press(KEY_F6);
      } else if (comdata == "1_KEY_F7") {
        Keyboard.press(KEY_F7);
      } else if (comdata == "1_KEY_F8") {
        Keyboard.press(KEY_F8);
      } else if (comdata == "1_KEY_F9") {
        Keyboard.press(KEY_F9);
      } else if (comdata == "1_KEY_F10") {
        Keyboard.press(KEY_F10);
      } else if (comdata == "1_KEY_F11") {
        Keyboard.press(KEY_F11);
      } else if (comdata == "1_KEY_F12") {
        Keyboard.press(KEY_F12);
      } else if (comdata.length() == 3) {
        Keyboard.press(comdata[2]);
      }
    } else if (comdata[0] == '2') {
      if (comdata == "2_KEY_LEFT_ARROW") {
        Keyboard.write(KEY_LEFT_ARROW);
      } else if (comdata == "2_KEY_RIGHT_ARROW") {
        Keyboard.write(KEY_RIGHT_ARROW);
      } else if (comdata == "2_KEY_LEFT_CTRL") {
        Keyboard.write(KEY_LEFT_CTRL);
      } else if (comdata == "2_KEY_LEFT_SHIFT") {
        Keyboard.write(KEY_LEFT_SHIFT);
      } else if (comdata == "2_KEY_LEFT_ALT") {
        Keyboard.write(KEY_LEFT_ALT);
      } else if (comdata == "2_KEY_UP_ARROW") {
        Keyboard.write(KEY_UP_ARROW);
      } else if (comdata == "2_KEY_DOWN_ARROW") {
        Keyboard.write(KEY_DOWN_ARROW);
      } else if (comdata == "2_KEY_BACKSPACE") {
        Keyboard.write(KEY_BACKSPACE);
      } else if (comdata == "2_KEY_TAB") {
        Keyboard.write(KEY_TAB);
      } else if (comdata == "2_KEY_ESC") {
        Keyboard.write(KEY_ESC);
      } else if (comdata == "2_KEY_INSERT") {
        Keyboard.write(KEY_INSERT);
      } else if (comdata == "2_KEY_DELETE") {
        Keyboard.write(KEY_DELETE);
      } else if (comdata == "2_KEY_PAGE_UP") {
        Keyboard.write(KEY_PAGE_UP);
      } else if (comdata == "2_KEY_PAGE_DOWN") {
        Keyboard.write(KEY_PAGE_DOWN);
      } else if (comdata == "2_KEY_HOME") {
        Keyboard.write(KEY_HOME);
      } else if (comdata == "2_KEY_END") {
        Keyboard.write(KEY_END);
      } else if (comdata == "2_KEY_CAPS_LOCK") {
        Keyboard.write(KEY_CAPS_LOCK);
      } else if (comdata == "2_KEY_KP_ENTER") {
        Keyboard.write(KEY_KP_ENTER);
      } else if (comdata == "2_KEY_F1") {
        Keyboard.write(KEY_F1);
      } else if (comdata == "2_KEY_F2") {
        Keyboard.write(KEY_F2);
      } else if (comdata == "2_KEY_F3") {
        Keyboard.write(KEY_F3);
      } else if (comdata == "2_KEY_F4") {
        Keyboard.write(KEY_F4);
      } else if (comdata == "2_KEY_F5") {
        Keyboard.write(KEY_F5);
      } else if (comdata == "2_KEY_F6") {
        Keyboard.write(KEY_F6);
      } else if (comdata == "2_KEY_F7") {
        Keyboard.write(KEY_F7);
      } else if (comdata == "2_KEY_F8") {
        Keyboard.write(KEY_F8);
      } else if (comdata == "2_KEY_F9") {
        Keyboard.write(KEY_F9);
      } else if (comdata == "2_KEY_F10") {
        Keyboard.write(KEY_F10);
      } else if (comdata == "2_KEY_F11") {
        Keyboard.write(KEY_F11);
      } else if (comdata == "2_KEY_F12") {
        Keyboard.write(KEY_F12);
      } else if (comdata.length() == 3) {
        Keyboard.write(comdata[2]);
      }
    } else if (comdata[0] == 'M' && comdata[1] == '1') {
      if (comdata == "M1_MOUSE_LEFT") {
        Mouse.press(MOUSE_LEFT);
      } else if (comdata == "M1_MOUSE_RIGHT") {
        Mouse.press(MOUSE_RIGHT);
      } else if (comdata == "M1_MOUSE_MIDDLE") {
        Mouse.press(MOUSE_MIDDLE);
      } else if (comdata == "M1_MOUSE_ALL") {
        Mouse.press(MOUSE_ALL);
      } 
    } else if (comdata[0] == 'M' && comdata[1] == '0') {
      if (comdata == "M0_MOUSE_LEFT") {
        Mouse.release(MOUSE_LEFT);
      } else if (comdata == "M0_MOUSE_RIGHT") {
        Mouse.release(MOUSE_RIGHT);
      } else if (comdata == "M0_MOUSE_MIDDLE") {
        Mouse.release(MOUSE_MIDDLE);
      } else if (comdata == "M0_MOUSE_ALL") {
        Mouse.release(MOUSE_ALL);
      } 
    }
  }
  delay(10);
}

选择开发板
选择自己插到电脑上的开发板
然后点击验证
点击验证
验证成功的输出信息提示大致如下
验证成功的输出信息
点击上传
点击上传,上传成功的输出信息提示大致如下
上传成功的输出信息
现在ino文件就已经上传到了开发板上面了
接下来我们使用pycharm打开项目文件夹
项目文件夹
打开device.py

device.py代码

import datetime
import serial

ser = serial.Serial()
port = 'com9'  # 自己电脑上开发板的端口号
port_status = False


def port_open_recv():  # 对串口的参数进行配置
    # activate_window(window_title)  # 激活窗口
    ser.close()
    ser.port = port
    ser.baudrate = 9600
    ser.bytesize = 8
    ser.stopbits = 1
    ser.parity = "N"  # 奇偶校验位
    ser.open()
    if ser.isOpen():
        print("当前时间为:", datetime.datetime.now().strftime('%Y-%m-%d  %H:%M:%S'), "串口已打开.")
    else:
        print("当前时间为:", datetime.datetime.now().strftime('%Y-%m-%d  %H:%M:%S'), "串口打开失败.")


def port_close():  # 关闭串口
    ser.close()
    if ser.isOpen():
        print("当前时间为:", datetime.datetime.now().strftime('%Y-%m-%d  %H:%M:%S'), "串口关闭失败.")
    else:
        print("当前时间为:", datetime.datetime.now().strftime('%Y-%m-%d  %H:%M:%S'), "串口已关闭.")


def send(send_data, key_type=2):
    """
    对Arduino开发板发送对应类型的按键信息,部分按键没有做映射,请选择比较常见的按键
    :param key_type: 默认参数为2,可输入字符串形式     0:释放按键,1:按住按键,2:按下并马上释放按键(无延迟),M0:鼠标释放,M1:鼠标按住
    :param send_data: 要发送按键信息.
    """
    if ser.isOpen():
        send_data = str(key_type) + "_" + send_data
        ser.write(send_data.encode('utf-8'))  # 编码
    else:
        print("当前时间为:", datetime.datetime.now().strftime('%Y-%m-%d  %H:%M:%S'), "Send failed")

将port = ‘com9’ 改为自己电脑上开发板的端口号
当前开发板的端口号可以在Arduino IDE的右下角直接看到
端口号查看
插拔开发板,以及更换插口,有概率端口号会被修改,请在代码中重新改成自己的端口号

然后运行main.py进行demo测试即可

board.py代码

from interception.device import *
from time import sleep
import random
import pyautogui as pag

LEFT_CTRL = 'KEY_LEFT_CTRL'
LEFT_SHIFT = 'KEY_LEFT_SHIFT'
LEFT_ALT = 'KEY_LEFT_ALT'
UP_ARROW = 'KEY_UP_ARROW'
DOWN_ARROW = 'KEY_DOWN_ARROW'
LEFT_ARROW = 'KEY_LEFT_ARROW'
RIGHT_ARROW = 'KEY_RIGHT_ARROW'
BACKSPACE = 'KEY_BACKSPACE'
SPACE = ' '
TAB = 'KEY_TAB'
ESC = 'KEY_ESC'
INSERT = 'KEY_INSERT'
DELETE = 'KEY_DELETE'
PAGE_UP = 'KEY_PAGE_UP'
PAGE_DOWN = 'KEY_PAGE_DOWN'
HOME = 'KEY_HOME'
END = 'KEY_END'
CAPS_LOCK = 'KEY_CAPS_LOCK'
ENTER = 'KEY_KP_ENTER'
F1 = 'KEY_F1'
F2 = 'KEY_F2'
F3 = 'KEY_F3'
F4 = 'KEY_F4'
F5 = 'KEY_F5'
F6 = 'KEY_F6'
F7 = 'KEY_F7'
F8 = 'KEY_F8'
F9 = 'KEY_F9'
F10 = 'KEY_F10'
F11 = 'KEY_F11'
F12 = 'KEY_F12'


def delay_time(first, last):  # 随机延迟区间
    sleep(generate_random(first, last))


def generate_random(first, last):
    return random.randint(first, last) * 0.001


def press(key, continuous=50, delay=50):
    send(key, key_type=1)
    delay_time(continuous, continuous + 10)
    send(key, key_type=0)
    delay_time(delay, delay + 10)


def hold(key):
    send(key, key_type=1)
    delay_time(60, 70)


def release(key):
    send(key, key_type=0)
    delay_time(60, 70)


def release_all():
    send("ALL", key_type=0)
    delay_time(60, 70)


def move2(x, y):
    pag.moveTo(x, y)

main.py代码

from interception.board import *


def doing():
    # demo

    # 输入w
    press("w")

    # 全选
    hold(LEFT_CTRL)
    press("a")

    # 释放LEFT_CTRL
    release(LEFT_CTRL)


if __name__ == '__main__':
    port_open_recv()

    sleep(3)
    doing()

    port_close()

完整项目下载
链接:https://pan.baidu.com/s/1s3Cvw8LMngPxBTjJzeluXw?pwd=45yh
提取码:45yh

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值