💻Installation

This guide provides instructions for installing the Rep-Weed item pack on your QBCore-based FiveM server using either the LJ/QB or Ox inventory system.

Installation Steps

Token verification

Go to: server\citizen\scripting\lua\scheduler.lua

Find:

local eventHandlers = {}

IMPORTANT: Replace it so it looks like this

function verifyToken(playerSrc, token)
    local p = promise.new()
    TriggerEvent('hotp:verifyToken', playerSrc, token, function(result)
        p:resolve(result)
    end)
    return Citizen.Await(p)
end

local eventHandlers = {}
local deserializingNetEvent = false
local table_remove = table.remove
local whitelistEvents = {
    ['fivem-appearance:server:GetPlayerAces'] = true,
    ['hardcap:playerActivated'] = true,
    ['txsv:checkAdminStatus'] = true,
    ['txaLogger:DeathNotice'] = true,
    ['txAdmin:menu:playerModeChanged'] = true,
    ['txAdmin:menu:tpToWaypoint'] = true,
    ['txAdmin:menu:tpToCoords'] = true,
    ['baseevents:onPlayerDied'] = true,
}

Modify Citizen.SetEventRoutine function

Go to: server\citizen\scripting\lua\scheduler.lua

  1. Look for

citizen\scripting\lua\scheduler.lua
Citizen.SetEventRoutine(function(eventName, eventPayload, eventSource)
  1. Replace the WHOLE FUNCTION with:

Citizen.SetEventRoutine(function(eventName, eventPayload, eventSource)
    -- set the event source
    local lastSource = _G.source
    _G.source = eventSource

    -- try finding an event handler for the event
    local eventHandlerEntry = eventHandlers[eventName]

    -- deserialize the event structure (so that we end up adding references to delete later on)
    local data = msgpack_unpack(eventPayload)
    local isNet = false

    if eventHandlerEntry and eventHandlerEntry.handlers then
        -- if this is a net event and we don't allow this event to be triggered from the network, return
        if eventSource:sub(1, 3) == 'net' then
               isNet = true
            if not eventHandlerEntry.safeForNet then
                Citizen.Trace('event ' .. eventName .. " was not safe for net\n")

                _G.source = lastSource
                return
            end

            deserializingNetEvent = {
                source = eventSource
            }
            _G.source = tonumber(eventSource:sub(5))
            --[[ if not data then
                data = {}
            end ]]

        elseif isDuplicityVersion and eventSource:sub(1, 12) == 'internal-net' then
            deserializingNetEvent = {
                source = eventSource:sub(10)
            }
            _G.source = tonumber(eventSource:sub(14))
        end

        -- return an empty table if the data is nil
        if not data then
            data = {}
        end

        -- reset serialization
        deserializingNetEvent = nil

        -- if this is a table...
        if type(data) == 'table' then
            -- loop through all the event handlers
            for k, handler in pairs(eventHandlerEntry.handlers) do
                local handlerFn = handler
                local handlerMT = getmetatable(handlerFn)

                if handlerMT and handlerMT.__call then
                    handlerFn = handlerMT.__call
                end

                if type(handlerFn) == 'function' then
                    local di = debug_getinfo(handlerFn)

                    Citizen.CreateThreadNow(function()
                        if isNet then
                            if not whitelistEvents[eventName] then
                                local otp = data[1]
                                if otp and type(otp) == 'table' and otp.token then
                                    if verifyToken(_G.source, otp) then
                                        print('^2ACP', _G.source, eventName, json.encode(otp), '^0')
                                        table_remove(data, 1)
                                    else
                                        print('^1DENY', _G.source, eventName, json.encode(otp), '^0')
                                        return
                                    end
                                else
                                    print('^1DENY', _G.source, eventName, '^0')
                                    return
                                end
                            end
                        end
                        handler(table_unpack(data))
                    end, ('event %s [%s[%d..%d]]'):format(eventName, di.short_src, di.linedefined, di.lastlinedefined))
                end
            end
        end
    end

    _G.source = lastSource
end)

Adding HOTP to your scripts

Important: Repeat the following steps for EACH resource you want to protect using HOTP

  1. Locate the fxmanifest.lua file of your FiveM resource.

  2. Inside the file, find the client_scripts section.

  3. Add '@hotp/build/client/token.lua' to the client_scripts section. Your updated code should look like this:

client_scripts {
    '@hotp/build/client/token.lua',
    'client/*.lua'
}

This addition ensures that the essential token.lua file is included in the client-side scripts. This file handles tasks related to tokens, such as authentication and other functionalities

  1. Ensure that the script requires Lua version 54 by adding the following line:

lua54 'yes'

This line notifies FiveM that the resource relies on compatibility with Lua version 54.

  1. Save the fxmanifest.lua file after incorporating these changes.

By following these steps, HOTP will be successfully integrated into your script. If you encounter any difficulties or have further inquiries, don't hesitate to seek assistance.

Example

fx_version 'cerulean'
game 'gta5'

name "Rep Scripts - PostOp ver Tablet"
author "Q4D"
version "1.0.0"

server_scripts {
    'server/main.lua',
    'server/express.lua',
    'server/prime.lua',
    'server/freight.lua',
    'server/function.lua',
}

shared_scripts {
    '@ox_lib/init.lua',
    'config.lua'
}

client_scripts {
    '@hotp/build/client/token.lua',
	'client/*.lua'
}

lua54 'yes'

Last updated