Skip to content

feat: adding jail feature#1131

Open
byayex wants to merge 2 commits into
citizenfx:developfrom
byayex:develop
Open

feat: adding jail feature#1131
byayex wants to merge 2 commits into
citizenfx:developfrom
byayex:develop

Conversation

@byayex

@byayex byayex commented Jul 3, 2026

Copy link
Copy Markdown

Adds a "jail" (timeout) action as an alternative to bans/kicks — instead of removing a player from the server, admins can now confine them in-game for a set duration.

  • Database: new jail action type, with DAO methods to register a jail, add served time, and mark a sentence as finished. Served time only counts while the player is actually online, and it's clamped to the sentence duration. Jails can be revoked the same way bans/warns can.
  • Config: added jailRoutingBucket (default 916) and per-game jail coordinates (jailPosFivem / jailPosRedm, defaulting to Mission Row PD and the Valentine sheriff jail), both validated on input.
  • Enforcement: new jailUtils.ts builds the "jail environment" (bucket + coords) sent to the client; wired through player classes, the player list, and FD3 message handling.
  • Client resources: added sv_jail.lua and cl_jail.lua to actually enforce the jail in-game (routing bucket isolation + teleport).
  • UI: new in-game jail overlay (JailPage.tsx, DialogJailView.tsx) and web panel form/tab (JailForm.tsx, PlayerJailTab.tsx) so admins can jail/release players and see jail history.
  • Events: documented playerJailed (fires on apply and on re-apply after reconnect, carries bucket/coords/remaining time) and playerJailReleased (fires on completion or revocation) so other resources like phone/jobs scripts can react.
  • Permissions: added a new players.jail permission.

Why

Bans and kicks are often too harsh for minor infractions. Jail gives admins a lighter-touch option while still exposing enough events/state (txAdminJailed state bag) for other resources to hook int

Copilot AI review requested due to automatic review settings July 3, 2026 01:49
@byayex
byayex requested a review from tabarra as a code owner July 3, 2026 01:49
@byayex

byayex commented Jul 3, 2026

Copy link
Copy Markdown
Author

PR results of #1055

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new “jail/timeout” punishment type across txAdmin’s backend, FXServer resource enforcement, and both the web panel and in-game (NUI) UIs, including config options and public events for other resources to react to jail state.

Changes:

  • Introduces jail as a first-class action type (DB types/DAO, history/search responses, revoke & completion handling, served-time tracking while online).
  • Adds server/client resource scripts (sv_jail.lua, cl_jail.lua) plus config-driven jail environment (routing bucket + per-game coordinates) and initial-data re-apply on reconnect.
  • Extends panel + NUI UIs to apply/revoke jails and display jail status/history, plus new permission and event documentation.

Reviewed changes

