Koja Scripts

Installation

Step-by-step setup of koja-mdt including server.cfg order, database, inventory items, ace permissions and a first-run checklist.

Installation

  1. Install the dependencies

    koja-mdt needs these resources started before it:
    • oxmysql
    • your framework (es_extended, qb-core or qbx_core)
    • koja-lib
    Optional: screenshot-basic for photo upload and selfies, and an inventory if you want item based features.
  2. Add the resource

    Use the release zip. It contains the built interface in web/build. Put the koja-mdt folder in your resources directory.
  3. Edit server.cfg

    Ensure koja-mdt after its dependencies:
    server.cfg
    ensure oxmysql
    ensure es_extended   # or qb-core / qbx_core
    ensure koja-lib
    ensure screenshot-basic   # optional
    ensure koja-mdt
    The manifest declares oxmysql and koja-lib as dependencies, so the resource will not start without them. To keep bodycam footage and images on Cloudflare R2, S3 or Fivemanage instead of the server disk, add the storage keys to server.cfg with set (never in shared/config.lua). See Storage and CDN.
  4. Database

    Nothing to import by hand in a normal install. On every start the resource reads koja-mdt.sql and runs it statement by statement. Every statement is CREATE TABLE IF NOT EXISTS, so restarts are safe. Columns added in later versions are added automatically with ALTER TABLE when missing.
    FileWhat it is
    koja-mdt.sqlAll tables. Run automatically at start.
    sql/custody.sql, sql/divisions.sql, sql/admin.sql, sql/web.sqlThe same module tables, run again by their own modules at start. Safe to ignore.
    sql/mail.sql, sql/forms.sqlCopies of the mail and forms tables, also contained in koja-mdt.sql. Safe to ignore.
    sql/jobs_fire.sqlOptional and not run automatically. ESX only: adds a fire job with grades to the jobs and job_grades tables if it does not exist yet. Import it yourself if you want a ready LSFD job.
    The penal code from shared/penalcode.lua is seeded into the database on first start. After that, charges are edited in game. See Database for the table list.
  5. Add inventory items (optional)

    Items are only needed for the features below. If you do not use them, skip this step.
    ItemConfigUsed for
    mdt_tabletConfig.Open.itemOpening the MDT by using the item. Set Config.Open.requireItem = true to make the item mandatory.
    citationConfig.Citations.itemPrinted traffic citations. Using it shows the paper.
    mdt_documentConfig.Forms.itemA signed form document. Using it shows the document.
    bodycamConfig.Bodycams.itemBody camera. Only required when Config.Bodycams.requireItem = true.
    Item names come from the config. Use the same names in your inventory.

    Add to ox_inventory/data/items.lua. Items are made usable through koja-lib:

    ox_inventory/data/items.lua
    ['mdt_tablet'] = {
        label = 'MDT Tablet',
        weight = 500,
        stack = false,
        close = true,
        server = { export = 'koja-lib.useItem' },
    },
    ['citation'] = {
        label = 'Citation',
        weight = 10,
        stack = false,
        close = true,
        consume = 0,
        description = 'A printed traffic citation.',
        server = { export = 'koja-lib.useItem' },
    },
    ['mdt_document'] = {
        label = 'Document',
        weight = 10,
        stack = false,
        close = true,
        consume = 0,
        description = 'A signed MDT document.',
        server = { export = 'koja-lib.useItem' },
    },
    ['bodycam'] = {
        label = 'Body camera',
        weight = 150,
        stack = false,
        close = true,
        consume = 0,
        server = { export = 'koja-lib.useItem' },
    },

    stack = false keeps each citation separate with its own metadata. consume = 0 means using the item does not remove it. The citation entry is the one from the official citations guide; the other three follow the same pattern.

    Copy docs/citation.png and docs/mdt_document.png into ox_inventory/web/images/.

    Add to qb-core/shared/items.lua:

    qb-core/shared/items.lua
    mdt_tablet = { name = 'mdt_tablet', label = 'MDT Tablet', weight = 500, type = 'item', image = 'mdt_tablet.png', unique = true, useable = true, shouldClose = true, description = 'Mobile data terminal.' },
    citation = { name = 'citation', label = 'Citation', weight = 10, type = 'item', image = 'citation.png', unique = true, useable = true, shouldClose = true, description = 'A printed traffic citation.' },
    mdt_document = { name = 'mdt_document', label = 'Document', weight = 10, type = 'item', image = 'mdt_document.png', unique = true, useable = true, shouldClose = true, description = 'A signed MDT document.' },
    bodycam = { name = 'bodycam', label = 'Body camera', weight = 150, type = 'item', image = 'bodycam.png', unique = true, useable = true, shouldClose = true, description = 'Department-issued body camera.' },
    INSERT IGNORE INTO `items` (`name`, `label`, `weight`, `rare`, `can_remove`) VALUES
      ('mdt_tablet', 'MDT Tablet', 1, 0, 1),
      ('citation', 'Citation', 1, 0, 1),
      ('mdt_document', 'Document', 1, 0, 1),
      ('bodycam', 'Body camera', 1, 0, 1);

    If your inventory does not store item metadata, using a citation opens the latest citation written to that player.

    Nothing to do. When koja_grid_inventory is started and Config.Inventory.system is 'auto', koja-mdt registers citation, mdt_document and bodycam itself from Config.Inventory.items (size, weight, image). Set Config.Inventory.registerItems = false to register them yourself, or Config.Inventory.system = 'framework' to use the framework inventory instead.

  6. Set ace permissions

    Two optional aces are used. Add them to server.cfg for your admins:
    server.cfg
    add_ace group.admin koja-mdt.admin allow
    add_ace group.admin koja-mdt.debug allow
    add_ace group.admin koja-mdt.cameras allow
    add_principal identifier.license:xxxxxxxxxxxxxxxx group.admin
    AceConfigGrants
    koja-mdt.adminConfig.Admin.aceFull access to the Admin panel, even without an MDT rank. By default the generic command ace also works (Config.Admin.allowCommandAce).
    koja-mdt.debugConfig.DebugTools.acesThe /mdtdebug demo and test commands. See Demo mode. The generic command ace also works.
    koja-mdt.camerasConfig.Cameras.adminAcePlacing and editing CCTV cameras.
  7. Map your jobs to departments

    Open shared/departments.lua and make sure the jobs of each department match the job names on your server. A framework job that is not listed in any department has no MDT access. See Departments and permissions.
  8. Restart and check the console

    Start the server. The console prints a startup banner with the detected framework, jail, inventory, radial and target integrations. If a line says none for something you use, check that the resource is started before koja-mdt or set the option explicitly. See Integrations.

First-run checklist

  • Server starts without SQL errors in the console.
  • koja-lib, oxmysql and your framework are started before koja-mdt.
  • Your job names are listed in shared/departments.lua.
  • Set Config.Locale to your server language. See Translations.
  • Join with a police job and press F6 or type /mdt. The tablet opens.
  • Go on duty from the dashboard or with /mdtduty.
  • Search a citizen and a plate to check the framework bridge returns data.
  • Write a test report and process a suspect to check fine and jail. See Config.Processing in Configuration.
  • If you use the tablet item, Config.Open.requireItem matches your inventory setup.
  • If you want photos, Config.Camera.uploadUrl is set and screenshot-basic is started.
  • Type /mdtweb and open the address to check the web portal.
  • Before going live: decide whether the demo tools stay on (Config.DebugTools.enabled) and who has the admin aces.