Page cover

keyboardOpen Files Preview

Here you can see the open files of the reports

chevron-rightconfig/config.luahashtag
Config = {}
Locales = {} -- Dont touch this

Config.Framework = 'ESX' -- 'ESX' or 'QBCORE'

Config.Locale = 'en' -- 'nl' or 'en'

Config.title = { normal = 'Nova', bold = 'Reports' } -- The title of the reports

Config.DarkColors = { -- Dark colors for the UI
    mainColor = "#7c3aed",
    hoverColor = "#6d28d9",
    backgroundColor = "#2e1065",
    borderColor = "#4c1d95",
    textColor = "#ffffff",
}

Config.LightColors = { -- Light colors for the UI
    mainColor = "#8b5cf6",
    hoverColor = "#7c3aed",
    backgroundColor = "#faf5ff",
    borderColor = "#8b5cf6",
    textColor = "#2e1065",
}

Config.AdminGroups = { -- The admins that can interact with the reports
    ['beheer'] = true,
    ['h.development'] = true,
    ['management'] = true,
    ['hoofdstaff'] = true,
    ['admin'] = true,
    ['moderator'] = true
}

Config.AllowedToDeleteGroups = { -- Groups that are allowed to delete reports
    ['beheer'] = true,
    ['h.development'] = true,
    ['management'] = true,
    ['hoofdstaff'] = true,
}

Config.ReportCreationCooldown = 30 -- Seconds

Config.MaxReports = 5 -- Max reports per player

Config.reportCategories = { -- The categories of the reports
    ['bug'] = 'Bug',
    ['complaint'] = 'Complaint',
    ['cheater'] = 'Cheater',
    ['question'] = 'Question',
    --['other'] = 'Other'
}

Config.FastReplys = { -- The fast replies for the reports
    {
        label = 'Hello',
        icon = "fas fa-handshake",
        message = 'Hello, how can I help you?'
    },
    {
        label = "One moment",
        icon = "fas fa-clock",
        message = "One moment, I'll look into it for you."
    },
    {
        label = "Create Ticket",
        icon = "fas fa-ticket-alt",
        message = "For this you will need to create a ticket in our support discord"
    },
    {
        label = "Check",
        icon = "fas fa-check",
        message = "I will check it."
    }
}

Config.AdminActions = { -- The admin actions that can be used
    {
        label = "Teleport To Player",
        event = "nv-reports:admin:teleportToPlayer",
        icon = "fas fa-people-arrows",
        requireConfirmation = true,
    },
    {
        label = "Bring Player",
        event = "nv-reports:admin:bringPlayer",
        icon = "fas fa-people-arrows",
        requireConfirmation = true,
    },
    {
        label = "Teleport Player To Location",
        event = "nv-reports:admin:teleportToLocation",
        icon = "fas fa-map-marker-alt",
        requireConfirmation = true,
        input = {
            type = 'select',
            title = "Select A Location",
            options = {
                { value = "blokkenpark", label = "Legion Square", coords = { x = 109.3393, y = -1088.2065, z = 29.3024, h = 343.0009 } },
                { value = "ziekenhuis", label = "Hospital", coords = { x = 299.5536, y = -580.3079, z = 43.2608, h = 64.6709 } },
                { value = "ziekenhuissandy", label = "Hospital Sandy", coords = { x = 1836.9712, y = 3671.7156, z = 34.2767, h = 209.6275 } },
                { value = "gemeentehuis", label = "Jobscenter", coords = { x = -262.1410, y = -975.3860, z = 31.2196, h = 247.8737 } },
                { value = "politiehq", label = "Police HQ", coords = { x = -1111.3109, y = -821.4714, z = 19.3160, h = 36.4947 } },
                { value = "cardealer", label = "Car Dealer", coords = { x = -37.5267, y = -1114.7413, z = 26.4366, h = 65.5317 } }
            }            
        }
    },
    {
        label = "Give Money",
        event = "nv-reports:admin:giveMoney",
        icon = "fas fa-money-bill",
        requireConfirmation = true,
        input = {
            type = 'number',
            title = "Give Money",
            placeholder = "Amount",
            default = 1000
        },
        permissions = {
            ['beheer'] = true,
            ['management'] = true,
            ['hoofdstaff'] = true,
        }
    },
    {
        label = "Remove Money",
        event = "nv-reports:admin:removeMoney",
        icon = "fas fa-money-bill",
        requireConfirmation = true,
        input = {
            type = 'number',
            title = "Remove Money",
            placeholder = "Amount",
            default = 1000
        },
        permissions = {
            ['beheer'] = true,
            ['management'] = true,
            ['hoofdstaff'] = true,
        }
    },
    {
        label = "Give Item",
        event = "nv-reports:admin:giveItem",
        icon = "fas fa-box",
        requireConfirmation = true,
        input = {
            type = 'multi',
            title = "Give Item",
            fields = {
                {
                    type = 'text',
                    label = 'Item Name',
                    placeholder = 'water',
                    required = true
                },
                {
                    type = 'number',
                    label = 'Amount',
                    placeholder = '5',
                    default = 1,
                    min = 1,
                    required = true
                }
            }
        },
        permissions = {
            ['beheer'] = true,
            ['management'] = true,
            ['hoofdstaff'] = true,
        }
    },
    {
        label = "Remove Item",
        event = "nv-reports:admin:removeItem",
        icon = "fas fa-trash",
        requireConfirmation = true,
        input = {
            type = 'multi',
            title = "Remove Item",
            fields = {
                {
                    type = 'text',
                    label = 'Item Name',
                    placeholder = 'water',
                    required = true
                },
                {
                    type = 'number',
                    label = 'Amount',
                    placeholder = '5',
                    default = 1,
                    min = 1,
                    required = true
                }
            }
        },
        permissions = {
            ['beheer'] = true,
            ['management'] = true,
            ['hoofdstaff'] = true,
        }
    },
    {
        label = "Clear Inventory",
        event = "nv-reports:admin:clearInventory",
        icon = "fas fa-trash-alt",
        requireConfirmation = true,
    },
    {
        label = "Player Size",
        event = "nv-reports:admin:setPlayerSize",
        icon = "fas fa-arrows-alt-v",
        requireConfirmation = true,
        input = {
            type = 'select',
            title = "Player Size",
            placeholder = "Select Size",
            options = {
                { value = "small", label = "Small" },
                { value = "normal", label = "Normal" }
            },
            required = true
        },
    },
    {
        label = "Set Job",
        event = "nv-reports:admin:setJob",
        icon = "fas fa-briefcase",
        requireConfirmation = true,
        input = {
            type = 'multi',
            title = "Set Job",
            fields = {
                {
                    type = 'text',
                    label = 'Job Name',
                    placeholder = 'unemployed',
                    required = true
                },
                {
                    type = 'number',
                    label = 'Grade',
                    placeholder = '0',
                    default = 0,
                    min = 0,
                    required = true
                }
            }
        },
        permissions = {
            ['beheer'] = true,
            ['management'] = true,
            ['hoofdstaff'] = true,
        }
    },
    {
        label = "Set Group",
        event = "nv-reports:admin:setGroup",
        icon = "fas fa-users",
        requireConfirmation = true,
        input = {
            type = 'select',
            title = "Set Group",
            placeholder = "Select Group",
            options = {
                { value = "user", label = "User" },
                { value = "jr.moderator", label = "Jr. Moderator" },
                { value = "moderator", label = "Moderator" },
                { value = "sr.moderator", label = "Sr. Moderator" },
                { value = "jr.admin", label = "Jr. Admin" },
                { value = "admin", label = "Admin" },
                { value = "sr.admin", label = "Sr. Admin" },
                { value = "hoofdstaff", label = "Hoofdstaff" },
                { value = "jr.management", label = "Jr. Management" },
                { value = "management", label = "Management" },
                { value = "beheer", label = "Beheer" }
            },
            required = true
        },
        permissions = {
            ['beheer'] = true,
            ['h.development'] = true,
            ['admin'] = true
        }
    },
    {
        label = "Fix Vehicle",
        event = "nv-reports:admin:fixVehicle",
        icon = "fas fa-wrench",
        requireConfirmation = true,
        permissions = {
            ['beheer'] = true,
            ['management'] = true,
            ['hoofdstaff'] = true,
            ['admin'] = true
        }
    },
    {
        label = "Heal Player",
        event = "nv-reports:admin:healPlayer",
        icon = "fas fa-heart",
        requireConfirmation = true,
    },
    {
        label = "Kill Player",
        event = "nv-reports:admin:killPlayer",
        icon = "fas fa-skull",
        requireConfirmation = true,
    },
    {
        label = "Freeze Player",
        event = "nv-reports:admin:freezePlayer",
        icon = "fas fa-snowflake",
        requireConfirmation = true,
    },
    {
        label = "Unfreeze Player",
        event = "nv-reports:admin:unfreezePlayer",
        icon = "fas fa-sun",
        requireConfirmation = true,
    },
}
chevron-rightconfig/webhook.luahashtag
Webhook = {
    ["report-creation"] = "https://discord.com/api/webhooks/", -- Report creation log
    ["report-claimed"] = "https://discord.com/api/webhooks/", -- Report claimed log
    ["report-closed"] = "https://discord.com/api/webhooks/", -- Report closed log
    ["report-deleted"] = "https://discord.com/api/webhooks/", -- Report deleted log
    ["admin-actions"] = "https://discord.com/api/webhooks/", -- Admin actions log
    ["cheater"] = "https://discord.com/api/webhooks/", -- Cheater log
    ["error"] = "https://discord.com/api/webhooks/", -- Error log for things like missing eventNames
    ["screenshotStorage"] = "https://discord.com/api/webhooks/" -- Where the screenshots are stored
}

