manups4e / ScaleformUI

ScaleformUI is a GTA menu styled API made with custom Scaleforms to be lighter, faster and visually better
Other
141 stars 49 forks source link

[LUA] Fix softlock if WarningInstance input buttons are disabled #150

Closed Asaayu closed 1 year ago

Asaayu commented 1 year ago

Because a UIMenu disables most controls, if ScaleformUI.Scaleforms.Warning:ShowWarningWithButtons is called while a UIMenu is open the user can get softlocked as the WarningInstance only checks enabled controls

if IsControlJustPressed(1, v.GamepadButton) or IsControlJustPressed(1, v.KeyboardButton) then

Adding additional IsDisabledControlJustPressed checks to the function fixes the issue, I'm just unaware if this creates any unintended side effects in other systems

IsControlJustPressed(1, v.GamepadButton) or
IsControlJustPressed(1, v.KeyboardButton) or
IsDisabledControlJustPressed(1, v.GamepadButton) or
IsDisabledControlJustPressed(1, v.KeyboardButton)
manups4e commented 1 year ago

🤔 iirc the WarningInstance blocks the menu from drawing.. in this case i'd block the menu control processing 🤔 this should enabled all controls.

Asaayu commented 1 year ago

The main issue seems to be that the warning check doesn't undo any actions (such as disabling controls) done by the UIMenu, it only skips drawing.

From a quick look I couldn't find any place where the UIMenu handles controls while open other then disabling controls if ControlDisablingEnabled is true, from reading, setting it to false while the menu is open would cause the UIMenu to skip the DisEnableControls function call regardless (see snippet), and the controls would remain disabled until the menu is closed (assuming the XXXAllControlActions natives don't require per-frame execution)

Snippet:

function UIMenu:Draw()
  if not self._Visible or ScaleformUI.Scaleforms.Warning:IsShowing() then return end
  while not ScaleformUI.Scaleforms._ui:IsLoaded() do Citizen.Wait(0) end

  HideHudComponentThisFrame(19)

  if self.Settings.ControlDisablingEnabled then
      self:DisEnableControls(false)
  end

Current Flow:

  1. UIMenu opened.
  2. UIMenu:Draw is called.
  3. The Draw function disables controls.
  4. UIMenu functions continue to run as normal.
  5. One second later a warning is opened.
  6. UIMenu:Draw is called again.
  7. The Draw function exits immediately on the first line due to if not self._Visible or ScaleformUI.Scaleforms.Warning:IsShowing() then return end.
  8. The warning checks if the enabled control is pressed
  9. The input check fails because that key has been disabled by the UIMenu Draw function previously
  10. User is now softlocked in the warning menu
manups4e commented 1 year ago

i've added a couple of commits if you wanna try them :D they should fix the issue https://github.com/manups4e/ScaleformUI/commit/9fdfd3baead62173a6f69d5839b092a36ad6341d and https://github.com/manups4e/ScaleformUI/commit/3f9e612c2e472646965f554212b786d0ff87b445

Asaayu commented 1 year ago

I'll give them a try and get back to you tomorrow 👍

manups4e commented 1 year ago

no problem!

Asaayu commented 1 year ago

Issue still present, I've used the following to check the state of both controls,

print(IsControlEnabled(1, v.GamepadButton), IsControlEnabled(1, v.KeyboardButton))
if IsControlJustPressed(1, v.GamepadButton) or IsControlJustPressed(1, v.KeyboardButton) then

Which returns false false, so both controls are still disabled when the warning is open, which softlocks the player.

manups4e commented 1 year ago

i see.. then we are good to go adding your merge :D