├── .github ├── FUNDING.yml ├── dependabot.yml └── ISSUE_TEMPLATE │ ├── feature_request.md │ └── bug_reports.md ├── .npmrc ├── examples ├── esbuild │ ├── .prettierignore │ ├── src │ │ ├── client │ │ │ ├── index.ts │ │ │ └── tsconfig.json │ │ └── server │ │ │ ├── index.ts │ │ │ └── tsconfig.json │ ├── .prettierrc.yaml │ ├── eslint.config.mjs │ ├── esbuild.ts │ ├── package.json │ └── tsconfig.json ├── tsc │ ├── .prettierignore │ ├── src │ │ ├── client │ │ │ ├── index.ts │ │ │ └── tsconfig.json │ │ └── server │ │ │ ├── index.ts │ │ │ └── tsconfig.json │ ├── .prettierrc.yaml │ ├── eslint.config.mjs │ ├── build.mjs │ ├── package.json │ └── tsconfig.json └── README.md ├── packages ├── server │ ├── src │ │ ├── models │ │ │ ├── index.ts │ │ │ └── Ace.ts │ │ ├── utils │ │ │ ├── index.ts │ │ │ ├── serializeToBuffer.ts │ │ │ └── UUID.ts │ │ ├── enums │ │ │ ├── index.ts │ │ │ ├── BucketLockdownMode.ts │ │ │ └── OrphanMode.ts │ │ ├── events │ │ │ ├── emitNetAll.ts │ │ │ ├── index.ts │ │ │ ├── emitNetAllSerialized.ts │ │ │ └── EventNames.ts │ │ ├── index.ts │ │ └── web │ │ │ ├── HttpResponse.ts │ │ │ ├── index.ts │ │ │ ├── HttpRequest.ts │ │ │ ├── requests.ts │ │ │ └── makeRequest.ts │ ├── .npmignore │ ├── tsconfig.json │ └── package.json ├── client │ ├── src │ │ ├── events │ │ │ ├── index.ts │ │ │ └── EventNames.ts │ │ ├── @types │ │ │ ├── Vector.ts │ │ │ ├── Matrix.ts │ │ │ ├── InvertAxis.ts │ │ │ ├── IDrawable.ts │ │ │ ├── EulerAngles.ts │ │ │ ├── index.ts │ │ │ ├── BlipData.ts │ │ │ └── HandlingData.ts │ │ ├── hashes │ │ │ └── index.ts │ │ ├── utils │ │ │ ├── Size.ts │ │ │ ├── index.ts │ │ │ ├── Point.ts │ │ │ └── PointF.ts │ │ ├── enums │ │ │ ├── parachute │ │ │ │ ├── index.ts │ │ │ │ ├── PedParachuteState.ts │ │ │ │ └── ParachuteLandingType.ts │ │ │ ├── others │ │ │ │ ├── index.ts │ │ │ │ ├── ForceType.ts │ │ │ │ ├── InvertAxisFlags.ts │ │ │ │ └── CameraShake.ts │ │ │ ├── hud │ │ │ │ ├── index.ts │ │ │ │ ├── LoadingSpinnerType.ts │ │ │ │ └── HudComponent.ts │ │ │ ├── ui │ │ │ │ ├── CheckboxStyle.ts │ │ │ │ ├── NotificationType.ts │ │ │ │ ├── InputMode.ts │ │ │ │ ├── CursorType.ts │ │ │ │ ├── Alignment.ts │ │ │ │ ├── ControlTypes.ts │ │ │ │ ├── index.ts │ │ │ │ ├── Font.ts │ │ │ │ ├── Language.ts │ │ │ │ ├── CheckpointCustomIconStyle.ts │ │ │ │ ├── MarkerTypes.ts │ │ │ │ └── CheckpointIcon.ts │ │ │ ├── blips │ │ │ │ ├── index.ts │ │ │ │ ├── BlipType.ts │ │ │ │ ├── BlipScale.ts │ │ │ │ ├── BlipDisplay.ts │ │ │ │ └── BlipColors.ts │ │ │ ├── environment │ │ │ │ ├── RopeType.ts │ │ │ │ ├── Relationship.ts │ │ │ │ ├── IntersectionsOptions.ts │ │ │ │ ├── index.ts │ │ │ │ ├── CloudHat.ts │ │ │ │ ├── SpeechModifier.ts │ │ │ │ ├── ZoneID.ts │ │ │ │ └── ExplosionType.ts │ │ │ ├── vehicles │ │ │ │ ├── CargobobHook.ts │ │ │ │ ├── VehicleDoorIndex.ts │ │ │ │ ├── VehicleRoofState.ts │ │ │ │ ├── VehicleToggleModType.ts │ │ │ │ ├── VehicleNeonLight.ts │ │ │ │ ├── LicensePlateType.ts │ │ │ │ ├── VehiclePaintType.ts │ │ │ │ ├── VehicleIndicatorsLights.ts │ │ │ │ ├── LicensePlateStyle.ts │ │ │ │ ├── index.ts │ │ │ │ ├── VehicleWheelIndex.ts │ │ │ │ ├── VehicleMods.ts │ │ │ │ ├── VehicleClass.ts │ │ │ │ └── VehicleDrivingFlags.ts │ │ │ ├── ped │ │ │ │ ├── RagdollType.ts │ │ │ │ ├── index.ts │ │ │ │ ├── Gender.ts │ │ │ │ ├── HelmetType.ts │ │ │ │ └── DrivingStyle.ts │ │ │ └── index.ts │ │ ├── models │ │ │ ├── PedBone.ts │ │ │ ├── PedBoneCollection.ts │ │ │ ├── index.ts │ │ │ ├── EntityBoneCollection.ts │ │ │ ├── VehicleToggleMod.ts │ │ │ ├── Prop.ts │ │ │ ├── EntityBone.ts │ │ │ ├── Player.ts │ │ │ ├── VehicleMod.ts │ │ │ └── VehicleWheel.ts │ │ ├── ui │ │ │ ├── index.ts │ │ │ ├── Notification.ts │ │ │ ├── Effects.ts │ │ │ ├── LoadingPrompt.ts │ │ │ └── Container.ts │ │ ├── index.ts │ │ ├── Checkpoint.ts │ │ └── GameplayCamera.ts │ ├── .npmignore │ ├── tsconfig.json │ └── package.json └── shared │ ├── .npmignore │ ├── src │ ├── enums │ │ ├── peds │ │ │ ├── index.ts │ │ │ ├── PedType.ts │ │ │ └── PedsEnum.ts │ │ ├── weapons │ │ │ ├── index.ts │ │ │ ├── AmmoTypesEnum.ts │ │ │ ├── VehicleWeaponsEnum.ts │ │ │ └── VehicleAmmoTypesEnum.ts │ │ ├── index.ts │ │ ├── others │ │ │ ├── index.ts │ │ │ ├── EntityOrphanMode.ts │ │ │ └── RadioStation.ts │ │ └── vehicle │ │ │ ├── index.ts │ │ │ ├── VehicleWindowTint.ts │ │ │ ├── VehicleLandingGearState.ts │ │ │ ├── VehicleWindowIndex.ts │ │ │ ├── VehicleWheelType.ts │ │ │ ├── VehicleLockState.ts │ │ │ └── VehicleSeat.ts │ ├── @types │ │ ├── utils │ │ │ ├── Errorable.ts │ │ │ ├── Nullable.ts │ │ │ ├── ArrayOrSingle.ts │ │ │ ├── Maybe.ts │ │ │ ├── PromiseOrValue.ts │ │ │ ├── Optional.ts │ │ │ └── index.ts │ │ ├── core │ │ │ ├── Callback.ts │ │ │ ├── AsyncCallback.ts │ │ │ ├── Dictionary.ts │ │ │ ├── Tuple.ts │ │ │ └── index.ts │ │ ├── interfaces │ │ │ ├── index.ts │ │ │ └── Serializable.ts │ │ └── index.ts │ ├── hashes │ │ ├── weapons │ │ │ ├── VehicleWeaponsHash.ts │ │ │ ├── index.ts │ │ │ ├── AmmoTypesHash.ts │ │ │ └── VehicleAmmoTypesHash.ts │ │ └── index.ts │ ├── decorators │ │ ├── index.ts │ │ ├── events │ │ │ ├── index.ts │ │ │ ├── on.ts │ │ │ ├── onNet.ts │ │ │ └── resourceEvent.ts │ │ ├── checks │ │ │ ├── index.ts │ │ │ ├── ClientOnly.ts │ │ │ ├── ServerOnly.ts │ │ │ └── Conditional.ts │ │ ├── game │ │ │ ├── index.ts │ │ │ └── command.ts │ │ └── core │ │ │ ├── index.ts │ │ │ ├── tick.ts │ │ │ ├── thread.ts │ │ │ ├── errorHandler.ts │ │ │ ├── singleton.ts │ │ │ ├── cooldown.ts │ │ │ ├── measureTime.ts │ │ │ └── middleware.ts │ ├── index.ts │ └── utils │ │ ├── vectors │ │ ├── index.ts │ │ └── Vector2.ts │ │ ├── enum │ │ ├── index.ts │ │ ├── getRandomEnumKey.ts │ │ ├── getRandomEnumEntry.ts │ │ └── getRandomEnumValue.ts │ │ ├── index.ts │ │ ├── maths │ │ ├── toDegrees.ts │ │ ├── toRadians.ts │ │ ├── index.ts │ │ ├── clamp.ts │ │ ├── lerp.ts │ │ ├── normalize.ts │ │ ├── isInRange.ts │ │ ├── getRandomInt.ts │ │ ├── distance2D.ts │ │ ├── mapRange.ts │ │ └── distance3D.ts │ │ ├── string │ │ ├── reverseString.ts │ │ ├── index.ts │ │ ├── capitalizeFirstLetter.ts │ │ ├── arrayToString.ts │ │ ├── stringToArray.ts │ │ ├── isPalindrome.ts │ │ ├── padString.ts │ │ ├── capitalizeWords.ts │ │ ├── countSubstringOccurrences.ts │ │ └── truncateString.ts │ │ ├── merge.ts │ │ ├── __tests__ │ │ ├── generateUniqueKey.test.ts │ │ ├── merge.test.ts │ │ └── serializeToJSON.test.ts │ │ ├── generateUniqueKey.ts │ │ ├── eventTimer.ts │ │ └── serializeToJSON.ts │ ├── tsconfig.json │ └── package.json ├── pnpm-workspace.yaml ├── scripts ├── clearBuild.ts ├── clearTurbo.ts └── utils.ts ├── .prettierrc ├── .deepsource.toml ├── .gitignore ├── .editorconfig ├── jestconfig.json ├── typedoc.json ├── turbo.json ├── eslint.config.js ├── LICENSE ├── DEVELOPMENT.md ├── CONTRIBUTING.md └── package.json /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | ko_fi: purpose 2 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | registry=https://registry.npmjs.org/ 2 | loglevel=warn 3 | -------------------------------------------------------------------------------- /examples/esbuild/.prettierignore: -------------------------------------------------------------------------------- 1 | dist/**/* 2 | node_modules/**/* 3 | -------------------------------------------------------------------------------- /examples/tsc/.prettierignore: -------------------------------------------------------------------------------- 1 | dist/**/* 2 | node_modules/**/* 3 | -------------------------------------------------------------------------------- /packages/server/src/models/index.ts: -------------------------------------------------------------------------------- 1 | export { Ace } from './Ace'; 2 | -------------------------------------------------------------------------------- /examples/tsc/src/client/index.ts: -------------------------------------------------------------------------------- 1 | console.log("Hello from client"); 2 | -------------------------------------------------------------------------------- /examples/tsc/src/server/index.ts: -------------------------------------------------------------------------------- 1 | console.log("Hello from server"); 2 | -------------------------------------------------------------------------------- /packages/client/src/events/index.ts: -------------------------------------------------------------------------------- 1 | export * from './EventNames'; 2 | -------------------------------------------------------------------------------- /examples/esbuild/src/client/index.ts: -------------------------------------------------------------------------------- 1 | console.log("Hello from client"); 2 | -------------------------------------------------------------------------------- /examples/esbuild/src/server/index.ts: -------------------------------------------------------------------------------- 1 | console.log("Hello from server"); 2 | -------------------------------------------------------------------------------- /packages/client/.npmignore: -------------------------------------------------------------------------------- 1 | .turbo 2 | node_modules 3 | src 4 | tsconfig.json 5 | -------------------------------------------------------------------------------- /packages/server/.npmignore: -------------------------------------------------------------------------------- 1 | .turbo 2 | node_modules 3 | src 4 | tsconfig.json 5 | -------------------------------------------------------------------------------- /packages/shared/.npmignore: -------------------------------------------------------------------------------- 1 | .turbo 2 | node_modules 3 | src 4 | tsconfig.json 5 | -------------------------------------------------------------------------------- /packages/shared/src/enums/peds/index.ts: -------------------------------------------------------------------------------- 1 | export { PedType } from './PedType'; 2 | -------------------------------------------------------------------------------- /packages/client/src/@types/Vector.ts: -------------------------------------------------------------------------------- 1 | export type Vector = [number, number, number]; 2 | -------------------------------------------------------------------------------- /packages/client/src/hashes/index.ts: -------------------------------------------------------------------------------- 1 | export { MaterialHash } from './MaterialHash'; 2 | -------------------------------------------------------------------------------- /packages/shared/src/@types/utils/Errorable.ts: -------------------------------------------------------------------------------- 1 | export type Errorable = T | Error; 2 | -------------------------------------------------------------------------------- /packages/shared/src/@types/utils/Nullable.ts: -------------------------------------------------------------------------------- 1 | export type Nullable = T | null; 2 | -------------------------------------------------------------------------------- /packages/shared/src/@types/core/Callback.ts: -------------------------------------------------------------------------------- 1 | export type Callback = (value: T) => void; 2 | -------------------------------------------------------------------------------- /packages/shared/src/@types/utils/ArrayOrSingle.ts: -------------------------------------------------------------------------------- 1 | export type ArrayOrSingle = T | T[]; 2 | -------------------------------------------------------------------------------- /packages/shared/src/@types/utils/Maybe.ts: -------------------------------------------------------------------------------- 1 | export type Maybe = T | null | undefined; 2 | -------------------------------------------------------------------------------- /packages/shared/src/enums/weapons/index.ts: -------------------------------------------------------------------------------- 1 | export { WeaponsEnum } from './WeaponsEnum'; 2 | -------------------------------------------------------------------------------- /packages/shared/src/@types/interfaces/index.ts: -------------------------------------------------------------------------------- 1 | export type { Serializable } from './Serializable'; 2 | -------------------------------------------------------------------------------- /packages/shared/src/@types/utils/PromiseOrValue.ts: -------------------------------------------------------------------------------- 1 | export type PromiseOrValue = Promise | T; 2 | -------------------------------------------------------------------------------- /packages/shared/src/@types/core/AsyncCallback.ts: -------------------------------------------------------------------------------- 1 | export type AsyncCallback = (value: T) => Promise; 2 | -------------------------------------------------------------------------------- /packages/shared/src/@types/core/Dictionary.ts: -------------------------------------------------------------------------------- 1 | export type Dictionary = { 2 | [key: string]: T; 3 | }; 4 | -------------------------------------------------------------------------------- /packages/shared/src/@types/utils/Optional.ts: -------------------------------------------------------------------------------- 1 | export type Optional = { 2 | [K in keyof T]?: T[K]; 3 | }; 4 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - "packages/client" 3 | - "packages/shared" 4 | - "packages/server" 5 | -------------------------------------------------------------------------------- /scripts/clearBuild.ts: -------------------------------------------------------------------------------- 1 | import { deleteDirectories } from './utils'; 2 | 3 | void deleteDirectories('packages', 'dist'); 4 | -------------------------------------------------------------------------------- /packages/shared/src/@types/index.ts: -------------------------------------------------------------------------------- 1 | export * from './core'; 2 | export * from './interfaces'; 3 | export * from './utils'; 4 | -------------------------------------------------------------------------------- /packages/shared/src/enums/weapons/AmmoTypesEnum.ts: -------------------------------------------------------------------------------- 1 | // @todo: finish 2 | export enum AmmoTypesEnum { 3 | Unknown = -1, 4 | } 5 | -------------------------------------------------------------------------------- /packages/shared/src/enums/weapons/VehicleWeaponsEnum.ts: -------------------------------------------------------------------------------- 1 | // @todo: finish 2 | export enum VehicleWeaponsEnum { 3 | Unknown = -1, 4 | } 5 | -------------------------------------------------------------------------------- /packages/client/src/@types/Matrix.ts: -------------------------------------------------------------------------------- 1 | import { Vector } from './Vector'; 2 | 3 | export type Matrix = [Vector, Vector, Vector, Vector]; 4 | -------------------------------------------------------------------------------- /packages/server/src/utils/index.ts: -------------------------------------------------------------------------------- 1 | export { serializeToBuffer } from './serializeToBuffer'; 2 | export { uuidv4, uuidv5 } from './UUID'; 3 | -------------------------------------------------------------------------------- /packages/shared/src/enums/weapons/VehicleAmmoTypesEnum.ts: -------------------------------------------------------------------------------- 1 | // @todo: finish 2 | export enum VehicleAmmoTypesEnum { 3 | Unknown = -1, 4 | } 5 | -------------------------------------------------------------------------------- /packages/shared/src/hashes/weapons/VehicleWeaponsHash.ts: -------------------------------------------------------------------------------- 1 | //@todo: finish that 2 | export enum VehicleWeaponsHash { 3 | Unknown = -1, 4 | } 5 | -------------------------------------------------------------------------------- /packages/client/src/utils/Size.ts: -------------------------------------------------------------------------------- 1 | export class Size { 2 | constructor( 3 | public width: number, 4 | public height: number, 5 | ) {} 6 | } 7 | -------------------------------------------------------------------------------- /packages/server/src/enums/index.ts: -------------------------------------------------------------------------------- 1 | export { BucketLockdownMode } from './BucketLockdownMode'; 2 | export { OrphanMode } from './OrphanMode'; 3 | -------------------------------------------------------------------------------- /packages/shared/src/decorators/index.ts: -------------------------------------------------------------------------------- 1 | export * from './checks'; 2 | export * from './core'; 3 | export * from './events'; 4 | export * from './game'; 5 | -------------------------------------------------------------------------------- /packages/shared/src/enums/index.ts: -------------------------------------------------------------------------------- 1 | export * from './others'; 2 | export * from './peds'; 3 | export * from './vehicle'; 4 | export * from './weapons'; 5 | -------------------------------------------------------------------------------- /packages/client/src/@types/InvertAxis.ts: -------------------------------------------------------------------------------- 1 | import { InvertAxisFlags } from '../enums'; 2 | 3 | export interface InvertAxis { 4 | flags: InvertAxisFlags; 5 | } 6 | -------------------------------------------------------------------------------- /packages/server/src/events/emitNetAll.ts: -------------------------------------------------------------------------------- 1 | export function emitNetAll(eventName: string, ...args: unknown[]): void { 2 | emitNet(eventName, -1, ...args); 3 | } 4 | -------------------------------------------------------------------------------- /packages/shared/src/@types/interfaces/Serializable.ts: -------------------------------------------------------------------------------- 1 | export interface Serializable { 2 | serialize(): string; 3 | deserialize(input: string): this; 4 | } 5 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 100, 3 | "trailingComma": "all", 4 | "singleQuote": true, 5 | "arrowParens": "avoid", 6 | "tabWidth": 4 7 | } 8 | -------------------------------------------------------------------------------- /packages/shared/src/decorators/events/index.ts: -------------------------------------------------------------------------------- 1 | export { On } from './on'; 2 | export { OnNet } from './onNet'; 3 | export { ResourceEvent } from './resourceEvent'; 4 | -------------------------------------------------------------------------------- /packages/client/src/enums/parachute/index.ts: -------------------------------------------------------------------------------- 1 | export { ParachuteLandingType } from './ParachuteLandingType'; 2 | export { PedParachuteState } from './PedParachuteState'; 3 | -------------------------------------------------------------------------------- /packages/server/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './enums'; 2 | export * from './events'; 3 | export * from './models'; 4 | export * from './utils'; 5 | export * from './web'; 6 | -------------------------------------------------------------------------------- /.deepsource.toml: -------------------------------------------------------------------------------- 1 | version = 1 2 | 3 | [[analyzers]] 4 | name = "javascript" 5 | 6 | [analyzers.meta] 7 | environment = [ 8 | "nodejs", 9 | "jest" 10 | ] -------------------------------------------------------------------------------- /scripts/clearTurbo.ts: -------------------------------------------------------------------------------- 1 | import { deleteDirectories, deleteDirectory } from './utils'; 2 | 3 | void deleteDirectories('packages', '.turbo'); 4 | void deleteDirectory('.turbo'); 5 | -------------------------------------------------------------------------------- /packages/shared/src/hashes/index.ts: -------------------------------------------------------------------------------- 1 | export * from './weapons'; 2 | 3 | export { VehiclesHash } from './VehiclesHash'; 4 | export { WeatherTypeHash } from './WeatherTypeHash'; 5 | -------------------------------------------------------------------------------- /packages/shared/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './@types'; 2 | export * from './decorators'; 3 | export * from './enums'; 4 | export * from './hashes'; 5 | export * from './utils'; 6 | -------------------------------------------------------------------------------- /packages/client/src/enums/others/index.ts: -------------------------------------------------------------------------------- 1 | export { CameraShake } from './CameraShake'; 2 | export { ForceType } from './ForceType'; 3 | export { InvertAxisFlags } from './InvertAxisFlags'; 4 | -------------------------------------------------------------------------------- /packages/shared/src/decorators/checks/index.ts: -------------------------------------------------------------------------------- 1 | export { ClientOnly } from './ClientOnly'; 2 | export { Conditional } from './Conditional'; 3 | export { ServerOnly } from './ServerOnly'; 4 | -------------------------------------------------------------------------------- /packages/client/src/enums/hud/index.ts: -------------------------------------------------------------------------------- 1 | export { HudColors } from './HudColors'; 2 | export { HudComponent } from './HudComponent'; 3 | export { LoadingSpinnerType } from './LoadingSpinnerType'; 4 | -------------------------------------------------------------------------------- /packages/server/src/events/index.ts: -------------------------------------------------------------------------------- 1 | export { emitNetAll } from './emitNetAll'; 2 | export { emitNetAllSerialized } from './emitNetAllSerialized'; 3 | export { EventNames } from './EventNames'; 4 | -------------------------------------------------------------------------------- /packages/shared/src/decorators/game/index.ts: -------------------------------------------------------------------------------- 1 | export { Command } from './command'; 2 | export { Config, getConfig } from './config'; 3 | export { RateLimitPerPlayer } from './rateLimitPerPlayer'; 4 | -------------------------------------------------------------------------------- /packages/shared/src/utils/vectors/index.ts: -------------------------------------------------------------------------------- 1 | export { Vector } from './Vector'; 2 | export { Vector2 } from './Vector2'; 3 | export { Vector3 } from './Vector3'; 4 | export { Vector4 } from './Vector4'; 5 | -------------------------------------------------------------------------------- /packages/shared/src/hashes/weapons/index.ts: -------------------------------------------------------------------------------- 1 | export { AmmoTypesHash } from './AmmoTypesHash'; 2 | export { VehicleAmmoTypesHash } from './VehicleAmmoTypesHash'; 3 | export { WeaponsHash } from './WeaponsHash'; 4 | -------------------------------------------------------------------------------- /packages/client/src/enums/ui/CheckboxStyle.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enum representing different styles for a checkbox. 3 | * 4 | * @enum {number} 5 | */ 6 | export enum CheckboxStyle { 7 | Tick, 8 | Cross, 9 | } 10 | -------------------------------------------------------------------------------- /packages/client/src/enums/blips/index.ts: -------------------------------------------------------------------------------- 1 | export { BlipColors } from './BlipColors'; 2 | export { BlipDisplay } from './BlipDisplay'; 3 | export { BlipScale } from './BlipScale'; 4 | export { BlipType } from './BlipType'; 5 | -------------------------------------------------------------------------------- /packages/client/src/enums/environment/RopeType.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Represents different types of ropes. 3 | * 4 | * @enum{number} 5 | */ 6 | export enum RopeType { 7 | ThickRope = 4, 8 | ThinMetalWire = 5, 9 | } 10 | -------------------------------------------------------------------------------- /packages/server/src/web/HttpResponse.ts: -------------------------------------------------------------------------------- 1 | export interface HttpResponse { 2 | writeHead(code: number, headers?: Record): void; 3 | write(data: string): void; 4 | send(data?: string): void; 5 | } 6 | -------------------------------------------------------------------------------- /packages/shared/src/utils/enum/index.ts: -------------------------------------------------------------------------------- 1 | export { getRandomEnumEntry } from './getRandomEnumEntry'; 2 | export { getRandomEnumKey } from './getRandomEnumKey'; 3 | export { getRandomEnumValue } from './getRandomEnumValue'; 4 | -------------------------------------------------------------------------------- /packages/client/src/utils/index.ts: -------------------------------------------------------------------------------- 1 | export { Color } from './Color'; 2 | export { Point } from './Point'; 3 | export { PointF } from './PointF'; 4 | export { Quaternion } from './Quaternion'; 5 | export { Size } from './Size'; 6 | -------------------------------------------------------------------------------- /packages/client/src/@types/IDrawable.ts: -------------------------------------------------------------------------------- 1 | import { Color, Point, Size } from '../utils'; 2 | 3 | export interface IDrawable { 4 | pos: Point; 5 | size?: Size; 6 | color?: Color; 7 | draw(offset?: Size, resolution?: Size): void; 8 | } 9 | -------------------------------------------------------------------------------- /packages/shared/src/@types/core/Tuple.ts: -------------------------------------------------------------------------------- 1 | export type Tuple = [...T]; 2 | export type Tuple2 = [T1, T2]; 3 | export type Tuple3 = [T1, T2, T3]; 4 | export type Tuple4 = [T1, T2, T3, T4]; 5 | -------------------------------------------------------------------------------- /packages/client/src/enums/vehicles/CargobobHook.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enum representing different types of hooks that can be attached to a Cargobob. 3 | * 4 | * @enum {number} 5 | */ 6 | export enum CargobobHook { 7 | Hook, 8 | Magnet, 9 | } 10 | -------------------------------------------------------------------------------- /packages/shared/src/enums/others/index.ts: -------------------------------------------------------------------------------- 1 | export { BlipSprites } from './BlipSprites'; 2 | export { EntityOrphanMode } from './EntityOrphanMode'; 3 | export { RadioStation } from './RadioStation'; 4 | export { WeatherEnum } from './WeatherEnum'; 5 | -------------------------------------------------------------------------------- /packages/server/src/events/emitNetAllSerialized.ts: -------------------------------------------------------------------------------- 1 | import { serializeToJSON } from '@fivem-ts/shared'; 2 | 3 | export function emitNetAllSerialized(eventName: string, ...args: unknown[]): void { 4 | emitNet(eventName, -1, serializeToJSON(args)); 5 | } 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | coverage 3 | .turbo 4 | dist 5 | npm-debug.log* 6 | yarn-debug.log* 7 | yarn-error.log* 8 | .DS_Store 9 | *.pem 10 | .idea 11 | .vscode 12 | test-results 13 | temp-docs 14 | package-lock.json 15 | pnpm-lock.yaml 16 | .k8 17 | -------------------------------------------------------------------------------- /packages/client/src/enums/ped/RagdollType.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Represents the types of Ragdoll available. 3 | * 4 | * @enum{number} 5 | */ 6 | export enum RagdollType { 7 | Normal = 0, 8 | StiffLegs = 1, 9 | NarrowLegs = 2, 10 | WideLegs = 3, 11 | } 12 | -------------------------------------------------------------------------------- /packages/client/src/enums/ped/index.ts: -------------------------------------------------------------------------------- 1 | export { Bone } from './Bone'; 2 | export { DrivingStyle } from './DrivingStyle'; 3 | export { Gender } from './Gender'; 4 | export { HelmetType } from './HelmetType'; 5 | export { RagdollType } from './RagdollType'; 6 | -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 |

fivem-ts examples