Webhook.EnableLogs = false -- Enable logs
chevron-rightclient/handler/actions.luahashtag
RegisterNetEvent('nv-reports:client:fixVehicle', function()
    local playerPed = PlayerPedId()
    local vehicle = GetVehiclePedIsIn(playerPed, false)
    
    if vehicle == 0 then
        return
    end

    SetVehicleUndriveable(vehicle, false)
    SetVehicleEngineOn(vehicle, true, true)
    SetVehicleEngineHealth(vehicle, 1000.0)
    SetVehicleBodyHealth(vehicle, 1000.0)
    SetVehicleFixed(vehicle)
end)

RegisterNetEvent('nv-reports:client:healPlayer', function()
    local playerPed = PlayerPedId()
   
    SetEntityHealth(playerPed, GetEntityMaxHealth(playerPed))
    ClearPedBloodDamage(playerPed)
    ResetPedVisibleDamage(playerPed)
    ClearPedLastWeaponDamage(playerPed)
end)

RegisterNetEvent('nv-reports:client:killPlayer', function()
    local playerPed = PlayerPedId()
  
    SetEntityHealth(playerPed, 0)
end)

RegisterNetEvent('nv-reports:client:freezePlayer', function(freeze)
    local playerPed = PlayerPedId()
    
    if freeze then
        FreezeEntityPosition(playerPed, true)
    else
        FreezeEntityPosition(playerPed, false)
    end
end)

RegisterNetEvent('nv-reports:client:setPlayerSize', function(size)
    local playerPed = PlayerPedId()
    
    if size == "small" then
        SetPedConfigFlag(playerPed, 223, true)
    elseif size == "normal" then
        SetPedConfigFlag(playerPed, 223, false)
    end
end)
chevron-rightclient/handler/utils.luahashtag
ReportsNotify = function(message)
    lib.notify({
        title = 'Reports',
        description = message,
        duration = 3000,
        position = 'top-right',
        style = {
            backgroundColor = '#141517',
            color = '#C1C2C5',
            ['.description'] = {
                color = '#909296'
            }
        },
        icon = 'fas fa-book',
        iconColor = '#ffa500'
    })
