Jixryo Core

The shared base every Jixryo script runs on. One bridge to your framework, inventory, target, dispatch, doors, phone and keys, the server helpers the scripts share, the game clock, handling layers and the suite HUD.

Version 1.4.2 Updated See it on its script page

On this page

Jixryo Core is the base the other Jixryo scripts run on. It comes with every script that needs it and is not sold on its own; you run one copy. Core knows which resource does each job on your server (qbx_core, ox_inventory, ox_target, cd_dispatch, ox_doorlock, lb-phone and the vehicle keys), so swapping one of them is a line in Core's config.lua, not a change to every script. It also carries the server helpers the scripts share, one game clock for the whole server, handling layers for cars, and the suite HUD.

What players get

Nothing to press and nothing to learn: Core shows through the scripts built on it.

  • Notifications in one stack. Every Jixryo notification goes through ox_lib's lib.notify, so it sits in the same stack and the same look as every other notification on your server.
  • The hint row and the prompt. A row of keys for what you can do here (up to eight), and an interaction prompt with its key, a label, a second line, a hold line that fills while the key is held, and up to three more actions.
  • Progress bars with a label, a time, an animation or a scenario and props in the hand. X cancels one that allows it; a dead player cannot start one unless the script says so.
  • A confirm dialog over the game, blurred by GTA itself: Confirm or Cancel, Esc cancels.
  • Handling layers. A script such as the mechanic puts a named layer on a car on top of its own handling line. Every game that has the car applies the layers, again when the car comes near or someone takes the wheel, and a cleared layer takes the car straight back to its own values. An engine sound a script sets is heard by everyone near the car.

What staff get

  • A start-up line in the console: Core's version and the resource picked for each job, with a yellow warning for a job whose resource is named in the config but is not running.
  • An audit log. Every staff or money action a Jixryo script reports lands in the console and the jixryo_audit table, and in a Discord channel if you set a webhook. Core reads the name of the resource that wrote each entry itself, so one script cannot write in another's name.
  • One game clock for the server. Read from your time-sync script when it shares the time, otherwise the middle answer of a few players' games, so no single game decides what time it is.
  • Numbered database steps. Each Jixryo script's tables are made and upgraded by steps recorded in jixryo_migrations, once per server.

Install

Core replaces nothing and adds no items.

  1. Put jixryo_core in your resources. Upload it as it is: its HUD page is already built in web/build.

  2. Start it after the resources it bridges and before any Jixryo script:

    server.cfg
    ensure ox_lib
    ensure oxmysql
    ensure qbx_core
    ensure ox_inventory
    ensure ox_target
    ensure ox_doorlock
    ensure lb-phone
    ensure cd_dispatch
    ensure jixryo_core

    Only ox_lib, oxmysql and qbx_core are required. The rest are the jobs Config.adapters names by default; if your server does not run one of them, set that line to 'none' (see Configuration), or the console warns at every start and that job's calls answer false.

  3. The database. On first start Core makes its two tables, jixryo_migrations and jixryo_audit.

  4. Restart the whole server after installing or updating Core. Each Jixryo script loads Core's modules into itself when it starts, so restarting jixryo_core alone leaves the others running the old copy.

How other scripts' calls behave

Core answers as no other resource: it is the one the Jixryo scripts call. This is what it does with the resources it bridges.

Your resourceWhat Core does with it
qbx_corePlayers, characters, jobs, gangs, duty, money and metadata through qbx_core's own exports. Someone still on the character screen is in no group, so a check on them answers false instead of erroring inside qbx_core.
ox_inventoryCounts, adds, removes, stashes and an all-or-nothing exchange through its server exports. Every call answers 0 or false while the inventory is not running.
ox_targetOptions on entities and zones. They are added by the calling script, so ox_target drops them when that script stops.
cd_dispatchAlerts the server-side way Codesign documents: cd_dispatch:AddNotification to every client with a unique id, and cd_dispatch shows them to the jobs in job_table. Core never calls cd_dispatch's GetPlayerInfo export. With 'cd_dispatch3d' the alert goes to the local server event instead, without an id.
ox_doorlockDoors by id or by name through getDoor, getDoorFromName and setDoorState. A call from the server skips ox_doorlock's own permission check, so the script checks its player first.
lb-phoneNotifications through SendNotification and mail through GetEquippedPhoneNumber, GetEmailAddress and SendMail, to the phone the player has equipped.
The vehicle keysGiveKeys, RemoveKeys and HasKeys on Jixryo Keys, else on qbx_vehiclekeys. Both answer the same exports, and Core looks for them on every call, so a keys script that starts after Core is fine.
Your time-sync scriptGlobalState.currentTime, or a getTime export from Renewed-Weathersync, qb-weathersync or weathersync. Without one, a few players' games are asked every 30 seconds.

Every alert, whatever the adapter, is also handed to the server event jixryo_core:dispatched as the cleaned alert. MDT puts it on its Calls page and live map. It is a server event only, never a net event, so no player's game can fire it.

Its own API

Exports, called as exports.jixryo_core:Name(...).

