How can I make this Lua script more reliable? - lua

So I've been trying to make my Lua scripts in LogitechGHUB better so that they don't skip a few shots or stop working all of a sudden for a couple of seconds, originally I made this code but no matter what I did it still failed at random moments
EnablePrimaryMouseButtonEvents(true);
function OnEvent(event,arg)
if IsKeyLockOn(LockKey)then
if IsMouseButtonPressed(RC) then
repeat
if IsMouseButtonPressed(LC) then
repeat
MoveMouseRelative(0,11)
if (coun2<2 and IsMouseButtonPressed(LC))
then
MoveMouseRelative(3,13)
end
if (coun2>10 and coun2<25 and IsMouseButtonPressed(LC))
then
MoveMouseRelative(0,1)
end
if (coun2>35 and coun2<55 and IsMouseButtonPressed(LC))
then
MoveMouseRelative(1,0)
end
if (coun2>65 and coun2<75 and IsMouseButtonPressed(LC))
then
MoveMouseRelative(1,1)
end
if (coun2>85 and IsMouseButtonPressed(LC))
then
MoveMouseRelative(1,1)
end
Sleep(1)
coun2 = coun2+1
until not IsMouseButtonPressed(LC)
coun2=0
end
until not IsMouseButtonPressed(RC)
end
end
end
LockKey="numlock"
coun2 = 0
LC=1
RC=3
I changed the idea of using counters to make it more customizable, for loops like this
EnablePrimaryMouseButtonEvents(true)
function OnEvent(event, arg)
if event == "MOUSE_BUTTON_PRESSED" and arg == 1 and IsMouseButtonPressed(3) and IsKeyLockOn("numlock") then
for i = 1, 2 do
MoveMouseRelative(3,20)
Sleep(1)
if not IsMouseButtonPressed(1) then return end
end
for i = 1, 135 do
MoveMouseRelative(1,12)
Sleep(1)
if not IsMouseButtonPressed(1) then return end
end
end
end
Which did in fact make it more consistent as long as I didn't use too many for loops, but it still occasionally stops moving the mouse for random periods of time. I tried changing the Sleep() functions for FastSleep() that I saw another user recommending, but it remained the same just faster. Is there a way of making the script less bound to fail or like something I'm not understanding that messes the code? Or should I simply try a different coding language?

Try
local LockKey = "numlock"
local moves = { -- dx/msec, dy/msec, msec
{0.3, 2.0, 30},
{0.0, 1.1, 100},
{0.0, 1.2, 150},
{0.0, 1.1, 100},
{0.1, 1.1, 200},
{0.0, 1.1, 100},
{0.1, 1.2, 100},
{0.0, 1.1, 100},
{0.1, 1.2, math.huge},
}
local function get_distance(t)
local x, y = 0, 0
for _, move in ipairs(moves) do
local vx, vy, mt = move[1], move[2], move[3]
if t < mt then
mt = t
end
x, y = x + vx*mt, y + vy*mt
t = t - mt
if t <= 0 then break end
end
return math.floor(x), math.floor(y)
end
function OnEvent(event, arg)
if event == "PROFILE_ACTIVATED" then
EnablePrimaryMouseButtonEvents(true)
elseif event == "MOUSE_BUTTON_PRESSED" and arg == 1
and IsMouseButtonPressed(3) and IsKeyLockOn(LockKey)
then
local t0 = GetRunningTime()
local t = t0
repeat
Sleep(10)
local oldx, oldy = get_distance(t - t0)
t = GetRunningTime()
local newx, newy = get_distance(t - t0)
MoveMouseRelative(newx - oldx, newy - oldy)
until not IsMouseButtonPressed(1)
end
end

Related

How to make two functions work separately and together in luascript? -software logitech GHUB