end
chevron-rightserver/handler/actions.luahashtag
RegisterNetEvent('nv-reports:admin:teleportToPlayer', function(adminSource, reportId)
    local xPlayer = GETPFI(adminSource)

    local actionConfig = getActionConfig('nv-reports:admin:teleportToPlayer')
    if not hasPermission(xPlayer.group, actionConfig and actionConfig.permissions) then
        SendLogToDiscord(Webhook.cheater, "Report System (Cheater)", "Unauthorized teleportToPlayer attempt by id: ".. adminSource .. " - " .. (xPlayer and GetPlayerName(adminSource) or "unknown player"), adminSource, 15158332)
        return
    end

        if not xPlayer or not Config.AdminGroups[xPlayer.group] then
            SendLogToDiscord(Webhook.cheater, "Report System (Cheater)", "Unauthorized admin action attempt by id: ".. adminSource .. " - " .. (xPlayer and GetPlayerName(adminSource) or "unknown player"), adminSource, 15158332)
        return
    end

    local report = GetReportDetails(reportId)

    if report and report[1] and report[1].player_id then
        local targetIdentifier = report[1].player_id
        local targetPlayer = GetPlayerFromIdentifier(targetIdentifier)
        
        if targetPlayer then
            local targetPed = GetPlayerPed(targetPlayer.source)
            local adminPed = GetPlayerPed(adminSource)
            local targetCoords = GetEntityCoords(targetPed)
            
            SetEntityCoords(adminPed, targetCoords.x, targetCoords.y, targetCoords.z, false, false, false, true)
            
            local logMessage = string.format(
                "## **Admin Action: Teleport to Player**\n" ..
                "**Admin:** %s (%s)\n" ..
                "**Report ID:** %s\n" ..
                "**Player:** %s (%s)\n" ..
                "**Action:** Admin teleported to player\n" ..
                "**Location:** %.2f, %.2f, %.2f",
                GetPlayerName(adminSource),
                adminSource,
                reportId,
                GetPlayerName(targetPlayer.source),
                targetPlayer.source,
                targetCoords.x,
                targetCoords.y,
                targetCoords.z
            )
            
            SendLogToDiscord(Webhook["admin-actions"], "Report System", logMessage, adminSource, 16776960)

            ReportsNotify(adminSource, 'You have been teleported to the player.')
            ReportsNotify(targetPlayer.source, 'A staff member has teleported to you.')
        else
            ReportsNotify(adminSource, 'Could not find the player. Is the player online?')

        end
    else
        ReportsNotify(adminSource, 'Could not find the report.')
    end
end)

RegisterNetEvent('nv-reports:admin:bringPlayer', function(adminSource, reportId)
    local xPlayer = GETPFI(adminSource)

    local actionConfig = getActionConfig('nv-reports:admin:bringPlayer')
    if not hasPermission(xPlayer.group, actionConfig and actionConfig.permissions) then
        SendLogToDiscord(Webhook.cheater, "Report System (Cheater)", "Unauthorized bringPlayer attempt by id: ".. adminSource .. " - " .. (xPlayer and GetPlayerName(adminSource) or "unknown player"), adminSource, 15158332)
        return
    end

    if not xPlayer or not Config.AdminGroups[xPlayer.group] then
        SendLogToDiscord(Webhook.cheater, "Report System (Cheater)", "Unauthorized admin action attempt by id: ".. adminSource .. " - " .. (xPlayer and GetPlayerName(adminSource) or "unknown player"), adminSource, 15158332)
        return
    end

    local report = GetReportDetails(reportId)

    if report and report[1] and report[1].player_id then
        local targetIdentifier = report[1].player_id
        local targetPlayer = GetPlayerFromIdentifier(targetIdentifier)

        if targetPlayer then
            local adminPed = GetPlayerPed(adminSource)
            local targetPed = GetPlayerPed(targetPlayer.source)
            local adminCoords = GetEntityCoords(adminPed)

            SetEntityCoords(targetPed, adminCoords.x, adminCoords.y, adminCoords.z, false, false, false, true)
            
            local logMessage = string.format(
                "## **Admin Action: Bring Player**\n" ..
                "**Admin:** %s (%s)\n" ..
                "**Report ID:** %s\n" ..
                "**Player:** %s (%s)\n" ..
                "**Action:** Player brought to admin\n" ..
                "**Location:** %.2f, %.2f, %.2f",
                GetPlayerName(adminSource),
                adminSource,
                reportId,
                GetPlayerName(targetPlayer.source),
                targetPlayer.source,
                adminCoords.x,
                adminCoords.y,
                adminCoords.z
            )
            
            SendLogToDiscord(Webhook["admin-actions"], "Report System", logMessage, adminSource, 16776960)
            
            ReportsNotify(adminSource, 'Player has been brought to you.')
            ReportsNotify(targetPlayer.source, 'You have been brought by an admin.')
        end
    else
        ReportsNotify(adminSource, 'Could not find the report.')
    end
end) 

