Editable Files

Client

local tgiann_clothing = GetResourceState("tgiann-clothing") ~= "missing"
local esx_skin = GetResourceState("esx_skin") ~= "missing"
local illenium_appearance = GetResourceState("illenium-appearance") ~= "missing"

---@param veh number
function giveVehicleKey(veh)
    --local plate = GetVehicleNumberPlateText(veh)
    debug(("GIVING KEY TO VEHICLE %s"):format(veh))
    tgiCore.GiveVehicleKey(veh, false)
end

---@param card table config.hacking.levels[index]
function policeAlert(card)
    TriggerServerEvent('police:server:policeAlert', 'Credi Card Hacking')
end

---@return number
function getPoliceCount()
    return exports["tgiann-core"]:getPoliceCount()
end

---@param active boolean
function changeClothe(active)
    if not config.job.clothe.active then return end
    if active then
        local clotheData = GetEntityModel(PlayerPedId()) == 1885233650 and config.job.clothe.male or config.job.clothe.female
        if tgiann_clothing then
            TriggerEvent("tgiann-clothing:changeScriptClothe", clotheData)
        else
            local newList = {}
            for i = 1, #clotheData do
                local data = clotheData[i]
                local mainTag = data.isProp and "p" or "c"
                if not newList[mainTag .. data.componentId] then
                    newList[mainTag .. data.componentId] = {
                        componentId = data.componentId,
                        isProp = data.isProp
                    }
                end
                if string.find(data.name, "_2") then
                    newList[mainTag .. data.componentId].textureId = data.val
                else
                    newList[mainTag .. data.componentId].drawableId = data.val
                end
            end

            for _, value in pairs(newList) do
                if value.isProp then
                    SetPedPropIndex(PlayerPedId(), value.componentId, value.drawableId, value.textureId or 0, 2)
                else
                    SetPedComponentVariation(PlayerPedId(), value.componentId, value.drawableId, value.textureId or 0, 2)
                end
            end
        end
    else
        if tgiann_clothing then
            TriggerEvent("tgiann-clothing:changeScriptClothe")
        elseif illenium_appearance then
            TriggerEvent("illenium-appearance:client:reloadSkin")
        elseif esx_skin then
            tgiCore.core.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin)
                TriggerEvent('skinchanger:loadSkin', skin)
            end)
        elseif config.framework == "qb" then
            TriggerServerEvent("qb-clothes:loadPlayerSkin")
            TriggerServerEvent("qb-clothing:loadPlayerSkin")
            TriggerEvent("qb-radialmenu:ResetClothing")
        else
            TriggerEvent("fivem-appearance:client:reloadSkin")
        end
    end
end

Server

---@return string
function createIban()
    local iban = ("00000074%s%s%s"):format(math.random(1000, 9999), math.random(1000, 9999), math.random(1000, 9999))
    if getAccount(iban) then return createIban() end
    return iban
end

---@param src number
---@param webhook "banLog" | "depositLog" | "withdrawLog" | "transferLog"
---@param msg string
function log(src, webhook, msg)
    TriggerEvent("tgiann-core:discordLog", webhooks[webhook], msg, src)
end

---@param src number
---@param msg string
function kickHacker(src, msg)
    local playerName = GetPlayerName(src) or "Unknown Player Name"
    msg = msg or "Unknown Reason"
    tgiCore.DebugErrorLog("^1[ANTICHEAT] ^0 [ " .. src .. " ]" .. playerName .. " | " .. msg)
    log(src, "banLog", msg)
    DropPlayer(src, "Hacker Detected", "Hacker Detected")
end

---@param citizenid string
---@return number
function getPlayerBankMoney(citizenid)
    local xPlayer = tgiCore.getPlayerById(citizenid)
    if xPlayer then return tgiCore.getMoney(xPlayer, "bank") end

    if config.framework == "esx" then
        local row = MySQL.single.await('SELECT `accounts` FROM `users` WHERE `identifier` = ? LIMIT 1', {
            citizenid
        })
        local accounts = json.decode(row?.accounts)
        return accounts?.bank or 0
    else
        local row = MySQL.single.await('SELECT `money` FROM `players` WHERE `citizenid` = ? LIMIT 1', {
            citizenid
        })
        local money = json.decode(row?.money)
        return money?.bank or 0
    end
end

---@param citizenid string
---@param moneyType string
---@return boolean, number
function removePlayerMoney(citizenid, moneyType, amount)
    local xPlayer = tgiCore.getPlayerById(citizenid)
    if xPlayer then
        local playerMoney = tgiCore.getMoney(xPlayer, moneyType)
        if playerMoney < amount then return false end
        local success = tgiCore.removeMoney(xPlayer, moneyType, amount)
        if not success then return false end
        return true, playerMoney - amount
    else
        if config.framework == "qb" then
            local result = MySQL.single.await("SELECT money FROM players WHERE citizenid = ?", { citizenid })
            if result then
                local moneyData = json.decode(result.money)
                if moneyData.bank < amount then return false end
                moneyData.bank = moneyData.bank - amount
                MySQL.update("UPDATE players SET money = ? WHERE citizenid = ?", { json.encode(moneyData), citizenid })
                return true, moneyData.bank
            end
        elseif config.framework == "esx" then
            local result = MySQL.single.await("SELECT accounts FROM users WHERE identifier = ?", { citizenid })
            if result then
                local moneyData = json.decode(result.accounts)
                if moneyData.bank < amount then return false end
                moneyData.bank = moneyData.bank - amount
                MySQL.update("UPDATE users SET accounts = ? WHERE identifier = ?", { json.encode(moneyData), citizenid })
                return true, moneyData.bank
            end
        end
        return false
    end
end

