SLEEK REPORT SYSTEM
Here check the installation guide
Last updated
Here check the installation guide
Last updated
This script is compatible with ESX and QB
Its only dependency is SCREENSHOT-BASIC. Used for in-game screenshots added to reports. Download it here:
IMPORTANT NOTICE FIRST
Our script uses a snippet of code programmed in C# (It is a hybrid between .LUA and C#). This doesn't cause any issues on your server or with the script, but you need to keep a couple of things in mind:
You need to have the latest artifacts released by FiveM (https://runtime.fivem.net/artifacts/fivem/build_server_windows/master/)
In the SERVER folder, you'll see many files, if you're used to only having one server.lua, it might seem strange. C# works like this, they're normal files. Don't worry!
INSTALLATION GUIDE
Download from KEYMASTER and Unzip the forge-report.pack.zip
and place this folder in your server's resource folder.
Add the resource to your server start config: ensure forge-report
, the name of the folder must not be changed or the resource will not function correctly. It should be ensured below the screenshot-basic and the core. Something like this:
ensure es_extended -- or qb-core
ensure screenshot-basic
ensure forge-report
-- The rest
Delete or remove from your resources folder any other Report System you have.
Clear the cache of your server and also of your own FiveM.
Reboot the entire server with the forge script well ensured in your server.cfg.
CONFIG
The following will explain all the settings, one of the most important things that I recommend you spend a few minutes to understand in order to offer your users the best possible experience.
Config = {}
-- βββββββ βββββββ ββββ ββββββββββββββ βββββββ βββ ββββββββββ ββββββ ββββββββββββ βββββββ ββββ βββ
-- ββββββββββββββββββββββ ββββββββββββββββββββββ βββ βββββββββββββββββββββββββββββββββββββββββββββ βββ
-- βββ βββ βββββββββ βββββββββ ββββββ βββββββ βββββββββββββββββββ βββ ββββββ βββββββββ βββ
-- βββ βββ βββββββββββββββββββ ββββββ ββββββ βββββββββββββββββββ βββ ββββββ βββββββββββββ
-- ββββββββββββββββββββ βββββββββ ββββββββββββββββββββββββ ββββββ βββ βββ βββββββββββββββ ββββββ
-- βββββββ βββββββ βββ ββββββββ βββ βββββββ βββββββ βββ ββββββ βββ βββ βββ βββββββ βββ βββββ
-- General Configuration:
Config.framework = "QB" -- Framework used: 'ESX', 'QB', or 'CUSTOM'
Config.sql = "OXMYSQL" -- OXMYSQL, MYSQL-ASYNC, GHMATTIMYSQL
Config.imageWebhook = "your_webhook" -- URL for the webhook to send images. Fill with your webhook URL
-- Command Configuration
Config.ReportCommand = 'report' -- Command for players to create a report
Config.AdminReportCommand = 'reports' -- Command for admins to view reports
-- Report Categories
Config.ReportCategories = {
'Antirol', -- Example category
'Other', -- Example category
-- Add more categories as needed
}
-- Admin Role Configuration
Config.AdminRoles = {
'god',
'superadmin', -- Highest level of admin
'admin', -- Regular admin
-- Add more roles as needed
}
-- Admin Options
Config.AdminOptions = {
OnDutyToggle = true, -- Option for admins to toggle duty status
SpectatePlayer = true, -- Allow admins to spectate players
TeleportOptions = true, -- Teleport options (GOTO, bring, etc.)
}
Config.ExitSpectatorKey = 22 -- The key to stop spectating a person -> https://docs.fivem.net/docs/game-references/controls/
-- Player Data Collection
Config.PlayerDataCollection = {
CollectHealthArmor = true, -- Collect health and armor data of the reporting player
CollectNearbyPlayers = true, -- Collect data of players near the reporting player
MaxDistance = 35, -- Max distance for collecting data of nearby players
}
-- Interface Configuration
Config.UI = {
color = '#31afd4',
translations = {
["SUBJECT"] = "SUBJECT",
["SUBJECT_PLACEHOLDER"] = "Clear title of your case...",
["INFORMATION"] = "INFORMATION",
["INFORMATION_PLACEHOLDER"] = "All the detailed information about your problem...",
["LINK"] = "link",
["LINK_PLACEHOLDER"] = "Video Link or Screenshot Link...",
["IMAGE"] = "IMAGE",
["SCREENSHOT"] = "Click to take screenshot of what you see",
["SEND"] = "SEND",
["ADMINSON"] = "ADMINS ON",
["DEFAULT_NOTICE"] = "If no admin is available, open a ticket in Discord",-- Default notice in the report UI
["YOUR_ID"] = "Your ID is:",
["REPORT_SYSTEM"] = "Report system",
["ADMINS_DUTY"] = "Admins duty",
["VIEW"] = "View",
["REPORT_HISTORY"] = "Report history",
["HEALTH"] = "Health",
["ARMOR"] = "Armor",
["PLAYERS_IN_AREA"] = "Players in area",
["SEND_TRANSCRIPTION"] = "Send chat transcription to the Discord LOG",
["WRITE_TO_ADMIN"] = "Write to the Admin...",
["WRITE_TO_USER"] = "Write to the Player...",
["SPECTATE"] = "SPECTATE",
["BRING"] = "BRING",
["GOTO"] = "GOTO",
["SOLVED"] = "SOLVED"
},
}
-- The order in which the reports are arranged in the menu
Config.SortType = "statusDESC" --date/statusASC/statusDESC
-- Notifications and Webhook Configuration
Config.Notifications = {
-- Webhook for report notifications
ReportWebhookUrl = 'your_webhook', -- Webhook URL for report submissions and results
-- Webhook for player information requests by admins
PlayerInfoWebhookUrl = 'your_webhook', -- Webhook URL for sending player information
-- Webhook for notifying when an administrator enters/exits duty
AdminDutyWebhookUrl = 'your_webhook', -- Webhook URL for sending duty information
NotifyAdminOnReport = true, -- Notify admins when a new report is submitted
NotifyPlayerOnResponse = true, -- Notify players when their report is responded to
}
-- Configure the aesthetics and texts of the logs
Config.Webhook = {
Color = 16753920,
Title = "**Report**",
Author = "Forge Reports",
IconUrl = "https://ferko.pl/wp-content/uploads/2022/01/fivem-4.png"
}
Config.WebhookText = {
report_received = '**New report received.**\n**Subject:** {subject}\n**Description:** {description}\n\n**ID:** {id}\n**Character:** {charname}\n**Identifier:** {identifier}\n**Discord:** <@!{discord}>\n**Steam:** [{steam}](https://steamcommunity.com/profiles/{steam})',
report_concluded = '**ReportID:** {reportId} has been closed.',
report_canceled = '**ReportID:** {reportId} has been canceled.',
report_user_respond = '**User responed**\n\n**ReportID:** {reportId}\n**Message:** {message}\n\n**ID:** {id}\n**Character:** {charname}\n**Identifier:** {identifier}\n**Discord:** <@!{discord}>\n**Steam:** [{steam}](https://steamcommunity.com/profiles/{steam})',
admin_on_duty = '**Admin has gone on duty**\n\n**ID:** {id}\n**Character:** {charname}\n**Identifier:** {identifier}\n**Discord:** <@!{discord}>\n**Steam:** [{steam}](https://steamcommunity.com/profiles/{steam})',
admin_off_duty = '**Admin has gone off duty**\n\n**ID:** {id}\n**Character:** {charname}\n**Identifier:** {identifier}\n**Discord:** <@!{discord}>\n**Steam:** [{steam}](https://steamcommunity.com/profiles/{steam})',
}
-- Configure or translate the texts of the notifications
Config.NotificationsText = {
report_received = 'Report received. An admin will review it shortly.',
user_response = 'A user has responded to report.',
admin_response = 'An admin has responded to your report.',
report_submitted = 'Your report has been submitted successfully.',
report_concluded = 'Your report has been concluded.',
report_canceled = 'Your report has been canceled.',
new_report = 'A new report has been submitted.',
player_offline = 'This Player is offline.'
}
Config.SpectateText = "Spectating: press [SPACE] to exit"
CREATE TABLE IF NOT EXISTS `forge_report` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`date_creation` datetime NOT NULL DEFAULT current_timestamp(),
`date_updated` datetime NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
`reporter_identifier` varchar(48) NOT NULL,
`reporter_steam_id` varchar(50) NOT NULL,
`reporter_discord_id` varchar(18) DEFAULT NULL,
`details` text NOT NULL DEFAULT '',
`chat` longtext NOT NULL DEFAULT '',
`state` enum('Completed','Pending','In Progress','Canceled') NOT NULL DEFAULT 'Pending',
`discord_ticket_opened` bit(1) NOT NULL DEFAULT b'0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;
function Notification(playerId, message)
TriggerClientEvent('chat:addMessage', playerId, message)
end
function GetPlayerIdFromIdentifier(identifier)
local playerId = 0
if Config.framework == "ESX" then
local xPlayer = ESX.GetPlayerFromIdentifier(identifier)
if xPlayer then
for k, v in pairs(GetPlayers()) do if ESX.GetPlayerFromId(v).getIdentifier() == identifier then playerId = tonumber(v) break end end
end
elseif Config.framework == "QB" then
--local xPlayer = QBCore.Functions.GetSource(identifier)
--if xPlayer then
for k, v in pairs(GetPlayers()) do if QBCore.Functions.GetPlayer(tonumber(v)).PlayerData.citizenid == identifier then playerId = tonumber(v) break end end
-- end
end
return playerId
end
function GetPlayerIdentifer(source)
local identifier = ""
if Config.framework == "ESX" then
local xPlayer = ESX.GetPlayerFromId(source)
identifier = xPlayer.getIdentifier()
elseif Config.framework == "QB" then
local xPlayer = QBCore.Functions.GetPlayer(source)
identifier = xPlayer.PlayerData.citizenid
end
return identifier
end
function GetCharacterName(source)
local name = ""
if Config.framework == "ESX" then
local xPlayer = ESX.GetPlayerFromId(source)
name = xPlayer.getName()
elseif Config.framework == "QB" then
local xPlayer = QBCore.Functions.GetPlayer(source)
name = xPlayer.PlayerData.charinfo.firstname.." "..xPlayer.PlayerData.charinfo.lastname
end
return name
end
function GetOfflineCharacterName(identifier)
local name = ""
if Config.framework == "ESX" then
local response = SqlFunc("fetchAll", 'SELECT firstname, lastname FROM users WHERE identifier = @identifier', { ['@identifier'] = identifier })
name = response[1].firstname.." "..response[1].lastname
elseif Config.framework == "QB" then
local response = SqlFunc("fetchAll", 'SELECT charinfo FROM players WHERE citizenid = @identifier', { ['@identifier'] = identifier })
data = json.decode(response[1].charinfo)
name = data.firstname.." "..data.lastname
end
return name
end
function CheckIfAdmin(source, ranks)
if Config.framework == "ESX" then
local esxPlayer = ESX.GetPlayerFromId(source)
if ranks then
for key, rank in pairs(ranks) do
if esxPlayer.group == rank then
return true
end
end
else
return esxPlayer.group == 'admin' or esxPlayer.group == 'superadmin'
end
elseif Config.framework == "QB" then
if ranks then
for key, rank in pairs(ranks) do
if QBCore.Functions.HasPermission(source, rank) then
return true
end
end
else
return QBCore.Functions.HasPermission(source, 'admin') or QBCore.Functions.HasPermission(source, 'god')
end
end
en
function Notification(message)
TriggerEvent('chat:addMessage', message)
end
If you want to edit the aesthetics or design. You have the HTML open so you can modify the style and everything as you want.
The script is RESPONSIVE for all resolutions as well.