RegisterNetEvent('nv-reports:admin:teleportToLocation', function(source, reportId, input)
    local admin = source
    local xAdmin = GETPFI(admin)

    if not xAdmin or not Config.AdminGroups[xAdmin.group] then
        SendLogToDiscord(Webhook.cheater, "Report System (Cheater)", "Unauthorized teleport attempt by id: ".. adminSource .. " - " .. (xAdmin and GetPlayerName(adminSource) or "unknown player"), adminSource, 15158332)
        return
    end

    local report = GetReportDetails(reportId)
    if not report or not report[1] then return end
    
    local targetPlayer = GetPlayerFromIdentifier(report[1].player_id)
    if not targetPlayer then
        xAdmin.showNotification("The player of this report is not online.", 'error')
        return
    end

    local coords = input.coords
    if not coords or not coords.x then
        SendLogToDiscord(Webhook.error, "Report System (Error)", "Invalid coordinates received for teleport: " .. json.encode(input), source, 15158332)
        xAdmin.showNotification("Invalid coordinates received, please report this to your developer.", 'error')
        return
    end

        local targetPed = GetPlayerPed(targetPlayer.source)
        SetEntityCoords(targetPed, coords.x, coords.y, coords.z)

    if coords.h then
        SetEntityHeading(targetPed, coords.h)
    end
    
    local logMessage = string.format(
        "## **Admin Action: Teleport to Location**\n" ..
        "**Admin:** %s (%s)\n" ..
        "**Report ID:** %s\n" ..
        "**Player:** %s (%s)\n" ..
        "**Action:** Player teleported to location\n" ..
        "**Location:** %s\n" ..
        "**Coordinates:** %.2f, %.2f, %.2f%s",
        GetPlayerName(admin),
        admin,
        reportId,
        GetPlayerName(targetPlayer.source),
        targetPlayer.source,
        input.label or 'Unknown location',
        coords.x,
        coords.y,
            coords.z,
        coords.h and string.format(", Heading: %.2f", coords.h) or ""
    )
    
    local xAdmin = GETPFI(admin)

    if not xAdmin or not Config.AdminGroups[xAdmin.group] then
        SendLogToDiscord(Webhook.cheater, "Report System (Cheater)", "Unauthorized teleport attempt by id: ".. adminSource .. " - " .. (xAdmin and GetPlayerName(adminSource) or "unknown player"), adminSource, 15158332)
        return
    end

    local report = GetReportDetails(reportId)
    if not report or not report[1] then return end
    
    local targetPlayer = GetPlayerFromIdentifier(report[1].player_id)
    if not targetPlayer then
        xAdmin.showNotification("The player of this report is not online.", 'error')
        return
    end

    local coords = input.coords
    if not coords or not coords.x then
        SendLogToDiscord(Webhook.error, "Report System (Error)", "Invalid coordinates received for teleport: " .. json.encode(input), source, 15158332)
        xAdmin.showNotification("Invalid coordinates received, please report this to your developer.", 'error')
        return
    end

    local targetPed = GetPlayerPed(targetPlayer.source)
    SetEntityCoords(targetPed, coords.x, coords.y, coords.z)

    if coords.h then
        SetEntityHeading(targetPed, coords.h)
    end
    
    local logMessage = string.format(
        "## **Admin Action: Teleport to Location**\n" ..
        "**Admin:** %s (%s)\n" ..
        "**Report ID:** %s\n" ..
        "**Player:** %s (%s)\n" ..
        "**Action:** Player teleported to location\n" ..
        "**Location:** %s\n" ..
        "**Coordinates:** %.2f, %.2f, %.2f%s",
        GetPlayerName(admin),
        admin,
        reportId,
        GetPlayerName(targetPlayer.source),
        targetPlayer.source,
        input.label or 'Unknown location',
        coords.x,
        coords.y,
        coords.z,
        coords.h and string.format(", Heading: %.2f", coords.h) or ""
    )
    
    SendLogToDiscord(Webhook["admin-actions"], "Report System", logMessage, admin, 16776960)
    
    ReportsNotify(admin, 'Player has been successfully teleported to ' .. input.label or 'the selected location')
    ReportsNotify(targetPlayer.source, 'You have been successfully teleported to ' .. input.label or 'the selected location' .. '.')
end)

RegisterNetEvent('nv-reports:admin:giveMoney', function(source, reportId, input)
    local admin = source
    local xAdmin = GETPFI(admin)

    local actionConfig = getActionConfig('nv-reports:admin:giveMoney')
    if not hasPermission(xAdmin.group, actionConfig and actionConfig.permissions) then
        SendLogToDiscord(Webhook.cheater, "Report System (Cheater)", "Unauthorized Give Money attempt by id: ".. admin .. " - " .. (xAdmin and GetPlayerName(admin) or "unknown player"), admin, 15158332)
        return
    end

    if not xAdmin or not Config.AdminGroups[xAdmin.group] then
        SendLogToDiscord(Webhook.cheater, "Report System (Cheater)", "Unauthorized Give Money attempt by id: ".. admin .. " - " .. (xAdmin and GetPlayerName(admin) or "unknown player"), admin, 15158332)
        return
    end

    local report = GetReportDetails(reportId)
    if not report or not report[1] then return end
    
    local targetPlayer = GetPlayerFromIdentifier(report[1].player_id)
    if not targetPlayer then
        xAdmin.showNotification("The player of this report is not online.", 'error')
        return
    end

    local amount = input
    if type(input) == "table" and input.amount then
        amount = input.amount
    end
    
    if not amount or amount <= 0 then
        SendLogToDiscord(Webhook.error, "Report System (Error)", "Invalid amount received for give money: " .. json.encode(input), source, 15158332)
        xAdmin.showNotification("An invalid amount was received, please report this to your developer.", 'error')
        return
    end

    targetPlayer.addAccountMoney('bank', amount)

    ReportsNotify(admin, 'You have given ' .. amount .. ' money to ' .. targetPlayer.name)
    ReportsNotify(targetPlayer.source, 'You have received ' .. amount .. ' money from ' .. xAdmin.name)
    
    local logMessage = string.format(
        "## **Admin Action: Give Money**\n" ..
        "**Admin:** %s (%s)\n" ..
        "**Report ID:** %s\n" ..
        "**Player:** %s (%s)\n" ..
        "**Action:** Player received money\n" ..
        "**Amount:** %s\n",
        GetPlayerName(admin),
        admin,
        reportId,
        GetPlayerName(targetPlayer.source),
        targetPlayer.source,
        amount
    )
    
    SendLogToDiscord(Webhook["admin-actions"], "Report System", logMessage, admin, 16776960)
end)

