0

长话短说:我正在使用 SikuliX 编写脚本,它应该像人类一样移动鼠标并进行点击(实际上是一个机器人)。SikuliX 使用 Jython 2.7 作为脚本语言。我为我的目的找到了不错的库(像人类一样移动鼠标): mouse.simba用类似 Pascal 的语言编写,并在 jython 中重写函数_humanWindMouse() 。它有效,但不像我预期的那样。

我的脚本的测试运行,绘制矩形:

https://prtscr.cx.ua/storage/5b/5b2203.jpg

使用具有相同坐标的原始函数的结果:

https://prtscr.cx.ua/storage/bb/bb3ff5.jpg

抱歉链接,我还不能发布图片(

我的代码:

import random
import time
import math
from time import sleep
from math import sqrt
from math import ceil
from math import hypot

from java.awt import Robot

def distance(x1, y1, x2, y2):
    return math.hypot(x2 - x1, y2 - y1)

def myrandom(x):
    return random.randint(0, x-1)

def myround(x):
    return int(round(x))

# function MMouseMove (MyMouseMove) for moving mouse using only coord
def MMouseMove(x,y):
    robot = Robot()
    robot.mouseMove(x,y)

# function HumanWindMouse by BenLand100 & Flight, python implementation
def humanWindMouse(xs, ys, xe, ye, gravity, wind):
    veloX = veloY = windX=windY=veloMag=dist=randomDist=lastDist=D=0
    lastX=lastY=MSP=W=TDist=0

    mouseSpeed = 20
    MSP = mouseSpeed
    sqrt2 = sqrt(2)
    sqrt3 = sqrt(3)
    sqrt5 = sqrt(5)

    TDist = distance(myround(xs), myround(ys), myround(xe), myround(ye))
    t = time.time() + 10000
    while True:
        if time.time() > t:
            break

        dist = hypot(xs - xe, ys - ye)
        wind = min(wind, dist)
        if dist < 1:
            dist = 1

        D = (myround((myround(TDist)*0.3))/7)
        if D > 25:
            D = 25
        if D < 5:
            D = 5

        rCnc = myrandom(6)
        if rCnc == 1:
            D = random.randint(2,3)

        if D <= myround(dist):
            maxStep = D
        else:
            maxStep = myround(dist)

        windX= windX / sqrt2
        windY= windY / sqrt2

        veloX= veloX + windX
        veloY= veloY + windY
        veloX= veloX + gravity * (xe - xs) / dist
        veloY= veloY + gravity * (ye - ys) / dist

        if hypot(veloX, veloY) > maxStep:
            temp = int(myround(maxStep) // 2)
            if temp == 0:
                temp = 1
            randomDist= maxStep / 2.0 + myrandom(temp)
            veloMag= sqrt(veloX * veloX + veloY * veloY)
            veloX= (veloX / veloMag) * randomDist
            veloY= (veloY / veloMag) * randomDist

        lastX= myround(xs)
        lastY= myround(ys)
        xs= xs + veloX
        ys= ys + veloY

        if lastX <> myround(xs) or lastY <> myround(ys):
            MMouseMove(myround(xs), myround(ys))

        W = (myrandom((myround(100/MSP)))*6)
        if W < 5:
            W = 5
        W = myround(W*0.9)
        sleep(W/1000.0)
        lastdist= dist

        if hypot(xs - xe, ys - ye) < 1:
            break

    if myround(xe) <> myround(xs) or myround(ye) <> myround(ys):
        MMouseMove(myround(xe), myround(ye)) 
    mouseSpeed = MSP    
    return;

def MMouse(x,y):
    mouseSpeed = 20
    randSpeed = (myrandom(mouseSpeed) / 2.0 + mouseSpeed) / 10.0
    curPos = Mouse.at()
    x1 = curPos.x
    y1 = curPos.y
    humanWindMouse(x1, y1, x, y, 5, 10.0/randSpeed)
    return;

我以这种方式使用它:

MMouseMove(227, 146)

mouseDown(Button.LEFT)
MMouse(396, 146)
MMouse(396, 252)
MMouse(227, 252)
MMouse(227, 146)
mouseUp(Button.LEFT)

exit()

mouseDown()mouseUp()是 SikuliX 中的内置函数
而且我没有使用内置mouseMove(),因为它从 A 到 B 太慢了。

任何帮助,将不胜感激

4

1 回答 1

0

经过几个小时的调试,我发现了问题:在源代码中,作者在调用他的函数时将调用的常量传递给了名为MOUSE_HUMAN变量的变量,这对我来说似乎是一个错误。这就是为什么我决定在我的代码中解决这个问题,并丢弃函数的一个参数和几行代码(这是错误的举动)。重新添加所需的代码后,我的功能可以正常工作,正如我所料。gravity_humanWindMouse()

所以,这是工作代码:

# function HumanWindMouse by BenLand100 & Flight, 
# python implementation by Nokse
def humanWindMouse(xs, ys, xe, ye, gravity, wind, targetArea):
    veloX = veloY = windX=windY=veloMag=dist=randomDist=lastDist=D=0
    lastX=lastY=MSP=W=TDist=0

    mouseSpeed = 20
    MSP = mouseSpeed
    sqrt2 = sqrt(2)
    sqrt3 = sqrt(3)
    sqrt5 = sqrt(5)

    TDist = distance(myround(xs), myround(ys), myround(xe), myround(ye))
    t = time.time() + 10000
    while True:
        if time.time() > t:
            break

        dist = hypot(xs - xe, ys - ye)
        wind = min(wind, dist)
        if dist < 1:
            dist = 1

        D = (myround((myround(TDist)*0.3))/7)
        if D > 25:
            D = 25
        if D < 5:
            D = 5

        rCnc = myrandom(6)
        if rCnc == 1:
            D = random.randint(2,3)

        if D <= myround(dist):
            maxStep = D
        else:
            maxStep = myround(dist)

        if dist >= targetArea:
            windX = windX / sqrt3 + (myrandom(myround(wind) * 2 + 1) - wind) / sqrt5
            windY = windY / sqrt3 + (myrandom(myround(wind) * 2 + 1) - wind) / sqrt5
        else:
            windX = windX / sqrt2
            windY = windY / sqrt2

        veloX = veloX + windX
        veloY = veloY + windY
        veloX = veloX + gravity * (xe - xs) / dist
        veloY = veloY + gravity * (ye - ys) / dist

        if hypot(veloX, veloY) > maxStep:
            halfSteps = int(myround(maxStep) // 2)
            if halfSteps == 0:
                halfSteps = 1
            randomDist = maxStep / 2.0 + myrandom(halfSteps)
            veloMag = sqrt(veloX * veloX + veloY * veloY)
            veloX = (veloX / veloMag) * randomDist
            veloY = (veloY / veloMag) * randomDist

        lastX = myround(xs)
        lastY = myround(ys)
        xs = xs + veloX
        ys = ys + veloY

        if lastX <> myround(xs) or lastY <> myround(ys):
            MMouseMove(myround(xs), myround(ys))

        W = (myrandom((myround(100/MSP)))*6)
        if W < 5:
            W = 5
        W = myround(W*0.9)
        sleep(W/1000.0)
        lastdist = dist
        #condition for exiting while loop
        if hypot(xs - xe, ys - ye) < 1:
            break

    if myround(xe) <> myround(xs) or myround(ye) <> myround(ys):
        MMouseMove(myround(xe), myround(ye)) 
    mouseSpeed = MSP    
    return; 

我用不同的参数对其进行了测试,并选择了这个:

humanWindMouse(xs, ys, x, y, 9, 10.0/randSpeed, 10.0*randSpeed)

但我建议先玩参数,了解它们如何影响鼠标的行为。

如何计算randSpeed,应该导入什么,以及子功能,例如myround(),可以在我的第一篇文章中找到。希望,这段代码有一天会帮助某人)

于 2018-08-10T12:18:45.287 回答