Skip to content

File BruteForce.cs

File List > LemonUI > LemonUI > Scaleform > BruteForce.cs

Go to the documentation of this file


#if FIVEM
using CitizenFX.Core;
using CitizenFX.Core.Native;
#elif RAGEMP
using RAGE.Game;
#elif RPH
using Rage;
using Rage.Native;
using Control = Rage.GameControl;
#elif ALTV
using AltV.Net.Client;
using LemonUI.Elements;
#elif SHVDN3 || SHVDNC
using GTA;
using GTA.Native;
#endif
using System;
using System.Collections.Generic;

namespace LemonUI.Scaleform
{
    public class BruteForce : BaseScaleform
    {
        #region Fields

        private static readonly Random random = new Random();
        private static readonly Sound soundRowSwitch = new Sound(string.Empty, "HACKING_MOVE_CURSOR");
        private static readonly Sound soundRowCompleted = new Sound(string.Empty, "HACKING_CLICK");
        private static readonly Sound soundRowFailed = new Sound(string.Empty, "HACKING_CLICK_BAD");
        private static readonly Sound soundSuccess = new Sound(string.Empty, "HACKING_SUCCESS");

        private int hideTime = -1;
        private int output = 0;
        private bool firstRun = true;
        private bool inProgress = false;

        private BruteForceBackground background = BruteForceBackground.Black;
        private string word = "LEMONADE";
        private int livesTotal = 5;
        private int livesCurrent = 5;
        private int closeAfter = -1;
        private TimeSpan end = TimeSpan.Zero;
        private TimeSpan countdown = TimeSpan.Zero;
        private bool showLives = true;

        #endregion

        #region Properties

        public string Word
        {
            get => word;
            set
            {
                if (value == null)
                {
                    throw new ArgumentNullException(nameof(value));
                }
                if (value.Length != 8)
                {
                    throw new ArgumentOutOfRangeException(nameof(value), "The word needs to be exactly 8 characters long.");
                }
                word = value;
                CallFunction("SET_ROULETTE_WORD", value);
            }
        }
        public BruteForceBackground Background
        {
            get => background;
            set
            {
                background = value;
                CallFunction("SET_BACKGROUND", (int)value);
            }
        }
        public int TotalLives
        {
            get => livesTotal;
            set
            {
                livesTotal = value;
                if (livesCurrent > value)
                {
                    livesCurrent = value;
                }
                CallFunction("SET_LIVES", livesCurrent, value);
            }
        }
        public int CurrentLives => livesCurrent;
        public List<string> SuccessMessages { get; } = new List<string>();
        public List<string> FailMessages { get; } = new List<string>();
        public int CloseAfter
        {
            get => closeAfter;
            set
            {
                if (value < -1)
                {
                    throw new ArgumentOutOfRangeException(nameof(value), "The Closure time can't be under -1.");
                }
                closeAfter = value;
            }
        }
        public bool CanRetry { get; set; } = false;
        public TimeSpan Countdown
        {
            get => countdown;
            set => countdown = value;
        }
        public bool ShowLives
        {
            get => showLives;
            set
            {
                showLives = value;
                CallFunction("SHOW_LIVES", value);
            }
        }
        public bool ResetOnRowFail { get; set; } = true;

        #endregion

        #region Events

        public event BruteForceFinishedEventHandler HackFinished;

        #endregion

        #region Constructors

        public BruteForce() : base("HACKING_PC")
        {
            Visible = false;
            for (int i = 0; i < 8; i++)
            {
                SetColumnSpeed(i, 100);
            }
        }

        #endregion

        #region Functions