RegisterNetEvent('nv-reports:admin:removeMoney', function(source, reportId, input)
    local admin = source
    local xAdmin = GETPFI(admin)

    local actionConfig = getActionConfig('nv-reports:admin:removeMoney')
    if not hasPermission(xAdmin.group, actionConfig and actionConfig.permissions) then
        SendLogToDiscord(Webhook.cheater, "Report System (Cheater)", "Unauthorized Remove Money attempt by id: ".. admin .. " - " .. (xAdmin and GetPlayerName(admin) or "unknown player"), admin, 15158332)
        return
    end

    if not xAdmin or not Config.AdminGroups[xAdmin.group] then
        SendLogToDiscord(Webhook.cheater, "Report System (Cheater)", "Unauthorized Remove Money attempt by id: ".. admin .. " - " .. (xAdmin and GetPlayerName(admin) or "unknown player"), admin, 15158332)
        return
    end

    local report = GetReportDetails(reportId)
    if not report or not report[1] then return end
    
    local targetPlayer = GetPlayerFromIdentifier(report[1].player_id)
    if not targetPlayer then
        xAdmin.showNotification("The player of this report is not online.", 'error')
        return
    end

    local amount = input
    if type(input) == "table" and input.amount then
        amount = input.amount
    end
    
    if not amount or amount <= 0 then
        SendLogToDiscord(Webhook.error, "Report System (Error)", "Invalid amount received for remove money: " .. json.encode(input), source, 15158332)
        xAdmin.showNotification("An invalid amount was received, please report this to your developer.", 'error')
        return
    end

    targetPlayer.removeAccountMoney('bank', amount)

    ReportsNotify(admin, 'You have removed ' .. amount .. ' money from ' .. targetPlayer.name)
    ReportsNotify(targetPlayer.source, 'You have had ' .. amount .. ' money removed from you.')
    
    local logMessage = string.format(
        "## **Admin Action: Remove Money**\n" ..
        "**Admin:** %s (%s)\n" ..
        "**Report ID:** %s\n" ..
        "**Player:** %s (%s)\n" ..
        "**Action:** Player had money removed\n" ..
        "**Amount:** %s\n",
        GetPlayerName(admin),
        admin,
        reportId,
        GetPlayerName(targetPlayer.source),
        targetPlayer.source,
        amount
    )
    
    SendLogToDiscord(Webhook["admin-actions"], "Report System", logMessage, admin, 16776960)
end)

RegisterNetEvent('nv-reports:admin:giveItem', function(source, reportId, input)
    local admin = source
    local xAdmin = GETPFI(admin)

    local actionConfig = getActionConfig('nv-reports:admin:giveItem')
    if not hasPermission(xAdmin.group, actionConfig and actionConfig.permissions) then
        SendLogToDiscord(Webhook.cheater, "Report System (Cheater)", "Unauthorized Give Item attempt by id: ".. admin .. " - " .. (xAdmin and GetPlayerName(admin) or "unknown player"), admin, 15158332)
        return
    end

    if not xAdmin or not Config.AdminGroups[xAdmin.group] then
        SendLogToDiscord(Webhook.cheater, "Report System (Cheater)", "Unauthorized Give Item attempt by id: ".. admin .. " - " .. (xAdmin and GetPlayerName(admin) or "unknown player"), admin, 15158332)
        return
    end

    local report = GetReportDetails(reportId)
    if not report or not report[1] then return end
    
    local targetPlayer = GetPlayerFromIdentifier(report[1].player_id)
    if not targetPlayer then
        xAdmin.showNotification("The player of this report is not online.", 'error')
        return
    end

    local itemName, count
    if type(input) == "table" then
        itemName = input["Item Naam"]
        count = input["Aantal"]
    else
        itemName, count = string.match(input, "(%S+)%s+(%d+)")
    end
    
    if not itemName or not count then
        xAdmin.showNotification("Please fill in both item name and amount", 'error')
        return
    end

    count = tonumber(count)
    if count <= 0 then
        xAdmin.showNotification("Amount must be greater than 0.", 'error')
        return
    end

    targetPlayer.addInventoryItem(itemName, count)

    ReportsNotify(admin, 'You have given ' .. count .. 'x ' .. itemName .. ' to ' .. targetPlayer.name)
    ReportsNotify(targetPlayer.source, 'You have received ' .. count .. 'x ' .. itemName .. ' from ' .. xAdmin.name)
    
    local logMessage = string.format(
        "## **Admin Action: Give Item**\n" ..
        "**Admin:** %s (%s)\n" ..
        "**Report ID:** %s\n" ..
        "**Player:** %s (%s)\n" ..
        "**Action:** Player received item\n" ..
        "**Item:** %s\n" ..
        "**Amount:** %s\n",
        GetPlayerName(admin),
        admin,
        reportId,
        GetPlayerName(targetPlayer.source),
        targetPlayer.source,
        itemName,
        count
    )
    
    SendLogToDiscord(Webhook["admin-actions"], "Report System", logMessage, admin, 16776960)
end)

RegisterNetEvent('nv-reports:admin:removeItem', function(source, reportId, input)
    local admin = source
    local xAdmin = GETPFI(admin)

    local actionConfig = getActionConfig('nv-reports:admin:removeItem')
    if not hasPermission(xAdmin.group, actionConfig and actionConfig.permissions) then
        SendLogToDiscord(Webhook.cheater, "Report System (Cheater)", "Unauthorized Remove Item attempt by id: ".. admin .. " - " .. (xAdmin and GetPlayerName(admin) or "unknown player"), admin, 15158332)
        return
    end

    if not xAdmin or not Config.AdminGroups[xAdmin.group] then
        SendLogToDiscord(Webhook.cheater, "Report System (Cheater)", "Unauthorized Remove Item attempt by id: ".. admin .. " - " .. (xAdmin and GetPlayerName(admin) or "unknown player"), admin, 15158332)
        return
    end

    local report = GetReportDetails(reportId)
    if not report or not report[1] then return end
    
    local targetPlayer = GetPlayerFromIdentifier(report[1].player_id)
    if not targetPlayer then
        xAdmin.showNotification("The player of this report is not online.", 'error')
        return
    end

    local itemName, count
    if type(input) == "table" then
        itemName = input["Item Name"]
        count = input["Amount"]
    else
        itemName, count = string.match(input, "(%S+)%s+(%d+)")
    end
    
    if not itemName or not count then
        xAdmin.showNotification("Please fill in both item name and amount", 'error')
        return
    end

    count = tonumber(count)
    if count <= 0 then
        xAdmin.showNotification("Amount must be greater than 0.", 'error')
        return
    end

    local playerItem = targetPlayer.getInventoryItem(itemName)
    if not playerItem or playerItem.count < count then
        xAdmin.showNotification("The player does not have enough " .. itemName .. ".", 'error')
        return
    end

    targetPlayer.removeInventoryItem(itemName, count)

    ReportsNotify(admin, 'You have removed ' .. count .. 'x ' .. itemName .. ' from ' .. targetPlayer.name)
    ReportsNotify(targetPlayer.source, 'You have had ' .. count .. 'x ' .. itemName .. ' removed by an Admin.')
    
    local logMessage = string.format(
        "## **Admin Action: Remove Item**\n" ..
        "**Admin:** %s (%s)\n" ..
        "**Report ID:** %s\n" ..
        "**Player:** %s (%s)\n" ..
        "**Action:** Player had item removed\n" ..
        "**Item:** %s\n" ..
        "**Amount:** %s\n",
        GetPlayerName(admin),
        admin,
        reportId,
        GetPlayerName(targetPlayer.source),
        targetPlayer.source,
        itemName,
        count
    )
    
    SendLogToDiscord(Webhook["admin-actions"], "Report System", logMessage, admin, 16776960)
end)

