[Release] Simple Hacking Minigame

This is my first release of a bunch of some scripts I wrote. More will come after I deem them ready enough.

The hacking minigame is inspired by the Hacking Minigame of Alpha Protocol, notoriously known for being horrible to play. You need to find two constant hex code blocks in a fast enough changing table of hexcode. It is purely a visual minigame. In the screen below you will see the left block hovering directly above a solution – need to move it one down and press space to be accepted as a correct solution.

Sample Implementation

function mycb(success, timeremaining)
	if success then
		print('Success with '..timeremaining..'s remaining.')
		TriggerEvent('mhacking:hide')
	else
		print('Failure')
		TriggerEvent('mhacking:hide')
	end
end


Citizen.CreateThread(function()
  while true do
    Citizen.Wait(0)
    if IsControlJustReleased(1,213) then -- Home key
	  TriggerEvent("mhacking:show")
	  TriggerEvent("mhacking:start",7,35,mycb)
    end
  end
end)

How to use the Resource

After loading the resource, you can call several events to control the minigame.

  • For your own implementation call mhacking:show to show the app and mhacking:hide to hide it.
  • Call mhacking:setmessage, while the app is not running, but you called mhacking:show prior to display a custom message, which is the parameter of the aforementioned event.
  • Call mhacking:start, to start the minigame. The event has the parameters: solution-size, time and a callback function which gets passed true or false, depending on whether the client has successfully solved the minigame or was timed out. Furthermore the remainingtime in ms is passed as a second parameter.
  • mhacking:seqstart is a wrapper for mhacking:start, mhacking:show, and mhacking:hide and has the same parameters as mhacking:start; but it can be passed tables instead. Depending on if tables have been passed or not the behaviour of the minigame slightly changes. e.g. calling TriggerEvent("mhacking:seqstart",{7,6,5,4},90,mycb) would trigger 4 minigames in series for which the player has 90s of time available in total to solve them, with decreasing solution-size. The callback gets called after every successful or failed game with a 3rd boolean parameter, indicating if this was the last hack after which the application is closed. e.g. function mycb(success, remainingtime, finish) end

The difficulty itself can be easily adjusted by the available time and solution-size; smaller codeblocks are more difficult to spot with less time, it becomes even more difficult. Very easy is usually about solution-size of 7, and 35s - 45s of time to find the correct spots, while I would deem hard or very hard something like solution-size of 3 and 10s - 12s time.
Missing a solution once will reduce the time by 5s, missing it twice by 10s, etc.

Download from GitHub: https://github.com/GHMatti/FiveM-Scripts/tree/master/mhacking

Changelog
  • 20171225: Initial Release
  • 20180102: Fixed mhacking not reseting mistakes
  • 20180110: Added time remaining in ms as a second parameter for the callback function; if the player dies, the script now sets the remaining time to 0, and fails the player. Added mhacking:setmessage to set messages while waiting for feedback and sequentialhack.lua to handle sequentialhacks without everyone needing to program their own implementation, which can be removed from the __resource.lua if one does not need it.

If someone has suggestions for improvements, especially a better idea for displaying the help to play this Minigame I am all ears.

33 Likes

This is pretty neat! Nice job!

1 Like

Will be using this for a stealing mission I’m working at, thanks for sharing.

2 Likes

awesome, dood! thanks for sharing your work :wink:

1 Like

Fixed an issue, where I forgot to set the number of mistakes made to 0.

Literally just added mistakes = 0; to resetGameState().

  • Added time remaining in ms as a second parameter for the callback function;
  • If the player dies, the script now sets the remaining time to 0, and fails the player.
  • Added mhacking:setmessage to set messages while waiting for feedback
  • Added sequentialhack.lua to handle sequentialhacks without everyone needing to program their own implementation, which can be removed from the __resource.lua if one does not need it.

Where I can change the timecondown, to have more time to play and check it, please?

There. The 35 are the 35s you have. Reading the first post would have helped

thanx for that fast sirius answer!

Hi. Can someone help me with adding this minigame before startnig a robbery and when “hacking” was successfull then start robbery but when someone failed hacking then prevent robbery and make shop or bank on cooldown

Awesome script, I am having a bug though where it does not close on a successful hack attempt.

The only thing I did was create a client side LUA with the implementation code you provided and added the it to __resource LUA.

Any help would be greatly appreciated…

Did you rename the resource at all?

That was it, it’s working now, thanks!