ExportSideWhat it does
Notify(data)ClientA notification through ox_lib: title, message (or description), type (info, success, error, warning) and duration. The server triggers the same thing with TriggerClientEvent('jixryo_core:notify', src, data).
ShowHints(list) / HideHints()ClientThe hint row: up to eight { keys, label } entries. One row per resource; the newest shows.
ShowPrompt(data) / HidePrompt()ClientThe interaction prompt: key, label, sub, disabled, hold (seconds), progress (0 to 1 while held) and up to three actions.
Progress(data)ClientA progress bar that blocks until it ends: label, duration, sub, canCancel, useWhileDead, anim, prop and disable (move, car, combat, mouse). True when it ran to the end, false when cancelled or refused.
CancelProgress() / IsBusy()ClientCancels the running bar; whether a bar or a dialog is up.
Confirm(data)ClientA dialog that blocks until answered: title, message, confirm, cancel, danger. True for confirm.
Blur(on)ClientGTA's screen blur behind a full-screen page. It stays on until every resource that asked for it lets go or stops.
PlaySound(name)ClientOne of the menu sounds in Config.sounds.
HandlingBase(vehicle, field)ClientA car's own value of a handling field, as this game first saw it.
HandlingApply(vehicle)ClientWorks a car's handling layers out again now.
GetConfig()BothThe adapters as resolved right now, plus the police, dispatch, phone and HUD settings.
Audit(src, action, details)ServerAn audit entry. The resource is read from the caller, never from the arguments.
ClockMinutes()ServerGTA minutes since midnight (0 to 1439), or nil before the first reading.

Events.

EventWhereWhat it carries
jixryo_core:notifyClient, from the serverA notification for one player.
jixryo_core:dispatchedServer onlyEvery cleaned alert, whatever the dispatch adapter; origin names the resource that raised it.
jixryo_core:dispatchServer onlyThe alert, when Config.adapters.dispatch is 'custom'.
jixryo_core:giveKeys, jixryo_core:removeKeysServer only(src, vehicle), when Config.adapters.keys is 'custom'.
jixryo_core:client:clock, jixryo_core:server:clockInternalThe server asking a player's game for GTA's clock, and the answer. Only the games asked are counted.

The Jx table is how the Jixryo scripts use Core. A resource adds '@jixryo_core/import.lua' to its shared_scripts after ox_lib and dependency 'jixryo_core'; each module loads the first time it is used and runs inside that resource.

ModuleThe main calls
Jx.validatenum, int, id, str, enum, bool, truthy, vec3: the clean value or nil, for everything a client sends.
Jx.ratelimit(src, key, seconds), lock / unlock, locked(src, key, fn, ...): cooldowns and in-flight locks per player.
Jx.playerServer: get, cid, source, name, job, gang, onDuty, hasGroup, coords, near, money, addMoney, removeMoney, metadata, setMetadata, police. Client: data, cid, job, onDuty, hasGroup.
Jx.permallowed(src, rule) with ace, groups, jobTypes and duty; ace(src, ace); staff(src).
Jx.inventorycount, has, canCarry, add, remove, registerStash, exchange(inv, take, give).
Jx.dispatchalert(data): code, title, message, coords, priority, jobs, sound, blip, origin.
Jx.doorsget, isLocked, setLocked.
Jx.phonenumber, notify, mail.
Jx.vehiclesgiveKeys, removeKeys, hasKeys; a vehicle is an entity or { netId = n }.
Jx.auditlog(src, action, details).
Jx.dbmigrate(steps): numbered steps, each run once per server.
Jx.hudServer: notify(src, data). Client: notify, hints, prompt, progress, cancelProgress, busy, confirm, sound, blur.
Jx.batterysetup, setChargers, use, stop, scale, plug, status, charge: a device's own charge kept on its item, for the Phone and the Tablet.
Jx.skillsadd, level, xp, has, effect, all, boost against Skills; level 0, effect 0 and add false with 'no_skills' when it is not running.
Jx.clockminutes, hour, between(from, to), inHours: the server's one reading, or this game's own clock on the client.
Jx.gizmoClient: available, mode('move' or 'rotate'), select(down), draw(entity): GTA's own 3D gizmo on a thing you are placing.
Jx.handlingServer: set(vehicle, layer, fields), clear, layers, sound. Client: layers, base, apply.
Jx.targetClient: addEntity, removeEntity, addSphere, addBox, removeZone.

Core writes two vehicle state bags, which any script may read: jxHandling (the layers) and jxSound (the engine sound).

Commands and keybinds

Core registers no commands and binds no keys of its own. The one control it reads is X (Config.hud.cancelControl, GTA control 73), which cancels a progress bar; the key drawn on the bar comes from Config.hud.cancelKey.

Configuration

Everything is in config.lua.