RegisterNetEvent('nv-reports:admin:setJob', function(source, reportId, input)
    local admin = source
    local xAdmin = GETPFI(admin)

    local actionConfig = getActionConfig('nv-reports:admin:setJob')
    if not hasPermission(xAdmin.group, actionConfig and actionConfig.permissions) then
        SendLogToDiscord(Webhook.cheater, "Report System (Cheater)", "Unauthorized Set Job attempt by id: ".. admin .. " - " .. (xAdmin and GetPlayerName(admin) or "unknown player"), admin, 15158332)
        return
    end

    if not xAdmin or not Config.AdminGroups[xAdmin.group] then
        SendLogToDiscord(Webhook.cheater, "Report System (Cheater)", "Unauthorized Set Job attempt by id: ".. admin .. " - " .. (xAdmin and GetPlayerName(admin) or "unknown player"), admin, 15158332)
        return
    end

    local report = GetReportDetails(reportId)
    if not report or not report[1] then return end
    
    local targetPlayer = GetPlayerFromIdentifier(report[1].player_id)
    if not targetPlayer then
        xAdmin.showNotification("The player of this report is not online.", 'error')
        return
    end

    local jobName, jobGrade
    if type(input) == "table" then
        jobName = input["Job Name"]
        jobGrade = input["Grade"]
    else
        xAdmin.showNotification("Invalid input for Set Job", 'error')
        return
    end
    
    if not jobName or jobGrade == nil then
        xAdmin.showNotification("Please fill in both job name and grade", 'error')
        return
    end

    jobGrade = tonumber(jobGrade)
    if jobGrade < 0 then
        xAdmin.showNotification("Grade must be 0 or higher.", 'error')
        return
    end

    local oldJob = targetPlayer.job.name
    local oldGrade = targetPlayer.job.grade

    targetPlayer.setJob(jobName, jobGrade)

    ReportsNotify(admin, 'You have changed the job of ' .. targetPlayer.name .. ' to ' .. jobName .. ' (Grade: ' .. jobGrade .. ')')
    ReportsNotify(targetPlayer.source, 'Your job has been changed to ' .. jobName .. ' (Grade: ' .. jobGrade .. ') by an Admin.')
    
    local logMessage = string.format(
        "## **Admin Action: Set Job**\n" ..
        "**Admin:** %s (%s)\n" ..
        "**Report ID:** %s\n" ..
        "**Player:** %s (%s)\n" ..
        "**Action:** Job changed\n" ..
        "**Old Job:** %s (Grade: %s)\n" ..
        "**New Job:** %s (Grade: %s)\n",
        GetPlayerName(admin),
        admin,
        reportId,
        GetPlayerName(targetPlayer.source),
        targetPlayer.source,
        oldJob,
        oldGrade,
        jobName,
        jobGrade
    )
    
    SendLogToDiscord(Webhook["admin-actions"], "Report System", logMessage, admin, 16776960)
end)

RegisterNetEvent('nv-reports:admin:setGroup', function(source, reportId, input)
    local admin = source
    local xAdmin = GETPFI(admin)

    local actionConfig = getActionConfig('nv-reports:admin:setGroup')
    if not hasPermission(xAdmin.group, actionConfig and actionConfig.permissions) then
        SendLogToDiscord(Webhook.cheater, "Report System (Cheater)", "Unauthorized Set Group attempt by id: ".. admin .. " - " .. (xAdmin and GetPlayerName(admin) or "unknown player"), admin, 15158332)
        return
    end

    if not xAdmin or not Config.AdminGroups[xAdmin.group] then
        SendLogToDiscord(Webhook.cheater, "Report System (Cheater)", "Unauthorized Set Group attempt by id: ".. admin .. " - " .. (xAdmin and GetPlayerName(admin) or "unknown player"), admin, 15158332)
        return
    end

    local report = GetReportDetails(reportId)
    if not report or not report[1] then return end
    
    local targetPlayer = GetPlayerFromIdentifier(report[1].player_id)
    if not targetPlayer then
        xAdmin.showNotification("The player of this report is not online.", 'error')
        return
    end

    local newGroup = input.value
    
    if not newGroup or newGroup == '' then
        xAdmin.showNotification("Please select a valid group", 'error')
        return
    end

    local oldGroup = targetPlayer.group

    targetPlayer.setGroup(newGroup)

    ReportsNotify(admin, 'You have changed the group of ' .. targetPlayer.name .. ' to ' .. newGroup)
    ReportsNotify(targetPlayer.source, 'Your group has been changed to ' .. newGroup .. ' by an Admin.')
    
    local logMessage = string.format(
        "## **Admin Action: Set Group**\n" ..
        "**Admin:** %s (%s)\n" ..
        "**Report ID:** %s\n" ..
        "**Player:** %s (%s)\n" ..
        "**Action:** Group changed\n" ..
        "**Old Group:** %s\n" ..
        "**New Group:** %s\n",
        GetPlayerName(admin),
        admin,
        reportId,
        GetPlayerName(targetPlayer.source),
        targetPlayer.source,
        oldGroup,
        newGroup
    )
    
    SendLogToDiscord(Webhook["admin-actions"], "Report System", logMessage, admin, 16776960)
end)