Copilot reviewed 48 out of 48 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
shared/playerApiTypes.ts Extends player history item typing to include jail and jail-specific fields.
shared/historyApiTypes.ts Adds jail stats, table action typing, and jail status for history UI.
resource/sv_jail.lua New server-side jail enforcement (bucket isolation, countdown, release events).
resource/sv_initialData.lua Re-applies pending jail (and emits public event) on initial data.
resource/menu/client/cl_functions.lua Extends persistent alert API to support translation interpolation options.
resource/cl_jail.lua New client-side jail enforcement (teleport/freeze/input block + NUI overlay).
panel/src/pages/Settings/tabCards/gameMenu.tsx Adds UI controls + validation for jail bucket and jail coordinates.
panel/src/pages/History/HistoryTable.tsx Adds jail row styling/icon and active-status icon handling.
panel/src/pages/History/HistorySearchBox.tsx Adds “Jails” filter option.
panel/src/pages/History/HistoryPage.tsx Adds jail totals and aggregates “New Actions Last 7d”.
panel/src/layout/PlayerModal/PlayerModal.tsx Adds a Jail tab to the player modal.
panel/src/layout/PlayerModal/PlayerJailTab.tsx Implements panel-side jail action submission to /player/jail.
panel/src/layout/PlayerModal/PlayerInfoTab.tsx Displays “currently jailed” banner and jail counts.
panel/src/layout/PlayerModal/PlayerHistoryTab.tsx Shows jail items and served-vs-duration footer info.
panel/src/layout/ActionModal/ActionModifyTab.tsx Allows revoking jail actions gated by players.jail permission.
panel/src/layout/ActionModal/ActionModal.tsx Adds jail-specific action modal title formatting.
panel/src/layout/ActionModal/ActionInfoTab.tsx Displays jail “Time Served”/status details.
panel/src/components/JailForm.tsx New reusable jail form (reason + duration selection/custom duration).
nui/src/state/playerModal.state.ts Adds Jail tab enum.
nui/src/state/permissions.state.ts Adds players.jail resolvable permission.
nui/src/MenuWrapper.tsx Mounts the new jail overlay page.
nui/src/hooks/useHudListenersService.tsx Adds translation options support for persistent alerts.
nui/src/components/PlayerModal/Tabs/DialogJailView.tsx Adds in-game (NUI) jail apply dialog.
nui/src/components/PlayerModal/Tabs/DialogInfoView.tsx Includes jail in player action counts.
nui/src/components/PlayerModal/Tabs/DialogHistoryView.tsx Adds jail revoke permission gating + jail history rendering.
nui/src/components/PlayerModal/Tabs/DialogBaseView.tsx Routes Jail tab to its dialog component.
nui/src/components/PlayerModal/PlayerModal.tsx Adds Jail tab button to the in-game player modal UI.
nui/src/components/JailPage/JailPage.tsx New full-screen jail overlay with local countdown tick.
locale/en.json Adds new jail-related translations for NUI + menu.
locale/de.json Adds jail-related keys (currently largely English phrasing).
fxmanifest.lua Registers new jail server/client scripts.
docs/permissions.md Documents new players.jail permission.
docs/events.md Documents playerJailed and playerJailReleased events/payloads.
core/routes/player/modal.ts Includes jail duration/served fields in player modal history mapping.
core/routes/player/actions.ts Adds /player/jail handler and jail environment/event dispatch.
core/routes/history/search.ts Adds derived jailStatus for history table rows.
core/routes/history/actions.ts Adds jail permission to revoke list and clears jail sessions on revoke.
core/modules/FxRunner/handleFd3Messages.ts Handles jail completion FD3 message and finishes jail in DB.
core/modules/FxPlayerlist/index.ts Sends pending jail data on connect (initial-data pathway).
core/modules/DiscordBot/commands/info.ts Includes jail counts in discord “info” output.
core/modules/Database/databaseTypes.ts Adds DatabaseActionJailType and extends DatabaseActionType union.
core/modules/Database/dao/stats.ts Adds jail counts to stats aggregation.
core/modules/Database/dao/actions.ts Adds DAO methods to register jail, add served time, and finish sentence.
core/modules/ConfigStore/schema/gameFeatures.ts Adds jail routing bucket + coordinate config schema validation/defaults.
core/modules/AdminStore/index.js Adds players.jail to permission label mapping.
core/lib/player/playerClasses.ts Tracks served time while online and applies pending jail on connect.
core/lib/player/jailUtils.ts Adds helper to build jail environment from config.
core/lib/misc.ts Adds minute-duration support option and coordinate-string parsing helper.

Comment thread resource/sv_jail.lua Outdated
Comment thread resource/sv_jail.lua Outdated
Comment thread resource/sv_jail.lua
Comment thread panel/src/components/JailForm.tsx
Comment thread core/routes/player/actions.ts Outdated
Comment on lines +267 to 272
if (oldestPendingWarn || oldestActiveJail) {
if (oldestActiveJail) {
this.startJailSession(oldestActiveJail.id);
}
this.#fxPlayerlist.dispatchInitialPlayerData(this.netid, oldestPendingWarn, oldestActiveJail);
}
Comment thread core/lib/misc.ts
Comment on lines 239 to 263
@@ -248,7 +248,9 @@ export const calcExpirationFromDuration = (inputDuration: string) => {
throw new Error(`The duration number must be at least 1.`);
}

if (unit.startsWith('hour')) {
if (allowMinutes && unit.startsWith('minute')) {
duration = multiplier * 60;
} else if (unit.startsWith('hour')) {
duration = multiplier * 3600;
} else if (unit.startsWith('day')) {
duration = multiplier * 86400;
@@ -257,7 +259,7 @@ export const calcExpirationFromDuration = (inputDuration: string) => {
} else if (unit.startsWith('month')) {
duration = multiplier * 2592000; //30 days
} else {
throw new Error(`Invalid ban duration. Supported units: hours, days, weeks, months`);
throw new Error(`Invalid duration. Supported units: ${allowMinutes ? 'minutes, ' : ''}hours, days, weeks, months`);
}
Comment thread core/lib/misc.ts
Comment on lines +271 to +280
/**
* Parses a "x, y, z" coordinates string into an object, or throws if invalid
*/
export const parseCoordsString = (coords: string) => {
const parts = coords.split(',').map((p) => parseFloat(p.trim()));
if (parts.length !== 3 || parts.some((p) => !Number.isFinite(p))) {
throw new Error(`Invalid coordinates string, expected "x, y, z" format.`);
}
return { x: parts[0], y: parts[1], z: parts[2] };
};
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants