Two Admin Scripts That Saved Me Hours of Server Management in QBCore

Published: (March 18, 2026 at 01:25 PM EDT)
4 min read
Source: Dev.to

Source: Dev.to

The problem with managing a live RP server

Running a QBCore RP server means dealing with two recurring headaches:

  • Players get stuck in the wrong job, or you need to assign roles fast during a session — doing it through the database or existing admin menus is slow.
  • Inactive players accumulate in the database over months. Ghosts with vehicles, characters, and data that will never be used again.

I built two scripts to solve both: lokat_adminjob for real‑time job management, and lokat_cleanup for database pruning.

lokat_adminjob — Job assignment from a UI panel

Permission system

The script checks permissions in two layers — txAdmin ACE first, then QBCore’s native admin/god flags. This works on both txAdmin‑managed servers and vanilla QBCore setups.

local function hasAdmin(src)
    if IsPlayerAceAllowed(src, Config.AceName) then
        return true
    end
    if QBCore.Functions.HasPermission(src, 'admin')
        or QBCore.Functions.HasPermission(src, 'god') then
        return true
    end
    return false
end

Permission checks always run server‑side; the client only sends requests. Unauthorized attempts to call the server event are blocked.

ps‑multijob integration

If a player has the same job as a side job in ps‑multijob and you assign it as their main job, a conflict occurs. The script handles this automatically — before setting a new main job, it removes any matching side‑job entry.

-- Remove conflicting side job before assigning main job
PMJ_RemoveJobByName(target, jobName)
target.Functions.SetJob(jobName, grade)

When removing a job entirely (setting to unemployed), it clears all side jobs as well — a single clean operation.

What the panel shows

When an admin opens the panel, the server sends a live snapshot:

  • All available jobs with their grade levels.
  • All currently online players with their current job.

The admin selects a player, chooses a job and grade, and submits. The change applies immediately, and notifications are sent to both the admin and the target player.

lokat_cleanup — Inactive player pruning tool

How it works

Open the UI with a command, set the inactivity threshold (default: 60 days), and the script queries the database for accounts where all characters’ last_updated timestamps are older than the threshold.

Results are grouped by license (one row per account) and display:

  • Character names linked to the account
  • Last active date
  • Number of owned vehicles
  • Total character count
-- Group by license, get the most recent activity across all characters
SELECT license FROM players
GROUP BY license
HAVING MAX(last_updated) <= (NOW() - INTERVAL ? DAY)

Safety checks

Before deleting any account, the server checks whether any character on that license is currently online. If so, the deletion is blocked.

for _, row in ipairs(rows) do
    local p = QBCore.Functions.GetPlayerByCitizenId(row.citizenid)
    if p then
        cb({ ok = false, error = 'player_online' })
        return
    end
end

You can also choose whether to delete associated vehicles — toggled per deletion.

Search and pagination

For large player databases, the UI supports character‑name search, pagination, and sorting (oldest‑first or newest‑first).

Config overview

Both scripts use a simple config file.

lokat_adminjob

Config.AceName = 'your_ace_permission_name'
Config.OpenCommand = 'your_command_name'
Config.MultiJob = { Enable = true }

lokat_cleanup

Config.MinDaysInactiveDefault = 60  -- adjust to your needs
Config.PageSize = 50
Config.UseAcePermission = true
Config.AceName = 'your_ace_permission_name'

Why these exist

Most admin tasks in QBCore require either direct database access or navigating menus that weren’t designed for speed. These two scripts are purpose‑built for the specific operations I performed repeatedly, eliminating a lot of friction from day‑to‑day server management.

Next up: Vol.5 — Building a Custom Vending Machine System for QBCore.

0 views
Back to Blog

Related posts

Read more »

Agents in 60 lines of python : Part 3

The Agent Loop The entire AI agent stack in 60 lines of Python. You've seen Claude search files, read them, then search again. ChatGPT with Code Interpreter wri...