@open-core/framework 0.2.1-beta.1 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +373 -373
- package/README.md +217 -217
- package/dist/adapters/node/node-entity-server.js +3 -0
- package/dist/adapters/node/node-exports.d.ts +2 -2
- package/dist/kernel/utils/vector3.d.ts +1 -0
- package/dist/kernel/utils/vector3.js +1 -0
- package/dist/runtime/client/services/appearance.service.js +4 -0
- package/dist/runtime/server/bootstrap.js +1 -1
- package/dist/runtime/server/bootstrap.validation.js +2 -0
- package/dist/runtime/server/bus/core-event-bus.js +5 -2
- package/dist/runtime/server/controllers/principal-export.controller.js +1 -1
- package/dist/runtime/server/decorators/command.d.ts +6 -3
- package/dist/runtime/server/decorators/onNet.d.ts +5 -2
- package/dist/runtime/server/decorators/throttle.js +3 -1
- package/dist/runtime/server/helpers/command-validation.helper.d.ts +1 -1
- package/dist/runtime/server/helpers/function-helper.d.ts +1 -1
- package/dist/runtime/server/services/chat.service.d.ts +33 -0
- package/dist/runtime/server/services/chat.service.js +67 -1
- package/dist/runtime/server/services/core/command.service.d.ts +1 -1
- package/dist/runtime/server/services/parallel/worker-pool.js +4 -0
- package/dist/runtime/server/services/ports/command-execution.port.d.ts +1 -1
- package/dist/runtime/server/services/remote/remote-command.service.d.ts +1 -1
- package/dist/runtime/server/services/services.register.js +2 -2
- package/package.json +100 -98
- package/dist/kernel/di/tokens.d.ts +0 -30
- package/dist/kernel/di/tokens.js +0 -38
- package/dist/runtime/client/interfaces/appearance.interface.d.ts +0 -25
- package/dist/runtime/client/interfaces/appearance.interface.js +0 -2
- package/dist/runtime/server/controllers/command.controller.d.ts +0 -15
- package/dist/runtime/server/controllers/command.controller.js +0 -100
- package/dist/runtime/server/services/access-control.service.d.ts +0 -59
- package/dist/runtime/server/services/access-control.service.js +0 -127
- package/dist/runtime/server/services/core/vehicle-modification.service.d.ts +0 -104
- package/dist/runtime/server/services/core/vehicle-modification.service.js +0 -330
- package/dist/runtime/server/services/core/vehicle.service.d.ts +0 -128
- package/dist/runtime/server/services/core/vehicle.service.js +0 -391
- package/dist/runtime/server/services/remote/remote-principal.provider.d.ts +0 -55
- package/dist/runtime/server/services/remote/remote-principal.provider.js +0 -130
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import { Server } from '../../..'
|
|
2
|
-
import { PrincipalProviderContract } from '../contracts'
|
|
3
|
-
/**
|
|
4
|
-
* **Core Security Service**
|
|
5
|
-
*
|
|
6
|
-
* This service acts as the central enforcement point for the Access Control system.
|
|
7
|
-
* It uses the configured `PrincipalProvider` to query roles and validates them against requirements.
|
|
8
|
-
*
|
|
9
|
-
* It is primarily used internally by the `@Guard` decorator, but can be injected
|
|
10
|
-
* into services to perform manual checks.
|
|
11
|
-
*/
|
|
12
|
-
export declare class AccessControlService {
|
|
13
|
-
private readonly principalProvider
|
|
14
|
-
constructor(principalProvider: PrincipalProviderContract)
|
|
15
|
-
/**
|
|
16
|
-
* Verifies if a player meets a minimum numeric rank requirement.
|
|
17
|
-
*
|
|
18
|
-
* @param player - The target player.
|
|
19
|
-
* @param minRank - The minimum numeric value required (Inclusive).
|
|
20
|
-
*
|
|
21
|
-
* @returns `true` if `Principal.rank >= minRank`.
|
|
22
|
-
*
|
|
23
|
-
* @throws {AppError} code `UNAUTHORIZED` if the player has no Principal (not logged in).
|
|
24
|
-
* @throws {AppError} code `NO_RANK_IN_PRINCIPAL` if the Principal exists but has no `rank` defined.
|
|
25
|
-
*/
|
|
26
|
-
hasRank(player: Server.Player, minRank: number): Promise<boolean>
|
|
27
|
-
/**
|
|
28
|
-
* Verifies if a player possesses a specific permission string.
|
|
29
|
-
*
|
|
30
|
-
* @remarks
|
|
31
|
-
* This method supports the **Wildcard ('*')** permission. If the principal has `'*'`
|
|
32
|
-
* in their permissions array, this method always returns `true`.
|
|
33
|
-
*
|
|
34
|
-
* @param player - The target player.
|
|
35
|
-
* @param permission - The specific permission key (e.g., `'admin.ban'`).
|
|
36
|
-
* @returns `true` if the player has the permission or the wildcard.
|
|
37
|
-
*/
|
|
38
|
-
hasPermission(player: Server.Player, permission: string): Promise<boolean>
|
|
39
|
-
/**
|
|
40
|
-
* **Strict Enforcement**
|
|
41
|
-
*
|
|
42
|
-
* Validates a set of requirements against a player. If any requirement fails,
|
|
43
|
-
* it throws an exception, halting the execution flow.
|
|
44
|
-
*
|
|
45
|
-
* Used primarily by the `@Guard` decorator logic.
|
|
46
|
-
*
|
|
47
|
-
* @param player - The server player to validate.
|
|
48
|
-
* @param requirements - An object containing rank and/or permission constraints.
|
|
49
|
-
*
|
|
50
|
-
* @throws {AppError} code `PERMISSION_DENIED` if validation fails.
|
|
51
|
-
*/
|
|
52
|
-
enforce(
|
|
53
|
-
player: Server.Player,
|
|
54
|
-
requirements: {
|
|
55
|
-
minRank?: number
|
|
56
|
-
permission?: string
|
|
57
|
-
},
|
|
58
|
-
): Promise<void>
|
|
59
|
-
}
|
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
var __decorate =
|
|
3
|
-
(this && this.__decorate) ||
|
|
4
|
-
function (decorators, target, key, desc) {
|
|
5
|
-
var c = arguments.length,
|
|
6
|
-
r =
|
|
7
|
-
c < 3
|
|
8
|
-
? target
|
|
9
|
-
: desc === null
|
|
10
|
-
? (desc = Object.getOwnPropertyDescriptor(target, key))
|
|
11
|
-
: desc,
|
|
12
|
-
d
|
|
13
|
-
if (typeof Reflect === 'object' && typeof Reflect.decorate === 'function')
|
|
14
|
-
r = Reflect.decorate(decorators, target, key, desc)
|
|
15
|
-
else
|
|
16
|
-
for (var i = decorators.length - 1; i >= 0; i--)
|
|
17
|
-
if ((d = decorators[i]))
|
|
18
|
-
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r
|
|
19
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r
|
|
20
|
-
}
|
|
21
|
-
var __metadata =
|
|
22
|
-
(this && this.__metadata) ||
|
|
23
|
-
((k, v) => {
|
|
24
|
-
if (typeof Reflect === 'object' && typeof Reflect.metadata === 'function')
|
|
25
|
-
return Reflect.metadata(k, v)
|
|
26
|
-
})
|
|
27
|
-
Object.defineProperty(exports, '__esModule', { value: true })
|
|
28
|
-
exports.AccessControlService = void 0
|
|
29
|
-
const tsyringe_1 = require('tsyringe')
|
|
30
|
-
const utils_1 = require('../../../kernel/utils')
|
|
31
|
-
const contracts_1 = require('../contracts')
|
|
32
|
-
/**
|
|
33
|
-
* **Core Security Service**
|
|
34
|
-
*
|
|
35
|
-
* This service acts as the central enforcement point for the Access Control system.
|
|
36
|
-
* It uses the configured `PrincipalProvider` to query roles and validates them against requirements.
|
|
37
|
-
*
|
|
38
|
-
* It is primarily used internally by the `@Guard` decorator, but can be injected
|
|
39
|
-
* into services to perform manual checks.
|
|
40
|
-
*/
|
|
41
|
-
let AccessControlService = class AccessControlService {
|
|
42
|
-
constructor(principalProvider) {
|
|
43
|
-
this.principalProvider = principalProvider
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Verifies if a player meets a minimum numeric rank requirement.
|
|
47
|
-
*
|
|
48
|
-
* @param player - The target player.
|
|
49
|
-
* @param minRank - The minimum numeric value required (Inclusive).
|
|
50
|
-
*
|
|
51
|
-
* @returns `true` if `Principal.rank >= minRank`.
|
|
52
|
-
*
|
|
53
|
-
* @throws {AppError} code `UNAUTHORIZED` if the player has no Principal (not logged in).
|
|
54
|
-
* @throws {AppError} code `NO_RANK_IN_PRINCIPAL` if the Principal exists but has no `rank` defined.
|
|
55
|
-
*/
|
|
56
|
-
async hasRank(player, minRank) {
|
|
57
|
-
const principal = await this.principalProvider.getPrincipal(player)
|
|
58
|
-
if (!principal) throw new utils_1.AppError('AUTH:UNAUTHORIZED', 'No principal found', 'core')
|
|
59
|
-
if (principal.rank === undefined)
|
|
60
|
-
throw new utils_1.AppError(
|
|
61
|
-
'GAME:NO_RANK_IN_PRINCIPAL',
|
|
62
|
-
"You're trying to compare a Principal rank, but there's no defined rank! ",
|
|
63
|
-
'core',
|
|
64
|
-
)
|
|
65
|
-
return principal.rank >= minRank
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* Verifies if a player possesses a specific permission string.
|
|
69
|
-
*
|
|
70
|
-
* @remarks
|
|
71
|
-
* This method supports the **Wildcard ('*')** permission. If the principal has `'*'`
|
|
72
|
-
* in their permissions array, this method always returns `true`.
|
|
73
|
-
*
|
|
74
|
-
* @param player - The target player.
|
|
75
|
-
* @param permission - The specific permission key (e.g., `'admin.ban'`).
|
|
76
|
-
* @returns `true` if the player has the permission or the wildcard.
|
|
77
|
-
*/
|
|
78
|
-
async hasPermission(player, permission) {
|
|
79
|
-
const principal = await this.principalProvider.getPrincipal(player)
|
|
80
|
-
if (!principal) return false
|
|
81
|
-
if (principal.permissions.includes('*')) return true
|
|
82
|
-
return principal.permissions.includes(permission)
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* **Strict Enforcement**
|
|
86
|
-
*
|
|
87
|
-
* Validates a set of requirements against a player. If any requirement fails,
|
|
88
|
-
* it throws an exception, halting the execution flow.
|
|
89
|
-
*
|
|
90
|
-
* Used primarily by the `@Guard` decorator logic.
|
|
91
|
-
*
|
|
92
|
-
* @param player - The server player to validate.
|
|
93
|
-
* @param requirements - An object containing rank and/or permission constraints.
|
|
94
|
-
*
|
|
95
|
-
* @throws {AppError} code `PERMISSION_DENIED` if validation fails.
|
|
96
|
-
*/
|
|
97
|
-
async enforce(player, requirements) {
|
|
98
|
-
if (requirements.minRank !== undefined) {
|
|
99
|
-
const hasRank = await this.hasRank(player, requirements.minRank)
|
|
100
|
-
if (!hasRank) {
|
|
101
|
-
throw new utils_1.AppError(
|
|
102
|
-
'AUTH:PERMISSION_DENIED',
|
|
103
|
-
`Access Denied: Requires minimum rank level ${requirements.minRank}`,
|
|
104
|
-
'core',
|
|
105
|
-
)
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
if (requirements.permission) {
|
|
109
|
-
const hasPerm = await this.hasPermission(player, requirements.permission)
|
|
110
|
-
if (!hasPerm) {
|
|
111
|
-
throw new utils_1.AppError(
|
|
112
|
-
'AUTH:PERMISSION_DENIED',
|
|
113
|
-
`Access Denied: Missing required permission '${requirements.permission}'`,
|
|
114
|
-
'core',
|
|
115
|
-
)
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
exports.AccessControlService = AccessControlService
|
|
121
|
-
exports.AccessControlService = AccessControlService = __decorate(
|
|
122
|
-
[
|
|
123
|
-
(0, tsyringe_1.injectable)(),
|
|
124
|
-
__metadata('design:paramtypes', [contracts_1.PrincipalProviderContract]),
|
|
125
|
-
],
|
|
126
|
-
AccessControlService,
|
|
127
|
-
)
|
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
import { VehicleService } from './vehicle.service'
|
|
2
|
-
import type { VehicleModificationOptions, VehicleMods } from '../../types/vehicle.types'
|
|
3
|
-
/**
|
|
4
|
-
* Service for handling vehicle modifications with validation.
|
|
5
|
-
*
|
|
6
|
-
* This service is separated from VehicleService to maintain single responsibility.
|
|
7
|
-
* All modifications are validated server-side before being applied.
|
|
8
|
-
*
|
|
9
|
-
* Security features:
|
|
10
|
-
* - Ownership validation
|
|
11
|
-
* - Proximity checks
|
|
12
|
-
* - Modification limits
|
|
13
|
-
* - Audit logging
|
|
14
|
-
*/
|
|
15
|
-
export declare class VehicleModificationService {
|
|
16
|
-
private readonly vehicleService
|
|
17
|
-
constructor(vehicleService: VehicleService)
|
|
18
|
-
/**
|
|
19
|
-
* Applies modifications to a vehicle with validation.
|
|
20
|
-
*
|
|
21
|
-
* @param options - Modification options
|
|
22
|
-
* @returns Success status
|
|
23
|
-
*/
|
|
24
|
-
applyModifications(options: VehicleModificationOptions): boolean
|
|
25
|
-
/**
|
|
26
|
-
* Sets vehicle colors with validation.
|
|
27
|
-
*
|
|
28
|
-
* @param networkId - Network ID of the vehicle
|
|
29
|
-
* @param primaryColor - Primary color ID
|
|
30
|
-
* @param secondaryColor - Secondary color ID
|
|
31
|
-
* @param requestedBy - Client ID requesting the change
|
|
32
|
-
* @returns Success status
|
|
33
|
-
*/
|
|
34
|
-
setColors(
|
|
35
|
-
networkId: number,
|
|
36
|
-
primaryColor: number,
|
|
37
|
-
secondaryColor: number,
|
|
38
|
-
requestedBy?: number,
|
|
39
|
-
): boolean
|
|
40
|
-
/**
|
|
41
|
-
* Sets vehicle livery with validation.
|
|
42
|
-
*
|
|
43
|
-
* @param networkId - Network ID of the vehicle
|
|
44
|
-
* @param livery - Livery index
|
|
45
|
-
* @param requestedBy - Client ID requesting the change
|
|
46
|
-
* @returns Success status
|
|
47
|
-
*/
|
|
48
|
-
setLivery(networkId: number, livery: number, requestedBy?: number): boolean
|
|
49
|
-
/**
|
|
50
|
-
* Toggles vehicle turbo with validation.
|
|
51
|
-
*
|
|
52
|
-
* @param networkId - Network ID of the vehicle
|
|
53
|
-
* @param enabled - Whether turbo should be enabled
|
|
54
|
-
* @param requestedBy - Client ID requesting the change
|
|
55
|
-
* @returns Success status
|
|
56
|
-
*/
|
|
57
|
-
setTurbo(networkId: number, enabled: boolean, requestedBy?: number): boolean
|
|
58
|
-
/**
|
|
59
|
-
* Sets vehicle window tint with validation.
|
|
60
|
-
*
|
|
61
|
-
* @param networkId - Network ID of the vehicle
|
|
62
|
-
* @param tint - Tint level (0-6)
|
|
63
|
-
* @param requestedBy - Client ID requesting the change
|
|
64
|
-
* @returns Success status
|
|
65
|
-
*/
|
|
66
|
-
setWindowTint(networkId: number, tint: number, requestedBy?: number): boolean
|
|
67
|
-
/**
|
|
68
|
-
* Sets vehicle neon lights with validation.
|
|
69
|
-
*
|
|
70
|
-
* @param networkId - Network ID of the vehicle
|
|
71
|
-
* @param enabled - Array of [left, right, front, back] enabled states
|
|
72
|
-
* @param color - RGB color array
|
|
73
|
-
* @param requestedBy - Client ID requesting the change
|
|
74
|
-
* @returns Success status
|
|
75
|
-
*/
|
|
76
|
-
setNeon(
|
|
77
|
-
networkId: number,
|
|
78
|
-
enabled: [boolean, boolean, boolean, boolean],
|
|
79
|
-
color?: [number, number, number],
|
|
80
|
-
requestedBy?: number,
|
|
81
|
-
): boolean
|
|
82
|
-
/**
|
|
83
|
-
* Resets all modifications on a vehicle.
|
|
84
|
-
*
|
|
85
|
-
* @param networkId - Network ID of the vehicle
|
|
86
|
-
* @param requestedBy - Client ID requesting the reset
|
|
87
|
-
* @returns Success status
|
|
88
|
-
*/
|
|
89
|
-
resetModifications(networkId: number, requestedBy?: number): boolean
|
|
90
|
-
/**
|
|
91
|
-
* Gets the current modifications of a vehicle.
|
|
92
|
-
*
|
|
93
|
-
* @param networkId - Network ID of the vehicle
|
|
94
|
-
* @returns Vehicle mods or undefined
|
|
95
|
-
*/
|
|
96
|
-
getModifications(networkId: number): VehicleMods | undefined
|
|
97
|
-
/**
|
|
98
|
-
* Validates modification values to prevent exploits.
|
|
99
|
-
*
|
|
100
|
-
* @param mods - Modifications to validate
|
|
101
|
-
* @returns Validated modifications
|
|
102
|
-
*/
|
|
103
|
-
private validateMods
|
|
104
|
-
}
|
|
@@ -1,330 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
var __decorate =
|
|
3
|
-
(this && this.__decorate) ||
|
|
4
|
-
function (decorators, target, key, desc) {
|
|
5
|
-
var c = arguments.length,
|
|
6
|
-
r =
|
|
7
|
-
c < 3
|
|
8
|
-
? target
|
|
9
|
-
: desc === null
|
|
10
|
-
? (desc = Object.getOwnPropertyDescriptor(target, key))
|
|
11
|
-
: desc,
|
|
12
|
-
d
|
|
13
|
-
if (typeof Reflect === 'object' && typeof Reflect.decorate === 'function')
|
|
14
|
-
r = Reflect.decorate(decorators, target, key, desc)
|
|
15
|
-
else
|
|
16
|
-
for (var i = decorators.length - 1; i >= 0; i--)
|
|
17
|
-
if ((d = decorators[i]))
|
|
18
|
-
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r
|
|
19
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r
|
|
20
|
-
}
|
|
21
|
-
var __metadata =
|
|
22
|
-
(this && this.__metadata) ||
|
|
23
|
-
((k, v) => {
|
|
24
|
-
if (typeof Reflect === 'object' && typeof Reflect.metadata === 'function')
|
|
25
|
-
return Reflect.metadata(k, v)
|
|
26
|
-
})
|
|
27
|
-
var __param =
|
|
28
|
-
(this && this.__param) ||
|
|
29
|
-
((paramIndex, decorator) => (target, key) => {
|
|
30
|
-
decorator(target, key, paramIndex)
|
|
31
|
-
})
|
|
32
|
-
Object.defineProperty(exports, '__esModule', { value: true })
|
|
33
|
-
exports.VehicleModificationService = void 0
|
|
34
|
-
const tsyringe_1 = require('tsyringe')
|
|
35
|
-
const vehicle_service_1 = require('./vehicle.service')
|
|
36
|
-
const logger_1 = require('../../../../kernel/shared/logger')
|
|
37
|
-
/**
|
|
38
|
-
* Service for handling vehicle modifications with validation.
|
|
39
|
-
*
|
|
40
|
-
* This service is separated from VehicleService to maintain single responsibility.
|
|
41
|
-
* All modifications are validated server-side before being applied.
|
|
42
|
-
*
|
|
43
|
-
* Security features:
|
|
44
|
-
* - Ownership validation
|
|
45
|
-
* - Proximity checks
|
|
46
|
-
* - Modification limits
|
|
47
|
-
* - Audit logging
|
|
48
|
-
*/
|
|
49
|
-
let VehicleModificationService = class VehicleModificationService {
|
|
50
|
-
constructor(vehicleService) {
|
|
51
|
-
this.vehicleService = vehicleService
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* Applies modifications to a vehicle with validation.
|
|
55
|
-
*
|
|
56
|
-
* @param options - Modification options
|
|
57
|
-
* @returns Success status
|
|
58
|
-
*/
|
|
59
|
-
applyModifications(options) {
|
|
60
|
-
const { networkId, mods, requestedBy } = options
|
|
61
|
-
const vehicle = this.vehicleService.getByNetworkId(networkId)
|
|
62
|
-
if (!vehicle) {
|
|
63
|
-
logger_1.coreLogger.warn('Vehicle not found for modification', { networkId })
|
|
64
|
-
return false
|
|
65
|
-
}
|
|
66
|
-
if (!vehicle.exists) {
|
|
67
|
-
logger_1.coreLogger.warn('Vehicle no longer exists', { networkId })
|
|
68
|
-
return false
|
|
69
|
-
}
|
|
70
|
-
if (requestedBy !== undefined) {
|
|
71
|
-
if (!this.vehicleService.validateOwnership(networkId, requestedBy)) {
|
|
72
|
-
logger_1.coreLogger.warn('Unauthorized modification attempt', {
|
|
73
|
-
networkId,
|
|
74
|
-
requestedBy,
|
|
75
|
-
owner: vehicle.ownership.clientID,
|
|
76
|
-
})
|
|
77
|
-
return false
|
|
78
|
-
}
|
|
79
|
-
if (!this.vehicleService.validateProximity(networkId, requestedBy, 15.0)) {
|
|
80
|
-
logger_1.coreLogger.warn('Player too far from vehicle for modification', {
|
|
81
|
-
networkId,
|
|
82
|
-
requestedBy,
|
|
83
|
-
})
|
|
84
|
-
return false
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
const validatedMods = this.validateMods(mods)
|
|
88
|
-
vehicle.applyMods(validatedMods)
|
|
89
|
-
logger_1.coreLogger.debug('Vehicle modifications applied', {
|
|
90
|
-
networkId,
|
|
91
|
-
requestedBy,
|
|
92
|
-
mods: Object.keys(validatedMods),
|
|
93
|
-
})
|
|
94
|
-
emitNet('opencore:vehicle:modified', -1, {
|
|
95
|
-
networkId,
|
|
96
|
-
mods: validatedMods,
|
|
97
|
-
})
|
|
98
|
-
return true
|
|
99
|
-
}
|
|
100
|
-
/**
|
|
101
|
-
* Sets vehicle colors with validation.
|
|
102
|
-
*
|
|
103
|
-
* @param networkId - Network ID of the vehicle
|
|
104
|
-
* @param primaryColor - Primary color ID
|
|
105
|
-
* @param secondaryColor - Secondary color ID
|
|
106
|
-
* @param requestedBy - Client ID requesting the change
|
|
107
|
-
* @returns Success status
|
|
108
|
-
*/
|
|
109
|
-
setColors(networkId, primaryColor, secondaryColor, requestedBy) {
|
|
110
|
-
return this.applyModifications({
|
|
111
|
-
networkId,
|
|
112
|
-
mods: { primaryColor, secondaryColor },
|
|
113
|
-
requestedBy,
|
|
114
|
-
})
|
|
115
|
-
}
|
|
116
|
-
/**
|
|
117
|
-
* Sets vehicle livery with validation.
|
|
118
|
-
*
|
|
119
|
-
* @param networkId - Network ID of the vehicle
|
|
120
|
-
* @param livery - Livery index
|
|
121
|
-
* @param requestedBy - Client ID requesting the change
|
|
122
|
-
* @returns Success status
|
|
123
|
-
*/
|
|
124
|
-
setLivery(networkId, livery, requestedBy) {
|
|
125
|
-
return this.applyModifications({
|
|
126
|
-
networkId,
|
|
127
|
-
mods: { livery },
|
|
128
|
-
requestedBy,
|
|
129
|
-
})
|
|
130
|
-
}
|
|
131
|
-
/**
|
|
132
|
-
* Toggles vehicle turbo with validation.
|
|
133
|
-
*
|
|
134
|
-
* @param networkId - Network ID of the vehicle
|
|
135
|
-
* @param enabled - Whether turbo should be enabled
|
|
136
|
-
* @param requestedBy - Client ID requesting the change
|
|
137
|
-
* @returns Success status
|
|
138
|
-
*/
|
|
139
|
-
setTurbo(networkId, enabled, requestedBy) {
|
|
140
|
-
return this.applyModifications({
|
|
141
|
-
networkId,
|
|
142
|
-
mods: { turbo: enabled },
|
|
143
|
-
requestedBy,
|
|
144
|
-
})
|
|
145
|
-
}
|
|
146
|
-
/**
|
|
147
|
-
* Sets vehicle window tint with validation.
|
|
148
|
-
*
|
|
149
|
-
* @param networkId - Network ID of the vehicle
|
|
150
|
-
* @param tint - Tint level (0-6)
|
|
151
|
-
* @param requestedBy - Client ID requesting the change
|
|
152
|
-
* @returns Success status
|
|
153
|
-
*/
|
|
154
|
-
setWindowTint(networkId, tint, requestedBy) {
|
|
155
|
-
const validTint = Math.max(0, Math.min(6, tint))
|
|
156
|
-
return this.applyModifications({
|
|
157
|
-
networkId,
|
|
158
|
-
mods: { windowTint: validTint },
|
|
159
|
-
requestedBy,
|
|
160
|
-
})
|
|
161
|
-
}
|
|
162
|
-
/**
|
|
163
|
-
* Sets vehicle neon lights with validation.
|
|
164
|
-
*
|
|
165
|
-
* @param networkId - Network ID of the vehicle
|
|
166
|
-
* @param enabled - Array of [left, right, front, back] enabled states
|
|
167
|
-
* @param color - RGB color array
|
|
168
|
-
* @param requestedBy - Client ID requesting the change
|
|
169
|
-
* @returns Success status
|
|
170
|
-
*/
|
|
171
|
-
setNeon(networkId, enabled, color, requestedBy) {
|
|
172
|
-
const mods = { neonEnabled: enabled }
|
|
173
|
-
if (color) {
|
|
174
|
-
mods.neonColor = color
|
|
175
|
-
}
|
|
176
|
-
return this.applyModifications({
|
|
177
|
-
networkId,
|
|
178
|
-
mods,
|
|
179
|
-
requestedBy,
|
|
180
|
-
})
|
|
181
|
-
}
|
|
182
|
-
/**
|
|
183
|
-
* Resets all modifications on a vehicle.
|
|
184
|
-
*
|
|
185
|
-
* @param networkId - Network ID of the vehicle
|
|
186
|
-
* @param requestedBy - Client ID requesting the reset
|
|
187
|
-
* @returns Success status
|
|
188
|
-
*/
|
|
189
|
-
resetModifications(networkId, requestedBy) {
|
|
190
|
-
const vehicle = this.vehicleService.getByNetworkId(networkId)
|
|
191
|
-
if (!vehicle) return false
|
|
192
|
-
if (requestedBy !== undefined) {
|
|
193
|
-
if (!this.vehicleService.validateOwnership(networkId, requestedBy)) {
|
|
194
|
-
return false
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
const defaultMods = {
|
|
198
|
-
spoiler: -1,
|
|
199
|
-
frontBumper: -1,
|
|
200
|
-
rearBumper: -1,
|
|
201
|
-
sideSkirt: -1,
|
|
202
|
-
exhaust: -1,
|
|
203
|
-
frame: -1,
|
|
204
|
-
grille: -1,
|
|
205
|
-
hood: -1,
|
|
206
|
-
fender: -1,
|
|
207
|
-
rightFender: -1,
|
|
208
|
-
roof: -1,
|
|
209
|
-
engine: -1,
|
|
210
|
-
brakes: -1,
|
|
211
|
-
transmission: -1,
|
|
212
|
-
horns: -1,
|
|
213
|
-
suspension: -1,
|
|
214
|
-
armor: -1,
|
|
215
|
-
turbo: false,
|
|
216
|
-
xenon: false,
|
|
217
|
-
windowTint: 0,
|
|
218
|
-
}
|
|
219
|
-
vehicle.applyMods(defaultMods)
|
|
220
|
-
logger_1.coreLogger.info('Vehicle modifications reset', { networkId, requestedBy })
|
|
221
|
-
emitNet('opencore:vehicle:modified', -1, {
|
|
222
|
-
networkId,
|
|
223
|
-
mods: defaultMods,
|
|
224
|
-
})
|
|
225
|
-
return true
|
|
226
|
-
}
|
|
227
|
-
/**
|
|
228
|
-
* Gets the current modifications of a vehicle.
|
|
229
|
-
*
|
|
230
|
-
* @param networkId - Network ID of the vehicle
|
|
231
|
-
* @returns Vehicle mods or undefined
|
|
232
|
-
*/
|
|
233
|
-
getModifications(networkId) {
|
|
234
|
-
const vehicle = this.vehicleService.getByNetworkId(networkId)
|
|
235
|
-
return vehicle === null || vehicle === void 0 ? void 0 : vehicle.mods
|
|
236
|
-
}
|
|
237
|
-
/**
|
|
238
|
-
* Validates modification values to prevent exploits.
|
|
239
|
-
*
|
|
240
|
-
* @param mods - Modifications to validate
|
|
241
|
-
* @returns Validated modifications
|
|
242
|
-
*/
|
|
243
|
-
validateMods(mods) {
|
|
244
|
-
const validated = {}
|
|
245
|
-
const modSlots = [
|
|
246
|
-
'spoiler',
|
|
247
|
-
'frontBumper',
|
|
248
|
-
'rearBumper',
|
|
249
|
-
'sideSkirt',
|
|
250
|
-
'exhaust',
|
|
251
|
-
'frame',
|
|
252
|
-
'grille',
|
|
253
|
-
'hood',
|
|
254
|
-
'fender',
|
|
255
|
-
'rightFender',
|
|
256
|
-
'roof',
|
|
257
|
-
'engine',
|
|
258
|
-
'brakes',
|
|
259
|
-
'transmission',
|
|
260
|
-
'horns',
|
|
261
|
-
'suspension',
|
|
262
|
-
'armor',
|
|
263
|
-
'wheels',
|
|
264
|
-
]
|
|
265
|
-
for (const slot of modSlots) {
|
|
266
|
-
if (mods[slot] !== undefined) {
|
|
267
|
-
const value = mods[slot]
|
|
268
|
-
validated[slot] = Math.max(-1, Math.min(50, value))
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
if (mods.turbo !== undefined) validated.turbo = Boolean(mods.turbo)
|
|
272
|
-
if (mods.xenon !== undefined) validated.xenon = Boolean(mods.xenon)
|
|
273
|
-
if (mods.wheelType !== undefined) {
|
|
274
|
-
validated.wheelType = Math.max(0, Math.min(12, mods.wheelType))
|
|
275
|
-
}
|
|
276
|
-
if (mods.windowTint !== undefined) {
|
|
277
|
-
validated.windowTint = Math.max(0, Math.min(6, mods.windowTint))
|
|
278
|
-
}
|
|
279
|
-
if (mods.livery !== undefined) {
|
|
280
|
-
validated.livery = Math.max(-1, Math.min(50, mods.livery))
|
|
281
|
-
}
|
|
282
|
-
if (mods.plateStyle !== undefined) {
|
|
283
|
-
validated.plateStyle = Math.max(0, Math.min(5, mods.plateStyle))
|
|
284
|
-
}
|
|
285
|
-
if (mods.primaryColor !== undefined) {
|
|
286
|
-
validated.primaryColor = Math.max(0, Math.min(160, mods.primaryColor))
|
|
287
|
-
}
|
|
288
|
-
if (mods.secondaryColor !== undefined) {
|
|
289
|
-
validated.secondaryColor = Math.max(0, Math.min(160, mods.secondaryColor))
|
|
290
|
-
}
|
|
291
|
-
if (mods.pearlescentColor !== undefined) {
|
|
292
|
-
validated.pearlescentColor = Math.max(0, Math.min(160, mods.pearlescentColor))
|
|
293
|
-
}
|
|
294
|
-
if (mods.wheelColor !== undefined) {
|
|
295
|
-
validated.wheelColor = Math.max(0, Math.min(160, mods.wheelColor))
|
|
296
|
-
}
|
|
297
|
-
if (mods.xenonColor !== undefined) {
|
|
298
|
-
validated.xenonColor = Math.max(0, Math.min(12, mods.xenonColor))
|
|
299
|
-
}
|
|
300
|
-
if (mods.neonEnabled !== undefined) {
|
|
301
|
-
validated.neonEnabled = mods.neonEnabled
|
|
302
|
-
}
|
|
303
|
-
if (mods.neonColor !== undefined) {
|
|
304
|
-
validated.neonColor = [
|
|
305
|
-
Math.max(0, Math.min(255, mods.neonColor[0])),
|
|
306
|
-
Math.max(0, Math.min(255, mods.neonColor[1])),
|
|
307
|
-
Math.max(0, Math.min(255, mods.neonColor[2])),
|
|
308
|
-
]
|
|
309
|
-
}
|
|
310
|
-
if (mods.extras !== undefined) {
|
|
311
|
-
validated.extras = {}
|
|
312
|
-
for (const [key, value] of Object.entries(mods.extras)) {
|
|
313
|
-
const extraId = Number(key)
|
|
314
|
-
if (extraId >= 0 && extraId <= 20) {
|
|
315
|
-
validated.extras[extraId] = Boolean(value)
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
return validated
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
exports.VehicleModificationService = VehicleModificationService
|
|
323
|
-
exports.VehicleModificationService = VehicleModificationService = __decorate(
|
|
324
|
-
[
|
|
325
|
-
(0, tsyringe_1.injectable)(),
|
|
326
|
-
__param(0, (0, tsyringe_1.inject)(vehicle_service_1.VehicleService)),
|
|
327
|
-
__metadata('design:paramtypes', [vehicle_service_1.VehicleService]),
|
|
328
|
-
],
|
|
329
|
-
VehicleModificationService,
|
|
330
|
-
)
|