Upgrade Scripts Docs

#Admin Panel

Open it in-game with:

/rewards-admin

The panel lists every player who has a rewards record - online or not - with search, sortable columns and pagination.

#Two access tiers

Config.AdminPanel = {
    AuditLog = true,

    View = {
        Groups = { 'mod', 'admin', 'superadmin', 'god' },
        Ace = 'upgrade_rewards.view',
        Identifiers = {
            -- 'discord:123456789012345678',
        },
    },
    Modify = {
        Groups = { 'superadmin', 'god' },
        Ace = 'upgrade_rewards.modify',
        Identifiers = {
            -- 'license:0123456789abcdef0123456789abcdef01234567',
        },
    },
}

View can open the panel, search players, and read their points history, referrals and audit log. The edit controls are hidden and the header shows a "View only" badge.

Modify can do all of that plus add and remove points, grant XP and set levels. Anyone who qualifies for Modify automatically has View.

Both tiers are enforced on the server, not just hidden in the interface, so a view-only member of staff cannot make changes by any other route.

#How a tier is matched

A player qualifies through any of three routes:

  • Groups - their framework permission group. QBCore and QBox use god, admin and mod; ESX uses superadmin, admin and mod.
  • Ace - an ace permission granted in server.cfg, which is useful for granting access to one person without changing their group:
add_ace identifier.license:abc123... upgrade_rewards.modify allow
add_ace group.admin upgrade_rewards.view allow
  • Identifiers - an explicit list. Any identifier form works: license:, discord:, steam: or fivem:.

Listing an identifier pins that person's tier. Someone in View.Identifiers stays view-only even if their group appears in Modify.Groups, unless they are also listed in Modify.Identifiers. That is the straightforward way to make one member of staff read-only without touching the group lists.

Note the defaults: if you are god or superadmin, you already qualify for Modify through Modify.Groups. To test view-only access on yourself, list your identifier under View, or take your group out of Modify.Groups.

Turning on Config.Debug prints the outcome of every permission check together with the rule that decided it, which is the quickest way to see why someone does or does not have access.

#Finding the right player

Search matches any of a player's character names, their FiveM name, their identifier, their rank title or their referral code.

The panel caches every character name it has ever seen for an identifier, pulled from your framework's character table and refreshed whenever a player loads in. A player with more than one character shows a "N characters" chip in the list, and opening them lists all of their characters. This matters because a FiveM name rarely matches the character name your staff know someone by.

The display name falls back sensibly: the character name from your framework, then the first cached character, then the FiveM name, then the raw identifier for records whose character no longer exists.

#What you can change

Opening a player shows their points, level, XP progress, rank, playtime, referral count and referral code, plus three tabs: points history, referrals and the admin log.

Modify-tier staff get three controls:

  • Add / Remove points - writes an entry to the player's history either way
  • Grant XP - adds XP and levels them if it crosses a threshold
  • Set Level - sets the level outright and resets XP to 0 for the new level. It does not grant level-up rewards.

Every change is applied immediately and the row updates in place.

#Audit log

With AuditLog = true (the default), every points, XP and level change made from the panel is recorded in the upgrade_admin_log table with who did it, what changed, and when. It shows on the Admin Log tab when you open a player, so a dispute can be answered without digging through Discord history.

Admin actions also post to Discord if you have webhooks enabled - see the AdminPoints and AdminXP events in Discord Webhooks.

#Performance

Points history is fetched when you open an individual player rather than being sent with the whole list, so the panel opens quickly even on servers with thousands of records.