        public void Reset()
        {
            inProgress = true;

            Background = background;
            RunProgram(4);
            RunProgram(83);
            TotalLives = livesTotal;
            Word = word;
            ShowLives = showLives;

#if ALTV
            long time = Alt.Natives.GetGameTimer();
#elif RAGEMP
            long time = Misc.GetGameTimer();
#elif FIVEM || RPH || SHVDN3 || SHVDNC
            long time = Game.GameTime;
#endif

            end = TimeSpan.FromMilliseconds(time) + countdown;
        }
        public void SetColumnSpeed(int index, float speed)
        {
            if (index >= 8 || index < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(index), "The index needs to be between 0 and 7.");
            }
            CallFunction("SET_COLUMN_SPEED", index, speed);
        }
        public void RunProgram(int program)
        {
            CallFunction("RUN_PROGRAM", program);
        }
        public override void Update()
        {
#if ALTV
            long time = Alt.Natives.GetGameTimer();
#elif RAGEMP
            long time = Misc.GetGameTimer();
#elif FIVEM || RPH || SHVDN3 || SHVDNC
            long time = Game.GameTime;
#endif

            // If there is a time set to hide the Hack window
            if (hideTime != -1)
            {
                // If that time has already passed, go ahead and hide the window
                if (hideTime <= time)
                {
                    Visible = false;
                    hideTime = -1;
                    return;
                }
            }

            // If this is the first run and is not in progress, reset it
            if (firstRun && !inProgress)
            {
                firstRun = false;
                Reset();
            }

            // If the hack minigame is not in progress but the player can retry and he pressed enter, reset it
            if (!inProgress && CanRetry && Controls.IsJustPressed(Control.FrontendAccept))
            {
                Reset();
                hideTime = -1;
            }

            // If the Hack minigame is in progress
            if (inProgress)
            {
                // If there is a countdown set
                if (countdown > TimeSpan.Zero)
                {
                    // Calculate the time left
                    TimeSpan span = countdown - (TimeSpan.FromMilliseconds(time) - end);

                    // If is lower or equal than zero, the player failed
                    if (span <= TimeSpan.Zero)
                    {
                        CallFunction("SET_COUNTDOWN", 0, 0, 0);
                        string err = FailMessages.Count == 0 ? string.Empty : FailMessages[random.Next(FailMessages.Count)];
                        CallFunction("SET_ROULETTE_OUTCOME", false, err);
                        hideTime = closeAfter == -1 ? -1 : (int)time + CloseAfter;
                        inProgress = false;
                        HackFinished?.Invoke(this, new BruteForceFinishedEventArgs(BruteForceStatus.OutOfTime));
                        return;
                    }
                    // Otherwise, update the visible time
                    else
                    {
                        CallFunction("SET_COUNTDOWN", span.Minutes, span.Seconds, span.Milliseconds);
                    }
                }

                // If the user pressed left, go to the left
                if (Controls.IsJustPressed(Control.MoveLeftOnly) || Controls.IsJustPressed(Control.FrontendLeft))
                {
                    soundRowSwitch.PlayFrontend();
                    CallFunction("SET_INPUT_EVENT", 10);
                }
                // If the user pressed right, go to the right
                else if (Controls.IsJustPressed(Control.MoveRightOnly) || Controls.IsJustPressed(Control.FrontendRight))
                {
                    soundRowSwitch.PlayFrontend();
                    CallFunction("SET_INPUT_EVENT", 11);
                }
                // If the user pressed accept, send the selection event
                else if (Controls.IsJustPressed(Control.FrontendAccept))
                {
                    output = CallFunctionReturn("SET_INPUT_EVENT_SELECT");
                }

                // If there is some output to receive
                if (output != 0)
                {
                    // If the value is ready, go ahead and check it
                    if (IsValueReady(output))
                    {
                        switch (GetValue<int>(output))
                        {
                            case 86: // Hack Completed
                                string ok = SuccessMessages.Count == 0 ? string.Empty : SuccessMessages[random.Next(SuccessMessages.Count)];
                                CallFunction("SET_ROULETTE_OUTCOME", true, ok);
                                soundSuccess.PlayFrontend();
                                HackFinished?.Invoke(this, new BruteForceFinishedEventArgs(BruteForceStatus.Completed));
                                hideTime = closeAfter == -1 ? -1 : (int)time + CloseAfter;
                                inProgress = false;
                                break;
                            case 87: // Row Failed (or lives failed)
                                livesCurrent--;
                                CallFunction("SET_LIVES", livesCurrent, livesTotal);
                                soundRowFailed.PlayFrontend();
                                if (livesCurrent <= 0)
                                {
                                    string err = FailMessages.Count == 0 ? string.Empty : FailMessages[random.Next(FailMessages.Count)];
                                    CallFunction("SET_ROULETTE_OUTCOME", false, err);
                                    hideTime = closeAfter == -1 ? -1 : (int)time + CloseAfter;
                                    inProgress = false;
                                    HackFinished?.Invoke(this, new BruteForceFinishedEventArgs(BruteForceStatus.OutOfLives));
                                }
                                break;
                            case 92: // Row Completed
                                soundRowCompleted.PlayFrontend();
                                break;
                        }
                        output = 0;
                    }
                }
            }
        }

        #endregion
    }
}