RegisterNetEvent('nv-reports:admin:fixVehicle', function(source, reportId)
    local admin = source
    local xAdmin = GETPFI(admin)

    if not xAdmin or not Config.AdminGroups[xAdmin.group] then
        SendLogToDiscord(Webhook.cheater, "Report System (Cheater)", "Unauthorized Fix Vehicle attempt by id: ".. admin .. " - " .. (xAdmin and GetPlayerName(admin) or "unknown player"), admin, 15158332)
        return
    end

    local report = GetReportDetails(reportId)
    if not report or not report[1] then return end
    
    local targetPlayer = GetPlayerFromIdentifier(report[1].player_id)
    if not targetPlayer then
        xAdmin.showNotification("The player of this report is not online.", 'error')
        return
    end

    TriggerClientEvent('nv-reports:client:fixVehicle', targetPlayer.source)

    ReportsNotify(admin, 'You have repaired the vehicle of ' .. targetPlayer.name .. '.')
    ReportsNotify(targetPlayer.source, 'Your vehicle has been repaired by an Admin.')
    
    local logMessage = string.format(
        "## **Admin Action: Fix Vehicle**\n" ..
        "**Admin:** %s (%s)\n" ..
        "**Report ID:** %s\n" ..
        "**Player:** %s (%s)\n" ..
        "**Action:** Vehicle repaired\n",
        GetPlayerName(admin),
        admin,
        reportId,
        GetPlayerName(targetPlayer.source),
        targetPlayer.source
    )
    
    SendLogToDiscord(Webhook["admin-actions"], "Report System", logMessage, admin, 16776960)
end)

RegisterNetEvent('nv-reports:admin:healPlayer', function(source, reportId)
    local admin = source
    local xAdmin = GETPFI(admin)

    if not xAdmin or not Config.AdminGroups[xAdmin.group] then
        SendLogToDiscord(Webhook.cheater, "Report System (Cheater)", "Unauthorized Heal Player attempt by id: ".. admin .. " - " .. (xAdmin and GetPlayerName(admin) or "unknown player"), admin, 15158332)
        return
    end

    local report = GetReportDetails(reportId)
    if not report or not report[1] then return end
    
    local targetPlayer = GetPlayerFromIdentifier(report[1].player_id)
    if not targetPlayer then
        xAdmin.showNotification("The player of this report is not online.", 'error')
        return
    end

    TriggerClientEvent('nv-reports:client:healPlayer', targetPlayer.source)

    ReportsNotify(admin, 'You have healed ' .. targetPlayer.name .. '.')
    ReportsNotify(targetPlayer.source, 'You have been healed by an Admin.')
    
    local logMessage = string.format(
        "## **Admin Action: Heal Player**\n" ..
        "**Admin:** %s (%s)\n" ..
        "**Report ID:** %s\n" ..
        "**Player:** %s (%s)\n" ..
        "**Action:** Player healed\n",
        GetPlayerName(admin),
        admin,
        reportId,
        GetPlayerName(targetPlayer.source),
        targetPlayer.source
    )
    
    SendLogToDiscord(Webhook["admin-actions"], "Report System", logMessage, admin, 16776960)
end)

RegisterNetEvent('nv-reports:admin:killPlayer', function(source, reportId)
    local admin = source
    local xAdmin = GETPFI(admin)

    if not xAdmin or not Config.AdminGroups[xAdmin.group] then
        SendLogToDiscord(Webhook.cheater, "Report System (Cheater)", "Unauthorized Kill Player attempt by id: ".. admin .. " - " .. (xAdmin and GetPlayerName(admin) or "unknown player"), admin, 15158332)
        return
    end

    local report = GetReportDetails(reportId)
    if not report or not report[1] then return end
    
    local targetPlayer = GetPlayerFromIdentifier(report[1].player_id)
    if not targetPlayer then
        xAdmin.showNotification("The player of this report is not online.", 'error')
        return
    end

    TriggerClientEvent('nv-reports:client:killPlayer', targetPlayer.source)

    ReportsNotify(admin, 'You have killed ' .. targetPlayer.name .. '.')
    --ReportsNotify(targetPlayer.source, 'You have been killed by an Admin.')
    
    local logMessage = string.format(
        "## **Admin Action: Kill Player**\n" ..
        "**Admin:** %s (%s)\n" ..
        "**Report ID:** %s\n" ..
        "**Player:** %s (%s)\n" ..
        "**Action:** Player killed\n",
        GetPlayerName(admin),
        admin,
        reportId,
        GetPlayerName(targetPlayer.source),
        targetPlayer.source
    )
    
    SendLogToDiscord(Webhook["admin-actions"], "Report System", logMessage, admin, 16776960)
end)

RegisterNetEvent('nv-reports:admin:freezePlayer', function(source, reportId)
    local admin = source
    local xAdmin = GETPFI(admin)

    if not xAdmin or not Config.AdminGroups[xAdmin.group] then
        SendLogToDiscord(Webhook.cheater, "Report System (Cheater)", "Unauthorized Freeze Player attempt by id: ".. admin .. " - " .. (xAdmin and GetPlayerName(admin) or "unknown player"), admin, 15158332)
        return
    end

    local report = GetReportDetails(reportId)
    if not report or not report[1] then return end
    
    local targetPlayer = GetPlayerFromIdentifier(report[1].player_id)
    if not targetPlayer then
        xAdmin.showNotification("The player of this report is not online.", 'error')
        return
    end

    TriggerClientEvent('nv-reports:client:freezePlayer', targetPlayer.source, true)

    ReportsNotify(admin, 'You have frozen ' .. targetPlayer.name .. '.')
    ReportsNotify(targetPlayer.source, 'You have been frozen by an Admin.')
    
    local logMessage = string.format(
        "## **Admin Action: Freeze Player**\n" ..
        "**Admin:** %s (%s)\n" ..
        "**Report ID:** %s\n" ..
        "**Player:** %s (%s)\n" ..
        "**Action:** Player frozen\n",
        GetPlayerName(admin),
        admin,
        reportId,
        GetPlayerName(targetPlayer.source),
        targetPlayer.source
    )
    
    SendLogToDiscord(Webhook["admin-actions"], "Report System", logMessage, admin, 16776960)
end)