---@param citizenid string
---@param moneyType string
---@param amount number
---@return number
function addPlayerMoney(citizenid, moneyType, amount)
    local xPlayer = tgiCore.getPlayerById(citizenid)
    if xPlayer then
        local playerMoney = tgiCore.getMoney(xPlayer, moneyType)
        tgiCore.addMoney(xPlayer, moneyType, amount)
        return playerMoney + amount
    else
        if config.framework == "qb" then
            local result = MySQL.single.await("SELECT money FROM players WHERE citizenid = ?", { citizenid })
            if result then
                local moneyData = json.decode(result.money)
                moneyData.bank = moneyData.bank + amount
                MySQL.update("UPDATE players SET money = ? WHERE citizenid = ?", { json.encode(moneyData), citizenid })
                return moneyData.bank
            end
        elseif config.framework == "esx" then
            local result = MySQL.single.await("SELECT accounts FROM users WHERE identifier = ?", { citizenid })
            if result then
                local moneyData = json.decode(result.accounts)
                moneyData.bank = moneyData.bank + amount
                MySQL.update("UPDATE users SET accounts = ? WHERE identifier = ?", { json.encode(moneyData), citizenid })
                return moneyData.bank
            end
        end
    end
    return false
end

---@param citizenid string
---@return string
function getPlayerName(citizenid)
    if config.framework == "esx" then
        local row = MySQL.single.await('SELECT `firstname`, `lastname` FROM `users` WHERE `identifier` = ? LIMIT 1', { citizenid })
        if not row then return "USER_NOT_FOUND" end
        return ("%s %s"):format(row.firstname, row.lastname)
    else
        local row = MySQL.single.await('SELECT `charinfo` FROM `players` WHERE `citizenid` = ? LIMIT 1', { citizenid })
        if not row then return "USER_NOT_FOUND" end
        local charinfo = json.decode(row.charinfo)
        return ("%s %s"):format(charinfo.firstname, charinfo.lastname)
    end
end

---The amount of government tax withheld when a player deposits or withdraws money
---@param amount number
function addGovernmentTax(amount)
    -- Your code here
    -- exports["myCustomGovernmentTaxScript"]:addTax(amount) -- Example
end

---@param src number
---@return { name: string; iban: string, id: number}[]
function getPlayerFriends(src)
    if config.phoneScripts.lbPhone then
        local phoneNumber = exports["lb-phone"]:GetEquippedPhoneNumber(src)
        local response = MySQL.query.await('SELECT pp.owner_id FROM phone_phone_contacts ppc JOIN phone_phones pp ON ppc.contact_phone_number = pp.phone_number WHERE ppc.phone_number = ?', {
            phoneNumber
        })

        local newList = {}
        for i = 1, #response do
            local playerAccount = getPlayerAccountsFromCitizenid(response[i].owner_id)
            if playerAccount then
                local playerAccountList = playerAccount.Functions.GetOwnedAccounts()
                for p = 1, #playerAccountList do
                    local index = #newList + 1
                    newList[index] = {
                        name = playerAccount.name,
                        iban = playerAccountList[p].iban,
                        id = index
                    }
                end
            end
        end

        return newList
    elseif config.phoneScripts.tgiannPhone then
        local xPlayer = tgiCore.getPlayer(src)
        if not xPlayer then return {} end
        local response = MySQL.query.await('SELECT p.citizenid FROM tgiann_phone_contacts c JOIN tgiann_phone_players p ON c.number = p.number WHERE c.citizenid = ?', {
            tgiCore.getCid(xPlayer)
        })

        local newList = {}
        for i = 1, #response do
            local playerAccount = getPlayerAccountsFromCitizenid(response[i].citizenid)
            if playerAccount then
                local playerAccountList = playerAccount.Functions.GetOwnedAccounts()
                for p = 1, #playerAccountList do
                    local index = #newList + 1
                    newList[index] = {
                        name = playerAccount.name,
                        iban = playerAccountList[p].iban,
                        id = index
                    }
                end
            end
        end

        return newList
    elseif config.phoneScripts.qbPhone then
        local xPlayer = tgiCore.getPlayer(src)
        if not xPlayer then return {} end
        local response = MySQL.query.await("SELECT p.citizenid FROM player_contacts pc JOIN players p ON p.charinfo LIKE CONCAT('%phone%', pc.number, '%') WHERE pc.citizenid = ?", {
            tgiCore.getCid(xPlayer)
        })

        local newList = {}
        for i = 1, #response do
            local playerAccount = getPlayerAccountsFromCitizenid(response[i].citizenid)
            if playerAccount then
                local playerAccountList = playerAccount.Functions.GetOwnedAccounts()
                for p = 1, #playerAccountList do
                    local index = #newList + 1
                    newList[index] = {
                        name = playerAccount.name,
                        iban = playerAccountList[p].iban,
                        id = index
                    }
                end
            end
        end

        return newList
    end


    return {}
end

---@return boolean
function gangAccountActive()
    return config.framework == "qb"
end

---@param citizenid string
---@return string, number
function getPlayerJobData(citizenid)
    local xPlayer = tgiCore.getPlayerById(citizenid)
    if not xPlayer then return "unknown", -1 end
    local job = tgiCore.getJob(xPlayer)
    local grade = config.framework == "esx" and tonumber(job.grade) or tonumber(job.grade.level)
    return job.name, grade
end

---@param citizenid string
---@return string, number
function getPlayerGangData(citizenid)
    if not gangAccountActive() then return "unknown", -1 end
    local xPlayer = tgiCore.getPlayerById(citizenid)
    if not xPlayer then return "unknown", -1 end
    local gang = xPlayer.PlayerData.gang
    local grade = gang.grade.level
    return job.name, grade
end

Last updated