[    149359] 
[    149594] nui://mhacking/hack.html:127, Uncaught (in promise) AbortError: The play() request was interrupted by a new load request. https://goo.gl/LdLk22
[    149594] 
[    149656] nui://mhacking/hack.html:127, Uncaught (in promise) AbortError: The play() request was interrupted by a new load request. https://goo.gl/LdLk22
[    149656] 
[    149672] nui://mhacking/hack.html:127, Uncaught (in promise) AbortError: The play() request was interrupted by a new load request. https://goo.gl/LdLk22
[    149672] 
[    150062] nui://mhacking/hack.html:127, Uncaught (in promise) AbortError: The play() request was interrupted by a new load request. https://goo.gl/LdLk22
[    150062] 
[    150140] nui://mhacking/hack.html:127, Uncaught (in promise) AbortError: The play() request was interrupted by a new load request. https://goo.gl/LdLk22
[    150140] 
[    150203] nui://mhacking/hack.html:127, Uncaught (in promise) AbortError: The play() request was interrupted by a new load request. https://goo.gl/LdLk22
[    150203] 
[    150219] nui://mhacking/hack.html:127, Uncaught (in promise) AbortError: The play() request was interrupted by a new load request. https://goo.gl/LdLk22

and now you could create a kind of script like this with what you have … I challenge you :stuck_out_tongue:

When using the seqstart function, if I fail on test 1, it continues the other sequence tests in the background, can still hear the noise. Any solution to what I am missing?

Hi @zr0iq i just write to congratulate you for this great work, i was reading all the html,javascript and lua code, that let me learn how works html resources much better and how integrate it, so thank you for this , the code is so clear, organized, refactorized and good-maked.

I hope you continue making things like this.

  • rep to you.

greetings.

Hello,

Can you help with a little problem…
How would you use your function mycb in a loop ?
Lets say I want to start a bank robbery which take location, name from config files and put it in a loop :

Citizen.CreateThread(function()
	while true do
		Citizen.Wait(1)
		local playerPos = GetEntityCoords(PlayerPedId(), true)

		for k,v in pairs(Banks) do
			local bankPos = v.position
			local distance = Vdist(playerPos.x, playerPos.y, playerPos.z, bankPos.x, bankPos.y, bankPos.z)

			if distance < Config.Marker.DrawDistance then
				if not holdingUpBank then
					DrawMarker(Config.Marker.Type, bankPos.x, bankPos.y, bankPos.z, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, Config.Marker.x, Config.Marker.y, Config.Marker.z, Config.Marker.r, Config.Marker.g, Config.Marker.b, Config.Marker.a, false, false, 2, true, false, false, false)

					if distance < 2 then
						Drawing.draw3DText(bankPos.x, bankPos.y, bankPos.z, _U('press_to_rob', v.nameOfBank), 1, 0.2, 0.1, 255, 255, 255, 215)
						if IsControlJustReleased(0, Keys['E']) then
							if IsPedArmed(PlayerPedId(), 4) then
								TriggerEvent("mhacking:show")
								TriggerEvent("mhacking:start",7,20,mycb)
							else
								ESX.ShowNotification(_U('no_threat'))
							end
						end
					end
				end
			end	
			end

		if holdingUpBank then
			local bankPos = Banks[bank].position
			if Vdist(playerPos.x, playerPos.y, playerPos.z, bankPos.x, bankPos.y, bankPos.z) > Config.MaxDistance then
				TriggerServerEvent('esx_holdupbank:tooFar', bank)
			end
		end
	end
end)

Then after that in mycb function is successfull it start the robby :

function mycb(success, timeremaining)
	if success then
		print('Success with '..timeremaining..'s remaining.')
		TriggerEvent('mhacking:hide')
		TriggerServerEvent('esx_holdupbank:robberyStarted', k)
	else
		print('Failure')
		TriggerEvent('mhacking:hide')
	end
end		

It doesn’t seem to work this way because in mycb the value “k” for the bank is not in the loop anymore so it will select a random bank in the config files even though you are at a different location so it will cancel the bank robbery because of the distance.

Thanks for your time.

Great idea, I’m looking into it

I am having a problem here. When I successfully started sequential hack, it works like I was expecting. But when I purposely do an errors in order to fail, it gives away it’s award anyway… I was trying to use it for esx_atmholdup.

And it doesn’t call reward from server once, but free times! :sweat_smile:

Any ideas how to set it so it won’t give away TriggerServerEvent(‘esx_atmholdup:done’) after messing up the hacking sequence?

function mycb(success, remainingtime, finish)
	if finish then		
		TriggerServerEvent('esx_atmholdup:done')   -- this is called in both success and failure!
		ESX.ShowNotification(_U('paycheck'))
	elseif success then
		ESX.ShowNotification('One firewall breached!')  -- this is called after 
	else
		print('Failure')
	end
end