I want this code to work together and separately when scrolllock is enabled. One using the mouse button(3) and the other the mouse button(2). Working separately they are working, however when I activate one the other does not work. I did a lot of research and it seems that there is a way to do it using a "coroutine", but I didn't find out how.
EnablePrimaryMouseButtonEvents(true);
function OnEvent(event, arg)
local r = 350
local x = 350
local s = 50
if IsKeyLockOn("scrolllock" )then
if IsMouseButtonPressed(3) then
local positions = { -- Move `MoveMouseRelative` args to an 2d array.
{-r,x},
{-r,x},
{r,x},
{r,x},
{r,-x},
{r,-x},
{-r,-x},
{-r,-x},
}
local index = 1
repeat
MoveMouseRelative(positions[index][1], positions[index][2])
Sleep(s)
index = (index % #positions) + 1 -- loop index when it reaches the array length.
until not IsMouseButtonPressed(3)
end
if IsMouseButtonPressed(2) then
repeat
PressAndReleaseKey("p")
Sleep(750)
until not IsMouseButtonPressed(2)
end
end
end
You should write each "task" in its own coroutine and write a coroutine-friendly implementation of Sleep().
local orig_Sleep = Sleep
local function Sleep(delay)
local co, is_main = coroutine.running()
if not is_main and co then
local tm = GetRunningTime() + delay
repeat
coroutine.yield(true)
until GetRunningTime() >= tm
else
orig_Sleep(delay)
end
end
local tasks = {}
local function add_task(task_function)
table.insert(tasks, coroutine.wrap(
function()
repeat
task_function()
coroutine.yield()
until nil
end
))
end
local function task_manager()
repeat
Sleep(5)
local active -- true when at least one task is inside "Sleep" now
for _, resume_task in ipairs(tasks) do
active = resume_task() or active
end
until not active
end
add_task(
function()
if IsKeyLockOn"scrolllock" and IsMouseButtonPressed(3) then
local r = 350
local x = 350
local s = 50
local positions = { -- `MoveMouseRelative` args
{-r,x},
{-r,x},
{r,x},
{r,x},
{r,-x},
{r,-x},
{-r,-x},
{-r,-x},
}
local index = 1
repeat
MoveMouseRelative(positions[index][1], positions[index][2])
Sleep(s)
index = (index % #positions) + 1 -- loop index when it reaches the array length.
until not IsMouseButtonPressed(3)
end
end
)
add_task(
function()
if IsKeyLockOn"scrolllock" and IsMouseButtonPressed(2) then
repeat
PressAndReleaseKey("p")
Sleep(750)
until not IsMouseButtonPressed(2)
end
end
)
EnablePrimaryMouseButtonEvents(true)
function OnEvent(event, arg)
task_manager()
end

Reverse MoveMouseRelative Lua Codding

function OnEvent(event, arg)
OutputLogMessage("event = %s, arg = %d\n", event, arg)
if event == "PROFILE_ACTIVATED" then
EnablePrimaryMouseButtonEvents(true)
elseif event == "PROFILE_DEACTIVATED" then
ReleaseMouseButton(2) -- to prevent it from being stuck on
elseif event == "MOUSE_BUTTON_PRESSED"
and (arg == 5 or arg == 4) then
recoil = recoil ~= arg and arg
elseif event == "MOUSE_BUTTON_PRESSED"
and arg == 1 and recoil == 5 then
MoveMouseRelative(0, -3)
for i = 1, 17 do
MoveMouseRelative(0, 2)
Sleep(15)
if not IsMouseButtonPressed(1) then return end
end
elseif event == "MOUSE_BUTTON_PRESSED"
and arg == 1 and recoil == 4 then
MoveMouseRelative(0, -3)
for i = 1, 35 do
Sleep(15)
MoveMouseRelative(0, 2)
if not IsMouseButtonPressed(1) then return end
end
if not IsMouseButtonPressed(1) then return end
end
end
This is the Lua Script , I wonder how i can get mouse initial position and after it to return to the initial position.
I tried to add MoveMousePosition(x,y)- (32767, 32767 ) at bottom of script but not worked in game . Only on desktop ..
I just want after MoveMouseRelative when i release mouse click to return center or first position .
As Luke100000 said, you need an "undo" movement (the same distance with the opposite sign).
function OnEvent(event, arg)
OutputLogMessage("event = %s, arg = %d\n", event, arg)
if event == "PROFILE_ACTIVATED" then
EnablePrimaryMouseButtonEvents(true)
elseif event == "MOUSE_BUTTON_PRESSED" and (arg == 5 or arg == 4) then
recoil = recoil ~= arg and arg
elseif event == "MOUSE_BUTTON_PRESSED" and arg == 1 and recoil == 5 then
MoveMouseRelative(0, -3)
local n = 0
for i = 1, 17 do
n = n + 1
MoveMouseRelative(0, 2)
Sleep(15)
if not IsMouseButtonPressed(1) then break end
end
repeat -- wait for LMB release
until not IsMouseButtonPressed(1)
for i = 1, n do
MoveMouseRelative(0, -2)
end
MoveMouseRelative(0, 3)
elseif event == "MOUSE_BUTTON_PRESSED" and arg == 1 and recoil == 4 then
MoveMouseRelative(0, -3)
local n = 0
for i = 1, 35 do
Sleep(15)
n = n + 1
MoveMouseRelative(0, 2)
if not IsMouseButtonPressed(1) then break end
end
repeat -- wait for LMB release
until not IsMouseButtonPressed(1)
for i = 1, n do
MoveMouseRelative(0, -2)
end
MoveMouseRelative(0, 3)
end
end
To undo any operations we need a stack, where you remember everything you did. But since we only have a single position and therefore the order does not matter, we use a simple number to store the total moved x and y instead.
local movedX = 0
local movedY = 0
function move(x, y)
MoveMouseRelative(x, y)
movedX = movedX + x
movedY = movedY + y
end
Now you use e.g. move(0, 2) only.
To undo we do the opposite; since we only have a number by subtracting it.
function undo()
MoveMouseRelative(-movedX, -movedY)
movedX = 0
movedY = 0
end
Unrelated, but in your loop, do not use return but break. That way you can reach the end of the event and add an undo() there.

How can I use non-integer without using float in LUA

In LUA for MoveMouse i can't use FLOAT. So i need to get around it. I don't know how to do this. So i need help.
function OnEvent(event, arg)
local multiplier = 2
if smth == CODE then
MoveMouseRelative(-1*multiplier, 0.1*multiplier)
Sleep(10)
MoveMouseRelative(-1*multiplier, 0.2*multiplier)
Sleep(10)
You can store fractional value in a variable and pass math.floor(value) to your functions.
Unspent fractional part will be accumulated for future using.
local x_frac, y_frac = 0
local function MoveMouseRelativeFractional(x, y)
x_frac = x_frac + x
y_frac = y_frac + y
local x_int = math.floor(x_frac)
local y_int = math.floor(y_frac)
x_frac = x_frac - x_int
y_frac = y_frac - y_int
if x_int ~= 0 or y_int ~= 0 then
MoveMouseRelative(x_int, y_int)
end
end
function OnEvent(event, arg)
local multiplier = 2
if smth == CODE then
MoveMouseRelativeFractional(-1*multiplier, 0.1*multiplier)
Sleep(10)
MoveMouseRelativeFractional(-1*multiplier, 0.2*multiplier)
Sleep(10)

Logitech gaming software lua script repeat toggle

I have a script which does a left click, then moves to the right about 1 cm, then clicks again and moves back to the left.
I would like this script to repeat itself continuously until i press a button, it doesn't really matter much which button it uses(except for MB 1, 2 and 3.
I have been trying for a while, with repeats and loops and the only thing i have achieved is a very complex script that makes the software crash after each run, which is slightly annoying.
I think there is something about the repeat function that i do not understand correctly.
Can anyone show me how to get this to work?
greetings
Edit: I have updated the code to what it is now, the original code is below it.
local mb4_status, exit_flag
local function Move(dx, dy, time, is_interruptable)
local t0 = GetRunningTime()
local prev_dx, prev_dy = 0, 0
repeat
Sleep(15)
local part = math.min(time, GetRunningTime() - t0) / time
local current_dx = math.floor(part * dx)
local current_dy = math.floor(part * dy)
local x, y = current_dx - prev_dx, current_dy - prev_dy
if x ~= 0 or y ~= 0 then
MoveMouseRelative(x, y)
end
prev_dx, prev_dy = current_dx, current_dy
local prev_mb4_status = mb4_status
mb4_status = IsMouseButtonPressed(4)
exit_flag = exit_flag or mb4_status and not prev_mb4_status
until part == 1 or is_interruptable and exit_flag
end
function OnEvent(event, arg)
if event == "MOUSE_BUTTON_PRESSED" and arg == 4 then
if exit_flag then
exit_flag = false
else
mb4_status = true
local x = 44
repeat
PressMouseButton(1)
Move(0, 0, 200, false) -- equivalent to Sleep(200)
ReleaseMouseButton(1)
Move(x, 0, 1000, true) -- mixture of MoveMouseRelative(44,0) + Sleep(1000)
x = -x
until exit_flag
end
end
end
function OnEvent(event, arg)
if (event == "MOUSE_BUTTON_PRESSED" and arg == 8) then
for i = 1, 1 do
PressMouseButton(1)
Sleep(200)
ReleaseMouseButton(1)
end
Sleep(500)
for i = 5, 15 do
MoveMouseRelative(4,0)
Sleep(1)
end
Sleep(500)
for i = 1, 1 do
PressMouseButton(1)
Sleep(200)
ReleaseMouseButton(1)
end
Sleep(500)
for i = 5, 15 do
MoveMouseRelative(-4,0)
Sleep(1)
end
Sleep(500)
end
end
I haven't tested this code but it should at least give you some idea how to approach this. Instead of long blocking sleeps my code checks how much time has passed since start and checks the abort condtion of any button being pressed while waiting.
function OnEvent(event, arg)
if (event == "MOUSE_BUTTON_PRESSED" and arg == 8) then
local function abortCondition()
return IsMouseButtonPressed(1) or IsMouseButtonPressed(2) or IsMouseButtonPressed(3)
end
local function abortableSleep(delay)
local startTime = GetRunningTime()
while GetRunningTime() <= startTime + delay do
if abortCondition() then return end
Sleep(5)
end
return true
end
local function delayedClick(button, delay)
PressMouseButton(button)
Sleep(10)
if not abortableSleep(delay-10) then return end
ReleaseMouseButton(button)
return true
end
repeat
if not delayedClick(1, 200) then return end
if not abortableSleep(500) then return end
for i = 0, 10 do
MoveMouseRelative(4,0)
Sleep(1)
end
if not abortableSleep(500) then return end
if not delayedClick(1, 200) then return end
for i = 0, 10 do
MoveMouseRelative(-4,0)
Sleep(1)
end
if not abortableSleep(500) then return end
until releaseCondition()
end
end
Please note Btn#4 is used instead of Btn#8
local mb4_status, exit_flag
local function Move(dx, dy, time, is_interruptable)
local t0 = GetRunningTime()
local prev_dx, prev_dy = 0, 0
repeat
Sleep(15)
local part = math.min(time, GetRunningTime() - t0) / time
local current_dx = math.floor(part * dx)
local current_dy = math.floor(part * dy)
local x, y = current_dx - prev_dx, current_dy - prev_dy
if x ~= 0 or y ~= 0 then
MoveMouseRelative(x, y)
end
prev_dx, prev_dy = current_dx, current_dy
local prev_mb4_status = mb4_status
mb4_status = IsMouseButtonPressed(4)
exit_flag = exit_flag or mb4_status and not prev_mb4_status
until part == 1 or is_interruptable and exit_flag
end
function OnEvent(event, arg)
if event == "MOUSE_BUTTON_PRESSED" and arg == 4 then
if exit_flag then
exit_flag = false
else
mb4_status = true
local x = 44
repeat
PressMouseButton(1)
Move(0, 0, 200, false) -- equivalent to Sleep(200)
ReleaseMouseButton(1)
Move(0, 0, 300, true) -- equivalent to Sleep(300)
Move(x, 0, 1000, true) -- mixture of MoveMouseRelative(44,0) + Sleep(1000)
Move(0, 0, 300, true)
x = -x
until exit_flag
end
end
end
UPDATE:
I've inserted sleep 300ms between move and click.
To change distance modify 44
Timings 200, 1000, 300 can also be modified
To change "start" button modify arg == 4
To change "stop" button modify IsMouseButtonPressed(4) (only 2-5)
Please note that script deliberately ignores every second press on "start" button because it assumes that "start" button is the same as "stop" button

Logitech Lua combining Rapid Fire with spray

So basically, this is what my script looks like at the moment, it’s a rapid fire macro and reduces the recoil of the guns, however I can never spray with this script for some reason as it’s very slow because I guess it’s reducing the recoil. I was wondering if I could shoot like 4, 5 bullets without any recoil (only auto shoot while holding mouse 3 not while tapping.) and continue with spray like normal spray without any delays while already holding mouse3. So 4 bullets no recoil and rest the regular spray on the same cycle. If that makes any sense. Any help would be greatly appreciated.
EnablePrimaryMouseButtonEvents(true);
function OnEvent(event, arg)
if IsKeyLockOn("scrolllock")then
if IsMouseButtonPressed(3) then
repeat
if IsMouseButtonPressed(3) then
repeat
PressMouseButton(1)
Sleep(15)
ReleaseMouseButton(1)
until not IsMouseButtonPressed(3)
end
until not IsMouseButtonPressed(3)
end
end
end
local rapid_fire_delay = 15 -- delay between simulation of LMB press/release
local LMB_Pressed
do -- initializing PRNG
local dt = 0
for c in GetDate():gmatch"." do
dt = (dt % 65537 * 23456 + c:byte())
end
math.randomseed(dt)
end
function OnEvent(event, arg)
if event == "MOUSE_BUTTON_PRESSED" and arg == 2 and IsKeyLockOn("scrolllock") then -- RMB press
for j = 1, math.random(4, 5) do -- first 4-5 bullets as rapid-fire
PressMouseButton(1)
Sleep(math.random(rapid_fire_delay, 2*rapid_fire_delay))
ReleaseMouseButton(1)
Sleep(math.random(rapid_fire_delay, 2*rapid_fire_delay))
if not IsMouseButtonPressed(3) then return end -- is RMB pressed?
end
PressMouseButton(1)
LMB_Pressed = true
elseif event == "MOUSE_BUTTON_RELEASED" and arg == 2 and LMB_Pressed then -- RMB release
ReleaseMouseButton(1)
LMB_Pressed = false
elseif event == "MOUSE_BUTTON_PRESSED" and arg == 5 then
repeat
Sleep(15)
PressKey("SPACEBAR")
Sleep(15)
ReleaseKey("SPACEBAR")
until not IsMouseButtonPressed(5)
end
end
The line for j = 1, math.random(4, 5) do means "a random quantity from 4 to 5 bullets".
If you want exactly 3 bullets change this line to for j = 1, 3 do
EDIT:
This is instruction on how to make the rapidfire turn on only after LMB double-click.
Usual slow LMB click will not trigger rapidfire.
local Prev_LMB_Time, LMB_Pressed = 0
function OnEvent(event, arg)
if event == "MOUSE_BUTTON_PRESSED" and arg == 1 then
if IsKeyLockOn("scrolllock") then
local tm = GetRunningTime()
tm, Prev_LMB_Time = tm - Prev_LMB_Time, tm
if tm < 200 then -- LMB double-click
for j = 1, 100 do
PressMouseButton(1)
Sleep(1)
ReleaseMouseButton(1)
Sleep(1)
if not IsMouseButtonPressed(4) then return end
end
end
end
PressMouseButton(1)
LMB_Pressed = true
elseif event == "MOUSE_BUTTON_RELEASED" and arg == 1 and LMB_Pressed then
ReleaseMouseButton(1)
LMB_Pressed = false
elseif event == "MOUSE_BUTTON_PRESSED" and arg == 5 then
repeat
Sleep(15)
PressKey("SPACEBAR")
Sleep(15)
ReleaseKey("SPACEBAR")
until not IsMouseButtonPressed(5)
end
end
Currently you have in GHUB:
Primary Click = G1
Back = G4 G8
What you should do in GHUB (in this order):
Bind "Primary Click" to G8 (from now on, use button#8 instead of LMB)
Bind "Back" to G1
Set the script
Now you should have the following:
Primary Click = G8
Back = G1 G4
Mouse button#8 is now "spare LMB" just in case LMB works incorrectly.

Resources