2 | 3 | ## Examples list 4 | 5 | - [esbuild](https://github.com/Purpose-Dev/fivem-ts/tree/main/examples/esbuild) 6 | - [tsc](https://github.com/Purpose-Dev/fivem-ts/tree/main/examples/tsc) 7 | -------------------------------------------------------------------------------- /packages/client/src/enums/ped/Gender.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enumeration representing gender. 3 | * It contains the following values: 4 | * - `Male` 5 | * - `Female` 6 | * 7 | * @enum{number} 8 | */ 9 | export enum Gender { 10 | Male, 11 | Female, 12 | } 13 | -------------------------------------------------------------------------------- /packages/shared/src/@types/core/index.ts: -------------------------------------------------------------------------------- 1 | export type { AsyncCallback } from './AsyncCallback'; 2 | export type { Callback } from './Callback'; 3 | export type { Dictionary } from './Dictionary'; 4 | export type { Tuple, Tuple2, Tuple3, Tuple4 } from './Tuple'; 5 | -------------------------------------------------------------------------------- /examples/tsc/.prettierrc.yaml: -------------------------------------------------------------------------------- 1 | trailingComma: es5 2 | bracketSpacing: true 3 | arrowParens: always 4 | endOfLine: auto 5 | htmlWhitespaceSensitivity: css 6 | bracketSameLine: true 7 | jsxSingleQuote: false 8 | printWidth: 200 9 | tabWidth: 4 10 | semi: true 11 | -------------------------------------------------------------------------------- /packages/client/src/enums/index.ts: -------------------------------------------------------------------------------- 1 | export * from './blips'; 2 | export * from './environment'; 3 | export * from './hud'; 4 | export * from './others'; 5 | export * from './parachute'; 6 | export * from './ped'; 7 | export * from './ui'; 8 | export * from './vehicles'; 9 | -------------------------------------------------------------------------------- /examples/esbuild/.prettierrc.yaml: -------------------------------------------------------------------------------- 1 | trailingComma: es5 2 | bracketSpacing: true 3 | arrowParens: always 4 | endOfLine: auto 5 | htmlWhitespaceSensitivity: css 6 | bracketSameLine: true 7 | jsxSingleQuote: false 8 | printWidth: 200 9 | tabWidth: 4 10 | semi: true 11 | -------------------------------------------------------------------------------- /packages/server/src/utils/serializeToBuffer.ts: -------------------------------------------------------------------------------- 1 | import { serializeToJSON } from '@fivem-ts/shared'; 2 | 3 | export function serializeToBuffer(data: unknown): Buffer { 4 | if (Buffer.isBuffer(data)) { 5 | return data; 6 | } 7 | 8 | return Buffer.from(serializeToJSON(data), 'utf8'); 9 | } 10 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | insert_final_newline = true 6 | indent_style = space 7 | indent_size = 4 8 | max_line_length = 100 9 | 10 | [*.md] 11 | trim_trailing_whitespace = false 12 | indent_size = 2 13 | 14 | [*.yml] 15 | trim_trailing_whitespace = false 16 | indent_size = 2 -------------------------------------------------------------------------------- /packages/client/src/enums/hud/LoadingSpinnerType.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enum representing different types of loading spinner animations. 3 | * 4 | * @enum{number} 5 | */ 6 | export enum LoadingSpinnerType { 7 | Clockwise1 = 1, 8 | Clockwise2, 9 | Clockwise3, 10 | SocialClubSaving, 11 | RegularClockwise, 12 | } 13 | -------------------------------------------------------------------------------- /packages/client/src/enums/parachute/PedParachuteState.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enum representing the various states of a ped in relation to parachute usage. 3 | * 4 | * @enum{number} 5 | */ 6 | export enum PedParachuteState { 7 | Normal = -1, 8 | Wearing, 9 | Opening, 10 | Open, 11 | LandingOrFallingToDoom, 12 | } 13 | -------------------------------------------------------------------------------- /packages/client/src/enums/vehicles/VehicleDoorIndex.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enumeration for vehicle door indices. 3 | * 4 | * @enum{number} 5 | */ 6 | export enum VehicleDoorIndex { 7 | FrontRightDoor = 1, 8 | FrontLeftDoor = 0, 9 | BackRightDoor = 3, 10 | BackLeftDoor = 2, 11 | Hood = 4, 12 | Trunk = 5, 13 | } 14 | -------------------------------------------------------------------------------- /packages/server/src/web/index.ts: -------------------------------------------------------------------------------- 1 | export type { HttpRequest } from './HttpRequest'; 2 | export type { HttpResponse } from './HttpResponse'; 3 | export type { RequestData, RequestHeaders, RequestMethods } from './makeRequest'; 4 | export { makeRequest } from './makeRequest'; 5 | export { del, get, put, post } from './requests'; 6 | -------------------------------------------------------------------------------- /packages/client/src/enums/environment/Relationship.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enum representing relationship relation between Peds 3 | * 4 | * @enum{number} 5 | */ 6 | export enum Relationship { 7 | Companion = 0, 8 | Respect = 1, 9 | Like = 2, 10 | Neutral = 3, 11 | Dislike = 4, 12 | Hate = 5, 13 | Pedestrians = 255, 14 | } 15 | -------------------------------------------------------------------------------- /packages/shared/src/@types/utils/index.ts: -------------------------------------------------------------------------------- 1 | export type { ArrayOrSingle } from './ArrayOrSingle'; 2 | export type { Errorable } from './Errorable'; 3 | export type { Maybe } from './Maybe'; 4 | export type { Nullable } from './Nullable'; 5 | export type { Optional } from './Optional'; 6 | export type { PromiseOrValue } from './PromiseOrValue'; 7 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "npm" 4 | directory: "/" 5 | schedule: 6 | interval: "daily" 7 | time: "03:00" 8 | timezone: "Europe/Paris" 9 | labels: 10 | - "dependencies" 11 | commit-message: 12 | prefix: "Chore" 13 | open-pull-requests-limit: 5 14 | -------------------------------------------------------------------------------- /packages/client/src/enums/ui/NotificationType.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enum representing various types of notifications. 3 | * 4 | * @enum{number} 5 | */ 6 | export enum NotificationType { 7 | Default = 0, 8 | Bubble = 1, 9 | Mail = 2, 10 | FriendRequest = 3, 11 | Default2 = 4, 12 | Reply = 7, 13 | ReputationPoints = 8, 14 | Money = 9, 15 | } 16 | -------------------------------------------------------------------------------- /packages/client/src/enums/others/ForceType.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enumeration representing different types of forces. 3 | * 4 | * ForceType is used to define constants that represent various force behaviors. 5 | * 6 | * @enum{number} 7 | */ 8 | export enum ForceType { 9 | MinForce, 10 | MaxForceRot, 11 | MinForce2, 12 | MaxForceRot2, 13 | ForceNoRot, 14 | ForceRotPlusForce, 15 | } 16 | -------------------------------------------------------------------------------- /packages/client/src/enums/ui/InputMode.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enum representing the input modes available for user interaction. 3 | * 4 | * The `InputMode` enum defines the mode of input being used by the user, 5 | * such as a combination of mouse and keyboard or a gamepad. 6 | * 7 | * @enum{number} 8 | */ 9 | export enum InputMode { 10 | MouseAndKeyboard = 0, 11 | GamePad = 2, 12 | } 13 | -------------------------------------------------------------------------------- /packages/client/src/enums/blips/BlipType.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enum representing different types of blips. 3 | * 4 | * @enum{number} 5 | */ 6 | export enum BlipType { 7 | Vehicle = 1, 8 | Ped = 2, 9 | Object = 3, 10 | Destination = 4, 11 | Cont = 5, 12 | PickupUnk = 6, 13 | Radius = 7, 14 | Pickup = 8, 15 | Cop = 9, 16 | Area = 10, 17 | Gallery = 11, 18 | PickupObject = 12, 19 | } 20 | -------------------------------------------------------------------------------- /packages/server/src/web/HttpRequest.ts: -------------------------------------------------------------------------------- 1 | export interface HttpRequest { 2 | address: string; 3 | headers: Record; 4 | method: string; 5 | path: string; 6 | body?: unknown; 7 | setDataHandler(handler: (data: string) => void): void; 8 | setDataHandler(handler: (data: ArrayBuffer) => void, binary: 'binary'): void; 9 | setCancelHandler(handler: () => void): void; 10 | } 11 | -------------------------------------------------------------------------------- /packages/shared/src/enums/vehicle/index.ts: -------------------------------------------------------------------------------- 1 | export { VehicleLandingGearState } from './VehicleLandingGearState'; 2 | export { VehicleLockState } from './VehicleLockState'; 3 | export { VehicleSeat } from './VehicleSeat'; 4 | export { VehicleWheelType } from './VehicleWheelType'; 5 | export { VehicleWindowIndex } from './VehicleWindowIndex'; 6 | export { VehicleWindowTint } from './VehicleWindowTint'; 7 | -------------------------------------------------------------------------------- /packages/shared/src/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './enum'; 2 | export * from './maths'; 3 | export * from './string'; 4 | export * from './vectors'; 5 | 6 | export { eventTimer } from './eventTimer'; 7 | export { generateUniqueKey } from './generateUniqueKey'; 8 | export { merge } from './merge'; 9 | export { serializeToJSON } from './serializeToJSON'; 10 | export { waitFor } from './waitFor'; 11 | -------------------------------------------------------------------------------- /packages/client/src/enums/environment/IntersectionsOptions.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * List of possible entity intersections. Used for RayCasting. 3 | * 4 | * @enum{number} 5 | */ 6 | export enum IntersectionsOptions { 7 | Everything = -1, 8 | Map = 1, 9 | MissionEntities, 10 | Peds1 = 12, 11 | Objects = 16, 12 | Unk1 = 32, 13 | Unk2 = 64, 14 | Unk3 = 128, 15 | Vegetation = 256, 16 | Unk4 = 512, 17 | } 18 | -------------------------------------------------------------------------------- /packages/client/src/@types/EulerAngles.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Represents the Euler angles in radians. 3 | */ 4 | export type EulerAngles = { 5 | /** 6 | * Rotation around the X-axis in radians. 7 | */ 8 | roll: number; 9 | 10 | /** 11 | * Rotation around the Y-axis in radians. 12 | */ 13 | pitch: number; 14 | 15 | /** 16 | * Rotation around the Z-axis in radians. 17 | */ 18 | yaw: number; 19 | }; 20 | -------------------------------------------------------------------------------- /packages/client/src/enums/others/InvertAxisFlags.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enum representing flags used to specify axis inversion. 3 | * 4 | * Values: 5 | * - `None`: No axis inversion (default). 6 | * - `X`: Invert the X-axis. 7 | * - `Y`: Invert the Y-axis. 8 | * - `Z`: Invert the Z-axis. 9 | * 10 | * @enum{number} 11 | */ 12 | export enum InvertAxisFlags { 13 | None = 0, 14 | X = 1, 15 | Y = 2, 16 | Z = 4, 17 | } 18 | -------------------------------------------------------------------------------- /packages/client/src/@types/index.ts: -------------------------------------------------------------------------------- 1 | export type { BlipData } from './BlipData'; 2 | export type { EulerAngles } from './EulerAngles'; 3 | export type { HandlingData } from './HandlingData'; 4 | export type { IDrawable } from './IDrawable'; 5 | export type { InvertAxis } from './InvertAxis'; 6 | export type { Matrix } from './Matrix'; 7 | export type { RadarZoomLevel } from './RadarZoomLevel'; 8 | export type { Vector } from './Vector'; 9 | -------------------------------------------------------------------------------- /packages/client/src/enums/ui/CursorType.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enum representing different cursor types. 3 | * 4 | * @enum{number} 5 | */ 6 | export enum CursorType { 7 | None = 0, 8 | Normal = 1, 9 | TransparentNormal = 2, 10 | PreGrab = 3, 11 | Grab = 4, 12 | MiddleFinger = 5, 13 | LeftArrow = 6, 14 | RightArrow = 7, 15 | UpArrow = 8, 16 | DownArrow = 9, 17 | HorizontalExpand = 10, 18 | Add = 11, 19 | Remove = 12, 20 | } 21 | -------------------------------------------------------------------------------- /packages/shared/src/utils/maths/toDegrees.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Converts an angle from radians to degrees. 3 | * 4 | * @example 5 | * ```ts 6 | * toDegrees(Math.PI); // 180 7 | * toDegrees(Math.PI / 2); // 90 8 | * ``` 9 | * 10 | * @param {number} radians - The angle in radians. 11 | * 12 | * @returns {number} The angle in degrees. 13 | */ 14 | export function toDegrees(radians: number): number { 15 | return radians * (180 / Math.PI); 16 | } 17 | -------------------------------------------------------------------------------- /packages/shared/src/utils/maths/toRadians.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Converts an angle from degrees to radians. 3 | * 4 | * @example 5 | * ```ts 6 | * toRadians(180); // Math.PI 7 | * toRadians(90); // Math.PI / 2 8 | * ``` 9 | * 10 | * @param {number} degrees - The angle in degrees. 11 | * 12 | * @returns {number} The angle in radians. 13 | */ 14 | export function toRadians(degrees: number): number { 15 | return degrees * (Math.PI / 180); 16 | } 17 | -------------------------------------------------------------------------------- /examples/esbuild/src/client/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["../../tsconfig.json"], 3 | "compilerOptions": { 4 | "target": "ES2017", 5 | "module": "ESNext", 6 | "lib": ["ES2017"], 7 | "moduleResolution": "Node", 8 | "types": [ 9 | "@fivem-ts/client", 10 | "@citizenfx/client" 11 | ], 12 | "baseUrl": "./" 13 | }, 14 | "include": [ 15 | "./**/*.ts" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /examples/esbuild/src/server/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["../../tsconfig.json"], 3 | "compilerOptions": { 4 | "target": "ES2017", 5 | "module": "CommonJS", 6 | "lib": ["ES2017"], 7 | "moduleResolution": "Node", 8 | "types": [ 9 | "@fivem-ts/server", 10 | "@citizenfx/server" 11 | ], 12 | "baseUrl": "./" 13 | }, 14 | "include": [ 15 | "./**/*.ts" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /packages/shared/src/enums/peds/PedType.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enum representing different types of pedestrians. 3 | * 4 | * PedType enumerates the possible pedestrian types in the system: 5 | * - `CivMale`: Represents a civilian male. 6 | * - `CivFemale`: Represents a civilian female. 7 | * - `Animal`: Represents an animal. 8 | * 9 | * @enum{string} 10 | */ 11 | export enum PedType { 12 | CivMale = 'CIVMALE', 13 | CivFemale = 'CIVFEMALE', 14 | Animal = 'ANIMAL', 15 | } 16 | -------------------------------------------------------------------------------- /packages/shared/src/utils/maths/index.ts: -------------------------------------------------------------------------------- 1 | export { clamp } from './clamp'; 2 | export { distance2D } from './distance2D'; 3 | export { distance3D } from './distance3D'; 4 | export { getRandomInt } from './getRandomInt'; 5 | export { isInRange } from './isInRange'; 6 | export { lerp } from './lerp'; 7 | export { mapRange } from './mapRange'; 8 | export { normalize } from './normalize'; 9 | export { toDegrees } from './toDegrees'; 10 | export { toRadians } from './toRadians'; 11 | -------------------------------------------------------------------------------- /packages/shared/src/utils/string/reverseString.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Reverses the characters in a string. 3 | * 4 | * @example 5 | * ```ts 6 | * const result = reverseString("Hello"); 7 | * console.log(result); // "olleH" 8 | * ``` 9 | * 10 | * @param {string} input - The string to be reversed. 11 | * 12 | * @returns {string} The reversed string. 13 | */ 14 | export function reverseString(input: string): string { 15 | return input.split('').reverse().join(''); 16 | } 17 | -------------------------------------------------------------------------------- /packages/client/src/enums/environment/index.ts: -------------------------------------------------------------------------------- 1 | export { AudioFlag } from './AudioFlag'; 2 | export { CloudHat } from './CloudHat'; 3 | export { ExplosionType } from './ExplosionType'; 4 | export { IntersectionsOptions } from './IntersectionsOptions'; 5 | export { MaterialEnum } from './MaterialEnum'; 6 | export { Relationship } from './Relationship'; 7 | export { RopeType } from './RopeType'; 8 | export { SpeechModifier } from './SpeechModifier'; 9 | export { ZoneID } from './ZoneID'; 10 | -------------------------------------------------------------------------------- /packages/shared/src/decorators/core/index.ts: -------------------------------------------------------------------------------- 1 | export { Cache } from './cache'; 2 | export { Cooldown } from './cooldown'; 3 | export { ErrorHandler } from './errorHandler'; 4 | export { MeasureTime } from './measureTime'; 5 | export { Middleware } from './middleware'; 6 | export { Retry, getRetryMetadata } from './retry'; 7 | export type { RetryValue } from './retry'; 8 | export { Singleton } from './singleton'; 9 | export { Thread } from './thread'; 10 | export { Tick } from './tick'; 11 | -------------------------------------------------------------------------------- /jestconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "transform": { 3 | "^.+\\.(t|j)sx?$": "ts-jest" 4 | }, 5 | "testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$", 6 | "moduleFileExtensions": ["ts", "js", "json", "node"], 7 | "reporters": [ 8 | "default", 9 | [ 10 | "jest-junit", 11 | { 12 | "outputDirectory": "./test-results", 13 | "outputName": "jest-junit.xml" 14 | } 15 | ] 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /examples/tsc/src/client/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["../../tsconfig.json"], 3 | "compilerOptions": { 4 | "target": "ES2017", 5 | "module": "ESNext", 6 | "lib": ["ES2017"], 7 | "moduleResolution": "Node", 8 | "types": [ 9 | "@fivem-ts/client", 10 | "@citizenfx/client" 11 | ], 12 | "baseUrl": "./", 13 | "outDir": "../../dist/client/" 14 | }, 15 | "include": [ 16 | "./**/*.ts" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /examples/tsc/src/server/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["../../tsconfig.json"], 3 | "compilerOptions": { 4 | "target": "ES2017", 5 | "module": "CommonJS", 6 | "lib": ["ES2017"], 7 | "moduleResolution": "Node", 8 | "types": [ 9 | "@fivem-ts/server", 10 | "@citizenfx/server" 11 | ], 12 | "baseUrl": "./", 13 | "outDir": "../../dist/server/" 14 | }, 15 | "include": [ 16 | "./**/*.ts" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /packages/client/src/enums/ui/Alignment.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enumeration representing alignment options. 3 | * 4 | * Provides different types of text alignment for UI components. 5 | * 6 | * - `Left`: Aligns text to the left. 7 | * - `Centered`: Centers the text. 8 | * - `Right`: Aligns text to the right. 9 | * 10 | * Example usage: 11 | * ```ts 12 | * const alignment: Alignment = Alignment.Left; 13 | * ``` 14 | * 15 | * @enum{number} 16 | */ 17 | export enum Alignment { 18 | Left, 19 | Centered, 20 | Right, 21 | } 22 | -------------------------------------------------------------------------------- /packages/client/src/models/PedBone.ts: -------------------------------------------------------------------------------- 1 | import { EntityBone, Ped } from '.'; 2 | import { Bone } from '../enums'; 3 | 4 | /** 5 | * Represents a specific bone in a pedestrian entity. 6 | * Extends EntityBone to provide additional functionality specific to pedestrians. 7 | * 8 | * @class PedBone 9 | * @extends EntityBone 10 | * @see {EntityBone} 11 | */ 12 | export class PedBone extends EntityBone { 13 | constructor(owner: Ped, boneId: Bone) { 14 | super(owner, GetPedBoneIndex(owner.Handle, boneId)); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /packages/client/src/enums/vehicles/VehicleRoofState.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enum representing the possible states of a vehicle's roof. 3 | * 4 | * Values: 5 | * - `Closed`: Indicates the roof is fully closed. 6 | * - `Closing`: Indicates the roof is in the process of closing. 7 | * - `Opened`: Indicates the roof is fully open. 8 | * - `Opening`: Indicates the roof is in the process of opening. 9 | * 10 | * @enum{number} 11 | */ 12 | export enum VehicleRoofState { 13 | Closed, 14 | Closing, 15 | Opened, 16 | Opening, 17 | } 18 | -------------------------------------------------------------------------------- /packages/client/src/enums/vehicles/VehicleToggleModType.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enum representing different types of toggleable vehicle modifications. 3 | * 4 | * Values: 5 | * - Turbo: Represents the turbo modification (value 18). 6 | * - TireSmoke: Represents the tire smoke modification (value 20). 7 | * - XenonHeadlights: Represents the xenon headlights modification (value 22). 8 | * 9 | * @enum{number} 10 | */ 11 | export enum VehicleToggleModType { 12 | Turbo = 18, 13 | TireSmoke = 20, 14 | XenonHeadlights = 22, 15 | } 16 | -------------------------------------------------------------------------------- /packages/client/src/ui/index.ts: -------------------------------------------------------------------------------- 1 | export { Container } from './Container'; 2 | export { Effects } from './Effects'; 3 | export { Fading } from './Fading'; 4 | export { Hud } from './Hud'; 5 | export { LoadingPrompt } from './LoadingPrompt'; 6 | export { Notification } from './Notification'; 7 | export { Rectangle } from './Rectangle'; 8 | export { Scaleform } from './Scaleform'; 9 | export { Screen } from './Screen'; 10 | export { Sprite } from './Sprite'; 11 | export { Text } from './Text'; 12 | export { Timerbar } from './Timerbar'; 13 | -------------------------------------------------------------------------------- /packages/shared/src/enums/vehicle/VehicleWindowTint.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enumeration representing different types of vehicle window tints. 3 | * 4 | * @enum {number} 5 | */ 6 | export enum VehicleWindowTint { 7 | /** No Tint */ 8 | None = 0, 9 | /** Completely black tint */ 10 | PureBlack = 1, 11 | /** Dark smoke tint */ 12 | DarkSmoke = 2, 13 | /** Light smoke tint */ 14 | LightSmoke = 3, 15 | /** Factory-provided tint */ 16 | Stock = 4, 17 | /** Limo-style dark tint */ 18 | Limo = 5, 19 | /** Green tint */ 20 | Green = 6, 21 | } 22 | -------------------------------------------------------------------------------- /packages/shared/src/utils/string/index.ts: -------------------------------------------------------------------------------- 1 | export { arrayToString } from './arrayToString'; 2 | export { capitalizeFirstLetter } from './capitalizeFirstLetter'; 3 | export { capitalizeWords } from './capitalizeWords'; 4 | export { countSubstringOccurrences } from './countSubstringOccurrences'; 5 | export { isPalindrome } from './isPalindrome'; 6 | export { padString } from './padString'; 7 | export { reverseString } from './reverseString'; 8 | export { stringToArray } from './stringToArray'; 9 | export { truncateString } from './truncateString'; 10 | -------------------------------------------------------------------------------- /packages/client/src/events/EventNames.ts: -------------------------------------------------------------------------------- 1 | export enum EventNames { 2 | CEventName = 'CEventName', 3 | EntityDamaged = 'entityDamaged', 4 | GameEventTriggered = 'gameEventTriggered', 5 | MumbleConnected = 'mumbleConnected', 6 | MumbleDisconnected = 'mumbleDisconnected', 7 | OnClientResourceStart = 'onClientResourceStart', 8 | OnClientResourceStop = 'onClientResourceStop', 9 | OnResourceStart = 'onResourceStart', 10 | OnResourceStarting = 'onResourceStarting', 11 | OnResourceStop = 'onResourceStop', 12 | PopulationPedCreating = 'populationPedCreating', 13 | } 14 | -------------------------------------------------------------------------------- /packages/client/src/enums/ui/ControlTypes.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enumeration representing different control types in game context. 3 | * 4 | * The `ControlTypes` enum provides two distinct values: 5 | * - `PlayerControl`: Represents controls specific to player actions. 6 | * - `FrontendControl`: Represents controls for frontend interactions and UI navigation. 7 | * 8 | * This can be used to distinguish between different control mechanisms in a game. 9 | * 10 | * @enum{number} 11 | */ 12 | export enum ControlTypes { 13 | PlayerControl = 0, 14 | FrontendControl = 2, 15 | } 16 | -------------------------------------------------------------------------------- /packages/shared/src/utils/maths/clamp.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Clamps a number to a specified range. 3 | * 4 | * @example 5 | * ```ts 6 | * clamp(5, 1, 10); // 5 7 | * clamp(0, 1, 10); // 1 8 | * clamp(15, 1, 10); // 10 9 | * ``` 10 | * 11 | * @param {number} num - The number to clamp. 12 | * @param {number} min - The minimum value. 13 | * @param {number} max - The maximum value. 14 | * 15 | * @returns {number} The clamped value. 16 | */ 17 | export function clamp(num: number, min: number, max: number): number { 18 | return num <= min ? min : num >= max ? max : num; 19 | } 20 | -------------------------------------------------------------------------------- /packages/shared/src/utils/maths/lerp.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Linearly interpolates between two values. 3 | * 4 | * @example 5 | * ```ts 6 | * lerp(0, 10, 0.5); // 5 7 | * lerp(0, 10, 0.75); // 7.5 8 | * ``` 9 | * 10 | * @param {number} start - The start value. 11 | * @param {number} end - The end value. 12 | * @param {number} amount - The interpolation factor between 0 and 1. 13 | * 14 | * @returns {number} The interpolated value. 15 | */ 16 | export function lerp(start: number, end: number, amount: number): number { 17 | return (1 - amount) * start + amount * end; 18 | } 19 | -------------------------------------------------------------------------------- /packages/shared/src/utils/maths/normalize.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Normalizes a value within a given range to a value between 0 and 1. 3 | * 4 | * @example 5 | * ```ts 6 | * normalize(75, 50, 100); // 0.5 7 | * ``` 8 | * 9 | * @param {number} value - The value to normalize. 10 | * @param {number} min - The minimum value of the range. 11 | * @param {number} max - The maximum value of the range. 12 | * 13 | * @returns {number} The normalized value. 14 | */ 15 | export function normalize(value: number, min: number, max: number): number { 16 | return (value - min) / (max - min); 17 | } 18 | -------------------------------------------------------------------------------- /packages/shared/src/utils/enum/getRandomEnumKey.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Returns a random key from the given enum type. 3 | * 4 | * @template T 5 | * 6 | * @param {T} enumType - The enum type from which to select a random key 7 | * 8 | * @returns {keyof T} A randomly selected key from the provided enum type. 9 | */ 10 | export function getRandomEnumKey(enumType: T): keyof T { 11 | const keys = Object.keys(enumType).filter(key => isNaN(Number(key))) as Array; 12 | const randomIndex: number = Math.floor(Math.random() * keys.length); 13 | return keys[randomIndex]; 14 | } 15 | -------------------------------------------------------------------------------- /packages/client/src/enums/vehicles/VehicleNeonLight.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enumeration representing the different neon light positions on a vehicle. 3 | * 4 | * Values: 5 | * - `Left`: Represents the neon light located on the left side of the vehicle. 6 | * - `Right`: Represents the neon light located on the right side of the vehicle. 7 | * - `Front`: Represents the neon light located on the front of the vehicle. 8 | * - `Back`: Represents the neon light located on the back of the vehicle. 9 | * 10 | * @enum{number} 11 | */ 12 | export enum VehicleNeonLight { 13 | Left, 14 | Right, 15 | Front, 16 | Back, 17 | } 18 | -------------------------------------------------------------------------------- /packages/shared/src/utils/string/capitalizeFirstLetter.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Capitalizes the first letter of a string. 3 | * 4 | * @example 5 | * ```ts 6 | * const result = capitalizeFirstLetter("hello"); 7 | * console.log(result); // "Hello" 8 | * ``` 9 | * 10 | * @param {string} input - The string to capitalize the first letter of. 11 | * 12 | * @returns {string} The string with its first letter capitalized. 13 | */ 14 | export function capitalizeFirstLetter(input: string): string { 15 | if (input.length === 0) { 16 | return input; 17 | } 18 | return input.charAt(0).toUpperCase() + input.slice(1); 19 | } 20 | -------------------------------------------------------------------------------- /packages/client/src/enums/others/CameraShake.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enumeration for different types of camera shake effects. 3 | * 4 | * @enum {string} 5 | */ 6 | export enum CameraShake { 7 | DeathFail = 'DEATH_FAIL_IN_EFFECT_SHAKE', 8 | Drunk = 'DRUNK_SHAKE', 9 | FamilyDrugTrip = 'FAMILY5_DRUG_TRIP_SHAKE', 10 | Hand = 'HAND_SHAKE', 11 | Jolt = 'JOLT_SHAKE', 12 | LargeExplosion = 'LARGE_EXPLOSION_SHAKE', 13 | MediumExplosion = 'MEDIUM_EXPLOSION_SHAKE', 14 | SmallExplosion = 'SMALL_EXPLOSION_SHAKE', 15 | RoadVibration = 'ROAD_VIBRATION_SHAKE', 16 | SkyDiving = 'SKY_DIVING_SHAKE', 17 | Vibrate = 'VIBRATE_SHAKE', 18 | } 19 | -------------------------------------------------------------------------------- /packages/shared/src/utils/maths/isInRange.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Checks if a value is within a specified range. 3 | * 4 | * @example 5 | * ```ts 6 | * isInRange(5, 1, 10); // true 7 | * isInRange(0, 1, 10); // false 8 | * ``` 9 | * 10 | * @param {number} value - The value to check. 11 | * @param {number} min - The minimum value of the range. 12 | * @param {number} max - The maximum value of the range. 13 | * 14 | * @returns {boolean} `true` if the value is within the range, `false` otherwise. 15 | */ 16 | export function isInRange(value: number, min: number, max: number): boolean { 17 | return value >= min && value <= max; 18 | } 19 | -------------------------------------------------------------------------------- /packages/server/src/enums/BucketLockdownMode.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enum representing the Lockdown Modes for a specific routing bucket. 3 | * 4 | * One of the aforementioned modes. 5 | * Sets the entity lockdown mode for a specific routing bucket. 6 | * 7 | * Lockdown modes are: 8 | * 9 | * - `strict`: No entities can be created by clients at all. 10 | * - `relaxed`: Only script-owned entities created by clients are blocked. 11 | * - `inactive`: Clients can create any entity they want. 12 | * 13 | * @enum {string} 14 | */ 15 | export enum BucketLockdownMode { 16 | Strict = 'strict', 17 | Relaxed = 'relaxed', 18 | Inactive = 'inactive', 19 | } 20 | -------------------------------------------------------------------------------- /packages/shared/src/utils/maths/getRandomInt.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Generates a random integer between the specified minimum and maximum values. 3 | * 4 | * @example 5 | * ```ts 6 | * getRandomInt(1, 10); // A random integer between 1 and 10 7 | * ``` 8 | * 9 | * @param {number} min - The minimum value (inclusive). 10 | * @param {number} max - The maximum value (inclusive). 11 | * 12 | * @returns {number} A random integer between min and max. 13 | */ 14 | export function getRandomInt(min: number, max: number): number { 15 | min = Math.ceil(min); 16 | max = Math.ceil(max); 17 | 18 | return Math.floor(Math.random() * (max - min)) + min; 19 | } 20 | -------------------------------------------------------------------------------- /packages/client/src/enums/vehicles/LicensePlateType.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enum representing the type of license plates a vehicle can have. 3 | * 4 | * Values: 5 | * - `FrontAndBackPlates` - Indicates that the vehicle requires both a front and back license plate. 6 | * - `FrontPlate` - Indicates that the vehicle only requires a front license plate. 7 | * - `BackPlate` - Indicates that the vehicle only requires a back license plate. 8 | * - `None` - Indicates that the vehicle does not require any license plates. 9 | * 10 | * @enum{number} 11 | */ 12 | export enum LicensePlateType { 13 | FrontAndBackPlates, 14 | FrontPlate, 15 | BackPlate, 16 | None, 17 | } 18 | -------------------------------------------------------------------------------- /packages/shared/src/utils/string/arrayToString.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Joins an array of strings into a single string with an optional separator. 3 | * 4 | * @example 5 | * ```ts 6 | * const result = arrayToString(["Hello", "World"], " "); 7 | * console.log(result); // "Hello World" 8 | * ``` 9 | * 10 | * @param {string} inputArray - The array of strings to join. 11 | * @param [separator=''] - The separator to use between each string. Defaults to an empty string. 12 | * 13 | * @returns {string} The concatenated string. 14 | */ 15 | export function arrayToString(inputArray: string[], separator = ''): string { 16 | return inputArray.join(separator); 17 | } 18 | -------------------------------------------------------------------------------- /packages/client/src/enums/parachute/ParachuteLandingType.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enum representing various types of parachute landings. 3 | * 4 | * Values: 5 | * - `None`: Represents no specific landing event. 6 | * - `Landing`: A standard or normal landing without issues. 7 | * - `Stumbling`: A landing where the individual stumbles upon touching the ground. 8 | * - `Rolling`: A landing involving a controlled roll to reduce the impact. 9 | * - `Ragdoll`: An uncontrolled landing where the individual loses stability. 10 | * 11 | * @enum{number} 12 | */ 13 | export enum ParachuteLandingType { 14 | None = -1, 15 | Landing, 16 | Stumbling, 17 | Rolling, 18 | Ragdoll, 19 | } 20 | -------------------------------------------------------------------------------- /typedoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://typedoc.org/schema.json", 3 | "exclude": ["**/*.test.ts", "**/node_modules/**"], 4 | "entryPoints": ["./src/index.ts"], 5 | "out": "temp-docs", 6 | "name": "fivem-ts - Documentation", 7 | "theme": "default", 8 | "plugin": ["./node_modules/typedoc-plugin-markdown"], 9 | "readme": "none", 10 | "excludeInternal": true, 11 | "excludeExternals": true, 12 | "excludePrivate": true, 13 | "excludeProtected": true, 14 | "includeVersion": true, 15 | "entryPointStrategy": "expand", 16 | "tsconfig": "tsconfig.index.json", 17 | "gitRevision": "main", 18 | "githubPages": true 19 | } 20 | -------------------------------------------------------------------------------- /packages/client/src/ui/Notification.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * The `Notification` class represents a game notification that can be hidden. 3 | */ 4 | export class Notification { 5 | /** 6 | * Creates an instance of the `Notification` class. 7 | * 8 | * @param handle - Identifier for the notification. 9 | */ 10 | constructor(private readonly handle: number) { 11 | this.handle = handle; 12 | } 13 | 14 | /** 15 | * Hides the notification. 16 | * 17 | * This method will remove the notification associated with the handle from the game's notification area. 18 | * 19 | * @returns {void} 20 | */ 21 | public hide(): void { 22 | RemoveNotification(this.handle); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/shared/src/enums/vehicle/VehicleLandingGearState.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enumeration representing the different states of a vehicle's landing gear. 3 | * 4 | * @enum{number} 5 | */ 6 | export enum VehicleLandingGearState { 7 | /** The landing gear is fully deployed. */ 8 | Deployed = 0, 9 | /** The landing gear is in the process of retracting. */ 10 | Closing = 1, 11 | /** The landing gear is in a state that should never occur. */ 12 | Never = 2, 13 | /** The landing gear is in the process of deploying. */ 14 | Opening = 3, 15 | /** The landing gear is fully retracted. */ 16 | Retracted = 4, 17 | /** The landing gear is broken and likely unusable. */ 18 | Broken = 5, 19 | } 20 | -------------------------------------------------------------------------------- /packages/shared/src/utils/maths/distance2D.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Calculates the distance between two points in 2D space. 3 | * 4 | * @example 5 | * ```ts 6 | * distance2D(0, 0, 3, 4); // 5 7 | * ``` 8 | * 9 | * @param {number} x1 - The x-coordinate of the first point. 10 | * @param {number} y1 - The y-coordinate of the first point. 11 | * @param {number} x2 - The x-coordinate of the second point. 12 | * @param {number} y2 - The y-coordinate of the second point. 13 | * 14 | * @returns {number} The distance between the two points. 15 | */ 16 | export function distance2D(x1: number, y1: number, x2: number, y2: number): number { 17 | return Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2); 18 | } 19 | -------------------------------------------------------------------------------- /packages/shared/src/utils/string/stringToArray.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Converts a string into an array of substrings, each with a maximum length of 99 characters. 3 | * 4 | * @example 5 | * ```ts 6 | * const result = stringToArray("This is a very long string that needs to be split."); 7 | * console.log(result); // ["This", "is", "a", "very", "long", "string", "that", "needs", "to", "be", "split"] 8 | * ``` 9 | * 10 | * @param {string} input - The input string to be split. 11 | * 12 | * @returns {string[]} An array of substrings, each up to 99 characters long. 13 | */ 14 | export function stringToArray(input: string): string[] { 15 | return input.trim() === '' ? [] : input.trim().split(/\s+/); 16 | } 17 | -------------------------------------------------------------------------------- /packages/client/src/models/PedBoneCollection.ts: -------------------------------------------------------------------------------- 1 | import { EntityBoneCollection, Ped, PedBone } from '.'; 2 | import { Bone } from '../enums'; 3 | 4 | /** 5 | * Represents a collection of bones associated with an entity. 6 | * 7 | * @class PedBoneCollection 8 | * @extends EntityBoneCollection 9 | * @see {EntityBoneCollection} 10 | */ 11 | export class PedBoneCollection extends EntityBoneCollection { 12 | /** 13 | * Retrieves the core `PedBone` of the associated entity. 14 | * 15 | * @returns {PedBone} The core `PedBone` representing the root or main bone of the entity. 16 | */ 17 | public override get Core(): PedBone { 18 | return new PedBone(this.owner as Ped, Bone.Unknown); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /packages/shared/src/utils/string/isPalindrome.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Checks if a string is a palindrome, ignoring case and non-alphanumeric characters. 3 | * 4 | * @example 5 | * ```ts 6 | * const result = isPalindrome("A man, a plan, a canal, Panama"); 7 | * console.log(result); // true 8 | * ``` 9 | * 10 | * @param {string} input - The input string to be checked. 11 | * 12 | * @returns {boolean} `true` if the input string is a palindrome, `false` otherwise. 13 | */ 14 | export function isPalindrome(input: string): boolean { 15 | const normalized = input.replace(/[^a-zA-Z0-9]/g, '').toLowerCase(); 16 | const reversed = normalized.split('').reverse().join(''); 17 | return normalized === reversed; 18 | } 19 | -------------------------------------------------------------------------------- /packages/client/src/enums/ui/index.ts: -------------------------------------------------------------------------------- 1 | export { Alignment } from './Alignment'; 2 | export { BadgeStyle } from './BadgeStyle'; 3 | export { CheckboxStyle } from './CheckboxStyle'; 4 | export { CheckpointCustomIconStyle } from './CheckpointCustomIconStyle'; 5 | export { CheckpointIcon } from './CheckpointIcon'; 6 | export { Controls } from './Controls'; 7 | export { ControlTypes } from './ControlTypes'; 8 | export { CursorType } from './CursorType'; 9 | export { Font } from './Font'; 10 | export { InputMode } from './InputMode'; 11 | export { Language } from './Language'; 12 | export { MarkerTypes } from './MarkerTypes'; 13 | export { NotificationType } from './NotificationType'; 14 | export { ScreenEffect } from './ScreenEffect'; 15 | -------------------------------------------------------------------------------- /packages/client/src/enums/vehicles/VehiclePaintType.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Represents different types of vehicle paint finishes. 3 | * 4 | * Values: 5 | * - `Normal`: Represents a standard paint finish. 6 | * - `Metallic`: Represents a metallic paint finish with metallic particles. 7 | * - `Pearl`: Represents a pearlescent paint finish. 8 | * - `Matte`: Represents a paint finish with a flat, non-reflective surface. 9 | * - `Metal`: Represents a shiny metallic paint finish. 10 | * - `Chrome`: Represents a highly reflective chrome paint finish. 11 | * 12 | * @enum{number} 13 | */ 14 | export enum VehiclePaintType { 15 | Normal = 0, 16 | Metallic = 1, 17 | Pearl = 2, 18 | Matte = 3, 19 | Metal = 4, 20 | Chrome = 5, 21 | } 22 | -------------------------------------------------------------------------------- /packages/client/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './@types'; 2 | export * from './enums'; 3 | export * from './events'; 4 | export * from './hashes'; 5 | export * from './models'; 6 | export * from './ui'; 7 | export * from './utils'; 8 | 9 | export { Audio } from './Audio'; 10 | export { Blip } from './Blip'; 11 | export { Camera } from './Camera'; 12 | export { Checkpoint } from './Checkpoint'; 13 | export { Game } from './Game'; 14 | export { GameplayCamera } from './GameplayCamera'; 15 | export { Model } from './Model'; 16 | export { ParticleEffect } from './ParticleEffect'; 17 | export { ParticleEffectAsset } from './ParticleEffectAsset'; 18 | export { RelationshipGroup } from './RelationshipGroup'; 19 | export { Rope } from './Rope'; 20 | -------------------------------------------------------------------------------- /packages/client/src/utils/Point.ts: -------------------------------------------------------------------------------- 1 | export class Point { 2 | constructor( 3 | public x: number = 0, 4 | public y: number = 0, 5 | ) {} 6 | 7 | public static parse(arg: [number, number] | { x: number; y: number } | string): Point { 8 | let point: Point = new Point(); 9 | 10 | if (typeof arg === 'object') { 11 | if (Array.isArray(arg)) { 12 | if (arg.length === 2) { 13 | point = new Point(arg[0], arg[1]); 14 | } 15 | } else if (arg.x && arg.y) { 16 | point = new Point(arg.x, arg.y); 17 | } 18 | } else { 19 | if (arg.indexOf(',') !== -1) { 20 | const [x, y]: number[] = arg.split(',').map(parseFloat); 21 | point = new Point(x, y); 22 | } 23 | } 24 | 25 | return point; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /packages/shared/src/utils/enum/getRandomEnumEntry.ts: -------------------------------------------------------------------------------- 1 | import { getRandomInt } from '../maths'; 2 | 3 | /** 4 | * Returns a random entry from the given enum type. 5 | * 6 | * @template T 7 | * 8 | * @param {object} enumType - The enum type from which to select a random entry. 9 | * 10 | * @returns {[keyof T, T[keyof T]]} - An array containing the random key-value pair from the enum. 11 | */ 12 | export function getRandomEnumEntry(enumType: T): [keyof T, T[keyof T]] { 13 | const values = Object.entries(enumType).filter(([key]): boolean => isNaN(Number(key))) as [ 14 | keyof T, 15 | T[keyof T], 16 | ][]; 17 | const randomIndex: number = getRandomInt(0, values.length); 18 | return values[randomIndex]; 19 | } 20 | -------------------------------------------------------------------------------- /turbo.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://turbo.build/schema.json", 3 | "ui": "tui", 4 | "tasks": { 5 | "build": { 6 | "dependsOn": ["shared:build", "client:build", "server:build"], 7 | "inputs": ["$TURBO_DEFAULT$", ".env*"], 8 | "outputs": ["dist/**"] 9 | }, 10 | "shared:build": { 11 | "outputs": ["dist/shared/**"] 12 | }, 13 | "client:build": { 14 | "dependsOn": ["shared:build"], 15 | "outputs": ["dist/client/**"] 16 | }, 17 | "server:build": { 18 | "dependsOn": ["shared:build"], 19 | "outputs": ["dist/server/**"] 20 | }, 21 | "lint": { 22 | "dependsOn": ["^lint"] 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /packages/server/src/enums/OrphanMode.ts: -------------------------------------------------------------------------------- 1 | export enum OrphanMode { 2 | /** 3 | * Default, this will delete the entity when it isn't relevant to any players 4 | * NOTE: this *doesn't* mean when they're no longer in scope 5 | */ 6 | DeleteWhenNotRelevant = 0, 7 | /** 8 | * The entity will be deleted whenever its original owner disconnects 9 | * NOTE: if this is set when the entities original owner has already left it will be 10 | * marked for deletion (similar to just calling DELETE_ENTITY) 11 | */ 12 | DeleteOnOwnerDisconnect = 1, 13 | /** 14 | * The entity will never be deleted by the server when it does relevancy checks 15 | * you should only use this on entities that need to be relatively persistent 16 | */ 17 | KeepEntity = 2, 18 | } 19 | -------------------------------------------------------------------------------- /packages/client/src/enums/environment/CloudHat.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enumeration representing different types of cloud hats. 3 | * 4 | * @enum{string} 5 | */ 6 | export enum CloudHat { 7 | Unknown = 1, 8 | AltoStratus = 'altostratus', 9 | Cirrus = 'Cirrus', 10 | Cirrocumulus = 'cirrocumulus', 11 | Clear01 = 'Clear 01', 12 | Cloudy01 = 'Cloudy 01', 13 | Contrails = 'Contrails', 14 | Horizon = 'Horizon', 15 | HorizonBand1 = 'horizonband1', 16 | HorizonBand2 = 'horizonband2', 17 | HorizonBand3 = 'horizonband3', 18 | Horsey = 'horsey', 19 | Nimbus = 'Nimbus', 20 | Puffs = 'Puffs', 21 | Rain = 'RAIN', 22 | Snowy01 = 'Snowy 01', 23 | Stormy01 = 'Stormy 01', 24 | StratosCumulus = 'stratoscumulus', 25 | Stripey = 'Stripey', 26 | Shower = 'shower', 27 | Wispy = 'Wispy', 28 | } 29 | -------------------------------------------------------------------------------- /packages/server/src/events/EventNames.ts: -------------------------------------------------------------------------------- 1 | export enum EventNames { 2 | EntityCreated = 'entityCreated', 3 | EntityCreating = 'entityCreating', 4 | EntityRemoved = 'entityRemoved', 5 | OnResourceListRefresh = 'onResourceListRefresh', 6 | OnResourceStart = 'onResourceStart', 7 | OnResourceStop = 'onResourceStop', 8 | OnServerResourceStart = 'onServerResourceStart', 9 | OnServerResourceStop = 'onServerResourceStop', 10 | PlayerConnecting = 'playerConnecting', 11 | PlayerJoining = 'playerJoining', 12 | PlayerEnteredScope = 'playerEnteredScope', 13 | PlayerLeftScope = 'playerLeftScope', 14 | PtFxEvent = 'ptFxEvent', 15 | RemoveAllWeaponsEvent = 'removeAllWeaponsEvent', 16 | StartProjectileEvent = 'startProjectileEvent', 17 | WeaponDamageEvent = 'weaponDamageEvent', 18 | } 19 | -------------------------------------------------------------------------------- /packages/client/src/enums/ped/HelmetType.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enumeration for types of helmets. 3 | * This enum provides a set of constants representing different types of helmets and their associated attributes. 4 | * Each helmet type is represented by a unique integer value. 5 | * 6 | * @enum{number} 7 | */ 8 | export enum HelmetType { 9 | None = 0, 10 | Bulky = 1, 11 | Job = 2, 12 | Sunny = 4, 13 | Wet = 8, 14 | Cold = 16, 15 | NotInCar = 32, 16 | BikeOnly = 64, 17 | NotIndoors = 128, 18 | FireRetardent = 256, 19 | Armoured = 512, 20 | LightlyArmoured = 1024, 21 | HighDetail = 2048, 22 | DefaultHelmet = 4096, 23 | RandomHelmet = 8192, 24 | ScriptHelmet = 16384, 25 | FlightHelmet = 32768, 26 | HideInFirstPerson = 65536, 27 | UsePhysicsHat = 131072, 28 | PilotHelmet = 262144, 29 | } 30 | -------------------------------------------------------------------------------- /packages/client/src/enums/ui/Font.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enum representing different font styles. 3 | * 4 | * The Font enum provides a set of predefined font styles that can be used to customize text appearance. 5 | * 6 | * Enum Members: 7 | * 8 | * - `ChaletLondon`: Represents the 'Chalet London' font style. 9 | * - `HouseScript`: Represents the 'House Script' font style. 10 | * - `Monospace`: Represents the 'Monospace' font style. 11 | * - `ChaletComprimeCologne`: Represents the 'Chalet Comprime Cologne' font style, with an explicit value of 4. 12 | * - `Pricedown`: Represents the 'Pricedown' font style, with an explicit value of 7. 13 | * 14 | * @enum{number} 15 | */ 16 | export enum Font { 17 | ChaletLondon, 18 | HouseScript, 19 | Monospace, 20 | ChaletComprimeCologne = 4, 21 | Pricedown = 7, 22 | } 23 | -------------------------------------------------------------------------------- /packages/shared/src/utils/string/padString.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Pads a string to a specified length with a given character. 3 | * 4 | * @example 5 | * ```ts 6 | * const result = padString("Hello", 10, "*"); 7 | * console.log(result); // "Hello*****" 8 | * ``` 9 | * 10 | * @param {string} input - The input string to be padded. 11 | * @param {number} targetLength - The target length of the resulting string. 12 | * @param [padChar=' '] - The character to pad the string with. Defaults to a space character. 13 | * 14 | * @returns The padded string. 15 | */ 16 | export function padString(input: string, targetLength: number, padChar = ' '): string { 17 | if (input.length >= targetLength) { 18 | return input; 19 | } 20 | const padding = padChar.repeat(targetLength - input.length); 21 | return input + padding; 22 | } 23 | -------------------------------------------------------------------------------- /packages/shared/src/utils/string/capitalizeWords.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Capitalizes the first letter of each word in a sentence. 3 | * 4 | * @example 5 | * ```ts 6 | * const result = capitalizeWords("hello world"); 7 | * console.log(result); // "Hello World" 8 | * ``` 9 | * 10 | * @param {string} input - The input string where each word's first letter will be capitalized. 11 | * 12 | * @returns {string} The string with each word's first letter capitalized. 13 | */ 14 | export function capitalizeWords(input: string): string { 15 | return input 16 | .split(/(\s+|-|(?<=\s)'|(?<=\b)')/) 17 | .map((part, index) => { 18 | if (index % 2 === 0 && part.length > 0 && !/^\s|-|'$/.test(part)) { 19 | return part.charAt(0).toUpperCase() + part.slice(1).toLowerCase(); 20 | } 21 | 22 | return part; 23 | }) 24 | .join(''); 25 | } 26 | -------------------------------------------------------------------------------- /packages/client/src/enums/vehicles/VehicleIndicatorsLights.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enum representing various states or types of vehicle indicator lights. 3 | * 4 | * Values: 5 | * - `None` (0): Represents the state where no indicator lights are active. 6 | * - `BlinkLeft` (1): Represents the left indicator light flashing. 7 | * - `BlinkRight` (2): Represents the right indicator light flashing. 8 | * - `BlinkBoth` (3): Represents both indicator lights flashing simultaneously. 9 | * - `StaticBoth` (8): Represents both indicator lights turned on constantly without flashing. 10 | * - `Interior` (64): Represents the activation of interior lighting. 11 | * 12 | * @enum{number} 13 | */ 14 | export enum VehicleIndicatorsLights { 15 | None = 0, 16 | BlinkLeft = 1, 17 | BlinkRight = 2, 18 | BlinkBoth = 3, 19 | StaticBoth = 8, 20 | Interior = 64, 21 | } 22 | -------------------------------------------------------------------------------- /examples/tsc/eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import tsParser from "@typescript-eslint/parser"; 2 | import tsPlugin from "@typescript-eslint/eslint-plugin"; 3 | 4 | export default [ 5 | { 6 | files: ["src/**/*.ts"], 7 | languageOptions: { 8 | parser: tsParser, 9 | }, 10 | plugins: { 11 | "@typescript-eslint": tsPlugin, 12 | }, 13 | rules: { 14 | "no-async-promise-executor": "off", 15 | "@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "^_" }], 16 | "@typescript-eslint/explicit-function-return-type": "off", 17 | "@typescript-eslint/no-explicit-any": "warn", 18 | "@typescript-eslint/no-var-requires": "error", 19 | }, 20 | ignores: [".circleci", ".github", "node_modules", "dist", "docs", "examples"], 21 | }, 22 | ]; 23 | -------------------------------------------------------------------------------- /packages/shared/src/utils/maths/mapRange.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Maps a value from one range to another. 3 | * 4 | * @example 5 | * ```ts 6 | * mapRange(5, 0, 10, 0, 100); // 50 7 | * ``` 8 | * 9 | * @param {number} value - The value to map. 10 | * @param {number} inMin - The minimum value of the input range. 11 | * @param {number} inMax - The maximum value of the input range. 12 | * @param {number} outMin - The minimum value of the output range. 13 | * @param {number} outMax - The maximum value of the output range. 14 | * 15 | * @returns {number} The mapped value. 16 | */ 17 | export function mapRange( 18 | value: number, 19 | inMin: number, 20 | inMax: number, 21 | outMin: number, 22 | outMax: number, 23 | ): number { 24 | if (inMin === inMax) { 25 | return NaN; 26 | } 27 | return ((value - inMin) * (outMax - outMin)) / (inMax - inMin) + outMin; 28 | } 29 | -------------------------------------------------------------------------------- /examples/esbuild/eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import tsParser from "@typescript-eslint/parser"; 2 | import tsPlugin from "@typescript-eslint/eslint-plugin"; 3 | 4 | export default [ 5 | { 6 | files: ["src/**/*.ts"], 7 | languageOptions: { 8 | parser: tsParser, 9 | }, 10 | plugins: { 11 | "@typescript-eslint": tsPlugin, 12 | }, 13 | rules: { 14 | "no-async-promise-executor": "off", 15 | "@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "^_" }], 16 | "@typescript-eslint/explicit-function-return-type": "off", 17 | "@typescript-eslint/no-explicit-any": "warn", 18 | "@typescript-eslint/no-var-requires": "error", 19 | }, 20 | ignores: [".circleci", ".github", "node_modules", "dist", "docs", "examples"], 21 | }, 22 | ]; 23 | -------------------------------------------------------------------------------- /packages/shared/src/utils/string/countSubstringOccurrences.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Counts the occurrences of a substring within a string. 3 | * 4 | * @example 5 | * ```ts 6 | * const result = countSubstringOccurrences("hello hello world", "hello"); 7 | * console.log(result); // 2 8 | * ``` 9 | * 10 | * @param {string} input - The string to search within. 11 | * @param {string} substring - The substring to count occurrences of. 12 | * 13 | * @returns {number} The number of times the substring occurs in the input string. 14 | */ 15 | export function countSubstringOccurrences(input: string, substring: string): number { 16 | if (substring.length === 0) { 17 | return 0; 18 | } 19 | let count = 0; 20 | let position = input.indexOf(substring); 21 | 22 | while (position !== -1) { 23 | count++; 24 | position = input.indexOf(substring, position + 1); 25 | } 26 | 27 | return count; 28 | } 29 | -------------------------------------------------------------------------------- /packages/client/src/enums/vehicles/LicensePlateStyle.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Represents the different styles of license plates available. 3 | * 4 | * Values: 5 | * - `BlueOnWhite1`: Represents the style with blue text on a white background. 6 | * - `BlueOnWhite2`: Represents another variation of the blue text on white background style. 7 | * - `BlueOnWhite3`: Represents a third variation of the blue text on white background style. 8 | * - `YellowOnBlack`: Represents the style with yellow text on a black background. 9 | * - `YellowOnBlue`: Represents the style with yellow text on a blue background. 10 | * - `NorthYankton`: Represents the North Yankton-specific license plate style. 11 | * 12 | * @enum{number} 13 | */ 14 | export enum LicensePlateStyle { 15 | BlueOnWhite1 = 3, 16 | BlueOnWhite2 = 0, 17 | BlueOnWhite3 = 4, 18 | YellowOnBlack = 1, 19 | YellowOnBlue = 2, 20 | NorthYankton = 5, 21 | } 22 | -------------------------------------------------------------------------------- /packages/client/src/enums/vehicles/index.ts: -------------------------------------------------------------------------------- 1 | export { CargobobHook } from './CargobobHook'; 2 | export { HandlingKeys } from './HandlingKeys'; 3 | export { LicensePlateStyle } from './LicensePlateStyle'; 4 | export { LicensePlateType } from './LicensePlateType'; 5 | export { VehicleClass } from './VehicleClass'; 6 | export { VehicleColor } from './VehicleColor'; 7 | export { VehicleDoorIndex } from './VehicleDoorIndex'; 8 | export { VehicleDrivingFlags } from './VehicleDrivingFlags'; 9 | export { VehicleIndicatorsLights } from './VehicleIndicatorsLights'; 10 | export { VehicleMods } from './VehicleMods'; 11 | export { VehicleNeonLight } from './VehicleNeonLight'; 12 | export { VehiclePaintType } from './VehiclePaintType'; 13 | export { VehicleRoofState } from './VehicleRoofState'; 14 | export { VehicleToggleModType } from './VehicleToggleModType'; 15 | export { VehicleWheelIndex } from './VehicleWheelIndex'; 16 | -------------------------------------------------------------------------------- /packages/shared/src/utils/maths/distance3D.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Calculates the distance between two points in 3D space. 3 | * 4 | * @example 5 | * ```ts 6 | * distance3D(0, 0, 0, 3, 4, 12); // 13 7 | * ``` 8 | * 9 | * @param {number} x1 - The x-coordinate of the first point. 10 | * @param {number} y1 - The y-coordinate of the first point. 11 | * @param {number} z1 - The z-coordinate of the first point. 12 | * @param {number} x2 - The x-coordinate of the second point. 13 | * @param {number} y2 - The y-coordinate of the second point. 14 | * @param {number} z2 - The z-coordinate of the second point. 15 | * 16 | * @returns {number} The distance between the two points. 17 | */ 18 | export function distance3D( 19 | x1: number, 20 | y1: number, 21 | z1: number, 22 | x2: number, 23 | y2: number, 24 | z2: number, 25 | ): number { 26 | return Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2 + (z2 - z1) ** 2); 27 | } 28 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature Request 3 | about: Suggest an idea or enhancement for this project 4 | title: '[FEATURE REQUEST]' 5 | labels: enhancement 6 | assignees: '' 7 | --- 8 | 9 | ## Is your feature request related to a problem? 10 | 11 | Describe the problem you're experiencing or the need you have. For example: "I'm often frustrated when [...]" 12 | 13 | ## Proposed Solution 14 | 15 | Explain clearly and concisely what you would like to see implemented or changed. For example: "I would like [...]" 16 | 17 | ## Alternatives Considered 18 | 19 | Outline any alternative solutions or approaches you’ve considered. For example: "I’ve thought about [...] but [...]" 20 | 21 | ## Additional Context 22 | 23 | Provide any other relevant details, context, or screenshots to help us understand your request better. For example: "Here’s a screenshot that illustrates the problem [...]" 24 | -------------------------------------------------------------------------------- /packages/shared/src/utils/enum/getRandomEnumValue.ts: -------------------------------------------------------------------------------- 1 | import { getRandomInt } from '../maths'; 2 | 3 | /** 4 | * Returns a random value from an enumerated type, filtered by the specified value type. 5 | * 6 | * @template T 7 | * 8 | * @param {object} enumType - The enumerated type object from which to select a random value. 9 | * @param {'string'|'number'} valueType - Specifies the type of the values to consider ('string' or 'number'). 10 | * 11 | * @returns {T[keyof T]} A random value from the enumerated type that matches the specified value type. 12 | */ 13 | export function getRandomEnumValue( 14 | enumType: T, 15 | valueType: 'string' | 'number', 16 | ): T[keyof T] { 17 | const values = Object.values(enumType).filter(value => typeof value === valueType) as Array< 18 | T[keyof T] 19 | >; 20 | const randomIndex: number = getRandomInt(0, values.length); 21 | return values[randomIndex]; 22 | } 23 | -------------------------------------------------------------------------------- /packages/shared/src/utils/string/truncateString.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Truncates a string to a specified length and optionally appends an ellipsis. 3 | * 4 | * @example 5 | * ```ts 6 | * const result = truncateString("This is a long string", 10, true); 7 | * console.log(result); // "This is a..." 8 | * ``` 9 | * 10 | * @param {string} input - The input string to be truncated. 11 | * @param {number} maxLength - The maximum length of the resulting string. 12 | * @param [useEllipsis=false] - Whether to append an ellipsis (`...`) if the string is truncated. Defaults to `false`. 13 | * 14 | * @returns {string} The truncated string. 15 | */ 16 | export function truncateString(input: string, maxLength: number, useEllipsis = false): string { 17 | if (input.length <= maxLength) { 18 | return input; 19 | } 20 | const truncated = input.substring(0, maxLength); 21 | return useEllipsis ? `${truncated.trimEnd()}...` : truncated; 22 | } 23 | -------------------------------------------------------------------------------- /packages/client/src/enums/vehicles/VehicleWheelIndex.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enum representing the indices of vehicle wheels 3 | * 4 | * Values: 5 | * - FrontLeftWheel: Index for the front left wheel. 6 | * - FrontRightWheel: Index for the front right wheel. 7 | * - MidLeftWheel: Index for the middle left wheel. 8 | * - MidRightWheel: Index for the middle right wheel. 9 | * - RearLeftWheel: Index for the rear left wheel. 10 | * - RearRightWheel: Index for the rear right wheel. 11 | * - TrailerMidLeftWheel: Index for the left wheel in the middle of the trailer. 12 | * - TrailerMidRightWheel: Index for the right wheel in the middle of the trailer. 13 | * 14 | * @enum{number} 15 | */ 16 | export enum VehicleWheelIndex { 17 | FrontLeftWheel = 0, 18 | FrontRightWheel = 1, 19 | MidLeftWheel = 2, 20 | MidRightWheel = 3, 21 | RearLeftWheel = 4, 22 | RearRightWheel = 5, 23 | TrailerMidLeftWheel = 45, 24 | TrailerMidRightWheel = 47, 25 | } 26 | -------------------------------------------------------------------------------- /packages/client/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "display": "Default", 4 | "compilerOptions": { 5 | "target": "ES2020", 6 | "module": "CommonJS", 7 | "lib": [ 8 | "ES2020" 9 | ], 10 | "types": ["@citizenfx/client"], 11 | "outDir": "./dist", 12 | "declaration": true, 13 | "declarationMap": false, 14 | "esModuleInterop": true, 15 | "incremental": false, 16 | "isolatedModules": true, 17 | "forceConsistentCasingInFileNames": true, 18 | "strict": true, 19 | "skipLibCheck": true, 20 | "experimentalDecorators": true, 21 | "emitDecoratorMetadata": true 22 | }, 23 | "exclude": [ 24 | "**/node_modules/**", 25 | ".turbo", 26 | "**/__tests__/**", 27 | "dist" 28 | ], 29 | "include": [ 30 | "src" 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /packages/server/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "display": "Default", 4 | "compilerOptions": { 5 | "target": "ES2020", 6 | "module": "CommonJS", 7 | "lib": [ 8 | "ES2020" 9 | ], 10 | "types": ["@citizenfx/server", "@types/node"], 11 | "outDir": "./dist", 12 | "declaration": true, 13 | "declarationMap": false, 14 | "esModuleInterop": true, 15 | "incremental": false, 16 | "isolatedModules": true, 17 | "forceConsistentCasingInFileNames": true, 18 | "strict": true, 19 | "skipLibCheck": true, 20 | "experimentalDecorators": true, 21 | "emitDecoratorMetadata": true 22 | }, 23 | "exclude": [ 24 | "**/node_modules/**", 25 | ".turbo", 26 | "**/__tests__/**", 27 | "dist" 28 | ], 29 | "include": [ 30 | "src" 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /examples/esbuild/esbuild.ts: -------------------------------------------------------------------------------- 1 | import * as esbuild from "esbuild"; 2 | import { BuildOptions, SameShape } from "esbuild"; 3 | 4 | const buildOptions: SameShape[] = [ 5 | { 6 | entryPoints: ["src/client/index.ts"], 7 | bundle: true, 8 | minify: true, 9 | outfile: "dist/client/index.js", 10 | platform: "browser", 11 | format: "iife", 12 | tsconfig: "src/client/tsconfig.json", 13 | }, 14 | { 15 | entryPoints: ["src/server/index.ts"], 16 | bundle: true, 17 | minify: true, 18 | outfile: "dist/server/index.js", 19 | platform: "node", 20 | format: "cjs", 21 | target: "node16", 22 | tsconfig: "src/server/tsconfig.json", 23 | }, 24 | ]; 25 | 26 | async function build(): Promise { 27 | for (const options of buildOptions) { 28 | await esbuild.build(options); 29 | } 30 | } 31 | 32 | void build(); 33 | -------------------------------------------------------------------------------- /packages/client/src/models/index.ts: -------------------------------------------------------------------------------- 1 | export { Entity } from './Entity'; 2 | export { EntityBone } from './EntityBone'; 3 | export { EntityBoneCollection } from './EntityBoneCollection'; 4 | export { Ped } from './Ped'; 5 | export { PedBone } from './PedBone'; 6 | export { PedBoneCollection } from './PedBoneCollection'; 7 | export { Player } from './Player'; 8 | export { Prop } from './Prop'; 9 | export { Vehicle } from './Vehicle'; 10 | export { VehicleDoor } from './VehicleDoor'; 11 | export { VehicleDoorCollection } from './VehicleDoorCollection'; 12 | export { VehicleMod } from './VehicleMod'; 13 | export { VehicleModCollection } from './VehicleModCollection'; 14 | export { VehicleToggleMod } from './VehicleToggleMod'; 15 | export { VehicleWheel } from './VehicleWheel'; 16 | export { VehicleWheelCollection } from './VehicleWheelCollection'; 17 | export { VehicleWindow } from './VehicleWindow'; 18 | export { VehicleWindowCollection } from './VehicleWindowCollection'; 19 | -------------------------------------------------------------------------------- /packages/shared/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "display": "Default", 4 | "compilerOptions": { 5 | "target": "ES2020", 6 | "module": "CommonJS", 7 | "lib": [ 8 | "ES2020" 9 | ], 10 | "types": ["@citizenfx/client", "@citizenfx/server", "@types/node"], 11 | "outDir": "./dist", 12 | "declaration": true, 13 | "declarationMap": false, 14 | "esModuleInterop": true, 15 | "incremental": false, 16 | "isolatedModules": true, 17 | "forceConsistentCasingInFileNames": true, 18 | "strict": true, 19 | "skipLibCheck": true, 20 | "experimentalDecorators": true, 21 | "emitDecoratorMetadata": true 22 | }, 23 | "exclude": [ 24 | "**/node_modules/**", 25 | ".turbo", 26 | "**/__tests__/**", 27 | "dist" 28 | ], 29 | "include": [ 30 | "src" 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /eslint.config.js: -------------------------------------------------------------------------------- 1 | const tsParser = require('@typescript-eslint/parser'); 2 | const tsPlugin = require('@typescript-eslint/eslint-plugin'); 3 | 4 | module.exports = [ 5 | { 6 | files: ['packages/**/*.ts'], 7 | languageOptions: { 8 | parser: tsParser, 9 | }, 10 | plugins: { 11 | '@typescript-eslint': tsPlugin, 12 | }, 13 | rules: { 14 | 'no-async-promise-executor': 'off', 15 | '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }], 16 | '@typescript-eslint/explicit-function-return-type': 'off', 17 | '@typescript-eslint/no-explicit-any': 'warn', 18 | '@typescript-eslint/no-var-requires': 'error', 19 | }, 20 | ignores: [ 21 | '.circleci', 22 | '.github', 23 | 'node_modules', 24 | 'dist', 25 | 'docs', 26 | 'examples', 27 | ], 28 | }, 29 | ]; 30 | -------------------------------------------------------------------------------- /packages/server/src/utils/UUID.ts: -------------------------------------------------------------------------------- 1 | import { createHash } from 'crypto'; 2 | 3 | export function uuidv4(): string { 4 | const chars: string[] = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.split(''); 5 | 6 | for (let i = 0; i < chars.length; i++) { 7 | if (chars[i] === 'x') { 8 | chars[i] = ((Math.random() * 16) | 0).toString(16); 9 | } else if (chars[i] === 'y') { 10 | chars[i] = ((Math.random() * 4) | 8).toString(16); 11 | } 12 | } 13 | 14 | return chars.join(''); 15 | } 16 | 17 | export function uuidv5(name: string, namespace: string): string { 18 | const nsBytes: Buffer = Buffer.from(namespace.replace(/-/g, ''), 'hex'); 19 | const nameBytes: Buffer = Buffer.from('name', 'utf8'); 20 | const hash: string = createHash('sha1').update(nsBytes).update(nameBytes).digest('hex'); 21 | 22 | return `${hash.slice(0, 8)}-${hash.slice(8, 12)}-5${hash.slice(13, 16)}-${((parseInt(hash.slice(16, 18), 16) & 0x3f) | 0x80).toString(16)}${hash.slice(18, 20)}-${hash.slice(20, 32)}`; 23 | } 24 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_reports.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug Report 3 | about: Help us improve by reporting issues 4 | title: '[BUG]' 5 | labels: bug 6 | assignees: '' 7 | --- 8 | 9 | ## Description 10 | 11 | Provide a clear and concise description of the issue you're experiencing. 12 | 13 | ## Steps to Reproduce 14 | 15 | To replicate the issue, follow these steps: 16 | 17 | 1. Navigate to '...' 18 | 2. Execute the following code: '...' 19 | 3. Download this example: '...' 20 | 4. Observe the error 21 | 22 | ## Expected Result 23 | 24 | Describe what you expected to happen. 25 | 26 | ## Screenshots 27 | 28 | If relevant, include screenshots to illustrate the issue. 29 | 30 | ## FiveM Client Details 31 | 32 | - **Canary**: [e.g. yes, no] 33 | - **Version**: [e.g. 2880] 34 | 35 | ## FiveM Server Details 36 | 37 | - **OneSync**: [e.g. on, off, population] 38 | - **Artifact**: [e.g. 2929] 39 | 40 | ## Additional Information 41 | 42 | Provide any other relevant context or details about the issue here. 43 | -------------------------------------------------------------------------------- /packages/client/src/utils/PointF.ts: -------------------------------------------------------------------------------- 1 | import { Vector3 } from '@fivem-ts/shared'; 2 | 3 | export class PointF { 4 | constructor( 5 | public x: number, 6 | public y: number, 7 | public z: number, 8 | ) {} 9 | 10 | public distanceTo(other: PointF): number { 11 | return Math.sqrt( 12 | Math.pow(this.x - other.x, 2) + 13 | Math.pow(this.y - other.y, 2) + 14 | Math.pow(this.z - other.z, 2), 15 | ); 16 | } 17 | 18 | public isNear(other: PointF, radius: number): boolean { 19 | return this.distanceTo(other) <= radius; 20 | } 21 | 22 | public equals(other: PointF): boolean { 23 | return this.x === other.x && this.y === other.y && this.z === other.z; 24 | } 25 | 26 | public toString(): string { 27 | return `PointF(x: ${this.x}, y: ${this.y}, z: ${this.z})`; 28 | } 29 | 30 | public static empty(): PointF { 31 | return new PointF(0, 0, 0); 32 | } 33 | 34 | public static fromVector(vector: Vector3): PointF { 35 | return new PointF(vector.x, vector.y, vector.z); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /packages/shared/src/enums/vehicle/VehicleWindowIndex.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enum representing the index of different windows in a vehicle. 3 | * 4 | * @enum{number} 5 | */ 6 | export enum VehicleWindowIndex { 7 | /** representing the front left window of the vehicle. */ 8 | FrontLeftWindow = 0, 9 | /** representing the front right window of the vehicle. */ 10 | FrontRightWindow = 1, 11 | /** representing the back left window of the vehicle. */ 12 | BackLeftWindow = 2, 13 | /** representing the back right window of the vehicle. */ 14 | BackRightWindow = 3, 15 | /** representing an extra window, usually custom, additional or Middle Left Window. */ 16 | ExtraWindow1 = 4, 17 | /** representing an extra window, usually custom, additional or Middle Rear Window. */ 18 | ExtraWindow2 = 5, 19 | /** representing an extra window, usually custom, additional or WindScreen. */ 20 | ExtraWindow3 = 6, 21 | /** representing an extra window, usually custom, additional or Rear WindScreen. */ 22 | ExtraWindow4 = 7, 23 | } 24 | -------------------------------------------------------------------------------- /packages/client/src/models/EntityBoneCollection.ts: -------------------------------------------------------------------------------- 1 | import { Entity, EntityBone } from '.'; 2 | import { Bone } from '../enums'; 3 | 4 | /** 5 | * Represents a collection of bones associated with an entity. 6 | * 7 | * @class EntityBoneCollection 8 | */ 9 | export class EntityBoneCollection { 10 | constructor(protected readonly owner: Entity) {} 11 | 12 | /** 13 | * Retrieves the core `EntityBone` of the associated entity. 14 | * 15 | * @returns {EntityBone} The core `EntityBone` representing the root or main bone of the entity. 16 | */ 17 | public get Core(): EntityBone { 18 | return new EntityBone(this.owner, Bone.Unknown); 19 | } 20 | 21 | /** 22 | * Checks if an entity has a specified bone by its name. 23 | * 24 | * @param {string} name - The name of the bone to check for. 25 | * 26 | * @returns {boolean} True if the bone exists, false otherwise. 27 | */ 28 | public hasBone(name: string): boolean { 29 | return GetEntityBoneIndexByName(this.owner.Handle, name) !== -1; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /examples/tsc/build.mjs: -------------------------------------------------------------------------------- 1 | import { exec } from "child_process"; 2 | import { promisify } from "util"; 3 | import { exit } from 'node:process'; 4 | 5 | const execPromise = promisify(exec); 6 | const projects = ["client", "server"]; 7 | 8 | async function build() { 9 | for (const project of projects) { 10 | const tsconfigPath = `src/${project}/tsconfig.json`; 11 | console.info(`Building project: ${project} (TSConfig: ${tsconfigPath})`); 12 | 13 | try { 14 | const { stdout, stderr } = await execPromise(`tsc --project ${tsconfigPath}`); 15 | if (stdout) console.log(`[${project}] Output:\n${stdout}`); 16 | if (stderr) console.warn(`[${project}] Warnings:\n${stderr}`); 17 | 18 | console.log(`[${project}] Build completed successfully.`); 19 | } catch (error) { 20 | console.error(`[${project}] Build failed: ${error.message}`); 21 | exit(1); 22 | } 23 | } 24 | 25 | console.info("All projects built successfully!"); 26 | } 27 | 28 | void build(); 29 | -------------------------------------------------------------------------------- /packages/shared/src/enums/vehicle/VehicleWheelType.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enum representing different types of vehicle wheels. 3 | * 4 | * @enum{number} 5 | */ 6 | export enum VehicleWheelType { 7 | /** Represents a sport-type wheel. */ 8 | Sport = 0, 9 | /** Represents a muscle car-type wheel. */ 10 | Muscle = 1, 11 | /** Represents a low rider car-type wheel. */ 12 | LowRider = 2, 13 | /** Represents an SUV-type wheel. */ 14 | Suv = 3, 15 | /** Represents an off-road-type wheel. */ 16 | OffRoad = 4, 17 | /** Represents a tuner car-type wheel. */ 18 | Tuner = 5, 19 | /** Represents a bike-type wheel. */ 20 | Bike = 6, 21 | /** Represents a high-end luxury-type wheel. */ 22 | HighEnd = 7, 23 | /** Represents the original Benny's wheel. */ 24 | BennysOriginal = 8, 25 | /** Represents a bespoke wheel from Benny's. */ 26 | BennysBespoke = 9, 27 | /** Represents an open-wheel race car-type wheel. */ 28 | OpenWheel = 10, 29 | /** Represents a street-type wheel. */ 30 | Street = 11, 31 | /** Represents a track-type wheel. */ 32 | Track = 12, 33 | } 34 | -------------------------------------------------------------------------------- /packages/client/src/enums/ui/Language.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * An enumeration representing different languages. 3 | * 4 | * Values: 5 | * - `American`: Represents American English. 6 | * - `French`: Represents the French language. 7 | * - `German`: Represents the German language. 8 | * - `Italian`: Represents the Italian language. 9 | * - `Spanish`: Represents the Spanish language. 10 | * - `Brazilian`: Represents Brazilian Portuguese. 11 | * - `Polish`: Represents the Polish language. 12 | * - `Russian`: Represents the Russian language. 13 | * - `Korean`: Represents the Korean language. 14 | * - `ChineseTrad`: Represents Traditional Chinese. 15 | * - `Japanese`: Represents the Japanese language. 16 | * - `Mexican`: Represents Mexican Spanish. 17 | * - `ChineseSimp`: Represents Simplified Chinese. 18 | * 19 | * @enum{number} 20 | */ 21 | export enum Language { 22 | American, 23 | French, 24 | German, 25 | Italian, 26 | Spanish, 27 | Brazilian, 28 | Polish, 29 | Russian, 30 | Korean, 31 | ChineseTrad, 32 | Japanese, 33 | Mexican, 34 | ChineseSimp, 35 | } 36 | -------------------------------------------------------------------------------- /packages/shared/src/decorators/core/tick.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * A decorator that schedules a method to be executed every game tick. 3 | * 4 | * The `@Tick` decorator registers the decorated method to be executed on each game tick. This is particularly useful 5 | * where a method needs to be run continuously at every update cycle. 6 | * 7 | * @example 8 | * ```ts 9 | * class GameLogic { 10 | * @Tick 11 | * public update() { 12 | * console.log('Updating game state...'); 13 | * } 14 | * } 15 | * 16 | * const game = new GameLogic(); 17 | * // The `update` method will now be called on every game tick. 18 | * ``` 19 | * 20 | * @param _target The prototype of the class. 21 | * @param propertyKey The name of the method being decorated. 22 | * @param descriptor The property descriptor for the method. 23 | */ 24 | export function Tick(_target: object, propertyKey: string, descriptor: PropertyDescriptor) { 25 | const originalMethod = descriptor.value; 26 | 27 | setTick(() => { 28 | originalMethod(); 29 | }); 30 | 31 | console.log(`Registered tick for function: ${propertyKey}`); 32 | } 33 | -------------------------------------------------------------------------------- /packages/shared/src/enums/vehicle/VehicleLockState.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enum for representing the state of a vehicle's lock. 3 | * 4 | * @enum{number} 5 | */ 6 | export enum VehicleLockState { 7 | /** The vehicle is in an undefined lock state. */ 8 | None = 0, 9 | /** The vehicle is unlocked and can be entered by anyone. */ 10 | Unlocked = 1, 11 | /** The vehicle is locked and cannot be entered or started. */ 12 | Locked = 2, 13 | /** The vehicle is locked, restricting only the player. */ 14 | LockoutPlayerOnly = 3, 15 | /** The player is locked inside the vehicle. */ 16 | LockedPlayerInside = 4, 17 | /** The vehicle starts in a locked state. */ 18 | InitiallyLocked = 5, 19 | /** The vehicle's doors are forcefully shut. */ 20 | ForceShutDoors = 6, 21 | /** The vehicle is locked but can be damaged. */ 22 | LockedCanBeDamaged = 7, 23 | /** The vehicle is locked, but the boot is unlocked. */ 24 | LockedWithBootUnlocked = 8, 25 | /** The vehicle is locked and all passengers must exit. */ 26 | LockedWithNoPassengers = 9, 27 | /** The vehicle is locked and cannot be entered. */ 28 | LockedCannotEnter = 10, 29 | } 30 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Riyane 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /examples/tsc/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tsc", 3 | "version": "1.0.0", 4 | "author": "Purpose-Dev", 5 | "description": "", 6 | "license": "ISC", 7 | "type": "module", 8 | "scripts": { 9 | "build": "node build.mjs", 10 | "format": "prettier --write \"**/*.{ts,js,json,md}\"", 11 | "format:check": "prettier --check \"**/*.{ts,js,json,md}\"", 12 | "lint": "eslint \"**/*.{ts,js}\"", 13 | "lint:fix": "pnpm run lint --fix", 14 | "test": "echo \"Error: no test specified\" && exit 1" 15 | }, 16 | "keywords": [], 17 | "dependencies": { 18 | "@fivem-ts/client": "latest", 19 | "@fivem-ts/server": "latest" 20 | }, 21 | "devDependencies": { 22 | "@citizenfx/client": "2.0.12180-1", 23 | "@citizenfx/server": "2.0.12180-1", 24 | "@types/node": "^22.10.5", 25 | "@typescript-eslint/eslint-plugin": "8.19.0", 26 | "@typescript-eslint/parser": "8.19.0", 27 | "esbuild": "^0.24.2", 28 | "eslint": "^9.17.0", 29 | "eslint-config-prettier": "^9.1.0", 30 | "prettier": "^3.4.2" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /packages/client/src/enums/ped/DrivingStyle.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enum representing various driving styles. 3 | * 4 | * - None: No specific driving style. 5 | * - Normal: Standard driving behavior. 6 | * - IgnoreLights: Ignores traffic lights. 7 | * - SometimesOvertakeTraffic: Occasionally overtakes traffic. 8 | * - Rushed: Drives in a hurried manner. 9 | * - AvoidTraffic: Prefers routes to avoid traffic. 10 | * - AvoidTrafficExtremely: Takes extreme measures to avoid traffic. 11 | * - AvoidHighwaysWhenPossible: Avoids highways when feasible. 12 | * - IgnorePathing: Disregards pathing rules. 13 | * - IgnoreRoads: Ignores standard road usage. 14 | * - ShortestPath: Chooses the shortest path. 15 | * - Backwards: Drives in reverse. 16 | * 17 | * @enum{number} 18 | */ 19 | export enum DrivingStyle { 20 | None = 0, 21 | Normal = 786603, 22 | IgnoreLights = 2883621, 23 | SometimesOvertakeTraffic = 5, 24 | Rushed = 1074528293, 25 | AvoidTraffic = 786468, 26 | AvoidTrafficExtremely = 6, 27 | AvoidHighwaysWhenPossible = 536870912, 28 | IgnorePathing = 16777216, 29 | IgnoreRoads = 4194304, 30 | ShortestPath = 262144, 31 | Backwards = 1024, 32 | } 33 | -------------------------------------------------------------------------------- /packages/shared/src/enums/others/EntityOrphanMode.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Sets what happens when the entity is orphaned and no longer has its original owner. 3 | * **NOTE**: This native doesn't guarantee the persistence of the entity. 4 | * https://github.com/citizenfx/fivem/commit/db0d747a9c900d93e336028ee495ed87ea946c83#diff-ace4096b9336f866094d85230f5cbddd788ad5c158cac2bc613b872c55cb53f4R23 5 | * 6 | * 7 | * @enum {number} 8 | */ 9 | export enum EntityOrphanMode { 10 | /** 11 | * Default, this will delete the entity when it isn't relevant to any players 12 | * NOTE: this *doesn't* mean when they're no longer in scope 13 | */ 14 | DeleteWhenNotRelevant = 0, 15 | /** 16 | * The entity will be deleted whenever its original owner disconnects 17 | * NOTE: if this is set when the entities original owner has already left it will be 18 | * marked for deletion (similar to just calling DELETE_ENTITY) 19 | */ 20 | DeleteOnOwnerDisconnect = 1, 21 | /** 22 | * The entity will never be deleted by the server when it does relevancy checks 23 | * you should only use this on entities that need to be relatively persistent 24 | */ 25 | KeepEntity = 2, 26 | } 27 | -------------------------------------------------------------------------------- /packages/client/src/models/VehicleToggleMod.ts: -------------------------------------------------------------------------------- 1 | import { Vehicle, VehicleToggleModType } from '..'; 2 | 3 | /** 4 | * Represents a vehicle modification that can be toggled on or off. 5 | */ 6 | export class VehicleToggleMod { 7 | constructor( 8 | private readonly owner: Vehicle, 9 | private readonly modType: VehicleToggleModType, 10 | ) {} 11 | 12 | public get Owner(): Vehicle { 13 | return this.owner; 14 | } 15 | 16 | public get ModType(): VehicleToggleModType { 17 | return this.modType; 18 | } 19 | 20 | public get IsInstalled(): boolean { 21 | return IsToggleModOn(this.owner.Handle, this.ModType); 22 | } 23 | 24 | public set IsInstalled(value: boolean) { 25 | ToggleVehicleMod(this.owner.Handle, this.ModType, value); 26 | } 27 | 28 | public get LocalizedModTypeName(): string { 29 | return GetModSlotName(this.owner.Handle, this.ModType); 30 | } 31 | 32 | /** 33 | * Removes a vehicle modification. 34 | * 35 | * This method removes a specific modification type from the vehicle owned by the current owner. 36 | * 37 | * @returns {void} 38 | */ 39 | public remove(): void { 40 | RemoveVehicleMod(this.owner.Handle, this.ModType); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /packages/shared/src/enums/others/RadioStation.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enumeration representing the available radio stations. 3 | * 4 | * This enum provides a list of radio station identifiers that can be used 5 | * in applications requiring reference to specific radio stations. 6 | * 7 | * @enum{string} 8 | */ 9 | export enum RadioStation { 10 | LosSantosRockRadio = 'RADIO_01_CLASS_ROCK', 11 | NonStopPopFM = 'RADIO_02_POP', 12 | RadioLosSantos = 'RADIO_03_HIPHOP_NEW', 13 | ChannelX = 'RADIO_04_PUNK', 14 | WestCoastTalkRadio = 'RADIO_05_TALK_01', 15 | RebelRadio = 'RADIO_06_COUNTRY', 16 | SoulwaxFM = 'RADIO_07_DANCE_01', 17 | EastLosFM = 'RADIO_08_MEXICAN', 18 | WestCoastClassics = 'RADIO_09_HIPHOP_OLD', 19 | BlueArk = 'RADIO_12_REGGAE', 20 | WorldwideFM = 'RADIO_13_JAZZ', 21 | FlyLoFM = 'RADIO_14_DANCE_02', 22 | TheLowdown = 'RADIO_15_MOTOWN', 23 | TheLab = 'RADIO_20_THELAB', 24 | RadioMirrorPark = 'RADIO_16_SILVERLAKE', 25 | Space = 'RADIO_17_FUNK', 26 | VinewoodBoulevardRadio = 'RADIO_18_90S_ROCK', 27 | BlondedLosSantos = 'RADIO_21_DLC_XM17', 28 | BlaineCountyRadio = 'RADIO_11_TALK_02', 29 | LosSantosUndergroundRadio = 'RADIO_22_DLC_BATTLE_MIX1_RADIO', 30 | Off = 'OFF', 31 | } 32 | -------------------------------------------------------------------------------- /DEVELOPMENT.md: -------------------------------------------------------------------------------- 1 | ### Getting Started 2 | 3 | 1. First, you need to have the latest git, node 12 or greater installed. OSX, Windows and Linux should all be supported as build environments. This may differ from FiveM's supported environments. 4 | 5 | **We do not use `yarn`, so it's not supported.** 6 | 7 | 1. For this repo by using the "Fork" button on the upper-right 8 | 2. Check out your fork 9 | 10 | ``` 11 | git clone git@github.com:yournamehere/fivem-ts.git 12 | ``` 13 | 14 | 3. Install or Update all dependencies 15 | 16 | ``` 17 | npm i 18 | ``` 19 | 20 | 4. Get coding! If you've changed or added new functionality, update any relevant documentation. Ensure your work is committed within a feature branch. 21 | 5. Ensure the project has no linting errors and builds 22 | 23 | ``` 24 | npm run lint 25 | npm run build 26 | ``` 27 | 28 | ### Relevant Commands 29 | 30 | 1. `npm i` - install and link all packages 31 | 2. `npm run format` - autoformats with eslint --fix and prettier 32 | 3. `npm run lint` - checks for linting issues 33 | 4. `npm run build` - builds using `tsc` 34 | 5. `npm run docs` - builds documentation 35 | 36 | ### Optional 37 | 38 | For updating dependencies you can use `npm update` 39 | -------------------------------------------------------------------------------- /packages/client/src/enums/environment/SpeechModifier.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * An enumeration representing various modifiers for speech 3 | * 4 | * @enum{number} 5 | */ 6 | export enum SpeechModifier { 7 | Standard = 0, 8 | AllowRepeat = 1, 9 | Beat = 2, 10 | Force = 3, 11 | ForceFrontend = 4, 12 | ForceNoRepeatFrontend = 5, 13 | ForceNormal = 6, 14 | ForceNormalClear = 7, 15 | ForceNormalCritical = 8, 16 | ForceShouted = 9, 17 | ForceShoutedClear = 10, 18 | ForceShoutedCritical = 11, 19 | ForcePreloadOnly = 12, 20 | Megaphone = 13, 21 | Helicopter = 14, 22 | ForceMegaphone = 15, 23 | ForceHelicopter = 16, 24 | Interrupt = 17, 25 | InterruptShouted = 18, 26 | InterruptShoutedClear = 19, 27 | InterruptShoutedCritical = 20, 28 | InterruptNoForce = 21, 29 | InterruptFrontend = 22, 30 | InterruptNoForceFrontend = 23, 31 | AddBlip = 24, 32 | AddBlipAllowRepeat = 25, 33 | AddBlipForce = 26, 34 | AddBlipShouted = 27, 35 | AddBlipShoutedForce = 28, 36 | AddBlipInterrupt = 29, 37 | AddBlipInterruptForce = 30, 38 | ForcePreloadOnlyShouted = 31, 39 | ForcePreloadOnlyShoutedClear = 32, 40 | ForcePreloadOnlyShoutedCritical = 33, 41 | Shouted = 34, 42 | ShoutedClear = 35, 43 | ShoutedCritical = 36, 44 | } 45 | -------------------------------------------------------------------------------- /examples/esbuild/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "esbuild", 3 | "version": "1.0.0", 4 | "author": "Purpose-Dev", 5 | "description": "", 6 | "license": "ISC", 7 | "type": "module", 8 | "scripts": { 9 | "build": "tsx esbuild.ts", 10 | "format": "prettier --write \"**/*.{ts,js,json,md}\"", 11 | "format:check": "prettier --check \"**/*.{ts,js,json,md}\"", 12 | "lint": "eslint \"**/*.{ts,js}\"", 13 | "lint:fix": "pnpm run lint --fix", 14 | "test": "echo \"Error: no test specified\" && exit 1" 15 | }, 16 | "keywords": [], 17 | "dependencies": { 18 | "@fivem-ts/client": "latest", 19 | "@fivem-ts/server": "latest" 20 | }, 21 | "devDependencies": { 22 | "@citizenfx/client": "2.0.12180-1", 23 | "@citizenfx/server": "2.0.12180-1", 24 | "@types/node": "^22.10.5", 25 | "@typescript-eslint/eslint-plugin": "8.19.0", 26 | "@typescript-eslint/parser": "8.19.0", 27 | "esbuild": "^0.24.2", 28 | "eslint": "^9.17.0", 29 | "eslint-config-prettier": "^9.1.0", 30 | "prettier": "^3.4.2", 31 | "tsx": "^4.19.2", 32 | "typescript": "^5.7.2" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /packages/client/src/enums/vehicles/VehicleMods.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enum representing various vehicle modifications that can be applied to a vehicle. 3 | * 4 | * @enum{number} 5 | */ 6 | export enum VehicleMods { 7 | Spoiler = 0, 8 | FrontBumper = 1, 9 | RearBumper = 2, 10 | Skirt = 3, 11 | Exhaust = 4, 12 | Chassis = 5, 13 | Grill = 6, 14 | Bonnet = 7, 15 | LeftWing = 8, 16 | RightWing = 9, 17 | Roof = 10, 18 | Engine = 11, 19 | Brakes = 12, 20 | Gearbox = 13, 21 | Horn = 14, 22 | Suspension = 15, 23 | Armour = 16, 24 | Nitrous = 17, 25 | Turbo = 18, 26 | Subwoofer = 19, 27 | TyreSmoke = 20, 28 | Hydraulics = 21, 29 | XenonLights = 22, 30 | Wheels = 23, 31 | WheelsRearOrHydraulics = 24, 32 | PlateHolder = 25, 33 | PlateVanity = 26, 34 | Interior1 = 27, 35 | Interior2 = 28, 36 | Interior3 = 29, 37 | Interior4 = 30, 38 | Interior5 = 31, 39 | Seats = 32, 40 | Steering = 33, 41 | Knob = 34, 42 | Plaque = 35, 43 | Ice = 36, 44 | Trunk = 37, 45 | Hydro = 38, 46 | EngineBay1 = 39, 47 | EngineBay2 = 40, 48 | EngineBay3 = 41, 49 | Chassis2 = 42, 50 | Chassis3 = 43, 51 | Chassis4 = 44, 52 | Chassis5 = 45, 53 | LeftDoor = 46, 54 | RightDoor = 47, 55 | LiveryMod = 48, 56 | LightBar = 49, 57 | } 58 | -------------------------------------------------------------------------------- /packages/client/src/models/Prop.ts: -------------------------------------------------------------------------------- 1 | import { Entity } from '.'; 2 | 3 | /** 4 | * Represents a Prop entity. 5 | * 6 | * This class extends the Entity class and provides functionalities specific to Prop entities. 7 | * 8 | * @class Prop 9 | * @extends Entity 10 | * @see {Entity} 11 | */ 12 | export class Prop extends Entity { 13 | constructor(id: number) { 14 | if (!(GetEntityType(id) !== 3)) { 15 | throw new Error('Prop: Attempted to create an instance with an invalid entity type.'); 16 | } 17 | 18 | super(id); 19 | } 20 | 21 | /** 22 | * Positions the object on the ground properly. 23 | * 24 | * This method uses the underlying 'PlaceObjectOnGroundProperly' function with 25 | * the current object's handle to adjust its position such that it rests 26 | * appropriately on the ground. 27 | * 28 | * @returns {void} 29 | */ 30 | public placeOnGround(): void { 31 | PlaceObjectOnGroundProperly(this.Handle); 32 | } 33 | 34 | /** 35 | * Places the object on the ground properly using the appropriate game function. 36 | * Adjusts the position of the object to ensure it is correctly aligned with the ground. 37 | * 38 | * @returns {void} 39 | */ 40 | public placeOnGround2(): void { 41 | PlaceObjectOnGroundProperly_2(this.Handle); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /packages/shared/src/utils/merge.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Combines two objects into a single object, merging their properties. 3 | * If both objects contain properties with the same key, the value from the second object (`sObj`) will overwrite the value from the first object (`fObj`). 4 | * 5 | * @example 6 | * ```typescript 7 | * const obj1 = { a: 1, b: 2 }; 8 | * const obj2 = { b: 3, c: 4 }; 9 | * const result = merge(obj1, obj2); 10 | * // result: { a: 1, b: 3, c: 4 } 11 | * ``` 12 | * 13 | * @remarks 14 | * - This function uses shallow merging, meaning nested objects will not be deeply merged. 15 | * - The resulting object is a new object and does not modify the input objects. 16 | * 17 | * @template T - The type of the first object. 18 | * @template U - The type of the second object. 19 | * 20 | * @param {T} fObj - The first object to be merged. 21 | * @param {U} sObj - The second object to be merged. Its properties will overwrite those of `fObj` in case of conflicts. 22 | * 23 | * @returns {T & U} - A new object containing all properties from both input objects, with type safety applied to ensure the merged object conforms to the union of the input types. 24 | */ 25 | export function merge(fObj: T, sObj: U): T & U { 26 | return Object.assign({}, fObj, sObj); 27 | } 28 | -------------------------------------------------------------------------------- /packages/shared/src/utils/__tests__/generateUniqueKey.test.ts: -------------------------------------------------------------------------------- 1 | import { generateUniqueKey } from '../generateUniqueKey'; 2 | 3 | describe('generateUniqueKey', () => { 4 | it('should generate a key containing the event name and a random number', () => { 5 | const eventName = 'eventStart'; 6 | const key = generateUniqueKey(eventName); 7 | expect(key).toMatch(new RegExp(`^${eventName}:[1-9][0-9]{0,4}$`)); 8 | }); 9 | 10 | it('should generate a key containing the event name, a random number, and the player ID if provided', () => { 11 | const eventName = 'eventStart'; 12 | const playerId = 42; 13 | const key = generateUniqueKey(eventName, playerId); 14 | expect(key).toMatch(new RegExp(`^${eventName}:[1-9][0-9]{0,4}:${playerId}$`)); 15 | }); 16 | 17 | it('should generate unique keys for the same event name', () => { 18 | const eventName = 'eventStart'; 19 | const key1 = generateUniqueKey(eventName); 20 | const key2 = generateUniqueKey(eventName); 21 | expect(key1).not.toBe(key2); 22 | }); 23 | 24 | it('should generate unique keys for the same event name and player ID', () => { 25 | const eventName = 'eventStart'; 26 | const playerId = 42; 27 | const key1 = generateUniqueKey(eventName, playerId); 28 | const key2 = generateUniqueKey(eventName, playerId); 29 | expect(key1).not.toBe(key2); 30 | }); 31 | }); 32 | -------------------------------------------------------------------------------- /packages/client/src/Checkpoint.ts: -------------------------------------------------------------------------------- 1 | import { Nullable, Vector3 } from '@fivem-ts/shared'; 2 | import { CheckpointIcon } from '.'; 3 | 4 | export class Checkpoint { 5 | private readonly handle: number; 6 | private position: Nullable; 7 | private targetPosition: Nullable; 8 | private icon: Nullable; 9 | private radius: Nullable; 10 | 11 | constructor(handle: number) { 12 | this.handle = handle; 13 | this.position = null; 14 | this.targetPosition = null; 15 | this.icon = null; 16 | this.radius = null; 17 | } 18 | 19 | public get Handle(): number { 20 | return this.handle; 21 | } 22 | 23 | public get Position(): Nullable { 24 | return this.position; 25 | } 26 | 27 | public set Position(pos: Vector3) { 28 | this.position = pos; 29 | } 30 | 31 | public get TargetPosition(): Nullable { 32 | return this.targetPosition; 33 | } 34 | 35 | public set TargetPosition(targetPos: Vector3) { 36 | this.targetPosition = targetPos; 37 | } 38 | 39 | public get Icon(): Nullable { 40 | return this.icon; 41 | } 42 | 43 | public set Icon(icon: CheckpointIcon) { 44 | this.icon = icon; 45 | } 46 | 47 | public get Radius(): Nullable { 48 | return this.radius; 49 | } 50 | 51 | public set Radius(radius: number) { 52 | this.radius = radius; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /packages/client/src/enums/environment/ZoneID.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enum of zones, Useful for using world zone related natives 3 | * 4 | * @enum{number} 5 | */ 6 | export enum ZoneID { 7 | AIRP, 8 | ALAMO, 9 | ALTA, 10 | ARMYB, 11 | BANHAMC, 12 | BANNING, 13 | BEACH, 14 | BHAMCA, 15 | BRADP, 16 | BRADT, 17 | BURTON, 18 | CALAFB, 19 | CANNY, 20 | CCREAK, 21 | CHAMH, 22 | CHIL, 23 | CHU, 24 | CMSW, 25 | CYPRE, 26 | DAVIS, 27 | DELBE, 28 | DELPE, 29 | DELSOL, 30 | DESRT, 31 | DOWNT, 32 | DTVINE, 33 | EAST_V, 34 | EBURO, 35 | ELGORL, 36 | ELYSIAN, 37 | GALFISH, 38 | GOLF, 39 | GRAPES, 40 | GREATC, 41 | HARMO, 42 | HAWICK, 43 | HORS, 44 | HUMLAB, 45 | JAIL, 46 | KOREAT, 47 | LACT, 48 | LAGO, 49 | LDAM, 50 | LEGSQU, 51 | LMESA, 52 | LOSPUER, 53 | MIRR, 54 | MORN, 55 | MOVIE, 56 | MTCHIL, 57 | MTGORDO, 58 | MTJOSE, 59 | MURRI, 60 | NCHU, 61 | NOOSE, 62 | OCEANA, 63 | PALCOV, 64 | PALETO, 65 | PALFOR, 66 | PALHIGH, 67 | PALMPOW, 68 | PBLUFF, 69 | PBOX, 70 | PROCOB, 71 | RANCHO, 72 | RGLEN, 73 | RICHM, 74 | ROCKF, 75 | RTRAK, 76 | SANAND, 77 | SANCHIA, 78 | SANDY, 79 | SKID, 80 | SLAB, 81 | STAD, 82 | STRAW, 83 | TATAMO, 84 | TERMINA, 85 | TEXTI, 86 | TONGVAH, 87 | TONGVAV, 88 | VCANA, 89 | VESP, 90 | VINE, 91 | WINDF, 92 | WVINE, 93 | ZANCUDO, 94 | ZP_ORT, 95 | ZQ_UAR, 96 | PROL, 97 | ISHeist, 98 | } 99 | -------------------------------------------------------------------------------- /packages/client/src/enums/hud/HudComponent.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enumeration of HUD components. 3 | * These components represent various elements that can be shown or hidden 4 | * on the player's HUD, such as the player's wanted level, weapon icon, 5 | * cash amount, and many others. 6 | * 7 | * @enum{number} 8 | */ 9 | export enum HudComponent { 10 | WantedStars = 1, 11 | WeaponIcon, 12 | Cash, 13 | MpCash, 14 | MpMessage, 15 | VehicleName, 16 | AreaName, 17 | Unused, 18 | StreetName, 19 | HelpText, 20 | FloatingHelpText1, 21 | FloatingHelpText2, 22 | CashChange, 23 | Reticle, 24 | SubtitleText, 25 | RadioStationsWheel, 26 | Saving, 27 | GamingStreamUnusde, 28 | WeaponWheel, 29 | WeaponWheelStats, 30 | DrugsPurse01, 31 | DrugsPurse02, 32 | DrugsPurse03, 33 | DrugsPurse04, 34 | MpTagCashFromBank, 35 | MpTagPackages, 36 | MpTagCuffKeys, 37 | MpTagDownloadData, 38 | MpTagIfPedFollowing, 39 | MpTagKeyCard, 40 | MpTagRandomObject, 41 | MpTagRemoteControl, 42 | MpTagCashFromSafe, 43 | MpTagWeaponsPackage, 44 | MpTagKeys, 45 | MpVehicle, 46 | MpVehicleHeli, 47 | MpVehiclePlane, 48 | PlayerSwitchAlert, 49 | MpRankBar, 50 | DirectorMode, 51 | ReplayController, 52 | ReplayMouse, 53 | ReplayHeader, 54 | ReplayOptions, 55 | ReplayHelpText, 56 | ReplayMiscText, 57 | ReplayTopLine, 58 | ReplayBottomLine, 59 | ReplayLeftBar, 60 | ReplayTimer, 61 | } 62 | -------------------------------------------------------------------------------- /examples/esbuild/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Base Options */ 4 | "esModuleInterop": true, 5 | "skipLibCheck": true, 6 | "verbatimModuleSyntax": false, 7 | "allowJs": true, 8 | "resolveJsonModule": true, 9 | "moduleDetection": "force", 10 | "allowSyntheticDefaultImports": true, 11 | 12 | /* Decorators */ 13 | "experimentalDecorators": true, 14 | "emitDecoratorMetadata": true, 15 | 16 | /* Strict */ 17 | "strict": true, 18 | "noImplicitAny": true, 19 | "strictNullChecks": true, 20 | "strictFunctionTypes": true, 21 | "strictBindCallApply": true, 22 | "strictPropertyInitialization": true, 23 | "noImplicitThis": true, 24 | "alwaysStrict": true, 25 | "pretty": true, 26 | "forceConsistentCasingInFileNames": true, 27 | 28 | /* Additional Checks */ 29 | "noUnusedLocals": true, 30 | "noUnusedParameters": true, 31 | "noImplicitReturns": true, 32 | "noFallthroughCasesInSwitch": true, 33 | "noUncheckedIndexedAccess": true, 34 | "allowUnreachableCode": false, 35 | 36 | /* Monorepo Options */ 37 | "composite": true, 38 | "declarationMap": true 39 | }, 40 | "exclude": ["node_modules", "dist", ".idea", ".dev-data", ".data"] 41 | } 42 | -------------------------------------------------------------------------------- /packages/shared/src/utils/generateUniqueKey.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Generates a unique key based on the event name and an optional player ID. 3 | * 4 | * @example 5 | * ```typescript 6 | * const key1 = generateUniqueKey("eventStart"); 7 | * // Possible output: "eventStart:45321" 8 | * 9 | * const key2 = generateUniqueKey("eventStart", 42); 10 | * // Possible output: "eventStart:67890:42" 11 | * ``` 12 | * 13 | * @remarks 14 | * - The unique key is generated by combining the event name with a random number and optionally a player ID. 15 | * - The random suffix is a number between 1 and 100,000, ensuring a low likelihood of collision. 16 | * - If `playerId` is provided, it is appended to the key for additional uniqueness. 17 | * - This function is not suitable for cryptographic purposes as the random number generator is not cryptographically secure. 18 | * 19 | * @param {string} eventName - The name of the event to include in the unique key. 20 | * @param {number} [playerId] - An optional player ID to include in the key. 21 | * 22 | * @returns {string} A unique string key constructed from the inputs and a random suffix. 23 | */ 24 | export function generateUniqueKey(eventName: string, playerId?: number): string { 25 | const randomSuffix: number = (Math.random() * 100000 + 1) | 0; 26 | return playerId !== undefined 27 | ? eventName + ':' + randomSuffix + ':' + playerId 28 | : eventName + ':' + randomSuffix; 29 | } 30 | -------------------------------------------------------------------------------- /packages/client/src/enums/ui/CheckpointCustomIconStyle.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enumeration representing different styles for checkpoint custom icons. 3 | * 4 | * Each member of this enumeration corresponds to a specific style of icon that can be used to 5 | * personalize the appearance of checkpoints. These styles can be leveraged to enhance visuals 6 | * and provide distinctive icons for various checkpoints in an application. 7 | * 8 | * Members include: 9 | * - Number: Represents a numerical style. 10 | * - SingleArrow: Represents a single arrow style. 11 | * - DoubleArrow: Represents a double arrow style. 12 | * - TripleArrow: Represents a triple arrow style. 13 | * - Ring: Represents a ring style. 14 | * - CycleArrow: Represents a cycling arrow style. 15 | * - Ring2: Represents an alternate ring style. 16 | * - RingPointer: Represents a ring with a pointer. 17 | * - SegmentedRing: Represents a segmented ring style. 18 | * - Sphere: Represents a spherical style. 19 | * - Dollar: Represents a dollar symbol style. 20 | * - QuintupleLines: Represents a style with five lines. 21 | * - BeastIcon: Represents a style with a beast icon. 22 | * 23 | * @enum{number} 24 | */ 25 | export enum CheckpointCustomIconStyle { 26 | Number, 27 | SingleArrow, 28 | DoubleArrow, 29 | TripleArrow, 30 | Ring, 31 | CycleArrow, 32 | Ring2, 33 | RingPointer, 34 | SegmentedRing, 35 | Sphere, 36 | Dollar, 37 | QuintupleLines, 38 | BeastIcon, 39 | } 40 | -------------------------------------------------------------------------------- /packages/server/src/web/requests.ts: -------------------------------------------------------------------------------- 1 | import { makeRequest, RequestData, RequestHeaders } from './makeRequest'; 2 | 3 | export async function get(url: string, headers?: RequestHeaders): Promise { 4 | try { 5 | return await makeRequest(url, 'GET', undefined, headers); 6 | } catch (error) { 7 | console.error(`Get request error on URL ${url}: `, error); 8 | throw error; 9 | } 10 | } 11 | 12 | export async function post( 13 | url: string, 14 | data: RequestData, 15 | headers?: RequestHeaders, 16 | ): Promise { 17 | try { 18 | return await makeRequest(url, 'POST', data, headers); 19 | } catch (error) { 20 | console.error(`Post request error on URL ${url}: `, error); 21 | throw error; 22 | } 23 | } 24 | 25 | export async function put(url: string, data: RequestData, headers?: RequestHeaders): Promise { 26 | try { 27 | return await makeRequest(url, 'PUT', data, headers); 28 | } catch (error) { 29 | console.error(`Put request error on URL ${url}: `, error); 30 | throw error; 31 | } 32 | } 33 | 34 | export async function del(url: string, headers?: RequestHeaders): Promise { 35 | try { 36 | return await makeRequest(url, 'DELETE', undefined, headers); 37 | } catch (error) { 38 | console.error(`Delete request error on URL ${url}: `, error); 39 | throw error; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /packages/shared/src/utils/__tests__/merge.test.ts: -------------------------------------------------------------------------------- 1 | import { merge } from '../merge'; 2 | 3 | describe('merge', () => { 4 | it('should merge two objects with unique keys', () => { 5 | const obj1 = { a: 1 }; 6 | const obj2 = { b: 2 }; 7 | const result = merge(obj1, obj2); 8 | expect(result).toEqual({ a: 1, b: 2 }); 9 | }); 10 | 11 | it('should overwrite properties in the first object with properties from the second object', () => { 12 | const obj1 = { a: 1, b: 2 }; 13 | const obj2 = { b: 3, c: 4 }; 14 | const result = merge(obj1, obj2); 15 | expect(result).toEqual({ a: 1, b: 3, c: 4 }); 16 | }); 17 | 18 | it('should return a new object and not mutate the original objects', () => { 19 | const obj1 = { a: 1 }; 20 | const obj2 = { b: 2 }; 21 | const result = merge(obj1, obj2); 22 | expect(result).not.toBe(obj1); 23 | expect(result).not.toBe(obj2); 24 | expect(obj1).toEqual({ a: 1 }); 25 | expect(obj2).toEqual({ b: 2 }); 26 | }); 27 | 28 | it('should handle empty objects correctly', () => { 29 | const obj1 = {}; 30 | const obj2 = { a: 1 }; 31 | const result = merge(obj1, obj2); 32 | expect(result).toEqual({ a: 1 }); 33 | }); 34 | 35 | it('should prioritize second object properties even if they are undefined', () => { 36 | const obj1 = { a: 1, b: 2 }; 37 | const obj2 = { b: undefined }; 38 | const result = merge(obj1, obj2); 39 | expect(result).toEqual({ a: 1, b: undefined }); 40 | }); 41 | }); 42 | -------------------------------------------------------------------------------- /packages/client/src/enums/ui/MarkerTypes.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enumeration of marker types. 3 | * 4 | * @enum{number} 5 | */ 6 | export enum MarkerTypes { 7 | MarkerTypeUpsideDownCone, 8 | MarkerTypeVerticalCylinder, 9 | MarkerTypeThickChevronUp, 10 | MarkerTypeThinChevronUp, 11 | MarkerTypeCheckeredFlagRect, 12 | MarkerTypeCheckeredFlagCircle, 13 | MarkerTypeVerticleCircle, 14 | MarkerTypePlaneModel, 15 | MarkerTypeLostMCTransparent, 16 | MarkerTypeLostMC, 17 | MarkerTypeNumber0, 18 | MarkerTypeNumber1, 19 | MarkerTypeNumber2, 20 | MarkerTypeNumber3, 21 | MarkerTypeNumber4, 22 | MarkerTypeNumber5, 23 | MarkerTypeNumber6, 24 | MarkerTypeNumber7, 25 | MarkerTypeNumber8, 26 | MarkerTypeNumber9, 27 | MarkerTypeChevronUpx1, 28 | MarkerTypeChevronUpx2, 29 | MarkerTypeChevronUpx3, 30 | MarkerTypeHorizontalCircleFat, 31 | MarkerTypeReplayIcon, 32 | MarkerTypeHorizontalCircleSkinny, 33 | MarkerTypeHorizontalCircleSkinny_Arrow, 34 | MarkerTypeHorizontalSplitArrowCircle, 35 | MarkerTypeDebugSphere, 36 | MarkerTypeDollarSign, 37 | MarkerTypeHorizontalBars, 38 | MarkerTypeWolfHead, 39 | MarkerTypeQuestionMark, 40 | MarkerTypePlaneSymbol, 41 | MarkerTypeHelicopterSymbol, 42 | MarkerTypeBoatSymbol, 43 | MarkerTypeCarSymbol, 44 | MarkerTypeMotorcycleSymbol, 45 | MarkerTypeBikeSymbol, 46 | MarkerTypeTruckSymbol, 47 | MarkerTypeParachuteSymbol, 48 | MarkerTypeJetpackSymbol, 49 | MarkerTypeSawbladeSymbol, 50 | MarkerTypeRectangleSymbol, 51 | } 52 | -------------------------------------------------------------------------------- /packages/shared/src/decorators/game/command.ts: -------------------------------------------------------------------------------- 1 | import 'reflect-metadata'; 2 | 3 | /** 4 | * A decorator to register a method as a command with a specified name. 5 | * 6 | * This decorator uses the `RegisterCommand` function to register the method as a command handler 7 | * and stores metadata about the command name using `reflect-metadata`. 8 | * 9 | * @example 10 | * ```ts 11 | * class MyCommands { 12 | * @Command('sayHello') 13 | * helloCommand() { 14 | * console.log('Hello, world!'); 15 | * } 16 | * } 17 | * ``` 18 | * 19 | * In the above example, the `helloCommand` method is registered as a command with the name `sayHello`. 20 | * 21 | * @param commandName - The name of the command to register. 22 | * 23 | * @throws Error if the command registration fails. 24 | * 25 | * @remarks 26 | * The `RegisterCommand` function is expected to handle the command registration logic 27 | * and `reflect-metadata` is used for storing and retrieving metadata associated with the command. 28 | * 29 | * @see [RegisterCommand](https://docs.fivem.net/natives/?_0x5FA79B0F) 30 | */ 31 | export function Command(commandName: string) { 32 | return function (target: object, propertyKey: string, descriptor: PropertyDescriptor) { 33 | Reflect.defineMetadata('command', { name: commandName }, target, propertyKey); 34 | 35 | RegisterCommand(commandName, descriptor.value, false); 36 | console.log(`Registered command: ${commandName}`); 37 | }; 38 | } 39 | -------------------------------------------------------------------------------- /examples/tsc/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Base Options */ 4 | "esModuleInterop": true, 5 | "skipLibCheck": true, 6 | "verbatimModuleSyntax": false, 7 | "allowJs": true, 8 | "resolveJsonModule": true, 9 | "moduleDetection": "force", 10 | "allowSyntheticDefaultImports": true, 11 | 12 | /* Decorators */ 13 | "experimentalDecorators": true, 14 | "emitDecoratorMetadata": true, 15 | 16 | /* Strict */ 17 | "strict": true, 18 | "noImplicitAny": true, 19 | "strictNullChecks": true, 20 | "strictFunctionTypes": true, 21 | "strictBindCallApply": true, 22 | "strictPropertyInitialization": true, 23 | "noImplicitThis": true, 24 | "alwaysStrict": true, 25 | "pretty": true, 26 | "forceConsistentCasingInFileNames": true, 27 | 28 | /* Additional Checks */ 29 | "noUnusedLocals": true, 30 | "noUnusedParameters": true, 31 | "noImplicitReturns": true, 32 | "noFallthroughCasesInSwitch": true, 33 | "noUncheckedIndexedAccess": true, 34 | "allowUnreachableCode": false, 35 | 36 | /* Monorepo Options */ 37 | "composite": true, 38 | "declarationMap": false, 39 | "inlineSourceMap": false, 40 | "sourceMap": false 41 | }, 42 | "exclude": ["node_modules", "dist", ".idea", ".dev-data", ".data"] 43 | } 44 | -------------------------------------------------------------------------------- /packages/client/src/models/EntityBone.ts: -------------------------------------------------------------------------------- 1 | import { Vector3 } from '@fivem-ts/shared'; 2 | import { Entity } from '.'; 3 | 4 | /** 5 | * Represents a bone of an entity in a game environment. 6 | * 7 | * @class EntityBone 8 | */ 9 | export class EntityBone { 10 | protected readonly index: number; 11 | 12 | constructor( 13 | protected readonly owner: Entity, 14 | boneIndex?: number, 15 | boneName?: string, 16 | ) { 17 | this.index = boneIndex 18 | ? boneIndex 19 | : GetEntityBoneIndexByName(this.owner.Handle, boneName ?? ''); 20 | } 21 | 22 | public get Owner(): Entity { 23 | return this.owner; 24 | } 25 | 26 | public get Index(): number { 27 | return this.index; 28 | } 29 | 30 | public get IsValid(): boolean { 31 | return this.Owner.exists() && this.index !== -1; 32 | } 33 | 34 | public get Position(): Vector3 { 35 | const boneCoords: number[] = GetWorldPositionOfEntityBone(this.owner.Handle, this.index); 36 | return new Vector3(boneCoords[0], boneCoords[1], boneCoords[2]); 37 | } 38 | 39 | public get Rotation(): Vector3 { 40 | const boneRotation: number[] = GetEntityBoneRotation(this.owner.Handle, this.index); 41 | return new Vector3(boneRotation[0], boneRotation[1], boneRotation[2]); 42 | } 43 | 44 | public get LocalRotation(): Vector3 { 45 | const boneRotation: number[] = GetEntityBoneRotationLocal(this.owner.Handle, this.index); 46 | return new Vector3(boneRotation[0], boneRotation[1], boneRotation[2]); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /packages/server/src/models/Ace.ts: -------------------------------------------------------------------------------- 1 | export namespace Ace { 2 | export type AceAllowed = 'allow' | 'deny'; 3 | 4 | export function addAce(principal: string | number, ace: string, allow: AceAllowed): void { 5 | if (typeof principal === 'number') principal = `player.${principal}`; 6 | 7 | ExecuteCommand(`add_ace ${principal} ${ace} ${allow}`); 8 | } 9 | 10 | export function removeAce(principal: string | number, ace: string, allow: AceAllowed): void { 11 | if (typeof principal === 'number') principal = `player.${principal}`; 12 | 13 | ExecuteCommand(`remove_ace ${principal} ${ace} ${allow}`); 14 | } 15 | 16 | export function addPrincipal(child: string | number, parent: string): void { 17 | if (typeof child === 'number') child = `player.${child}`; 18 | 19 | ExecuteCommand(`add_principal ${child} ${parent}`); 20 | } 21 | 22 | export function removePrincipal(child: string | number, parent: string): void { 23 | if (typeof child === 'number') child = `player.${child}`; 24 | 25 | ExecuteCommand(`remove_principal ${child} ${parent}`); 26 | } 27 | 28 | export function isPlayerAceAllowed(playerSrc: string, object: string): boolean { 29 | return IsPlayerAceAllowed(playerSrc, object); 30 | } 31 | 32 | export function isPrincipalAceAllowed(principal: string, object: string): boolean { 33 | return IsPrincipalAceAllowed(principal, object); 34 | } 35 | 36 | export function isAceAllowed(object: string): boolean { 37 | return IsAceAllowed(object); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /packages/shared/src/decorators/core/thread.ts: -------------------------------------------------------------------------------- 1 | import 'reflect-metadata'; 2 | 3 | /** 4 | * A decorator that executes a method periodically at a specified interval. 5 | * 6 | * The `@Thread` decorator schedules the decorated method to be executed repeatedly after a specified delay. 7 | * This is useful for scenarios where you need a method to be run on a regular interval, such as updating 8 | * status, checking conditions, or performing background tasks. 9 | * 10 | * @example 11 | * ```ts 12 | * class StatusUpdater { 13 | * @Thread(5000) // Runs every 5 seconds 14 | * public updateStatus() { 15 | * console.log('Updating status...'); 16 | * } 17 | * } 18 | * 19 | * const updater = new StatusUpdater(); 20 | * // The `updateStatus` method will now be called every 5 seconds. 21 | * ``` 22 | * 23 | * @param delay The interval in milliseconds between successive executions of the method. 24 | * 25 | * @returns A decorator function that modifies the behavior of the method to run periodically. 26 | */ 27 | export function Thread(delay: number) { 28 | return function (target: object, propertyKey: string, descriptor: PropertyDescriptor) { 29 | const originalMethod = descriptor.value; 30 | 31 | setInterval(async () => { 32 | originalMethod.call(target); 33 | }, delay); 34 | 35 | Reflect.defineMetadata('threadOnly', delay, target, propertyKey); 36 | console.log(`Registered thread function: ${propertyKey} with delay ${delay}ms`); 37 | }; 38 | } 39 | -------------------------------------------------------------------------------- /packages/client/src/enums/ui/CheckpointIcon.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * An enumeration representing different types of checkpoint icons. 3 | * 4 | * These icons are commonly used in gaming and simulation environments 5 | * to mark various types of checkpoints, directions, and actions. 6 | * 7 | * @enum{number} 8 | */ 9 | export enum CheckpointIcon { 10 | CylinderSingleArrow, 11 | CylinderDoubleArrow, 12 | CylinderTripleArrow, 13 | CylinderCycleArrow, 14 | CylinderCheckerboard, 15 | CylinderMechanic, 16 | CylinderSingleArrow2, 17 | CylinderDoubleArrow2, 18 | CylinderTripleArrow2, 19 | CylinderCycleArrow2, 20 | CylinderCheckerboard2, 21 | RingSingleArrow, 22 | RingDoubleArrow, 23 | RingTripleArrow, 24 | RingCycleArrow, 25 | RingCheckerboard, 26 | SingleArrow, 27 | DoubleArrow, 28 | TripleArrow, 29 | CycleArrow, 30 | Checkerboard, 31 | CylinderSingleArrow3, 32 | CylinderDoubleArrow3, 33 | CylinderTripleArrow3, 34 | CylinderCycleArrow3, 35 | CylinderCheckerboard3, 36 | CylinderSingleArrow4, 37 | CylinderDoubleArrow4, 38 | CylinderTripleArrow4, 39 | CylinderCycleArrow4, 40 | CylinderCheckerboard4, 41 | CylinderSingleArrow5, 42 | CylinderDoubleArrow5, 43 | CylinderTripleArrow5, 44 | CylinderCycleArrow5, 45 | CylinderCheckerboard5, 46 | RingPlaneUp, 47 | RingPlaneLeft, 48 | RingPlaneRight, 49 | RingPlaneDown, 50 | Empty, 51 | Ring, 52 | Empty2, 53 | CylinderCustomShape, 54 | CylinderCustomShape2, 55 | CylinderCustomShape3, 56 | Cyclinder, 57 | Cyclinder2, 58 | Cyclinder3, 59 | } 60 | -------------------------------------------------------------------------------- /packages/shared/src/decorators/events/on.ts: -------------------------------------------------------------------------------- 1 | import 'reflect-metadata'; 2 | 3 | /** 4 | * A decorator that subscribes a method to a specified local event. 5 | * 6 | * The `@On` decorator is used to associate a method with a named event. When the specified event is triggered, the decorated method will be automatically called with the event's arguments. 7 | * 8 | * **Usage:** 9 | * - This decorator listens for an event and invokes the decorated method whenever the event is fired. 10 | * 11 | * @example 12 | * ```ts 13 | * class EventHandler { 14 | * @On('userLoggedIn') 15 | * onUserLoggedIn(userId: number, userName: string) { 16 | * console.log(`User logged in: ${userName} (ID: ${userId})`); 17 | * } 18 | * } 19 | * ``` 20 | * 21 | * @param eventName The name of the event to subscribe to. 22 | * @returns A method decorator that subscribes the decorated method to the specified event. 23 | */ 24 | export function On(eventName: string) { 25 | return function (target: object, propertyKey: string, descriptor: PropertyDescriptor) { 26 | Reflect.defineMetadata('onEvent', eventName, target, propertyKey); 27 | const originalMethod = descriptor.value; 28 | 29 | if (typeof originalMethod === 'function') { 30 | on(eventName, (...args: unknown[]) => (originalMethod as Function).apply(target, args)); 31 | console.log(`Subscribed to event: ${eventName} for function: ${String(propertyKey)}`); 32 | } else { 33 | console.warn(`Method ${String(propertyKey)} is not a method`); 34 | } 35 | }; 36 | } 37 | -------------------------------------------------------------------------------- /packages/shared/src/decorators/core/errorHandler.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * A decorator that wraps a method with error handling logic. 3 | * 4 | * The `@ErrorHandler` decorator catches any errors thrown by the decorated method and 5 | * passes them to the provided error handler function. This allows for centralized error 6 | * handling and custom responses to errors. 7 | * 8 | * @example 9 | * ```ts 10 | * 11 | * function logError(error: unknown): void { 12 | * console.error('An error occurred:', error); 13 | * } 14 | * 15 | * class ExampleClass { 16 | * @ErrorHandler(logError) 17 | * riskyMethod() { 18 | * throw new Error('Something went wrong'); 19 | * } 20 | * } 21 | * 22 | * const example = new ExampleClass(); 23 | * example.riskyMethod(); // Logs: An error occurred: Error: Something went wrong 24 | * ``` 25 | * 26 | * @param handleError A function to handle errors. This function is called with the error 27 | * that was thrown by the decorated method. 28 | * 29 | * @returns A function that can be used as a method decorator. 30 | */ 31 | export function ErrorHandler(handleError: (error: unknown) => void) { 32 | return function (_target: object, propertyKey: string, descriptor: PropertyDescriptor) { 33 | const originalMethod = descriptor.value; 34 | 35 | descriptor.value = function (...args: unknown[]) { 36 | try { 37 | return originalMethod.apply(this, args); 38 | } catch (error) { 39 | handleError(error); 40 | } 41 | }; 42 | 43 | console.log(`Registered error handler for function: ${propertyKey}`); 44 | }; 45 | } 46 | -------------------------------------------------------------------------------- /packages/shared/src/decorators/events/onNet.ts: -------------------------------------------------------------------------------- 1 | import 'reflect-metadata'; 2 | 3 | /** 4 | * A decorator that subscribes a method to a network event. 5 | * 6 | * The `@OnNet` decorator is used to associate a method with a network event. When the specified network event occurs, the decorated method will be automatically called with the event's arguments. 7 | * 8 | * **Usage:** 9 | * - This decorator listens for a network event and invokes the decorated method whenever the event is triggered. 10 | * 11 | * @example 12 | * ```ts 13 | * class NetworkHandler { 14 | * @OnNet('playerJoined') 15 | * onPlayerJoined(playerId: number, playerName: string) { 16 | * console.log(`Player joined: ${playerName} (ID: ${playerId})`); 17 | * } 18 | * } 19 | * ``` 20 | * 21 | * @param eventName The name of the network event to subscribe to. 22 | * @returns A method decorator that subscribes the decorated method to the specified network event. 23 | */ 24 | export function OnNet(eventName: string) { 25 | return function (target: object, propertyKey: string, descriptor: PropertyDescriptor) { 26 | Reflect.defineMetadata('onNetEvent', eventName, target, propertyKey); 27 | 28 | const originalMethod = descriptor.value; 29 | 30 | if (typeof originalMethod === 'function') { 31 | onNet(eventName, (...args: unknown[]) => 32 | (originalMethod as Function).apply(target, args), 33 | ); 34 | console.log(`Subscribed to event: ${eventName} for function: ${String(propertyKey)}`); 35 | } else { 36 | console.warn(`Method ${String(propertyKey)} is not a function.`); 37 | } 38 | }; 39 | } 40 | -------------------------------------------------------------------------------- /packages/shared/src/decorators/checks/ClientOnly.ts: -------------------------------------------------------------------------------- 1 | import 'reflect-metadata'; 2 | 3 | /** 4 | * A decorator that ensures a method is only executed on the client side. 5 | * 6 | * The `@ClientOnly` decorator modifies the behavior of the decorated method to prevent its execution 7 | * on the server side. If the method is called on the server side, a warning is logged and the method is replaced 8 | * with an empty function to prevent any unintended behavior. 9 | * 10 | * **Note:** This decorator intended to be used in environments where both server and client code can be executed, 11 | * such as in frameworks that support both server-side and client-side execution 12 | * 13 | * @example 14 | * ```ts 15 | * class Example { 16 | * @ClientOnly 17 | * public clientMethod() { 18 | * console.log('This method should only run on the client side.'); 19 | * } 20 | * } 21 | * 22 | * const example = new Example(); 23 | * example.clientMethod(); // Executes only if running on the client side. 24 | * ``` 25 | * 26 | * @param _target 27 | * @param propertyKey The name of the method being decorated. 28 | * @param descriptor The property descriptor for the method. 29 | * 30 | */ 31 | export function ClientOnly(_target: object, propertyKey: string, descriptor: PropertyDescriptor) { 32 | if (IsDuplicityVersion()) { 33 | console.warn(`Client-side function '${propertyKey}' attempted to run on server side`); 34 | descriptor.value = () => {}; 35 | } 36 | 37 | Reflect.defineMetadata('clientOnly', true, descriptor); 38 | console.log(`Registered client-side function: '${propertyKey}'`); 39 | } 40 | -------------------------------------------------------------------------------- /packages/shared/src/decorators/core/singleton.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * A decorator that ensures a class follows the Singleton pattern. 3 | * 4 | * The `@Singleton` decorator enforces that a class can have only one instance. When a class is decorated with 5 | * `@Singleton`, any subsequent instantiations will return the same instance rather than creating a new one. 6 | * This is useful for scenarios where you want to ensure a single point of control or a global state. 7 | * 8 | * @typeParam T constructor type of the class being decorated. 9 | * 10 | * @example 11 | * ```ts 12 | * @Singleton 13 | * class Configuration { 14 | * public settings: any; 15 | * 16 | * constructor() { 17 | * this.settings = { theme: 'dark' }; 18 | * } 19 | * } 20 | * 21 | * const instance1 = new Configuration(); 22 | * const instance2 = new Configuration(); 23 | * 24 | * console.log(instance1 === instance2); // true 25 | * ``` 26 | * 27 | * @param constructor The class constructor to decorate. 28 | * 29 | * @returns A new class that extends the original class, ensuring only one instance is created. 30 | */ 31 | export function Singleton(constructor: T) { 32 | return class extends constructor { 33 | public static instance: T; 34 | 35 | constructor(...args: any[]) { 36 | if (constructor.prototype.constructor.instance) { 37 | return constructor.prototype.constructor.instance; 38 | } 39 | 40 | super(...args); 41 | constructor.prototype.constructor.instance = this; 42 | Reflect.defineMetadata('singletonInstance', this, constructor); 43 | } 44 | }; 45 | } 46 | -------------------------------------------------------------------------------- /packages/client/src/@types/BlipData.ts: -------------------------------------------------------------------------------- 1 | import { BlipSprites, Vector3 } from '@fivem-ts/shared'; 2 | import { Blip, BlipColors, BlipDisplay, BlipScale } from '../'; 3 | 4 | /** 5 | * Represents the data structure for a blip, including properties related to its appearance, position, and behavior. 6 | * 7 | * @property {Blip} blip - The blip instance associated with this data. 8 | * @property {number} id - Unique identifier for the blip. 9 | * @property {'AREA' | 'COORDS' | 'RADIUS'} type - The type of blip, determining its spatial representation. 10 | * @property {BlipColors} color - The color of the blip. 11 | * @property {Vector3} coords - The 3D coordinates where the blip is located. 12 | * @property {BlipDisplay} display - Display settings for the blip. 13 | * @property {number} height - The height at which the blip is displayed. 14 | * @property {string} name - The name or label associated with the blip. 15 | * @property {number} radius - The radius of the blip if type is 'RADIUS'. 16 | * @property {BlipScale} scale - The scale of the blip icon. 17 | * @property {boolean} shortRange - Indicates if the blip is only visible at short range. 18 | * @property {BlipSprites} sprite - The icon or sprite used for the blip. 19 | * @property {number} width - The width of the blip. 20 | */ 21 | export type BlipData = { 22 | blip: Blip; 23 | id: number; 24 | type: 'AREA' | 'COORDS' | 'RADIUS'; 25 | color: BlipColors; 26 | coords: Vector3; 27 | display: BlipDisplay; 28 | height: number; 29 | name: string; 30 | radius: number; 31 | scale: BlipScale; 32 | shortRange: boolean; 33 | sprite: BlipSprites; 34 | width: number; 35 | }; 36 | -------------------------------------------------------------------------------- /packages/shared/src/decorators/checks/ServerOnly.ts: -------------------------------------------------------------------------------- 1 | import 'reflect-metadata'; 2 | 3 | /** 4 | * A decorator that ensures a method is only executed on the server side. 5 | * 6 | * The `@ServerOnly` decorator modifies the behavior of the decorated method to prevent its execution 7 | * on the client side. If the method is called on the client side, a warning is logged and the method is replaced 8 | * with an empty function to prevent any unintended behavior. 9 | * 10 | * **Note:** This decorator intended to be used in environments where both server and client code can be executed, 11 | * such as in frameworks that support both server-side and client-side execution 12 | * 13 | * @example 14 | * ```ts 15 | * class Example { 16 | * @ServerOnly 17 | * public serverMethod() { 18 | * console.log('This method should only run on the server side.'); 19 | * } 20 | * } 21 | * 22 | * const example = new Example(); 23 | * example.serverMethod(); // Executes only if running on the server side. 24 | * ``` 25 | * 26 | * @param _target The prototype of the class. 27 | * @param propertyKey The name of the method being decorated. 28 | * @param descriptor The property descriptor for the method. 29 | * 30 | */ 31 | export function ServerOnly(_target: object, propertyKey: string, descriptor: PropertyDescriptor) { 32 | if (!IsDuplicityVersion()) { 33 | console.warn(`Server-side function '${propertyKey}' attempted to run on client side`); 34 | descriptor.value = () => {}; 35 | } 36 | 37 | Reflect.defineMetadata('serverOnly', true, descriptor); 38 | console.log(`Registered server-side function: '${propertyKey}'`); 39 | } 40 | -------------------------------------------------------------------------------- /packages/shared/src/utils/eventTimer.ts: -------------------------------------------------------------------------------- 1 | const eventTimers: Record = {}; 2 | 3 | /** 4 | * Manages the timing of events to prevent them from being triggered too frequently. 5 | * 6 | * @example 7 | * ```typescript 8 | * if (eventTimer("jump", 1000)) { 9 | * console.log("Jump action executed"); 10 | * } else { 11 | * console.log("Jump action is on cooldown"); 12 | * } 13 | * ``` 14 | * 15 | * @privateRemarks 16 | * - The function uses a global record (`eventTimers`) to track the next available time an event can be triggered. 17 | * - If the current time is less than the stored time for the event, the event is considered "on cooldown." 18 | * - Otherwise, the event is allowed, and the next available time is updated based on the provided delay. 19 | * 20 | * @remarks 21 | * - The function uses `GetGameTimer()` to fetch the current time. Ensure this function is available in the execution environment. 22 | * - The `delay` should be a positive number. If it is `0` or negative, the event will not be throttled. 23 | * 24 | * @param {string} eventName The name of the event to be managed. 25 | * @param {number} delay The delay in milliseconds before the event can be triggered again. 26 | * 27 | * @returns {boolean} Returns true if the event can be triggered, otherwise false. 28 | */ 29 | export function eventTimer(eventName: string, delay: number): boolean { 30 | if (delay && delay > 0) { 31 | const currentTime: number = GetGameTimer(); 32 | 33 | if ((eventTimers[eventName] || 0) > currentTime) { 34 | return false; 35 | } 36 | 37 | eventTimers[eventName] = currentTime + delay; 38 | } 39 | 40 | return true; 41 | } 42 | -------------------------------------------------------------------------------- /packages/shared/src/decorators/checks/Conditional.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * A decorator that conditionally executes a method based on a provided condition function. 3 | * 4 | * The `@Conditional` decorator wraps the decorated method and only executes it if the provided condition function 5 | * returns `true` for the given arguments. If the condition is not met, the method is not executed and a warning 6 | * message is logged to the console. 7 | * 8 | * @example 9 | * ```ts 10 | * class Example { 11 | * @Conditional((active) => active === true) 12 | * public performAction(active: boolean) { 13 | * console.log(`Action performed! with active value is ${active}`); 14 | * } 15 | * } 16 | * 17 | * const example = new Example(); 18 | * example.performAction(false); // Condition not met for function: performAction 19 | * example.performAction(true); // Action performed! with active value is true 20 | * ``` 21 | * 22 | * @param conditionFunc A function that takes the method's arguments and returns a boolean indicating whether the method should be executed. 23 | * 24 | */ 25 | export function Conditional(conditionFunc: (...args: unknown[]) => boolean) { 26 | return function (_target: object, propertyKey: string, descriptor: PropertyDescriptor) { 27 | const originalMethod = descriptor.value; 28 | 29 | descriptor.value = function (...args: unknown[]) { 30 | if (conditionFunc(...args)) { 31 | return originalMethod.apply(this, args); 32 | } else { 33 | console.warn(`Condition not met for function: ${propertyKey}`); 34 | } 35 | }; 36 | 37 | console.log(`Registered conditional execution for function: ${propertyKey}`); 38 | }; 39 | } 40 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | We welcome contributions and assistance! If you want to know where to start, check out our [Github Projects sorted by name](https://github.com/Purpose-Dev/fivem-ts/projects?query=is%3Aopen+sort%3Aname-asc). 4 | 5 | If you want to add a new feature, note that we strive to support the FiveM OneSync system, so keep that in mind when submitting feature requests. 6 | 7 | ## Development 8 | 9 | To get setup for development, refer to [DEVELOPMENT.md](./DEVELOPMENT.md) 10 | 11 | ## Issues 12 | 13 | We use GitHub issues to track public bugs and requests. Please ensure your bug description is clear and has sufficient instructions to be able to reproduce the issue. The best way is to provide an example resource in JS that uses any of the fivem-ts features directly. 14 | 15 | ## Pull Requests 16 | 17 | All active development of this project happens on GitHub. We actively welcome your [pull requests](https://help.github.com/articles/creating-a-pull-request). 18 | 19 | We require that all pull requests are made in the development branch. Please beware of that when opening a new PR. 20 | 21 | ## Commit Message Conventions 22 | 23 | We don't have any strict commit message rules, but we encourage you to keep your commit messages short and descriptive. 24 | 25 | ``` 26 | docs: Scaleform + LoadingPrompt 27 | ``` 28 | 29 | ``` 30 | Added bone collections and Camera PointAt functions 31 | ``` 32 | 33 | Both these commit messages are descriptive, short and to the point. 34 | 35 | ## License 36 | 37 | By contributing to fivem-ts, you agree that your contributions will be licensed under the [LICENSE](./LICENSE) file in the project root directory. 38 | -------------------------------------------------------------------------------- /packages/client/src/ui/Effects.ts: -------------------------------------------------------------------------------- 1 | import { ScreenEffect } from '../enums'; 2 | 3 | /** 4 | * The `Effects` module provides functions to manage screen effects, such as starting, stopping, and checking the status of various screen effects. 5 | */ 6 | export namespace Effects { 7 | /** 8 | * Starts a specified screen effect. 9 | * 10 | * @param effectName {ScreenEffect} - The name of the screen effect to start. 11 | * @param duration {number} - The duration of the effect in milliseconds (optional). If not specified, the effect will use a default duration of 0. 12 | * @param looped {boolean} - Whether the effect should loop (optional). Defaults to `false` if not specified. 13 | * 14 | * @returns {void} 15 | */ 16 | export function start(effectName: ScreenEffect, duration?: number, looped?: boolean): void { 17 | StartScreenEffect(effectName, duration ?? 0, looped ?? false); 18 | } 19 | 20 | /** 21 | * Stops a specified screen effect. If no effect is specified, all active screen effects will be stopped. 22 | * 23 | * @param screenEffect {ScreenEffect} - The screen effect to stop (optional). If `null`, all screen effects will be stopped. 24 | * 25 | * @returns {void} 26 | */ 27 | export function stop(screenEffect?: ScreenEffect): void { 28 | screenEffect === undefined ? StopAllScreenEffects() : StopScreenEffect(screenEffect); 29 | } 30 | 31 | /** 32 | * Checks if a specified screen effect is currently active. 33 | * 34 | * @param screenEffect {ScreenEffect} - The screen effect to check. 35 | * 36 | * @returns {boolean} `true` if the specified screen effect is active, otherwise `false`. 37 | */ 38 | export function isActive(screenEffect: ScreenEffect): boolean { 39 | return GetScreenEffectIsActive(screenEffect); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /packages/client/src/enums/vehicles/VehicleClass.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enum representing various vehicle classes. 3 | * 4 | * Values: 5 | * - `Compacts`: Represents compact vehicles. 6 | * - `Sedans`: Represents sedan vehicles. 7 | * - `SUVs`: Represents sport utility vehicles. 8 | * - `Coupes`: Represents coupe vehicles. 9 | * - `Muscle`: Represents muscle cars. 10 | * - `SportsClassics`: Represents classic sports cars. 11 | * - `Sports`: Represents modern sports cars. 12 | * - `Super`: Represents supercars. 13 | * - `Motorcycles`: Represents motorcycles. 14 | * - `OffRoad`: Represents off-road vehicles. 15 | * - `Industrial`: Represents industrial vehicles. 16 | * - `Utility`: Represents utility vehicles. 17 | * - `Vans`: Represents vans. 18 | * - `Cycles`: Represents bicycles or cycles. 19 | * - `Boats`: Represents watercraft or boats. 20 | * - `Helicopters`: Represents helicopters. 21 | * - `Planes`: Represents airplanes or planes. 22 | * - `Service`: Represents service vehicles. 23 | * - `Emergency`: Represents emergency response vehicles. 24 | * - `Military`: Represents military vehicles. 25 | * - `Commercial`: Represents commercial vehicles. 26 | * - `Trains`: Represents trains. 27 | * - `OpenWheel`: Represents open-wheel race cars. 28 | * 29 | * @enum{number} 30 | */ 31 | export enum VehicleClass { 32 | Compacts = 0, 33 | Sedans = 1, 34 | SUVs = 2, 35 | Coupes = 3, 36 | Muscle = 4, 37 | SportsClassics = 5, 38 | Sports = 6, 39 | Super = 7, 40 | Motorcycles = 8, 41 | OffRoad = 9, 42 | Industrial = 10, 43 | Utility = 11, 44 | Vans = 12, 45 | Cycles = 13, 46 | Boats = 14, 47 | Helicopters = 15, 48 | Planes = 16, 49 | Service = 17, 50 | Emergency = 18, 51 | Military = 19, 52 | Commercial = 20, 53 | Trains = 21, 54 | OpenWheel = 22, 55 | } 56 | -------------------------------------------------------------------------------- /packages/client/src/enums/blips/BlipScale.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enum representing different scales for blips. 3 | * 4 | * This enum provides a set of predefined scales for blips, which can be used in various applications 5 | * such as maps or game markers to adjust the size of the blips. The scales range from `Mini` (0.3) to 6 | * `XXL` (2.0), with intermediate values to allow for more precise control over blip sizes. 7 | * 8 | * Available Native Function: 9 | * - [`SetBlipScale`](https://docs.fivem.net/natives/?_0xD38744167B2FA257): Set a specified scale for a blip 10 | * 11 | * Enum Values: 12 | * - `Mini`: Represents the smallest blip scale with a value of `0.3`. 13 | * - `Small`: Represents a small blip scale with a value of `0.6`. 14 | * - `MediumSmall`: Represents a medium-small blip scale with a value of `0.8`. 15 | * - `Medium`: Represents a medium blip scale with a value of `1.0`. 16 | * - `MediumLarge`: Represents a medium-large blip scale with a value of `1.2`. 17 | * - `Large`: Represents a large blip scale with a value of `1.5`. 18 | * - `XL`: Represents an extra-large blip scale with a value of `1.7`. 19 | * - `XXL`: Represents the largest blip scale with a value of `2.0`. 20 | * 21 | * @enum{number} 22 | */ 23 | export enum BlipScale { 24 | /** Represents the smallest blip scale. */ 25 | Mini = 0.3, 26 | /** Represents a small blip scale. */ 27 | Small = 0.6, 28 | /** Represents a medium-small blip scale. */ 29 | MediumSmall = 0.8, 30 | /** Represents a medium blip scale. */ 31 | Medium = 1.0, 32 | /** Represents a medium-large blip scale. */ 33 | MediumLarge = 1.2, 34 | /** Represents a large blip scale. */ 35 | Large = 1.5, 36 | /** Represents an extra-large blip scale. */ 37 | XL = 1.7, 38 | /** Represents the largest blip scale. */ 39 | XXL = 2.0, 40 | } 41 | -------------------------------------------------------------------------------- /packages/client/src/@types/HandlingData.ts: -------------------------------------------------------------------------------- 1 | import { Vector } from './Vector'; 2 | 3 | export type HandlingData = { 4 | handlingName: string; 5 | fMass: number; 6 | fInitialDragCoeff: number; 7 | fPercentSubmerged: number; 8 | vecCentreOfMassOffset: Vector; 9 | vecInertiaMultiplier: Vector; 10 | fDriveBiasFront: number; 11 | nInitialDriveGears: number; 12 | fInitialDriveForce: number; 13 | fDriveInertia: number; 14 | fClutchChangeRateScaleUpShift: number; 15 | fClutchChangeRateScaleDownShift: number; 16 | fInitialDriveMaxFlatVel: number; 17 | fBrakeForce: number; 18 | fBrakeBiasFront: number; 19 | fHandBrakeForce: number; 20 | fSteeringLock: number; 21 | fTractionCurveMax: number; 22 | fTractionCurveMin: number; 23 | fTractionCurveLateral: number; 24 | fTractionSpringDeltaMax: number; 25 | fLowSpeedTractionLossMult: number; 26 | fCamberStiffnesss: number; 27 | fTractionBiasFront: number; 28 | fTractionLossMult: number; 29 | fSuspensionForce: number; 30 | fSuspensionCompDamp: number; 31 | fSuspensionReboundDamp: number; 32 | fSuspensionUpperLimit: number; 33 | fSuspensionLowerLimit: number; 34 | fSuspensionRaise: number; 35 | fSuspensionBiasFront: number; 36 | fAntiRollBarForce: number; 37 | fAntiRollBarBiasFront: number; 38 | fRollCentreHeightFront: number; 39 | fRollCentreHeightRear: number; 40 | fCollisionDamageMult: number; 41 | fWeaponDamageMult: number; 42 | fDeformationDamageMult: number; 43 | fEngineDamageMult: number; 44 | fPetrolTankVolume: number; 45 | fOilVolume: number; 46 | fSeatOffsetDistX: number; 47 | fSeatOffsetDistY: number; 48 | fSeatOffsetDistZ: number; 49 | nMonetaryValue: number; 50 | strModelFlags: number; 51 | strHandlingFlags: number; 52 | strDamageFlags: number; 53 | AIHandling: 'AVERAGE' | 'TRUCK' | 'SPORTS_CAR' | 'CRAP'; 54 | }; 55 | -------------------------------------------------------------------------------- /packages/client/src/models/Player.ts: -------------------------------------------------------------------------------- 1 | import { Nullable } from '@fivem-ts/shared'; 2 | import { Ped } from '.'; 3 | 4 | /** 5 | * Represents a player entity. 6 | */ 7 | export class Player { 8 | protected pvp = false; 9 | protected ped: Nullable = null; 10 | 11 | constructor(private readonly owner: number) { 12 | this.PvpEnabled = true; 13 | } 14 | 15 | /** 16 | * Gets the owner identifier. 17 | * 18 | * @returns {number} The identifier of the owner. 19 | */ 20 | public get Owner(): number { 21 | return this.owner; 22 | } 23 | 24 | /** 25 | * Determines whether PvP mode is enabled. 26 | * 27 | * @returns {boolean} Returns true if PvP is enabled, otherwise false. 28 | */ 29 | public get PvpEnabled(): boolean { 30 | return this.pvp; 31 | } 32 | 33 | /** 34 | * Sets the PvP enabled status. 35 | * 36 | * @param {boolean} value - A boolean indicating whether PvP should be enabled (true) or disabled (false). 37 | */ 38 | public set PvpEnabled(value: boolean) { 39 | this.pvp = value; 40 | NetworkSetFriendlyFireOption(value); 41 | SetCanAttackFriendly(this.Owner, value, value); 42 | } 43 | 44 | /** 45 | * Retrieves the Ped instance associated with the current PlayerPedId. 46 | * If the Ped handle has changed, a new Ped instance is created. 47 | * 48 | * @returns {Nullable} The current Ped instance, or null if none exists. 49 | */ 50 | public get Ped(): Nullable { 51 | const pedId: number = PlayerPedId(); 52 | 53 | if (this.ped === null || this.ped.Handle !== pedId) { 54 | this.ped = new Ped(pedId); 55 | } 56 | 57 | return this.ped; 58 | } 59 | 60 | /** 61 | * Retrieves the name of the player associated with the current owner. 62 | * 63 | * @returns {string} The name of the player. 64 | */ 65 | public get Name(): string { 66 | return GetPlayerName(this.Owner); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /packages/client/src/GameplayCamera.ts: -------------------------------------------------------------------------------- 1 | import { Vector3 } from '@fivem-ts/shared'; 2 | 3 | /** 4 | * The current rendering gameplay camera 5 | */ 6 | export abstract class GameplayCamera { 7 | /** 8 | * Get the world position of gameplay camera. 9 | */ 10 | public static get Position(): Vector3 { 11 | const coords: number[] = GetGameplayCamCoords(); 12 | return new Vector3(coords[0], coords[1], coords[2]); 13 | } 14 | 15 | /** 16 | * Get the rotation of gameplay camera. 17 | */ 18 | public static get Rotation(): Vector3 { 19 | const rot: number[] = GetGameplayCamRot(2); 20 | return new Vector3(rot[0], rot[1], rot[2]); 21 | } 22 | 23 | /** 24 | * Get the forward vector of gameplay camera. 25 | */ 26 | public static get ForwardVector(): Vector3 { 27 | const rotation: Vector3 = this.Rotation.multiply(Math.PI / 180); 28 | const normalized: Vector3 = Vector3.normalize( 29 | new Vector3( 30 | -Math.sin(rotation.z) * Math.abs(Math.cos(rotation.x)), 31 | Math.cos(rotation.z) * Math.abs(Math.cos(rotation.x)), 32 | Math.sin(rotation.x), 33 | ), 34 | ); 35 | 36 | return new Vector3(normalized.x, normalized.y, normalized.z); 37 | } 38 | 39 | /** 40 | * Get the pitch of the gameplay camera relative to player. 41 | */ 42 | public static get RelativePitch(): number { 43 | return GetGameplayCamRelativePitch(); 44 | } 45 | 46 | /** 47 | * Set gameplay camera pitch relative to player. 48 | */ 49 | public static set RelativePitch(pitch: number) { 50 | SetGameplayCamRelativePitch(pitch, 1); 51 | } 52 | 53 | /** 54 | * Get heading of gameplay camera. 55 | */ 56 | public static get RelativeHeading(): number { 57 | return GetGameplayCamRelativeHeading(); 58 | } 59 | 60 | /** 61 | * Get heading of gameplay camera. 62 | */ 63 | public static set RelativeHeading(heading: number) { 64 | SetGameplayCamRelativeHeading(heading); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /packages/shared/src/decorators/core/cooldown.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * A decorator that enforces a cooldown period between successive calls to a method. 3 | * 4 | * The `@Cooldown` decorator ensures that a method can only be executed once every specified 5 | * number of milliseconds. If the method is called again before the cooldown period has elapsed, 6 | * a warning is logged, and the method is not executed. 7 | * 8 | * @example 9 | * ```ts 10 | * class ExampleClass { 11 | * @Cooldown(1000) // 1 second cooldown 12 | * performAction() { 13 | * console.log('Action performed'); 14 | * } 15 | * } 16 | * 17 | * const example = new ExampleClass(); 18 | * 19 | * // The first call will execute the method 20 | * example.performAction(); // Outputs: Action performed 21 | * 22 | * // Subsequent calls within 1 second will be ignored 23 | * example.performAction(); // Outputs: Function performAction is on cooldown. 24 | * 25 | * // After 1 second, the method can be called again 26 | * setTimeout(() => example.performAction(), 1000); // Outputs: Action performed 27 | * ``` 28 | * 29 | * @param {number} milliseconds The cooldown period (in milliseconds) that must elapse between method calls. 30 | * 31 | * @returns A function that can be used as a method decorator. 32 | */ 33 | export function Cooldown(milliseconds: number) { 34 | return function (_target: object, propertyKey: string, descriptor: PropertyDescriptor) { 35 | const originalMethod = descriptor.value; 36 | let lastCallTime = 0; 37 | 38 | descriptor.value = function (...args: unknown[]) { 39 | const now = Date.now(); 40 | if (now - lastCallTime >= milliseconds) { 41 | lastCallTime = now; 42 | return originalMethod.apply(this, args); 43 | } else { 44 | console.warn(`Function ${propertyKey} is on cooldown.`); 45 | } 46 | }; 47 | 48 | console.log(`Registered cooldown for function: ${propertyKey}`); 49 | }; 50 | } 51 | -------------------------------------------------------------------------------- /scripts/utils.ts: -------------------------------------------------------------------------------- 1 | import { Dirent, promises as fs, Stats } from 'fs'; 2 | import * as path from 'path'; 3 | 4 | async function directoryExists(dirPath: string): Promise { 5 | try { 6 | await fs.access(dirPath); 7 | return true; 8 | } catch { 9 | return false; 10 | } 11 | } 12 | 13 | export async function deleteDirectories(basePath: string, globPattern: string): Promise { 14 | const baseDir: string = path.resolve(basePath); 15 | 16 | try { 17 | const directories: Dirent[] = await fs.readdir(baseDir, { withFileTypes: true }); 18 | 19 | for (const dir of directories) { 20 | if (dir.isDirectory()) { 21 | const distDir: string = path.join(baseDir, dir.name, globPattern); 22 | 23 | if (await directoryExists(distDir)) { 24 | console.info(`Deleting: ${distDir}`); 25 | await fs.rm(distDir, { recursive: true, force: true }); 26 | } 27 | } 28 | } 29 | 30 | console.log(`Finished processing all ${globPattern} directories.`); 31 | } catch (err) { 32 | console.error(`An error occurred while processing directories: ${err}`); 33 | } 34 | } 35 | 36 | export async function deleteDirectory(dirPath: string): Promise { 37 | const baseDir: string = path.resolve(dirPath); 38 | 39 | try { 40 | const stat: Stats = await fs.lstat(baseDir); 41 | 42 | if (stat.isDirectory()) { 43 | if (await directoryExists(path.join(baseDir))) { 44 | console.info(`Deleting directory: ${baseDir}`); 45 | await fs.rm(baseDir, { recursive: true, force: true }); 46 | console.log(`Successfully deleted directory: ${baseDir}`); 47 | } 48 | } else { 49 | console.log('Path exists but is not a directory.'); 50 | } 51 | } catch (err: any) { 52 | if (err.code === 'ENOENT') { 53 | console.warn(`Directory does not exist: ${baseDir}`); 54 | } else { 55 | console.error(`An error occurred while deleting directory: ${err.message}`); 56 | throw err; 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /packages/shared/src/decorators/core/measureTime.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * A decorator that measures the execution time of a method. 3 | * 4 | * The `@MeasureTime` decorator wraps a method, logging the time it takes to execute in milliseconds. 5 | * This can be useful for performance profiling and identifying slow methods. 6 | * 7 | * @example 8 | * ```ts 9 | * class ExampleClass { 10 | * @MeasureTime 11 | * processData(data: string): string { 12 | * // Simulate some processing time 13 | * for (let i = 0; i < 1e6; i++) { 14 | * 15 | * } 16 | * return `Processed ${data}`; 17 | * } 18 | * } 19 | * 20 | * const example = new ExampleClass(); 21 | * example.processData('test'); 22 | * // Logs: 23 | * // [processData] Execution time: 123.456ms 24 | * ``` 25 | * 26 | * @param _target The target object that owns the method. 27 | * @param propertyKey The name of the method being decorated. 28 | * @param descriptor The method descriptor, which provides access to the method itself. 29 | * 30 | * @returns A function that can be used as a method decorator. 31 | */ 32 | export function MeasureTime(_target: object, propertyKey: string, descriptor: PropertyDescriptor) { 33 | const originalMethod = descriptor.value; 34 | 35 | descriptor.value = function (...args: unknown[]) { 36 | const start: number = performance.now(); 37 | const result = originalMethod.apply(this, args); 38 | const end: number = performance.now(); 39 | const durationMs: number = end - start; 40 | 41 | const { duration, unit } = 42 | durationMs >= 1000 43 | ? { duration: durationMs / 1000, unit: 's' } 44 | : durationMs >= 1 45 | ? { duration: durationMs, unit: 'ms' } 46 | : { duration: durationMs * 1000, unit: 'μs' }; 47 | 48 | console.debug(`[${propertyKey}] Execution time: ${duration.toFixed(3)} ${unit}`); 49 | return result; 50 | }; 51 | 52 | console.log(`Registered measure time for function: ${propertyKey}`); 53 | } 54 | -------------------------------------------------------------------------------- /packages/client/src/models/VehicleMod.ts: -------------------------------------------------------------------------------- 1 | import { Vehicle, VehicleMods } from '..'; 2 | 3 | /** 4 | * A class representing vehicle mod. 5 | */ 6 | export class VehicleMod { 7 | constructor( 8 | private readonly owner: Vehicle, 9 | private readonly modType: VehicleMods, 10 | ) {} 11 | 12 | public get Owner(): Vehicle { 13 | return this.owner; 14 | } 15 | 16 | public get ModType(): VehicleMods { 17 | return this.modType; 18 | } 19 | 20 | public get IdentifierHash(): number { 21 | return GetVehicleModIdentifierHash(this.owner.Handle, this.modType, this.Index); 22 | } 23 | 24 | public get Index(): number { 25 | return GetVehicleMod(this.owner.Handle, this.modType); 26 | } 27 | 28 | public set Index(index: number) { 29 | SetVehicleMod(this.owner.Handle, this.modType, index, this.Variation); 30 | } 31 | 32 | public get IsHswExclusive(): boolean { 33 | return IsVehicleModHswExclusive(this.owner.Handle, this.modType, this.Index); 34 | } 35 | 36 | public get ModCount(): number { 37 | return GetNumVehicleMods(this.owner.Handle, this.modType); 38 | } 39 | 40 | public get ModifierValue(): number { 41 | return GetVehicleModModifierValue(this.owner.Handle, this.modType, this.Index); 42 | } 43 | 44 | public get Variation(): boolean { 45 | return GetVehicleModVariation(this.owner.Handle, this.modType); 46 | } 47 | 48 | public set Variation(value: boolean) { 49 | SetVehicleMod(this.owner.Handle, this.modType, this.Index, value); 50 | } 51 | 52 | /** 53 | * Preloads a vehicle mod for the given owner's handle, modification type, and index. 54 | * 55 | * @returns {void} 56 | */ 57 | public preload(): void { 58 | PreloadVehicleMod(this.owner.Handle, this.modType, this.Index); 59 | } 60 | 61 | /** 62 | * Removes the vehicle mod from the owner's vehicle based on the specified modification type. 63 | * 64 | * @returns {void} 65 | */ 66 | public remove(): void { 67 | RemoveVehicleMod(this.owner.Handle, this.ModType); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /packages/shared/src/decorators/events/resourceEvent.ts: -------------------------------------------------------------------------------- 1 | import 'reflect-metadata'; 2 | 3 | /** 4 | * A decorator that registers a method to be called when a specific resource event occurs. 5 | * 6 | * The `@ResourceEvent` decorator is used to execute a method in response to resource start or stop events. 7 | * The method decorated with `@ResourceEvent` will be called automatically when the specified event occurs for the current resource. 8 | * 9 | * **Events:** 10 | * - `'start'`: The method will be called when the resource starts. 11 | * - `'stop'`: The method will be called when the resource stops. 12 | * 13 | * @example 14 | * ```ts 15 | * class MyScript { 16 | * @ResourceEvent('start') 17 | * onStart() { 18 | * console.log('Resource started'); 19 | * } 20 | * 21 | * @ResourceEvent('stop') 22 | * onStop() { 23 | * console.log('Resource stopped'); 24 | * } 25 | * } 26 | * ``` 27 | * 28 | * @param resourceEvent {'start' | 'stop'} The type of resource event to listen for. Must be either `'start'` or `'stop'`. 29 | * @returns A method decorator that subscribes the decorated method to the specified resource event. 30 | */ 31 | export function ResourceEvent(resourceEvent: 'start' | 'stop') { 32 | return function (target: object, propertyKey: string, descriptor: PropertyDescriptor) { 33 | Reflect.defineMetadata('resourceEvent', resourceEvent, target, propertyKey); 34 | 35 | if (resourceEvent === 'start') { 36 | on('onResourceStart', (resourceName: string) => { 37 | if (GetCurrentResourceName() === resourceName) { 38 | descriptor.value(); 39 | } 40 | }); 41 | console.log(`Registered on script start: ${propertyKey}`); 42 | } else if (resourceEvent === 'stop') { 43 | on('onResourceStop', (resourceName: string) => { 44 | if (GetCurrentResourceName() === resourceName) { 45 | descriptor.value(); 46 | } 47 | }); 48 | console.log(`Registered on script stop: ${propertyKey}`); 49 | } 50 | }; 51 | } 52 | -------------------------------------------------------------------------------- /packages/client/src/enums/vehicles/VehicleDrivingFlags.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Represents the flags that can be used to configure the driving behavior of a vehicle. 3 | * 4 | * Values: 5 | * - None: No specific driving behaviors selected. 6 | * - FollowTraffic: Directs the vehicle to follow general traffic rules. 7 | * - YieldToPeds: Makes the vehicle yield to pedestrians. 8 | * - AvoidVehicles: Enables vehicle avoidance logic for other vehicles. 9 | * - AvoidEmptyVehicles: Enables vehicle avoidance logic specifically for empty vehicles. 10 | * - AvoidPeds: Makes the vehicle avoid hitting pedestrians. 11 | * - AvoidObjects: Directs the vehicle to avoid static or dynamic objects. 12 | * - StopAtTrafficLights: Instructs the vehicle to stop at traffic lights. 13 | * - UseBlinkers: Controls whether the vehicle will use blinkers during turns. 14 | * - AllowGoingWrongWay: Allows the vehicle to drive against traffic flow or on a wrong-way path. 15 | * - Reverse: Enables the ability for the vehicle to reverse as part of its driving behavior. 16 | * - AllowMedianCrossing: Permits the vehicle to cross over medians where traffic separation exists. 17 | * - DriveBySight: Configures the vehicle to navigate primarily based on visible surroundings. 18 | * - IgnorePathFinding: Disables pathfinding logic for the vehicle. 19 | * - TryToAvoidHighways: Configures the vehicle to attempt to avoid highways during navigation. 20 | * - StopAtDestination: Ensures the vehicle will stop at its defined destination. 21 | * 22 | * @enum{number} 23 | */ 24 | export enum VehicleDrivingFlags { 25 | None = 0, 26 | FollowTraffic = 1, 27 | YieldToPeds = 2, 28 | AvoidVehicles = 4, 29 | AvoidEmptyVehicles = 8, 30 | AvoidPeds = 16, 31 | AvoidObjects = 32, 32 | StopAtTrafficLights = 128, 33 | UseBlinkers = 256, 34 | AllowGoingWrongWay = 512, 35 | Reverse = 1024, 36 | AllowMedianCrossing = 262144, 37 | DriveBySight = 4194304, 38 | IgnorePathFinding = 16777216, 39 | TryToAvoidHighways = 536870912, 40 | StopAtDestination = 2147483648, 41 | } 42 | -------------------------------------------------------------------------------- /packages/client/src/enums/environment/ExplosionType.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * List of explosion sources. 3 | * 4 | * @enum{number} 5 | */ 6 | export enum ExplosionType { 7 | DontCare = -1, 8 | Grenade = 0, 9 | GrenadeLauncher = 1, 10 | StickyBomb = 2, 11 | Molotov = 3, 12 | Rocket = 4, 13 | TankShell = 5, 14 | HiOctane = 6, 15 | Car = 7, 16 | Plane = 8, 17 | PetrolPump = 9, 18 | Bike = 10, 19 | DirSteam = 11, 20 | DirFlame = 12, 21 | DirWaterHydrant = 13, 22 | DirGasCanister = 14, 23 | Boat = 15, 24 | ShipDestroy = 16, 25 | Truck = 17, 26 | Bullet = 18, 27 | SmokeGrenadeLauncher = 19, 28 | SmokeGrenade = 20, 29 | BzGas = 21, 30 | Flare = 22, 31 | GasCanister = 23, 32 | Extinguisher = 24, 33 | _0x988620B8 = 25, 34 | Train = 26, 35 | Barrel = 27, 36 | Propane = 28, 37 | Blimp = 29, 38 | FlameExplode = 30, 39 | Tanker = 31, 40 | PlaneRocket = 32, 41 | VehicleBullet = 33, 42 | GasTank = 34, 43 | BirdCrap = 35, 44 | RailGun = 36, 45 | Blimp2 = 37, 46 | Firework = 38, 47 | Snowball = 39, 48 | Proxmine = 40, 49 | ValkyrieCannon = 41, 50 | AirDefence = 42, 51 | PipeBomb = 43, 52 | VehicleMine = 44, 53 | ExplosiveAmmo = 45, 54 | ApcShell = 46, 55 | BombCluster = 47, 56 | BombGas = 48, 57 | BombIncendiary = 49, 58 | BombStandard = 50, 59 | Torpedo = 51, 60 | TorpedoUnderwater = 52, 61 | BombushkaCannon = 53, 62 | BombClusterSecondary = 54, 63 | HunterBarrage = 55, 64 | HunterCannon = 56, 65 | RogueCannon = 57, 66 | MineUnderwater = 58, 67 | OrbitalCannon = 59, 68 | BombStandardWide = 60, 69 | ExplosiveAmmoShotgun = 61, 70 | Oppressor2Cannon = 62, 71 | MortarKinetic = 63, 72 | VehicleMineKinetic = 64, 73 | VehicleMineEmp = 65, 74 | VehicleMineSpike = 66, 75 | VehicleMineSlick = 67, 76 | VehicleMineTar = 68, 77 | Drone = 69, 78 | RayGun = 70, 79 | BuriedMine = 71, 80 | Missile = 72, 81 | RcTankRocket = 73, 82 | BombWater = 74, 83 | BombWaterSecondary = 75, 84 | _0xF728C4A9 = 76, 85 | _0xBAEC056F = 77, 86 | FlashGrenade = 78, 87 | StunGrenade = 79, 88 | _0x763D3B3B = 80, 89 | MissileLarge = 81, 90 | SubmarineBig = 82, 91 | } 92 | -------------------------------------------------------------------------------- /packages/shared/src/decorators/core/middleware.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * A decorator that adds middleware functions before and after a method execution. 3 | * 4 | * The `@Middleware` decorator allows you to specify functions to run before (`preFn`) and after (`postFn`) the 5 | * execution of a method. This can be useful for adding common logic such as logging, validation, or transformation 6 | * around method calls. 7 | * 8 | * @example 9 | * ```ts 10 | * function logStart(...args: any[]) { 11 | * console.log('Method started with args:', args); 12 | * } 13 | * 14 | * function logEnd(result: unknown) { 15 | * console.log(`Method ended with return value: ${result}`); 16 | * } 17 | * 18 | * class ExampleClass { 19 | * @Middleware(logStart, logEnd) 20 | * processData(data: string): string { 21 | * return `Processed ${data}`; 22 | * } 23 | * } 24 | * 25 | * const example = new ExampleClass(); 26 | * example.processData('test'); 27 | * // Logs: 28 | * // Method started with args: ['test'] 29 | * // Method ended with return value: test 30 | * ``` 31 | * 32 | * @param preFn The function to execute before the method. It receives the same arguments as the method. 33 | * @param postFn The function to execute after the method. It receives the same arguments as the method. 34 | * 35 | * @returns A function that can be used as a method decorator. 36 | * 37 | */ 38 | export function Middleware(preFn: Function, postFn: Function) { 39 | return function (_target: object, propertyKey: string, descriptor: PropertyDescriptor) { 40 | const originalMethod = descriptor.value; 41 | 42 | descriptor.value = function (...args: unknown[]) { 43 | if (preFn) preFn(...args); 44 | const result = originalMethod.apply(this, args); 45 | 46 | if (postFn) { 47 | if (typeof result === 'undefined') { 48 | postFn('Result is undefined because return type is a void'); 49 | } else { 50 | postFn(...args); 51 | } 52 | } 53 | 54 | return result; 55 | }; 56 | 57 | console.log(`Registered middleware for function: ${propertyKey}`); 58 | }; 59 | } 60 | -------------------------------------------------------------------------------- /packages/shared/src/utils/serializeToJSON.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Serializes a value to a JSON string. 3 | * 4 | * This function takes any value, such as objects, arrays, numbers, strings, etc., 5 | * and converts it into a JSON-formatted string. This is useful for storing or transmitting data 6 | * in a format that is widely supported and can be easily parsed by other systems. 7 | * 8 | * @example 9 | * ```typescript 10 | * // Example 1: Serializing an object 11 | * const obj = { name: "John", age: 30 }; 12 | * const jsonString = serializeToJSON(obj); 13 | * console.log(jsonString); 14 | * // Output: '{"name":"John","age":30}' 15 | * 16 | * // Example 2: Serializing an array 17 | * const arr = [1, 2, 3]; 18 | * const jsonArrayString = serializeToJSON(arr); 19 | * console.log(jsonArrayString); 20 | * // Output: '[1,2,3]' 21 | * 22 | * // Example 3: Serializing a primitive value 23 | * const num = 42; 24 | * const jsonNumberString = serializeToJSON(num); 25 | * console.log(jsonNumberString); 26 | * // Output: '42' 27 | * ``` 28 | * @remarks 29 | * - This function leverages `JSON.stringify` to convert the input value into a JSON-formatted string. 30 | * - It is particularly useful for storing or transmitting data in a format that is widely supported across platforms and programming languages. 31 | * - Be cautious when serializing objects with circular references, as `JSON.stringify` will throw an error in such cases. 32 | * - This function does not handle circular references or unsupported data types (e.g., `BigInt`). Consider using libraries such as `flatted` or `json5` for more complex serialization needs. 33 | * 34 | * @param {unknown} data The value to be serialized to JSON. This can be an object, array, string, number, etc. 35 | * 36 | * @returns {string} A JSON string representing the serialized data. 37 | */ 38 | export function serializeToJSON(data: unknown): string { 39 | if (data === undefined || typeof data === 'function') { 40 | return ''; 41 | } 42 | 43 | try { 44 | return JSON.stringify(data) || ''; 45 | } catch { 46 | return ''; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /packages/shared/src/enums/peds/PedsEnum.ts: -------------------------------------------------------------------------------- 1 | // @todo: finish peds enum 2 | 3 | /** 4 | * The `PedsEnum` enumeration represents game peds. 5 | * 6 | * This can be especially useful for strongly typing certain 7 | * parameters or return values rather than using strings or numbers. 8 | * 9 | * Developers can extend this `enum` as needed for additional 10 | * predefined peds. 11 | * 12 | * @enum{string} 13 | */ 14 | export enum PedsEnum { 15 | // Ambient Female 16 | AmbientFemaleMBeach01 = 'a_f_m_beach_01', 17 | AmbientFemaleMBevHills01 = 'a_f_m_bevhills_01', 18 | AmbientFemaleMBevHills02 = 'a_f_m_bevhills_02', 19 | AmbientFemaleMBodyBuild01 = 'a_f_m_bodybuild_01', 20 | AmbientFemaleMBusiness02 = 'a_f_m_business_02', 21 | AmbientFemaleMDownTown01 = 'a_f_m_downtown_01', 22 | AmbientFemaleMEastSA01 = 'a_f_m_eastsa_01', 23 | AmbientFemaleMEastSA02 = 'a_f_m_eastsa_02', 24 | AmbientFemaleMFatBla01 = 'a_f_m_fatbla_01', 25 | AmbientFemaleMFatCult01 = 'a_f_m_fatcult_01', 26 | AmbientFemaleMFatWhite01 = 'a_f_m_fatwhite_01', 27 | AmbientFemaleMKTown01 = 'a_f_m_ktown_01', 28 | AmbientFemaleMKTown02 = 'a_f_m_ktown_02', 29 | AmbientFemaleMProlhost01 = 'a_f_m_prolhost_01', 30 | AmbientFemaleMSalton01 = 'a_f_m_salton_01', 31 | AmbientFemaleMSkidrow01 = 'a_f_m_skidrow_01', 32 | AmbientFemaleMSoucent01 = 'a_f_m_soucent_01', 33 | AmbientFemaleMSoucent02 = 'a_f_m_soucent_02', 34 | AmbientFemaleMSoucentMc01 = 'a_f_m_soucentmc_01', 35 | AmbientFemaleMTourist01 = 'a_f_m_tourist_01', 36 | AmbientFemaleMTramp01 = 'a_f_m_tramp_01', 37 | AmbientFemaleMTrampbeac01 = 'a_f_m_trampbeac_01', 38 | AmbientFemaleOGenstreet01 = 'a_f_o_genstreet_01', 39 | AmbientFemaleOIndian01 = 'a_f_o_indian_01', 40 | AmbientFemaleOKTown01 = 'a_f_o_ktown_01', 41 | AmbientFemaleOKSalton01 = 'a_f_o_salton_01', 42 | AmbientFemaleOSoucent01 = 'a_f_o_soucent_01', 43 | AmbientFemaleOSoucent02 = 'a_f_o_soucent_02', 44 | AmbientFemaleYBeach01 = 'a_f_y_beach_01', 45 | AmbientFemaleYBevhills01 = 'a_f_y_bevhills_01', 46 | AmbientFemaleYBevhills02 = 'a_f_y_bevhills_02', 47 | AmbientFemaleYBevhills03 = 'a_f_y_bevhills_03', 48 | } 49 | -------------------------------------------------------------------------------- /packages/client/src/ui/LoadingPrompt.ts: -------------------------------------------------------------------------------- 1 | import { LoadingSpinnerType } from '../enums'; 2 | 3 | /** 4 | * A utility module to manage a loading prompt that appears at the bottom right of the screen. 5 | * The loading prompt can display a custom message and spinner, and it can be shown or hidden as needed. 6 | * 7 | * @example 8 | * ```ts 9 | * import { LoadingPrompt } from '@fivem-ts/client'; 10 | * 11 | * // Show the loading prompt with a custom message 12 | * LoadingPrompt.show("Hello World"); 13 | * 14 | * // Hide the loading prompt after 10 seconds 15 | * setTimeout(() => { 16 | * LoadingPrompt.hide(); 17 | * }, 10000); 18 | * ``` 19 | */ 20 | export namespace LoadingPrompt { 21 | /** 22 | * Checks whether the loading prompt is currently being displayed. 23 | * 24 | * @returns `true` if the loading prompt is active, `false` otherwise. 25 | */ 26 | export function getIsActive(): boolean { 27 | return IsLoadingPromptBeingDisplayed(); 28 | } 29 | 30 | /** 31 | * Shows the loading prompt with an optional custom text and spinner type. 32 | * If the prompt is already active, it will be hidden and then shown again with the new settings. 33 | * 34 | * @param loadingText - The text to display in the loading prompt. If not provided, no text will be displayed. 35 | * @param spinnerType - The type of spinner to display. If not provided, a default spinner is used. 36 | */ 37 | export function show(loadingText?: string, spinnerType?: LoadingSpinnerType): void { 38 | if (getIsActive()) { 39 | hide(); 40 | } 41 | 42 | if (loadingText === undefined) { 43 | BeginTextCommandBusyString(''); 44 | } else { 45 | BeginTextCommandBusyString('STRING'); 46 | AddTextComponentSubstringPlayerName(loadingText); 47 | } 48 | 49 | EndTextCommandBusyString( 50 | spinnerType ? spinnerType.valueOf() : LoadingSpinnerType.RegularClockwise.valueOf(), 51 | ); 52 | } 53 | 54 | /** 55 | * Hides the loading prompt if it is currently being displayed. 56 | */ 57 | export function hide(): void { 58 | if (getIsActive()) { 59 | RemoveLoadingPrompt(); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fivem-ts", 3 | "version": "0.7.5", 4 | "author": "Purpose-Dev", 5 | "description": "Javascript/Typescript wrapper (Forked from fivem-js) for the FiveM natives", 6 | "license": "MIT", 7 | "packageManager": "pnpm@9.11.0", 8 | "homepage": "https://github.com/Purpose-Dev/fivem-ts", 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/Purpose-Dev/fivem-ts.git" 12 | }, 13 | "bugs": { 14 | "url": "https://github.com/Purpose-Dev/fivem-ts/issues", 15 | "email": "riyane.dev@gmail.com" 16 | }, 17 | "funding": { 18 | "url": "https://ko-fi.com/purpose", 19 | "type": "ko_fi" 20 | }, 21 | "scripts": { 22 | "build:dev": "turbo run build", 23 | "build:prod": "tsx scripts/clearBuild.ts && turbo run build", 24 | "lint": "eslint --config eslint.config.js", 25 | "format": "prettier --write \"**/*.{ts,tsx,md}\"", 26 | "postversion": "git push && git push --tags", 27 | "prepare": "pnpm run build:prod", 28 | "prepublishOnly": "pnpm run lint", 29 | "preversion": "pnpm run lint", 30 | "test": "jest --config jestconfig.json", 31 | "version": "pnpm run format && git add -A src" 32 | }, 33 | "keywords": [ 34 | "fivem", 35 | "typescript", 36 | "javascript", 37 | "wrapper", 38 | "citizenfx", 39 | "natives", 40 | "library", 41 | "fivem-js", 42 | "fivem-ts" 43 | ], 44 | "devDependencies": { 45 | "@types/jest": "^29.5.14", 46 | "@types/node": "^22.13.8", 47 | "@typescript-eslint/eslint-plugin": "8.25.0", 48 | "@typescript-eslint/parser": "8.25.0", 49 | "eslint": "^9.21.0", 50 | "eslint-config-prettier": "^10.0.2", 51 | "jest": "^29.7.0", 52 | "prettier": "^3.5.3", 53 | "ts-jest": "^29.2.6", 54 | "tsx": "^4.19.3", 55 | "turbo": "^2.4.4", 56 | "typescript": "^5.8.2" 57 | }, 58 | "dependencies": { 59 | "reflect-metadata": "^0.2.2" 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /packages/client/src/enums/blips/BlipDisplay.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enum representing various display options for blips. 3 | * 4 | * This enum defines how blips (markers or icons) should be displayed on different types of maps or screens. 5 | * The values specify whether a blip is visible, and on which map or minimap it should appear. The enum 6 | * includes several options for controlling the visibility and interactivity of blips. 7 | * 8 | * Available Native Function: 9 | * - [`SetBlipDisplay`](https://docs.fivem.net/natives/?_0x9029B2F3DA924928): Set a specified display ID for a blip 10 | * 11 | * Enum Values: 12 | * - `DoesntShowUp`: The blip does not show up on any map, value `0`. 13 | * - `DoesntShowUp2`: The blip does not show up on any map (alternative state), value `1`. 14 | * - `OnBoth`: The blip shows up on both the main map and the minimap, value `2`. 15 | * - `OnMainMap`: The blip shows up only on the main map, value `3`. 16 | * - `OnMainMap2`: The blip shows up only on the main map (alternative state), value `4`. 17 | * - `OnMinimapOnly`: The blip shows up only on the minimap, value `5`. 18 | * - `OnBoth2`: The blip shows up on both the main map and the minimap (alternative state), value `6`. 19 | * - `DoesntShowUp3`: The blip does not show up on any map (another alternative state), value `7`. 20 | * - `OnBothNotSelectable`: The blip shows up on both the main map and the minimap but is not selectable, value `8`. 21 | * - `OnMinimapOnly2`: The blip shows up only on the minimap (alternative state), value `9`. 22 | * - `OnBothNotSelectable2`: The blip shows up on both the main map and the minimap but is not selectable (alternative state), value `10`. 23 | * 24 | * Anything higher than 10 seems to be exactly the same as 10. 25 | * Rockstar seem to only use 0, 2, 3, 4, 5 and 8 in the decompiled scripts. 26 | * 27 | * @enum{number} 28 | */ 29 | export enum BlipDisplay { 30 | DoesntShowUp = 0, 31 | DoesntShowUp2 = 1, 32 | OnBoth = 2, 33 | OnMainMap = 3, 34 | OnMainMap2 = 4, 35 | OnMinimapOnly = 5, 36 | OnBoth2 = 6, 37 | DoesntShowUp3 = 7, 38 | OnBothNotSelectable = 8, 39 | OnMinimapOnly2 = 9, 40 | OnBothNotSelectable2 = 10, 41 | } 42 | -------------------------------------------------------------------------------- /packages/shared/src/hashes/weapons/AmmoTypesHash.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enum representing different ammo types with their associated hash values. 3 | * 4 | * Each ammo type is assigned a unique numerical value that serves as its identifier. 5 | * 6 | * @enum{number} 7 | */ 8 | export enum AmmoTypesHash { 9 | Unknown = -1, 10 | AcidPackage = 1003730930, 11 | Ball = -6986138, 12 | BzGas = -1686864220, 13 | EmpLauncher = -237025091, 14 | FertilizerCan = 1963932634, 15 | FireExtinguisher = 1359393852, 16 | Firework = -1356599793, 17 | Flare = 1808594799, 18 | FlareGun = 1173416293, 19 | Grenade = 1003688881, 20 | GrenadeLauncher = 1003267566, 21 | GrenadeLauncherSmoke = 826266432, 22 | HazardCan = 1618528319, 23 | HomingLauncher = -1726673363, 24 | Mg = 1788949567, 25 | MgArmorPiercing = 784861712, 26 | MgFmj = 234717365, 27 | MgIncendiary = 1461941360, 28 | MgTracer = 1226421483, 29 | Minigun = -1614428030, 30 | Molotov = 1446246869, 31 | PetrolCan = -899475295, 32 | PipeBomb = 357983224, 33 | Pistol = 1950175060, 34 | PistolFmj = -1132792829, 35 | PistolHollowPoint = -836519658, 36 | PistolIncendiary = -1416716039, 37 | PistolTracer = -1193480661, 38 | Proxmine = -1356724057, 39 | RailGun = 2034517757, 40 | RailGunXm3 = 1322889087, 41 | RayPistol = -1526023308, 42 | Rifle = 218444191, 43 | RifleArmorPiercing = 423744068, 44 | RifleFmj = 1586900444, 45 | RifleIncendiary = -1829688883, 46 | RifleTracer = -1340502689, 47 | Rpg = 1742569970, 48 | Shotgun = -1878508229, 49 | ShotgunArmorPiercing = 1923327840, 50 | ShotgunExplosive = -309302955, 51 | ShotgunHollowPoint = 2089185906, 52 | ShotgunIncendiary = -609429612, 53 | Smg = 1820140472, 54 | SmgFmj = 758230489, 55 | SmgHollowPoint = 670318226, 56 | SmgIncendiary = -332892697, 57 | SmgTracer = 1569785553, 58 | SmokeGrenade = -435287898, 59 | Sniper = 1285032059, 60 | SniperArmorPiercing = -1497580119, 61 | SniperExplosive = -1378784071, 62 | SniperFmj = -168704490, 63 | SniperIncendiary = 796697766, 64 | SniperRemote = -19235536, 65 | SniperTracer = 1184011213, 66 | Snowball = -2112339603, 67 | SnowLauncher = 843865465, 68 | StickyBomb = 1411692055, 69 | StunGun = -1339118112, 70 | Tranquilizer = 1964004553, 71 | } 72 | -------------------------------------------------------------------------------- /packages/shared/src/hashes/weapons/VehicleAmmoTypesHash.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enum representing various types of vehicle ammunition with corresponding hash values. 3 | * 4 | * @enum{number} 5 | */ 6 | export enum VehicleAmmoTypesHash { 7 | Unknown = -1, 8 | ApcCannon = -767591211, 9 | ApcMissile = 119573070, 10 | ArenaHomingMissile = 1669062227, 11 | AvengerCannon = 1849772700, 12 | BarrageGl = 1364454752, 13 | BirdCrap = 1117307028, 14 | ChernoMissile = -1278325590, 15 | DuneGrenadeLauncher = 1742067183, 16 | EnemyLaser = -1372674932, 17 | HackerMissile = -2009808731, 18 | HunterBarrage = 935462248, 19 | HunterMissile = -119401255, 20 | KhanjaliCannonHeavy = 617011510, 21 | KhanjaliGL = -1630507076, 22 | KosatkaTorpedo = 2109218223, 23 | MobileOpsCannon = 764589401, 24 | Monster3Kinetic = 2074953483, 25 | MortarExplosive = 814030577, 26 | MortarKinetic = 648487681, 27 | Mule4GL = -206645419, 28 | OppressorMissile = 570854289, 29 | Oppressor2Missile = 914231229, 30 | PlaneRocket = 1198741878, 31 | PlayerLaser = -165357558, 32 | Pounder2GL = 1624456817, 33 | Pounder2Missile = 948447183, 34 | RcTankRocket = -1585454291, 35 | RogueMissile = -1421421393, 36 | ScramJetMissile = -1664293218, 37 | SpaceRocket = 527765612, 38 | Stinger = -1857257158, 39 | StrikeForceBarrage = 987449399, 40 | SubCarMissile = 456482729, 41 | SubCarTorpedo = -684945118, 42 | SubMarineMissile = -232790657, 43 | TampaMortar = -405037695, 44 | Tank = -1474608608, 45 | ThrusterMissile = -379666311, 46 | TrailerAA = 881918194, 47 | TrailerMissile = -11173636, 48 | VehicleBomb = -1615671818, 49 | VehicleBombCluster = 1584038003, 50 | VehicleBombGas = 314485403, 51 | VehicleBombIncendiary = -111286589, 52 | VehicleBombWater = 706470892, 53 | VehicleBombWide = -117387562, 54 | VehicleMine = 612448028, 55 | VehicleMineEmp = 1653442244, 56 | VehicleMineEmpRc = -930619152, 57 | VehicleMineKinetic = -1140465749, 58 | VehicleMineKineticRc = -338616823, 59 | VehicleMineSlick = -418520852, 60 | VehicleMineSlickRc = -590129723, 61 | VehicleMineSpike = 1782795920, 62 | VehicleMineSpikeRc = -1317227407, 63 | VehicleMineTar = -1733963618, 64 | VehicleMineTarRc = -1955683003, 65 | VigilanteMissile = 1507289724, 66 | } 67 | -------------------------------------------------------------------------------- /packages/client/src/models/VehicleWheel.ts: -------------------------------------------------------------------------------- 1 | import { Vehicle } from '.'; 2 | 3 | /** 4 | * Represents a wheel of a vehicle and provides methods to interact with its state. 5 | */ 6 | export class VehicleWheel { 7 | constructor( 8 | private readonly _owner: Vehicle, 9 | private _index: number, 10 | ) {} 11 | 12 | public get Owner(): Vehicle { 13 | return this._owner; 14 | } 15 | 16 | public get Index(): number { 17 | return this._index; 18 | } 19 | 20 | public set Index(index: number) { 21 | this._index = index; 22 | } 23 | 24 | public exists(): boolean { 25 | return DoesVehicleTyreExist(this.Owner.Handle, this.Index); 26 | } 27 | 28 | public get Health(): number { 29 | return GetTyreHealth(this.Owner.Handle, this.Index); 30 | } 31 | 32 | public set Health(value: number) { 33 | SetTyreHealth(this.Owner.Handle, this.Index, value); 34 | } 35 | 36 | public get WearMultiplier(): number { 37 | return GetTyreWearMultiplier(this.Owner.Handle, this.Index); 38 | } 39 | 40 | /** 41 | * Determines if the vehicle's tire is burst. 42 | * 43 | * @param {boolean} completely - Flag indicating if the check should consider complete burst. 44 | * 45 | * @returns {boolean} - Returns true if the tire is burst based on the provided condition, otherwise false. 46 | */ 47 | public isBurstable(completely: boolean): boolean { 48 | return IsVehicleTyreBurst(this.Owner.Handle, this.Index, completely); 49 | } 50 | 51 | /** 52 | * Causes the vehicle tyre to burst for the vehicle associated with the owner. 53 | * 54 | * This method utilizes `SetVehicleTyreBurst` to simulate a tyre burst effect. 55 | * The tyre index and bursting properties are specified in the parameters of the method. 56 | * 57 | * @returns {void} No return value. 58 | */ 59 | public burst(): void { 60 | SetVehicleTyreBurst(this.Owner.Handle, this.Index, true, 1000); 61 | } 62 | 63 | /** 64 | * Repairs a specific vehicle tire associated with the vehicle owner. 65 | * This method ensures that the tire at the provided index of the owner's vehicle is fixed. 66 | * 67 | * @returns {void} Does not return any value. 68 | */ 69 | public fix(): void { 70 | SetVehicleTyreFixed(this.Owner.Handle, this.Index); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /packages/client/src/enums/blips/BlipColors.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enumeration of all Blip Colors 3 | * 4 | * Available Native Functions: 5 | * - [`SetBlipColour`](https://docs.fivem.net/natives/?_0x03D7FB09E75D6B7E): Set a specified color to a blip 6 | * - [`GetBlipColour`](https://docs.fivem.net/natives/?_0xDF729E8D20CF7327): Get the color id of a specified blip 7 | * - [`SetMainPlayerBlipColour`](https://docs.fivem.net/natives/?_0x7B21E0BB01E8224A): Set player blip a specified color 8 | * - [`SetBlipRouteColour`](https://docs.fivem.net/natives/?_0x837155CD2F63DA09) Set a color for a blip route 9 | * 10 | * The enum values correspond to the default colors used in the game Blips 11 | * 12 | * @enum{number} 13 | */ 14 | export enum BlipColors { 15 | White, 16 | Red, 17 | Green, 18 | Blue, 19 | White2, 20 | Yellow, 21 | LightRed, 22 | Violet, 23 | Pink, 24 | LightOrange, 25 | LightBrown, 26 | LightGreen, 27 | LightBlue, 28 | LightPurple, 29 | DarkPurple, 30 | Cyan, 31 | LightYellow, 32 | Orange, 33 | LightBlue2, 34 | DarkPink, 35 | DarkYellow, 36 | DarkOrange, 37 | LightGray, 38 | LightPink, 39 | LemonGreen, 40 | ForestGreen, 41 | ElectricBlue, 42 | BrightPurple, 43 | DarkYellow2, 44 | DarkBlue, 45 | DarkCyan, 46 | LightBrown2, 47 | LightBlue3, 48 | LightYellow2, 49 | LightPink2, 50 | LightRed2, 51 | Beige, 52 | White3, 53 | Blue2, 54 | LightGray2, 55 | DarkGray, 56 | PinkReed, 57 | Blue3, 58 | LightGreen2, 59 | LightOrange2, 60 | White4, 61 | Gold, 62 | Orange2, 63 | BrilliantRose, 64 | Red2, 65 | MediumPurple, 66 | Salmon, 67 | DarkGreen, 68 | BlizzardBlue, 69 | OracleBlue, 70 | Silver, 71 | Brown, 72 | Blue4, 73 | EastBay, 74 | Red3, 75 | YellowOrange, 76 | MulberryPink, 77 | AltoGray, 78 | JellyBeanBlue, 79 | DarkOrange2, 80 | Mamba, 81 | YellowOrange2, 82 | Blue5, 83 | Blue6, 84 | Green2, 85 | YellowOrange3, 86 | YellowOrange4, 87 | TransparentBlack, 88 | YellowOrange5, 89 | Blue7, 90 | Red4, 91 | DeepRed, 92 | Blue8, 93 | OracleBlue2, 94 | TransparentRed, 95 | TransparentBlue, 96 | Orange3, 97 | LightGreen3, 98 | Purple, 99 | Blue9, 100 | TransparentBlack2, 101 | } 102 | -------------------------------------------------------------------------------- /packages/shared/src/utils/__tests__/serializeToJSON.test.ts: -------------------------------------------------------------------------------- 1 | import { serializeToJSON } from '../serializeToJSON'; 2 | 3 | describe('serializeToJSON', () => { 4 | it('should serialize an object to a JSON string', () => { 5 | const obj = { name: 'John', age: 30 }; 6 | const result = serializeToJSON(obj); 7 | expect(result).toBe('{"name":"John","age":30}'); 8 | }); 9 | 10 | it('should serialize an array to a JSON string', () => { 11 | const arr = [1, 2, 3]; 12 | const result = serializeToJSON(arr); 13 | expect(result).toBe('[1,2,3]'); 14 | }); 15 | 16 | it('should serialize a primitive value (number) to a JSON string', () => { 17 | const num = 42; 18 | const result = serializeToJSON(num); 19 | expect(result).toBe('42'); 20 | }); 21 | 22 | it('should serialize a primitive value (string) to a JSON string', () => { 23 | const str = 'hello'; 24 | const result = serializeToJSON(str); 25 | expect(result).toBe('"hello"'); 26 | }); 27 | 28 | it('should return an empty string for undefined', () => { 29 | const result = serializeToJSON(undefined); 30 | expect(result).toBe(''); 31 | }); 32 | 33 | it('should return an empty string for a function', () => { 34 | const func = () => {}; 35 | const result = serializeToJSON(func); 36 | expect(result).toBe(''); 37 | }); 38 | 39 | it('should return an empty string for a value that causes JSON.stringify to throw an error', () => { 40 | const circularObj: any = {}; 41 | circularObj.self = circularObj; // Creates a circular reference 42 | const result = serializeToJSON(circularObj); 43 | expect(result).toBe(''); 44 | }); 45 | 46 | it('should serialize null to a JSON string', () => { 47 | const result = serializeToJSON(null); 48 | expect(result).toBe('null'); 49 | }); 50 | 51 | it('should serialize a boolean value to a JSON string', () => { 52 | const bool = true; 53 | const result = serializeToJSON(bool); 54 | expect(result).toBe('true'); 55 | }); 56 | 57 | it('should serialize an empty object to a JSON string', () => { 58 | const result = serializeToJSON({}); 59 | expect(result).toBe('{}'); 60 | }); 61 | 62 | it('should serialize an empty array to a JSON string', () => { 63 | const result = serializeToJSON([]); 64 | expect(result).toBe('[]'); 65 | }); 66 | }); 67 | -------------------------------------------------------------------------------- /packages/server/src/web/makeRequest.ts: -------------------------------------------------------------------------------- 1 | import fetch from 'cross-fetch'; 2 | 3 | /** 4 | * Defines the headers to include in the HTTP request 5 | * 6 | * This interface represents an object where the keys are header names 7 | * and the values are header values 8 | * 9 | * @example 10 | * ```ts 11 | * const headers: RequestHeaders = { 12 | * 'Authorization': 'Bearer token', 13 | * 'Accept': 'application/json' 14 | * } 15 | * ``` 16 | */ 17 | export interface RequestHeaders { 18 | [key: string]: string; 19 | } 20 | 21 | /** 22 | * Represents the data to be included in the HTTP request body 23 | * 24 | * This interface represents an object where the keys are property names 25 | * and the values are property values. The structure of the data is flexible 26 | * and can vary depending on the API endpoint and the data being sent 27 | * 28 | * @example 29 | * ```ts 30 | * const data: RequestData = { 31 | * 'name': 'John Doe', 32 | * 'age': 30 33 | * } 34 | * ``` 35 | */ 36 | export interface RequestData { 37 | [key: string]: unknown; 38 | } 39 | 40 | /** 41 | * Defines the allowed Http methods for make requests. 42 | * 43 | * This type restricts the values to common HTTP methods. It is used 44 | * to specify which HTTP method will be used for the request. 45 | * 46 | * Possible Values: 47 | * - 'GET': Retrieves data from the server 48 | * - 'POST': Submit data to the server 49 | * - 'PUT': Update existing data on the server 50 | * - 'DELETE': Removes data from the server. 51 | * 52 | * @example 53 | * ```ts 54 | * const methods: RequestMethods = 'POST'; 55 | * ``` 56 | */ 57 | export type RequestMethods = 'GET' | 'POST' | 'PUT' | 'DELETE'; 58 | 59 | export async function makeRequest( 60 | url: string, 61 | method: RequestMethods, 62 | data?: RequestData, 63 | headers?: RequestHeaders, 64 | ): Promise { 65 | const options: RequestInit = { 66 | method, 67 | headers: { 68 | 'Content-Type': 'application/json', 69 | ...headers, 70 | }, 71 | }; 72 | 73 | if (data) options.body = JSON.stringify(data); 74 | 75 | const response: Response = await fetch(url, options); 76 | 77 | if (!response.ok) { 78 | throw new Error(`Http error! Status: ${response.status}`); 79 | } 80 | 81 | return await response.json(); 82 | } 83 | -------------------------------------------------------------------------------- /packages/shared/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@fivem-ts/shared", 3 | "version": "1.0.0", 4 | "author": "Purpose-Dev", 5 | "description": "FiveM Typescript wrapper shared part", 6 | "license": "ISC", 7 | "main": "dist/index.js", 8 | "types": "dist/index.d.ts", 9 | "scripts": { 10 | "build": "tsc" 11 | }, 12 | "keywords": [ 13 | "fivem", 14 | "shared", 15 | "typescript", 16 | "javascript", 17 | "wrapper", 18 | "citizenfx", 19 | "natives", 20 | "library", 21 | "fivem-ts", 22 | "fivem-js" 23 | ], 24 | "devDependencies": { 25 | "@citizenfx/client": "2.0.13005-1", 26 | "@citizenfx/server": "2.0.13005-1" 27 | }, 28 | "exports": { 29 | ".": { 30 | "types": "./src/index.d.ts", 31 | "default": "./dist/index.js", 32 | "import": "./dist/index.js", 33 | "require": "./dist/index.js" 34 | }, 35 | "./@types": { 36 | "types": "./dist/@types/index.d.ts", 37 | "default": "./dist/@types/index.js", 38 | "import": "./dist/@types/index.js", 39 | "require": "./dist/@types/index.js" 40 | }, 41 | "./decorators": { 42 | "types": "./dist/decorators/index.d.ts", 43 | "default": "./dist/decorators/index.js", 44 | "import": "./dist/decorators/index.js", 45 | "require": "./dist/decorators/index.js" 46 | }, 47 | "./enums": { 48 | "types": "./dist/enums/index.d.ts", 49 | "default": "./dist/enums/index.js", 50 | "import": "./dist/enums/index.js", 51 | "require": "./dist/enums/index.js" 52 | }, 53 | "./hashes": { 54 | "types": "./dist/hashes/index.d.ts", 55 | "default": "./dist/hashes/index.js", 56 | "import": "./dist/hashes/index.js", 57 | "require": "./dist/hashes/index.js" 58 | }, 59 | "./utils": { 60 | "types": "./dist/utils/index.d.ts", 61 | "default": "./dist/utils/index.js", 62 | "import": "./dist/utils/index.js", 63 | "require": "./dist/utils/index.js" 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /packages/shared/src/enums/vehicle/VehicleSeat.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Enum representing different types of vehicle seats. 3 | * 4 | * @enum{number} 5 | */ 6 | export enum VehicleSeat { 7 | /** Indicates the absence of a seat. */ 8 | None = -3, 9 | /** Can represent any seat in the vehicle. */ 10 | Any = -2, 11 | /** Represents the driver's seat. */ 12 | Driver = -1, 13 | /** Represents a generic passenger seat. */ 14 | Passenger = 0, 15 | /** Represents the left front seat (typically the same as the driver's seat). */ 16 | LeftFront = -1, 17 | /** Represents the right front seat (typically the front passenger seat). */ 18 | RightFront = 0, 19 | /** Represents the left rear seat. */ 20 | LeftRear = 1, 21 | /** Represents the right rear seat. */ 22 | RightRear = 2, 23 | /** Represents additional seat, useful for vehicles with more than the standard number of seats. */ 24 | ExtraSeat1 = 3, 25 | /** Represents additional seat, useful for vehicles with more than the standard number of seats. */ 26 | ExtraSeat2 = 4, 27 | /** Represents additional seat, useful for vehicles with more than the standard number of seats. */ 28 | ExtraSeat3 = 5, 29 | /** Represents additional seat, useful for vehicles with more than the standard number of seats. */ 30 | ExtraSeat4 = 6, 31 | /** Represents additional seat, useful for vehicles with more than the standard number of seats. */ 32 | ExtraSeat5 = 7, 33 | /** Represents additional seat, useful for vehicles with more than the standard number of seats. */ 34 | ExtraSeat6 = 8, 35 | /** Represents additional seat, useful for vehicles with more than the standard number of seats. */ 36 | ExtraSeat7 = 9, 37 | /** Represents additional seat, useful for vehicles with more than the standard number of seats. */ 38 | ExtraSeat8 = 10, 39 | /** Represents additional seat, useful for vehicles with more than the standard number of seats. */ 40 | ExtraSeat9 = 11, 41 | /** Represents additional seat, useful for vehicles with more than the standard number of seats. */ 42 | ExtraSeat10 = 12, 43 | /** Represents additional seat, useful for vehicles with more than the standard number of seats. */ 44 | ExtraSeat11 = 13, 45 | /** Represents additional seat, useful for vehicles with more than the standard number of seats. */ 46 | ExtraSeat12 = 14, 47 | } 48 | -------------------------------------------------------------------------------- /packages/client/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@fivem-ts/client", 3 | "version": "0.9.6", 4 | "author": "Purpose-Dev", 5 | "description": "FiveM Typescript wrapper client Part", 6 | "license": "ISC", 7 | "main": "dist/index.js", 8 | "types": "dist/index.d.ts", 9 | "files": ["dist/**/*"], 10 | "scripts": { 11 | "build": "tsc" 12 | }, 13 | "keywords": [ 14 | "fivem", 15 | "client", 16 | "typescript", 17 | "javascript", 18 | "wrapper", 19 | "citizenfx", 20 | "natives", 21 | "library", 22 | "fivem-ts", 23 | "fivem-js" 24 | ], 25 | "devDependencies": { 26 | "@citizenfx/client": "2.0.13005-1" 27 | }, 28 | "dependencies": { 29 | "@fivem-ts/shared": "latest" 30 | }, 31 | "exports": { 32 | ".": { 33 | "types": "./dist/index.d.ts", 34 | "default": "./dist/index.js", 35 | "import": "./dist/index.js", 36 | "require": "./dist/index.js" 37 | }, 38 | "./@types": { 39 | "types": "./dist/@types/index.d.ts", 40 | "default": "./dist/@types/index.js", 41 | "import": "./dist/@types/index.js", 42 | "require": "./dist/@types/index.js" 43 | }, 44 | "./enums": { 45 | "types": "./dist/enums/index.d.ts", 46 | "default": "./dist/enums/index.js", 47 | "import": "./dist/enums/index.js", 48 | "require": "./dist/enums/index.js" 49 | }, 50 | "./events": { 51 | "types": "./dist/events/index.d.ts", 52 | "default": "./dist/events/index.js", 53 | "import": "./dist/events/index.js", 54 | "require": "./dist/events/index.js" 55 | }, 56 | "./hashes": { 57 | "types": "./dist/hashes/index.d.ts", 58 | "default": "./dist/hashes/index.js", 59 | "import": "./dist/hashes/index.js", 60 | "require": "./dist/hashes/index.js" 61 | }, 62 | "./utils": { 63 | "types": "./dist/utils/index.d.ts", 64 | "default": "./dist/utils/index.js", 65 | "import": "./dist/utils/index.js", 66 | "require": "./dist/utils/index.js" 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /packages/server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@fivem-ts/server", 3 | "version": "0.9.9", 4 | "author": "Purpose-Dev", 5 | "description": "FiveM Typescript wrapper server Part", 6 | "license": "ISC", 7 | "main": "dist/index.js", 8 | "types": "dist/index.d.ts", 9 | "files": ["dist/**/*"], 10 | "scripts": { 11 | "build": "tsc" 12 | }, 13 | "keywords": [ 14 | "fivem", 15 | "server", 16 | "typescript", 17 | "javascript", 18 | "wrapper", 19 | "citizenfx", 20 | "natives", 21 | "library", 22 | "fivem-ts", 23 | "fivem-js" 24 | ], 25 | "dependencies": { 26 | "@fivem-ts/shared": "latest", 27 | "cross-fetch": "^4.1.0" 28 | }, 29 | "devDependencies": { 30 | "@citizenfx/server": "2.0.13005-1" 31 | }, 32 | "exports": { 33 | ".": { 34 | "types": "./dist/index.d.ts", 35 | "default": "./dist/index.js", 36 | "import": "./dist/index.js", 37 | "require": "./dist/index.js" 38 | }, 39 | "./enums": { 40 | "types": "./dist/enums/index.d.ts", 41 | "default": "./dist/enums/index.js", 42 | "import": "./dist/enums/index.js", 43 | "require": "./dist/enums/index.js" 44 | }, 45 | "./events": { 46 | "types": "./dist/events/index.d.ts", 47 | "default": "./dist/events/index.js", 48 | "import": "./dist/events/index.js", 49 | "require": "./dist/events/index.js" 50 | }, 51 | "./models": { 52 | "types": "./dist/models/index.d.ts", 53 | "default": "./dist/models/index.js", 54 | "import": "./dist/models/index.js", 55 | "require": "./dist/models/index.js" 56 | }, 57 | "./utils": { 58 | "types": "./dist/utils/index.d.ts", 59 | "default": "./dist/utils/index.js", 60 | "import": "./dist/utils/index.js", 61 | "require": "./dist/utils/index.js" 62 | }, 63 | "./web": { 64 | "types": "./dist/web/index.d.ts", 65 | "default": "./dist/web/index.js", 66 | "import": "./dist/web/index.js", 67 | "require": "./dist/web/index.js" 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /packages/shared/src/utils/vectors/Vector2.ts: -------------------------------------------------------------------------------- 1 | import { Vector } from '.'; 2 | 3 | export class Vector2 extends Vector { 4 | constructor(x: number, y: number) { 5 | super(x, y); 6 | } 7 | 8 | public get Length(): number { 9 | return Math.sqrt(this.x * this.x + this.y * this.y); 10 | } 11 | 12 | public get normalize(): Vector2 { 13 | const length: number = this.Length; 14 | 15 | if (length === 0) return new Vector2(0, 0); 16 | 17 | const normalizedX: number = this.x / length; 18 | const normalizedY: number = this.y / length; 19 | 20 | return new Vector2(normalizedX, normalizedY); 21 | } 22 | 23 | public override clone(): Vector2 { 24 | return new Vector2(this.x, this.y); 25 | } 26 | 27 | public override distanceSquared(vector: Vector2): number { 28 | const dx: number = this.x - vector.x; 29 | const dy: number = this.y - vector.y; 30 | 31 | return dx * dx + dy * dy; 32 | } 33 | 34 | public override distance(vector: Vector2): number { 35 | return Math.sqrt(this.distanceSquared(vector)); 36 | } 37 | 38 | public override crossProduct(vector: Vector2): number { 39 | return this.x * vector.y - this.y * vector.x; 40 | } 41 | 42 | public override dotProduct(vector: Vector2): number { 43 | return this.x * vector.x + this.y * vector.y; 44 | } 45 | 46 | public override add(vector: Vector2 | number): Vector2 { 47 | if (typeof vector === 'number') { 48 | return new Vector2(this.x + vector, this.y + vector); 49 | } 50 | 51 | return new Vector2(this.x + vector.x, this.y + vector.y); 52 | } 53 | 54 | public override subtract(vector: Vector2 | number): Vector2 { 55 | if (typeof vector === 'number') { 56 | return new Vector2(this.x - vector, this.y - vector); 57 | } 58 | 59 | return new Vector2(this.x - vector.x, this.y - vector.y); 60 | } 61 | 62 | public override multiply(vector: Vector2 | number): Vector2 { 63 | if (typeof vector === 'number') { 64 | return new Vector2(this.x * vector, this.y * vector); 65 | } 66 | 67 | return new Vector2(this.x * vector.x, this.y * vector.y); 68 | } 69 | 70 | public override divide(vector: Vector2 | number): Vector2 { 71 | if (typeof vector === 'number') { 72 | return new Vector2(this.x / vector, this.y / vector); 73 | } 74 | 75 | return new Vector2(this.x / vector.x, this.y / vector.y); 76 | } 77 | 78 | public override replace(vector: Vector2): void { 79 | this.x = vector.x; 80 | this.y = vector.y; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /packages/client/src/ui/Container.ts: -------------------------------------------------------------------------------- 1 | import { IDrawable, Point, Size, Color } from '../'; 2 | 3 | /** 4 | * Represents a drawable container that can hold and manage other drawable items. 5 | * The container has a position, size, and color, and it can draw itself and its child items on the screen. 6 | */ 7 | export class Container implements IDrawable { 8 | public pos: Point; 9 | public size: Size; 10 | public color: Color; 11 | public items: IDrawable[]; 12 | 13 | /** 14 | * Creates an instance of a `Container`. 15 | * 16 | * @param pos {Point} - The position of the container on the screen. 17 | * @param size {Size} - The size of the container. 18 | * @param color {Color} - The color of the container. 19 | */ 20 | constructor(pos: Point, size: Size, color: Color) { 21 | this.pos = pos; 22 | this.size = size; 23 | this.color = color; 24 | this.items = []; 25 | } 26 | 27 | /** 28 | * Adds a single drawable item to the container. 29 | * 30 | * @param item {IDrawable} - The drawable item to add. 31 | * 32 | * @returns {void} 33 | */ 34 | public addItem(item: IDrawable): void { 35 | this.items.push(item); 36 | } 37 | 38 | /** 39 | * Adds multiple drawable items to the container. 40 | * 41 | * @param items {IDrawable[]} - An array of drawable items to add. 42 | * 43 | * @returns {void} 44 | */ 45 | public addItems(items: IDrawable[]): void { 46 | this.items.push(...items); 47 | } 48 | 49 | /** 50 | * Draws the container and its contained items on the screen. 51 | * 52 | * @param offset {Size} - An optional size offset to apply when drawing the container. 53 | * @param resolution {Size} - The resolution of the screen. Defaults to a new `Size(0, 0)` if not provided. 54 | * 55 | * @returns {void} 56 | */ 57 | public draw(offset?: Size, resolution?: Size): void { 58 | offset = offset ?? new Size(0, 0); 59 | resolution = resolution ?? new Size(0, 0); 60 | 61 | const h: number = this.size.height / resolution.height; 62 | const w: number = this.size.width / resolution.width; 63 | const x: number = (this.pos.x + offset.width) / resolution.width + w * 0.5; 64 | const y: number = (this.pos.y + offset.height) / resolution.height + h * 0.5; 65 | 66 | DrawRect(x, y, w, h, this.color.r, this.color.g, this.color.b, this.color.a); 67 | 68 | for (const item of this.items) { 69 | item.draw(new Size(this.pos.x + offset.width, this.pos.y + offset.height), resolution); 70 | } 71 | } 72 | } 73 | --------------------------------------------------------------------------------