RegisterNetEvent('nv-reports:admin:unfreezePlayer', function(source, reportId)
    local admin = source
    local xAdmin = GETPFI(admin)

    if not xAdmin or not Config.AdminGroups[xAdmin.group] then
        SendLogToDiscord(Webhook.cheater, "Report System (Cheater)", "Unauthorized Unfreeze Player attempt by id: ".. admin .. " - " .. (xAdmin and GetPlayerName(admin) or "unknown player"), admin, 15158332)
        return
    end

    local report = GetReportDetails(reportId)
    if not report or not report[1] then return end
    
    local targetPlayer = GetPlayerFromIdentifier(report[1].player_id)
    if not targetPlayer then
        xAdmin.showNotification("The player of this report is not online.", 'error')
        return
    end

    TriggerClientEvent('nv-reports:client:freezePlayer', targetPlayer.source, false)

    ReportsNotify(admin, 'You have unfrozen ' .. targetPlayer.name .. '.')
    ReportsNotify(targetPlayer.source, 'You have been unfrozen by an Admin.')
    
    local logMessage = string.format(
        "## **Admin Action: Unfreeze Player**\n" ..
        "**Admin:** %s (%s)\n" ..
        "**Report ID:** %s\n" ..
        "**Player:** %s (%s)\n" ..
        "**Action:** Player unfrozen\n",
        GetPlayerName(admin),
        admin,
        reportId,
        GetPlayerName(targetPlayer.source),
        targetPlayer.source
    )
    
    SendLogToDiscord(Webhook["admin-actions"], "Report System", logMessage, admin, 16776960)
end)

RegisterNetEvent('nv-reports:admin:clearInventory', function(source, reportId)
    local admin = source
    local xAdmin = GETPFI(admin)

    if not xAdmin or not Config.AdminGroups[xAdmin.group] then
        SendLogToDiscord(Webhook.cheater, "Report System (Cheater)", "Unauthorized Clear Inventory attempt by id: ".. admin .. " - " .. (xAdmin and GetPlayerName(admin) or "unknown player"), admin, 15158332)
        return
    end

    local report = GetReportDetails(reportId)
    if not report or not report[1] then return end
       
    local targetPlayer = GetPlayerFromIdentifier(report[1].player_id)
    if not targetPlayer then
        xAdmin.showNotification("The player of this report is not online.", 'error')
        return 
    end

    local inventory = targetPlayer.getInventory()
    local itemCount = 0
    local itemsList = {}

    for _, item in pairs(inventory) do
        if item.count > 0 then
            targetPlayer.removeInventoryItem(item.name, item.count)
            
            itemCount = itemCount + item.count
            table.insert(itemsList, item.name .. " (x" .. item.count .. ")")
        end
    end

    ReportsNotify(admin, 'You have cleared the inventory of ' .. targetPlayer.name .. '. (' .. itemCount .. ' items removed)')
    ReportsNotify(targetPlayer.source, 'Your inventory has been cleared by an Admin.')
    
    local logMessage = string.format(
        "## **Admin Action: Clear Inventory**\n" ..
        "**Admin:** %s (%s)\n" ..
        "**Report ID:** %s\n" ..
        "**Player:** %s (%s)\n" ..
        "**Action:** Inventory cleared\n" ..
        "**Items removed:** %s\n" ..
        "**Total items:** %s\n",
        GetPlayerName(admin),
        admin,
        reportId,
        GetPlayerName(targetPlayer.source),
        targetPlayer.source,
        table.concat(itemsList, ", ") or "No items",
        itemCount
    )
    
    SendLogToDiscord(Webhook["admin-actions"], "Report System", logMessage, admin, 16776960)
end)

RegisterNetEvent('nv-reports:admin:setPlayerSize', function(source, reportId, input)
    local admin = source
    local xAdmin = GETPFI(admin)

    if not xAdmin or not Config.AdminGroups[xAdmin.group] then
        SendLogToDiscord(Webhook.cheater, "Report System (Cheater)", "Unauthorized Set Player Size attempt by id: ".. admin .. " - " .. (xAdmin and GetPlayerName(admin) or "unknown player"), admin, 15158332)
        return
    end

    local report = GetReportDetails(reportId)
    if not report or not report[1] then return end
    
    local targetPlayer = GetPlayerFromIdentifier(report[1].player_id)
    if not targetPlayer then
        xAdmin.showNotification("The player of this report is not online.", 'error')
        return
    end

    local size = input.value
    
    if not size or (size ~= "small" and size ~= "normal") then
        xAdmin.showNotification("Please select a valid size.", 'error')
        return
    end

    TriggerClientEvent('nv-reports:client:setPlayerSize', targetPlayer.source, size)

    local sizeLabel = size == "small" and "small" or "normal"
    ReportsNotify(admin, 'You have changed the size of ' .. targetPlayer.name .. ' to ' .. sizeLabel .. '.')
    ReportsNotify(targetPlayer.source, 'Your size has been changed to ' .. sizeLabel .. ' by an Admin.')

    local logMessage = string.format(
        "## **Admin Action: Player Size**\n" ..
        "**Admin:** %s (%s)\n" ..
        "**Report ID:** %s\n" ..
        "**Player:** %s (%s)\n" ..
        "**Action:** Player size changed\n" ..
        "**New size:** %s\n",
        GetPlayerName(admin),
        admin,
        reportId,
        GetPlayerName(targetPlayer.source),
        targetPlayer.source,
        sizeLabel
    )
    
    SendLogToDiscord(Webhook["admin-actions"], "Report System", logMessage, admin, 16776960)
end
chevron-rightserver/handler/log.luahashtag
chevron-rightserver/handler/utils.luahashtag
chevron-rightframework/server-framework.luahashtag
chevron-rightframework/client-framework.luahashtag

Last updated