SettingDefaultWhat it does
Config.adapters.framework'qbx_core'The framework.
Config.adapters.inventory'ox_inventory'The inventory.
Config.adapters.target'ox_target'The third eye.
Config.adapters.dispatch'cd_dispatch''cd_dispatch' (classic), 'cd_dispatch3d', 'custom' or 'none'.
Config.adapters.doors'ox_doorlock'The doors.
Config.adapters.phone'lb-phone'The phone notifications and mail go to.
Config.adapters.keys'auto''auto' (Jixryo Keys, else qbx_vehiclekeys), 'jixryo_vehiclekeys', 'qbx_vehiclekeys', 'custom' or 'none'.
Config.police.jobTypes{ 'leo' }Job types whose on-duty players count as police.
Config.police.jobs{}Job names that count as police as well.
Config.dispatch.jobs{ 'police' }The jobs an alert goes to when a script names none.
Config.dispatch.sound1cd_dispatch's sound: 1 one tone, 2 two tones, 3 panic.
Config.dispatch.blipsprite 161, colour 1, scale 1.2, flashes, 5 minutes, radius 0The alert's blip when a script names none.
Config.phone.notifyApp'Mail'The lb-phone app a notification shows under when a script names none.
Config.phone.mailSender'Unknown'The sender of mail that names none.
Config.hud.notifyDuration5000How long a notification stays, in milliseconds, when a script does not say.
Config.hud.cancelControl73The GTA control that cancels a progress bar (X).
Config.hud.cancelKey'X'The keycap drawn on the bar.
Config.sounds.enabledtrueGTA's menu sounds on every suite element; false mutes them all.
Config.sounds.hover, click, confirm, back, tick, error, open, close, notifyGTA's HUD_FRONTEND_DEFAULT_SOUNDSET soundsWhich sound plays for each.
Config.clock.resources{ 'Renewed-Weathersync', 'qb-weathersync', 'weathersync' }Time-sync scripts asked for a getTime export.
Config.clock.every30Seconds between readings.
Config.clock.msPerMinute2000How fast the clock runs between readings. 2000 is GTA's own; match your time-sync script.
Config.clock.askPlayers3How many players' games are asked when no script shares the time.
Config.audit.consoletrueAudit entries in the console.
Config.audit.databasetrueAudit entries in jixryo_audit.
Config.audit.webhookConvar'jixryo_audit_webhook'The convar that holds a Discord webhook.

For a Discord audit channel, put the webhook in server.cfg, never in a file that gets shared:

server.cfg
set jixryo_audit_webhook "https://discord.com/api/webhooks/..."

Every entry arrives there as "Jixryo audit" with the player, the resource and the details.

Security

Core is where the Jixryo scripts get their checks, and it trusts no player's game.

  • Every value a client sends goes through Jx.validate: finite numbers in range, trimmed text without control characters cut to a length, one of the allowed values, coordinates inside the map. Anything else is nil and the script refuses.
  • Distances are measured on the server. Jx.player.near reads where the player really is, never where their game says.
  • One action at a time. Jx.rate.locked stops the same player running one action twice at once (a double payout), and Jx.rate.limit keeps cooldowns per player. Both forget a player who drops.
  • Items move all or nothing. Jx.inventory.exchange checks that everything can be taken and everything can be carried, then moves it, and puts everything back if a step fails part way.
  • Permissions are one check. An ACE, a job or gang with a minimum grade, a job type, and on duty when asked; a rule with only an ACE refuses everyone else. group.X also passes on the ACE X, which is how Qbox grants its admins.
  • The audit log cannot be forged. The resource on each entry is the one that made the call.
  • Alerts never come from a player. jixryo_core:dispatched is a server event only. The clock counts an answer only from a game the server asked, and takes the middle of several.
  • The HUD takes clean text only. Labels and titles are cut to length and stripped of control characters; a hint row holds eight entries, a prompt three actions.
  • Handling layers are bounded. Field names must be handling.meta's, numbers must be finite, multipliers run from 0.05 to 20, and a car holds at most 16 layers of 32 fields.
  • Doors need your check. Jx.doors.setLocked runs as the server and skips ox_doorlock's own permission check, so a script checks its player before calling it.

Tests

Core's own suites run the real modules in real Lua 5.4 on a stand-in server: 2 tests on Jx.player (someone still choosing a character is in no group, and a character's job and grade answer as qbx_core's do) and 2 on Jx.gizmo (the held button grabs an axis once, and letting go releases it). Beyond those, most other Jixryo suites load Core's real modules (validate, db, rate, perm, player, audit, hud, dispatch, skills, vehicles, inventory, battery, handling and clock among them) instead of stand-ins, so Core is exercised by every one of them.

Check it in game

  1. Start the server. The console prints [jixryo_core] version 1.4.2, adapters: ... with the resource picked for each job. A yellow line names any adapter whose resource is not running.
  2. Look in the database: jixryo_migrations and jixryo_audit exist.
  3. Start any Jixryo action with a progress bar and press X: the bar stops and the action does not finish.
  4. Open a Jixryo page that asks a yes or no question: the game blurs behind it, and Esc answers no.
  5. With a webhook set, do one staff action in a Jixryo script: the entry shows in the console, in jixryo_audit and in your Discord channel.
Next step

Ready to look around?

Browse the suite, or paste your server.cfg and see what each script does to your server.