Logitech/LGHUB Lua - Loop with break

4.3k views Asked by At

i recently picked up Lua while making a macro script for my LG mouse. Unfortunately the Lua-API is really restricted with debug, io and file not working (source: http://www.softpanorama.org/Hardware/Peripherals/Keyboards/Logitech_G_keyboard_macros/lua_scripting.shtml#Limitations) Here is also the official reference: https://douile.github.io/logitech-toggle-keys/APIDocs.pdf

The script is running a LGHUB macro while i want to attach mouse movement to that macro while it is running. There is no function for checking if a macro is currently running to just loop and stop the lua-side. So I'm looking for a possibility in Lua to 'run a loop independent' which does not stop the execution of the rest of my script (to check if a status variable [isMacroRunning] has changed). I also want to break that macro if i hit another button while the macro is running. BUT if i loop the mouse-movement, i cannot trigger another onEvent-function because the script-pointer(?) is still stuck in my loop. My current idea is to break that with a coroutine but iam not sure how to continue while no key-input is happening.

The script doesnt stop and wait if it encounters 'PlayMacro()', also this API-Function has no return value to just attach lua actions to the PlayMacro-function.

There would be also the possibility to transfer the LGHUB-macro (essentially its just pressButton A and leftclick for 40s then release the buttons) but that doesnt solve the problem (at least i cant find a solution within this) with the function being stuck in the loop and no way to break it. For example, if MouseButton11 triggers a loop and i press MouseButton10, the $arg variable does not change to 10 but stays at 11 because the script-pointer(?) is still in the loop instead of triggering the onEvent function.

The script seems to get executed once at load (example on switching mouse-profiles) and then the onEvent-function listens. If i could somehow run a looping check on [isMacroRunning] while still be able to trigger the onEvent-function, i can make this work. But otherwise i know to little about Lua and its behavior.

Edit1: Added "essential script" which only describes the needed core-functions. This is not working due to a 2nd onEvent cannot be triggered until the 1st onEvent has finished. But the 1st onEvent is designed to break on a variable change. The variable change is triggered in the 2nd onEvent. Needed solution: some kind of workaround or use of other Lua functions to seperate the 1st onEvent execution from the 2nd onEvent.

Essential Script:

```
isMacroRunning = false

function wiggle()
    PressKey("a")
    while true do
        if not isMacroRunning then break end

        OutputLogMessage("wiggle\n")
        MoveMouseRelative (5, 0)
        Sleep(150)
        MoveMouseRelative (-5, 0)
        Sleep(150)
    end
end

function OnEvent(event, arg)
    if (event == "MOUSE_BUTTON_PRESSED" and arg == 11) then
        isMacroRunning = true
        wiggle()
    end
    if(event == "MOUSE_BUTTON_PRESSED" and arg == 10 and isMacroRunning) then
        isMacroRunning = false
        ReleaseKey("a")
    end
end
´´´

Full Script:

    local isMacroRunning = false
    
    coco = coroutine.create(function()
        while true do
            if not isMacroRunning then break end
            MoveMouseRelative (5, 0)
            Sleep(150)
            MoveMouseRelative (-5, 0)
            Sleep(150)
            coroutine.yield()
        end
    end)
    
    function OnEvent(event, arg)
        if (event == "MOUSE_BUTTON_PRESSED" and arg == 11) then
            isMacroRunning = true
            runMacro()
        elseif(event == "MOUSE_BUTTON_PRESSED" and arg == 10 and isMacroRunning) then
            isMacroRunning = false
            runMacro()
        end
    end
    
    function runMacro()
        if isMacroRunning then
            PlayMacro('farm')
            coroutine.resume(coco)
            OutputLogMessage("Start Macro\n")
        else
            AbortMacro()
            OutputLogMessage("Aborted\n")
        end
    end
    
    
    coroutine.resume(coco)
´´´
1

There are 1 answers

1
Egor Skriptunoff On BEST ANSWER

Step 1.
Make sure you're not using MB#4 ("backward") in the game.
If some action is assigned to MB#4 in the game, do the following:

  • choose keyboard button you don't currently use in the game (for example, F12)
  • goto GHUB(KEYS tab); bind F12 to your physical MB#4
  • goto game options; bind the action to F12 instead of MB#4

Now when you press physical MB#4, the game sees F12 and executes your old action.


Step 2.
Goto GHUB(SYSTEM tab); bind "Back" to MB#10


Step 3.
The script.

function OnEvent(event, arg)
   if event == "MOUSE_BUTTON_PRESSED" and arg == 11 then
      PressMouseButton(1)      -- down LMB
      PressKey("A")            -- down "A"
      repeat
         MoveMouseRelative(5,0)
         Sleep(150)
         MoveMouseRelative(-5,0)
         Sleep(150)
      until IsMouseButtonPressed(4)  -- btn#4 is bound to btn#10
      ReleaseKey("A")          -- up "A"
      ReleaseMouseButton(1)    -- up LMB
   end
end

How does it work:
When you press MB#11, the loop starts.
When you later press MB#10, IsMouseButtonPressed() sees that button#4 is pressed, and the loop exits.