@open-core/framework 1.0.5-beta.2 → 1.0.5
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/dist/adapters/contracts/IEngineEvents.d.ts +3 -3
- package/dist/adapters/contracts/IExports.d.ts +2 -2
- package/dist/adapters/contracts/client/IClientLocalPlayerBridge.d.ts +21 -0
- package/dist/adapters/contracts/client/IClientLocalPlayerBridge.js +6 -0
- package/dist/adapters/contracts/client/IClientRuntimeBridge.d.ts +5 -5
- package/dist/adapters/contracts/client/camera/IClientCameraPort.d.ts +107 -0
- package/dist/adapters/contracts/client/camera/IClientCameraPort.js +8 -0
- package/dist/adapters/contracts/client/camera/index.d.ts +1 -0
- package/dist/adapters/contracts/client/camera/index.js +1 -0
- package/dist/adapters/contracts/client/index.d.ts +4 -0
- package/dist/adapters/contracts/client/index.js +4 -0
- package/dist/adapters/contracts/client/ped/IClientPedPort.d.ts +62 -0
- package/dist/adapters/contracts/client/ped/IClientPedPort.js +5 -0
- package/dist/adapters/contracts/client/ped/index.d.ts +1 -0
- package/dist/adapters/contracts/client/ped/index.js +1 -0
- package/dist/adapters/contracts/client/progress/IClientProgressPort.d.ts +53 -0
- package/dist/adapters/contracts/client/progress/IClientProgressPort.js +8 -0
- package/dist/adapters/contracts/client/progress/index.d.ts +1 -0
- package/dist/adapters/contracts/client/progress/index.js +1 -0
- package/dist/adapters/contracts/client/spawn/IClientSpawnBridge.d.ts +5 -6
- package/dist/adapters/contracts/client/spawn/IClientSpawnBridge.js +5 -1
- package/dist/adapters/contracts/client/spawn/IClientSpawnPort.d.ts +19 -0
- package/dist/adapters/contracts/client/spawn/IClientSpawnPort.js +2 -0
- package/dist/adapters/contracts/client/spawn/index.d.ts +2 -0
- package/dist/adapters/contracts/client/spawn/index.js +2 -0
- package/dist/adapters/contracts/client/spawn/types.d.ts +3 -0
- package/dist/adapters/contracts/client/ui/webview/IClientWebViewBridge.d.ts +1 -0
- package/dist/adapters/contracts/client/ui/webview/types.d.ts +2 -0
- package/dist/adapters/contracts/client/vehicle/IClientVehiclePort.d.ts +166 -0
- package/dist/adapters/contracts/client/vehicle/IClientVehiclePort.js +8 -0
- package/dist/adapters/contracts/client/vehicle/index.d.ts +1 -0
- package/dist/adapters/contracts/client/vehicle/index.js +1 -0
- package/dist/adapters/contracts/transport/events.api.d.ts +3 -3
- package/dist/adapters/contracts/transport/rpc.api.d.ts +3 -3
- package/dist/adapters/node/transport/node.events.d.ts +4 -4
- package/dist/adapters/node/transport/node.rpc.d.ts +3 -3
- package/dist/adapters/node/transport/node.rpc.js +1 -1
- package/dist/contracts.d.ts +1 -0
- package/dist/contracts.js +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/kernel/logger/client-log-console.js +8 -8
- package/dist/kernel/logger/index.d.ts +1 -1
- package/dist/kernel/logger/index.js +1 -1
- package/dist/kernel/logger/logger.types.d.ts +1 -0
- package/dist/kernel/logger/logger.types.js +35 -0
- package/dist/kernel/logger/transports/buffered.transport.js +4 -4
- package/dist/kernel/logger/transports/console.transport.js +2 -2
- package/dist/kernel/logger/transports/simple-console.transport.js +2 -2
- package/dist/runtime/client/adapter/index.d.ts +5 -0
- package/dist/runtime/client/adapter/index.js +5 -0
- package/dist/runtime/client/adapter/node-camera-port.d.ts +19 -0
- package/dist/runtime/client/adapter/node-camera-port.js +31 -0
- package/dist/runtime/client/adapter/node-client-adapter.js +15 -1
- package/dist/runtime/client/adapter/node-local-player-bridge.d.ts +3 -0
- package/dist/runtime/client/adapter/node-local-player-bridge.js +9 -0
- package/dist/runtime/client/adapter/node-log-console.js +8 -8
- package/dist/runtime/client/adapter/node-ped-port.d.ts +20 -0
- package/dist/runtime/client/adapter/node-ped-port.js +38 -0
- package/dist/runtime/client/adapter/node-progress-port.d.ts +8 -0
- package/dist/runtime/client/adapter/node-progress-port.js +27 -0
- package/dist/runtime/client/adapter/node-runtime-bridge.d.ts +2 -4
- package/dist/runtime/client/adapter/node-spawn-bridge.d.ts +5 -5
- package/dist/runtime/client/adapter/node-spawn-bridge.js +8 -4
- package/dist/runtime/client/adapter/node-vehicle-port.d.ts +31 -0
- package/dist/runtime/client/adapter/node-vehicle-port.js +73 -0
- package/dist/runtime/client/adapter/node-webview-bridge.d.ts +1 -0
- package/dist/runtime/client/adapter/node-webview-bridge.js +2 -0
- package/dist/runtime/client/controllers/appearance.controller.d.ts +3 -3
- package/dist/runtime/client/controllers/appearance.controller.js +11 -10
- package/dist/runtime/client/controllers/spawner.controller.js +4 -3
- package/dist/runtime/client/services/camera.d.ts +4 -26
- package/dist/runtime/client/services/camera.js +21 -27
- package/dist/runtime/client/services/notification.service.d.ts +3 -3
- package/dist/runtime/client/services/notification.service.js +7 -7
- package/dist/runtime/client/services/ped.service.d.ts +6 -21
- package/dist/runtime/client/services/ped.service.js +31 -78
- package/dist/runtime/client/services/progress.service.d.ts +4 -50
- package/dist/runtime/client/services/progress.service.js +11 -143
- package/dist/runtime/client/services/session-bridge.service.js +3 -2
- package/dist/runtime/client/services/spawn.service.d.ts +3 -5
- package/dist/runtime/client/services/spawn.service.js +12 -17
- package/dist/runtime/client/services/vehicle-client.service.d.ts +3 -3
- package/dist/runtime/client/services/vehicle-client.service.js +43 -143
- package/dist/runtime/client/services/vehicle.service.d.ts +4 -41
- package/dist/runtime/client/services/vehicle.service.js +24 -130
- package/dist/runtime/client/webview-bridge.d.ts +3 -0
- package/dist/runtime/client/webview-bridge.js +6 -0
- package/dist/runtime/client/webview.service.d.ts +1 -0
- package/dist/runtime/client/webview.service.js +5 -0
- package/dist/runtime/server/adapter/node-player-appearance-lifecycle-server.js +3 -2
- package/dist/runtime/server/adapter/node-player-lifecycle-server.js +4 -3
- package/dist/runtime/server/adapter/node-vehicle-lifecycle-server.js +2 -1
- package/dist/runtime/server/apis/chat.api.js +6 -5
- package/dist/runtime/server/apis/npcs.api.js +2 -1
- package/dist/runtime/server/apis/parallel-compute.api.js +1 -0
- package/dist/runtime/server/apis/vehicle-modification.api.js +6 -4
- package/dist/runtime/server/apis/vehicles.api.js +7 -4
- package/dist/runtime/server/bootstrap.js +13 -12
- package/dist/runtime/server/controllers/command-export.controller.js +4 -2
- package/dist/runtime/server/controllers/remote-command-execution.controller.js +2 -1
- package/dist/runtime/server/controllers/vehicle.controller.js +6 -5
- package/dist/runtime/server/decorators/command.d.ts +2 -0
- package/dist/runtime/server/decorators/command.js +3 -1
- package/dist/runtime/server/entities/npc.d.ts +1 -1
- package/dist/runtime/server/entities/player.d.ts +1 -1
- package/dist/runtime/server/entities/player.js +10 -3
- package/dist/runtime/server/helpers/command-validation.helper.js +20 -7
- package/dist/runtime/server/helpers/function-helper.d.ts +1 -0
- package/dist/runtime/server/helpers/function-helper.js +15 -8
- package/dist/runtime/server/implementations/local/channel.local.d.ts +1 -1
- package/dist/runtime/server/implementations/local/channel.local.js +3 -2
- package/dist/runtime/server/ports/channel.api-port.d.ts +1 -1
- package/dist/runtime/server/services/parallel/worker-pool.d.ts +1 -1
- package/dist/runtime/server/services/parallel/worker-pool.js +38 -6
- package/dist/runtime/server/services/parallel/worker.js +1 -0
- package/dist/runtime/server/system/schema-generator.d.ts +1 -1
- package/dist/runtime/server/system/schema-generator.js +6 -3
- package/dist/runtime/shared/helpers/process-tuple-schema.js +3 -0
- package/dist/runtime/shared/types/system-types.d.ts +55 -0
- package/dist/runtime/shared/types/system-types.js +54 -0
- package/package.json +21 -11
|
@@ -17,6 +17,7 @@ const FALLBACK_CAPABILITIES = {
|
|
|
17
17
|
supportsBidirectionalMessaging: true,
|
|
18
18
|
supportsExecute: false,
|
|
19
19
|
supportsHeadless: false,
|
|
20
|
+
supportsChatMode: false,
|
|
20
21
|
};
|
|
21
22
|
function createFallbackBridge() {
|
|
22
23
|
const runtime = di.resolve(IClientRuntimeBridge);
|
|
@@ -34,6 +35,7 @@ function createFallbackBridge() {
|
|
|
34
35
|
runtime.setWebViewInputPassthrough(options?.inputPassthrough ?? false);
|
|
35
36
|
},
|
|
36
37
|
blur: () => runtime.setWebViewFocus(false, false),
|
|
38
|
+
markAsChat: () => { },
|
|
37
39
|
send: (viewId, event, payload) => {
|
|
38
40
|
runtime.sendWebViewMessage(JSON.stringify({ __opencoreWebView: true, viewId, action: event, data: payload }));
|
|
39
41
|
},
|
|
@@ -85,6 +87,9 @@ let WebViewService = class WebViewService {
|
|
|
85
87
|
blur(viewId) {
|
|
86
88
|
this.bridge.blur(viewId);
|
|
87
89
|
}
|
|
90
|
+
markAsChat(viewId) {
|
|
91
|
+
this.bridge.markAsChat(viewId);
|
|
92
|
+
}
|
|
88
93
|
send(viewId, event, payload) {
|
|
89
94
|
this.bridge.send(viewId, event, payload);
|
|
90
95
|
}
|
|
@@ -16,6 +16,7 @@ import { IPedAppearanceServer } from '../../../adapters/contracts/server/IPedApp
|
|
|
16
16
|
import { IPlayerAppearanceLifecycleServer } from '../../../adapters/contracts/server/player-appearance/IPlayerAppearanceLifecycleServer';
|
|
17
17
|
import { IPlayerServer } from '../../../adapters/contracts/server/IPlayerServer';
|
|
18
18
|
import { Players } from '../ports/players.api-port';
|
|
19
|
+
import { SYSTEM_EVENTS } from '../../shared/types/system-types';
|
|
19
20
|
let NodePlayerAppearanceLifecycleServer = class NodePlayerAppearanceLifecycleServer extends IPlayerAppearanceLifecycleServer {
|
|
20
21
|
pedAdapter;
|
|
21
22
|
playerServer;
|
|
@@ -38,7 +39,7 @@ let NodePlayerAppearanceLifecycleServer = class NodePlayerAppearanceLifecycleSer
|
|
|
38
39
|
if (!target) {
|
|
39
40
|
return { success: false, errors: ['Player not found'] };
|
|
40
41
|
}
|
|
41
|
-
this.events.emit(
|
|
42
|
+
this.events.emit(SYSTEM_EVENTS.appearance.apply, target, appearance);
|
|
42
43
|
return { success: true, appearance };
|
|
43
44
|
}
|
|
44
45
|
applyClothing(playerSrc, appearance) {
|
|
@@ -56,7 +57,7 @@ let NodePlayerAppearanceLifecycleServer = class NodePlayerAppearanceLifecycleSer
|
|
|
56
57
|
const target = this.resolveTarget(playerSrc);
|
|
57
58
|
if (!target)
|
|
58
59
|
return false;
|
|
59
|
-
this.events.emit(
|
|
60
|
+
this.events.emit(SYSTEM_EVENTS.appearance.reset, target);
|
|
60
61
|
return true;
|
|
61
62
|
}
|
|
62
63
|
resolveTarget(playerSrc) {
|
|
@@ -13,6 +13,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
|
13
13
|
import { inject, injectable } from 'tsyringe';
|
|
14
14
|
import { EventsAPI } from '../../../adapters/contracts/transport/events.api';
|
|
15
15
|
import { IPlayerLifecycleServer } from '../../../adapters/contracts/server/player-lifecycle/IPlayerLifecycleServer';
|
|
16
|
+
import { SYSTEM_EVENTS } from '../../shared/types/system-types';
|
|
16
17
|
let NodePlayerLifecycleServer = class NodePlayerLifecycleServer extends IPlayerLifecycleServer {
|
|
17
18
|
events;
|
|
18
19
|
constructor(events) {
|
|
@@ -23,7 +24,7 @@ let NodePlayerLifecycleServer = class NodePlayerLifecycleServer extends IPlayerL
|
|
|
23
24
|
const target = this.resolveTarget(playerSrc);
|
|
24
25
|
if (!target)
|
|
25
26
|
return;
|
|
26
|
-
this.events.emit(
|
|
27
|
+
this.events.emit(SYSTEM_EVENTS.spawner.spawn, target, {
|
|
27
28
|
position: request.position,
|
|
28
29
|
model: request.model,
|
|
29
30
|
heading: request.heading,
|
|
@@ -34,13 +35,13 @@ let NodePlayerLifecycleServer = class NodePlayerLifecycleServer extends IPlayerL
|
|
|
34
35
|
const target = this.resolveTarget(playerSrc);
|
|
35
36
|
if (!target)
|
|
36
37
|
return;
|
|
37
|
-
this.events.emit(
|
|
38
|
+
this.events.emit(SYSTEM_EVENTS.spawner.teleport, target, request.position, request.heading);
|
|
38
39
|
}
|
|
39
40
|
respawn(playerSrc, request) {
|
|
40
41
|
const target = this.resolveTarget(playerSrc);
|
|
41
42
|
if (!target)
|
|
42
43
|
return;
|
|
43
|
-
this.events.emit(
|
|
44
|
+
this.events.emit(SYSTEM_EVENTS.spawner.respawn, target, request.position, request.heading);
|
|
44
45
|
}
|
|
45
46
|
resolveTarget(playerSrc) {
|
|
46
47
|
const clientId = Number(playerSrc);
|
|
@@ -15,6 +15,7 @@ import { IVehicleLifecycleServer } from '../../../adapters/contracts/server/vehi
|
|
|
15
15
|
import { IPlatformContext } from '../../../adapters/contracts/IPlatformContext';
|
|
16
16
|
import { IVehicleServer } from '../../../adapters/contracts/server/IVehicleServer';
|
|
17
17
|
import { EventsAPI } from '../../../adapters/contracts/transport/events.api';
|
|
18
|
+
import { SYSTEM_EVENTS } from '../../shared/types/system-types';
|
|
18
19
|
let NodeVehicleLifecycleServer = class NodeVehicleLifecycleServer extends IVehicleLifecycleServer {
|
|
19
20
|
vehicleServer;
|
|
20
21
|
platformContext;
|
|
@@ -42,7 +43,7 @@ let NodeVehicleLifecycleServer = class NodeVehicleLifecycleServer extends IVehic
|
|
|
42
43
|
const clientId = Number(request.playerSrc);
|
|
43
44
|
if (Number.isNaN(clientId))
|
|
44
45
|
return;
|
|
45
|
-
this.events.emit(
|
|
46
|
+
this.events.emit(SYSTEM_EVENTS.vehicle.warpInto, clientId, request.networkId, request.seatIndex);
|
|
46
47
|
}
|
|
47
48
|
};
|
|
48
49
|
NodeVehicleLifecycleServer = __decorate([
|
|
@@ -12,6 +12,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
|
12
12
|
};
|
|
13
13
|
import { inject, injectable } from 'tsyringe';
|
|
14
14
|
import { EventsAPI } from '../../../adapters/contracts/transport/events.api';
|
|
15
|
+
import { SYSTEM_EVENTS } from '../../shared/types/system-types';
|
|
15
16
|
import { Players } from '../ports/players.api-port';
|
|
16
17
|
/**
|
|
17
18
|
* Service for sending chat messages to players.
|
|
@@ -35,7 +36,7 @@ let Chat = class Chat {
|
|
|
35
36
|
* @param color - Message color (RGB). Defaults to white.
|
|
36
37
|
*/
|
|
37
38
|
broadcast(message, author = 'SYSTEM', color = { r: 255, g: 255, b: 255 }) {
|
|
38
|
-
this.events.emit(
|
|
39
|
+
this.events.emit(SYSTEM_EVENTS.chat.message, 'all', {
|
|
39
40
|
args: [author, message],
|
|
40
41
|
color: color,
|
|
41
42
|
});
|
|
@@ -49,7 +50,7 @@ let Chat = class Chat {
|
|
|
49
50
|
* @param color - Message color (RGB).
|
|
50
51
|
*/
|
|
51
52
|
sendPrivate(player, message, author = 'Private', color = { r: 200, g: 200, b: 200 }) {
|
|
52
|
-
this.events.emit(
|
|
53
|
+
this.events.emit(SYSTEM_EVENTS.chat.addMessage, player.clientID, {
|
|
53
54
|
args: [author, message],
|
|
54
55
|
color: color,
|
|
55
56
|
});
|
|
@@ -60,7 +61,7 @@ let Chat = class Chat {
|
|
|
60
61
|
* @param player - Target player.
|
|
61
62
|
*/
|
|
62
63
|
clearChat(player) {
|
|
63
|
-
this.events.emit(
|
|
64
|
+
this.events.emit(SYSTEM_EVENTS.chat.clear, player.clientID);
|
|
64
65
|
}
|
|
65
66
|
/**
|
|
66
67
|
* Send a chat message to multiple players.
|
|
@@ -72,7 +73,7 @@ let Chat = class Chat {
|
|
|
72
73
|
*/
|
|
73
74
|
sendMany(players, message, author = 'SYSTEM', color = { r: 255, g: 255, b: 255 }) {
|
|
74
75
|
const targetIds = players.map((p) => (typeof p === 'number' ? p : p.clientID));
|
|
75
|
-
this.events.emit(
|
|
76
|
+
this.events.emit(SYSTEM_EVENTS.chat.addMessage, targetIds, {
|
|
76
77
|
args: [author, message],
|
|
77
78
|
color: color,
|
|
78
79
|
});
|
|
@@ -116,7 +117,7 @@ let Chat = class Chat {
|
|
|
116
117
|
* Clear chat for all connected players.
|
|
117
118
|
*/
|
|
118
119
|
clearChatAll() {
|
|
119
|
-
this.events.emit(
|
|
120
|
+
this.events.emit(SYSTEM_EVENTS.chat.clear, 'all');
|
|
120
121
|
}
|
|
121
122
|
};
|
|
122
123
|
Chat = __decorate([
|
|
@@ -19,6 +19,7 @@ import { INpcLifecycleServer } from '../../../adapters/contracts/server/npc-life
|
|
|
19
19
|
import { IPedServer } from '../../../adapters/contracts/server/IPedServer';
|
|
20
20
|
import { coreLogger } from '../../../kernel/logger';
|
|
21
21
|
import { WorldContext } from '../../core/world';
|
|
22
|
+
import { SYSTEM_EVENTS } from '../../shared/types/system-types';
|
|
22
23
|
import { NPC } from '../entities/npc';
|
|
23
24
|
/**
|
|
24
25
|
* Server-side API responsible for the full NPC (ped) lifecycle:
|
|
@@ -311,7 +312,7 @@ let Npcs = class Npcs {
|
|
|
311
312
|
netId: npc.netId,
|
|
312
313
|
remainingNpcs: this.npcById.size,
|
|
313
314
|
});
|
|
314
|
-
this.events.emit(
|
|
315
|
+
this.events.emit(SYSTEM_EVENTS.npc.deleted, 'all', npc.npcId);
|
|
315
316
|
return true;
|
|
316
317
|
}
|
|
317
318
|
/**
|
|
@@ -4,6 +4,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
4
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
+
import { performance } from 'node:perf_hooks';
|
|
7
8
|
import { injectable } from 'tsyringe';
|
|
8
9
|
import { v4 as uuid } from 'uuid';
|
|
9
10
|
import { WorkerPool } from '../services/parallel/worker-pool';
|
|
@@ -10,9 +10,11 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|
|
10
10
|
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
11
11
|
return function (target, key) { decorator(target, key, paramIndex); }
|
|
12
12
|
};
|
|
13
|
-
import { inject
|
|
13
|
+
import { inject } from 'tsyringe';
|
|
14
14
|
import { EventsAPI } from '../../../adapters/contracts/transport/events.api';
|
|
15
15
|
import { coreLogger } from '../../../kernel/logger';
|
|
16
|
+
import { SYSTEM_EVENTS } from '../../shared/types/system-types';
|
|
17
|
+
import { Bind } from '../decorators/bind';
|
|
16
18
|
import { Vehicles } from './vehicles.api';
|
|
17
19
|
/**
|
|
18
20
|
* Service for handling vehicle modifications with validation.
|
|
@@ -73,7 +75,7 @@ let VehicleModification = class VehicleModification {
|
|
|
73
75
|
requestedBy,
|
|
74
76
|
mods: Object.keys(validatedMods),
|
|
75
77
|
});
|
|
76
|
-
this.events.emit(
|
|
78
|
+
this.events.emit(SYSTEM_EVENTS.vehicle.modified, 'all', {
|
|
77
79
|
networkId,
|
|
78
80
|
mods: validatedMods,
|
|
79
81
|
});
|
|
@@ -200,7 +202,7 @@ let VehicleModification = class VehicleModification {
|
|
|
200
202
|
windowTint: 0,
|
|
201
203
|
};
|
|
202
204
|
coreLogger.info('Vehicle modifications reset', { networkId, requestedBy });
|
|
203
|
-
this.events.emit(
|
|
205
|
+
this.events.emit(SYSTEM_EVENTS.vehicle.modified, 'all', {
|
|
204
206
|
networkId,
|
|
205
207
|
mods: defaultMods,
|
|
206
208
|
});
|
|
@@ -304,7 +306,7 @@ let VehicleModification = class VehicleModification {
|
|
|
304
306
|
}
|
|
305
307
|
};
|
|
306
308
|
VehicleModification = __decorate([
|
|
307
|
-
|
|
309
|
+
Bind('singleton'),
|
|
308
310
|
__param(0, inject(Vehicles)),
|
|
309
311
|
__param(1, inject(EventsAPI)),
|
|
310
312
|
__metadata("design:paramtypes", [Vehicles,
|
|
@@ -10,15 +10,17 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|
|
10
10
|
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
11
11
|
return function (target, key) { decorator(target, key, paramIndex); }
|
|
12
12
|
};
|
|
13
|
-
import { inject
|
|
13
|
+
import { inject } from 'tsyringe';
|
|
14
14
|
import { IHasher } from '../../../adapters/contracts/IHasher';
|
|
15
15
|
import { EventsAPI } from '../../../adapters/contracts/transport/events.api';
|
|
16
16
|
import { IEntityServer } from '../../../adapters/contracts/server/IEntityServer';
|
|
17
17
|
import { IVehicleLifecycleServer } from '../../../adapters/contracts/server/vehicle-lifecycle/IVehicleLifecycleServer';
|
|
18
18
|
import { IVehicleServer } from '../../../adapters/contracts/server/IVehicleServer';
|
|
19
19
|
import { coreLogger } from '../../../kernel/logger';
|
|
20
|
+
import { SYSTEM_EVENTS } from '../../shared/types/system-types';
|
|
20
21
|
import { Vehicle } from '../entities/vehicle';
|
|
21
22
|
import { Players } from '../ports/players.api-port';
|
|
23
|
+
import { Bind } from '../decorators/bind';
|
|
22
24
|
const DEFAULT_PLAYER_VEHICLE_OFFSET = { x: 0, y: 3, z: 0 };
|
|
23
25
|
/**
|
|
24
26
|
* Server-side service for managing vehicle entities.
|
|
@@ -130,7 +132,7 @@ let Vehicles = class Vehicles {
|
|
|
130
132
|
persistent,
|
|
131
133
|
totalVehicles: this.vehiclesByNetworkId.size,
|
|
132
134
|
});
|
|
133
|
-
this.events.emit(
|
|
135
|
+
this.events.emit(SYSTEM_EVENTS.vehicle.created, 'all', vehicle.serialize());
|
|
134
136
|
return {
|
|
135
137
|
networkId,
|
|
136
138
|
handle,
|
|
@@ -178,6 +180,7 @@ let Vehicles = class Vehicles {
|
|
|
178
180
|
...options,
|
|
179
181
|
position: spawnPosition,
|
|
180
182
|
heading: spawnHeading,
|
|
183
|
+
plate: ownership.type === 'player' ? player.name : 'anom',
|
|
181
184
|
ownership,
|
|
182
185
|
});
|
|
183
186
|
if (result.success) {
|
|
@@ -289,7 +292,7 @@ let Vehicles = class Vehicles {
|
|
|
289
292
|
networkId,
|
|
290
293
|
totalVehicles: this.vehiclesByNetworkId.size,
|
|
291
294
|
});
|
|
292
|
-
this.events.emit(
|
|
295
|
+
this.events.emit(SYSTEM_EVENTS.vehicle.deleted, 'all', networkId);
|
|
293
296
|
return true;
|
|
294
297
|
}
|
|
295
298
|
/**
|
|
@@ -381,7 +384,7 @@ let Vehicles = class Vehicles {
|
|
|
381
384
|
}
|
|
382
385
|
};
|
|
383
386
|
Vehicles = __decorate([
|
|
384
|
-
|
|
387
|
+
Bind('singleton'),
|
|
385
388
|
__param(0, inject(Players)),
|
|
386
389
|
__param(1, inject(IEntityServer)),
|
|
387
390
|
__param(2, inject(IVehicleServer)),
|
|
@@ -12,6 +12,7 @@ import { getFrameworkModeScope, setRuntimeContext, validateRuntimeOptions, } fro
|
|
|
12
12
|
import { BinaryProcessManager } from './system/managers/binary-process.manager';
|
|
13
13
|
import { SessionRecoveryService } from './services/session-recovery.local';
|
|
14
14
|
import { registerServicesServer } from './services/services.register';
|
|
15
|
+
import { SYSTEM_EVENTS } from '../shared/types/system-types';
|
|
15
16
|
import { METADATA_KEYS } from './system/metadata-server.keys';
|
|
16
17
|
import { registerSystemServer } from './system/processors.register';
|
|
17
18
|
const CORE_WAIT_TIMEOUT = 10000;
|
|
@@ -163,13 +164,13 @@ export async function initServer(options, plugins) {
|
|
|
163
164
|
const engineEvents = GLOBAL_CONTAINER.resolve(IEngineEvents);
|
|
164
165
|
const events = GLOBAL_CONTAINER.resolve(EventsAPI);
|
|
165
166
|
// 1. Broadast to resources already running
|
|
166
|
-
engineEvents.emit(
|
|
167
|
-
events.emit(
|
|
168
|
-
// 2. Listen for '
|
|
169
|
-
engineEvents.on(
|
|
170
|
-
engineEvents.emit(
|
|
167
|
+
engineEvents.emit(SYSTEM_EVENTS.core.ready);
|
|
168
|
+
events.emit(SYSTEM_EVENTS.core.ready, 'all');
|
|
169
|
+
// 2. Listen for '_systemcore:request-ready' for resources starting late (hot-reload)
|
|
170
|
+
engineEvents.on(SYSTEM_EVENTS.core.requestReady, () => {
|
|
171
|
+
engineEvents.emit(SYSTEM_EVENTS.core.ready);
|
|
171
172
|
});
|
|
172
|
-
loggers.bootstrap.info(`'core
|
|
173
|
+
loggers.bootstrap.info(`'${SYSTEM_EVENTS.core.ready}' logic initialized and broadcasted`);
|
|
173
174
|
}
|
|
174
175
|
const logLevelLabel = LogLevelLabels[getLogLevel()];
|
|
175
176
|
loggers.bootstrap.info(`LogLevel Setted: ${logLevelLabel}`);
|
|
@@ -192,13 +193,13 @@ function createCoreDependency(coreName) {
|
|
|
192
193
|
const exportsService = GLOBAL_CONTAINER.resolve(IExports);
|
|
193
194
|
const onReady = () => {
|
|
194
195
|
if (!resolved) {
|
|
195
|
-
loggers.bootstrap.debug(`Core '${coreName}' detected via 'core
|
|
196
|
+
loggers.bootstrap.debug(`Core '${coreName}' detected via '${SYSTEM_EVENTS.core.ready}' event!`);
|
|
196
197
|
cleanup();
|
|
197
198
|
resolve();
|
|
198
199
|
}
|
|
199
200
|
};
|
|
200
|
-
engineEvents.on(
|
|
201
|
-
loggers.bootstrap.debug(`Listening for 'core
|
|
201
|
+
engineEvents.on(SYSTEM_EVENTS.core.ready, onReady);
|
|
202
|
+
loggers.bootstrap.debug(`Listening for '${SYSTEM_EVENTS.core.ready}' event from Core`);
|
|
202
203
|
// 2. Check if already ready via export (Polling)
|
|
203
204
|
const checkReady = () => {
|
|
204
205
|
if (resolved)
|
|
@@ -223,15 +224,15 @@ function createCoreDependency(coreName) {
|
|
|
223
224
|
// 3. Request status (for hot-reload cases where Core is already up)
|
|
224
225
|
// This is sent AFTER registering the listener so we can receive the response
|
|
225
226
|
if (!resolved) {
|
|
226
|
-
loggers.bootstrap.debug(`Requesting Core status via 'core
|
|
227
|
-
engineEvents.emit(
|
|
227
|
+
loggers.bootstrap.debug(`Requesting Core status via '${SYSTEM_EVENTS.core.requestReady}' event`);
|
|
228
|
+
engineEvents.emit(SYSTEM_EVENTS.core.requestReady);
|
|
228
229
|
}
|
|
229
230
|
// 4. Timeout protection
|
|
230
231
|
timeout = setTimeout(() => {
|
|
231
232
|
if (!resolved) {
|
|
232
233
|
loggers.bootstrap.warn(`Timeout waiting for Core '${coreName}' after ${CORE_WAIT_TIMEOUT}ms`);
|
|
233
234
|
cleanup();
|
|
234
|
-
reject(new Error(`[OpenCore] Timeout waiting for CORE '${coreName}'. The Core did not emit 'core
|
|
235
|
+
reject(new Error(`[OpenCore] Timeout waiting for CORE '${coreName}'. The Core did not emit '${SYSTEM_EVENTS.core.ready}' or expose 'isCoreReady' within ${CORE_WAIT_TIMEOUT}ms.`));
|
|
235
236
|
}
|
|
236
237
|
}, CORE_WAIT_TIMEOUT);
|
|
237
238
|
});
|
|
@@ -11,9 +11,11 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
|
11
11
|
return function (target, key) { decorator(target, key, paramIndex); }
|
|
12
12
|
};
|
|
13
13
|
import { inject } from 'tsyringe';
|
|
14
|
+
import { z } from 'zod';
|
|
14
15
|
import { IEngineEvents } from '../../../adapters/contracts/IEngineEvents';
|
|
15
16
|
import { AppError, SecurityError } from '../../../kernel/error';
|
|
16
17
|
import { loggers } from '../../../kernel/logger';
|
|
18
|
+
import { buildRemoteCommandExecuteEventName, SYSTEM_EVENTS } from '../../shared/types/system-types';
|
|
17
19
|
import { CommandErrorObserverContract } from '../contracts/security/command-error-observer.contract';
|
|
18
20
|
import { Controller, Export, Public } from '../decorators';
|
|
19
21
|
import { OnNet } from '../decorators/onNet';
|
|
@@ -211,7 +213,7 @@ let CommandExportController = class CommandExportController {
|
|
|
211
213
|
// Validate security BEFORE delegating to resource
|
|
212
214
|
await this.validateSecurity(player, commandName, remoteEntry.metadata.security);
|
|
213
215
|
// Delegate to resource via local event (server-to-server, not network)
|
|
214
|
-
const eventName =
|
|
216
|
+
const eventName = buildRemoteCommandExecuteEventName(remoteEntry.resourceName);
|
|
215
217
|
this.engineEvents.emit(eventName, clientID, commandName, args);
|
|
216
218
|
loggers.command.debug(`Delegated remote command execution to ${remoteEntry.resourceName}`, {
|
|
217
219
|
command: commandName,
|
|
@@ -294,7 +296,7 @@ let CommandExportController = class CommandExportController {
|
|
|
294
296
|
};
|
|
295
297
|
__decorate([
|
|
296
298
|
Public(),
|
|
297
|
-
OnNet(
|
|
299
|
+
OnNet(SYSTEM_EVENTS.command.execute, z.tuple([z.string().min(1), z.array(z.string())])),
|
|
298
300
|
__metadata("design:type", Function),
|
|
299
301
|
__metadata("design:paramtypes", [Player, String, Array]),
|
|
300
302
|
__metadata("design:returntype", Promise)
|
|
@@ -14,6 +14,7 @@ import { inject } from 'tsyringe';
|
|
|
14
14
|
import { IEngineEvents } from '../../../adapters/contracts/IEngineEvents';
|
|
15
15
|
import { IResourceInfo } from '../../../adapters/contracts/IResourceInfo';
|
|
16
16
|
import { loggers } from '../../../kernel/logger';
|
|
17
|
+
import { buildRemoteCommandExecuteEventName } from '../../shared/types/system-types';
|
|
17
18
|
import { CommandErrorObserverContract } from '../contracts/security/command-error-observer.contract';
|
|
18
19
|
import { Controller } from '../decorators';
|
|
19
20
|
import { normalizeToAppError } from '../helpers/normalize-app-error';
|
|
@@ -73,7 +74,7 @@ let RemoteCommandExecutionController = class RemoteCommandExecutionController {
|
|
|
73
74
|
*/
|
|
74
75
|
registerEventHandler() {
|
|
75
76
|
const resourceName = this.resourceInfo.getCurrentResourceName();
|
|
76
|
-
const eventName =
|
|
77
|
+
const eventName = buildRemoteCommandExecuteEventName(resourceName);
|
|
77
78
|
this.engineEvents.on(eventName, async (clientID, commandName, args) => {
|
|
78
79
|
await this.handleCommandExecution(clientID, commandName, args);
|
|
79
80
|
});
|
|
@@ -12,6 +12,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
|
12
12
|
};
|
|
13
13
|
import { inject } from 'tsyringe';
|
|
14
14
|
import { EventsAPI } from '../../../adapters/contracts/transport/events.api';
|
|
15
|
+
import { SYSTEM_EVENTS } from '../../shared/types/system-types';
|
|
15
16
|
import { Controller, OnNet } from '../decorators';
|
|
16
17
|
import { Player } from '../entities/player';
|
|
17
18
|
import { Vehicles } from '../apis/vehicles.api';
|
|
@@ -34,11 +35,11 @@ let VehicleController = class VehicleController {
|
|
|
34
35
|
handleGetData(player, networkId) {
|
|
35
36
|
const vehicle = this.vehicleService.getByNetworkId(networkId);
|
|
36
37
|
if (!vehicle) {
|
|
37
|
-
this.events.emit(
|
|
38
|
+
this.events.emit(SYSTEM_EVENTS.vehicle.dataResult, player.clientID, null);
|
|
38
39
|
return null;
|
|
39
40
|
}
|
|
40
41
|
const data = vehicle.serialize();
|
|
41
|
-
this.events.emit(
|
|
42
|
+
this.events.emit(SYSTEM_EVENTS.vehicle.dataResult, player.clientID, data);
|
|
42
43
|
return data;
|
|
43
44
|
}
|
|
44
45
|
/**
|
|
@@ -47,18 +48,18 @@ let VehicleController = class VehicleController {
|
|
|
47
48
|
handleGetPlayerVehicles(player) {
|
|
48
49
|
const vehicles = this.vehicleService.getPlayerVehicles(player.clientID);
|
|
49
50
|
const serialized = vehicles.map((v) => v.serialize());
|
|
50
|
-
this.events.emit(
|
|
51
|
+
this.events.emit(SYSTEM_EVENTS.vehicle.playerVehiclesResult, player.clientID, serialized);
|
|
51
52
|
return serialized;
|
|
52
53
|
}
|
|
53
54
|
};
|
|
54
55
|
__decorate([
|
|
55
|
-
OnNet(
|
|
56
|
+
OnNet(SYSTEM_EVENTS.vehicle.getData),
|
|
56
57
|
__metadata("design:type", Function),
|
|
57
58
|
__metadata("design:paramtypes", [Player, Number]),
|
|
58
59
|
__metadata("design:returntype", void 0)
|
|
59
60
|
], VehicleController.prototype, "handleGetData", null);
|
|
60
61
|
__decorate([
|
|
61
|
-
OnNet(
|
|
62
|
+
OnNet(SYSTEM_EVENTS.vehicle.getPlayerVehicles),
|
|
62
63
|
__metadata("design:type", Function),
|
|
63
64
|
__metadata("design:paramtypes", [Player]),
|
|
64
65
|
__metadata("design:returntype", void 0)
|
|
@@ -36,6 +36,8 @@ export interface CommandMetadata extends CommandConfig {
|
|
|
36
36
|
security?: SecurityMetadata;
|
|
37
37
|
/** True if the last parameter uses the spread operator (...args) */
|
|
38
38
|
hasSpreadParam?: boolean;
|
|
39
|
+
/** True when a parameter defines a JS default value. */
|
|
40
|
+
defaultParams?: boolean[];
|
|
39
41
|
}
|
|
40
42
|
type ServerCommandHandler = (() => any) | ((player: Player, ...args: any[]) => any);
|
|
41
43
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Player } from '../entities/player';
|
|
2
|
-
import { getParameterNames, getSpreadParameterIndices } from '../helpers/function-helper';
|
|
2
|
+
import { getDefaultParameterIndices, getParameterNames, getSpreadParameterIndices, } from '../helpers/function-helper';
|
|
3
3
|
import { METADATA_KEYS } from '../system/metadata-server.keys';
|
|
4
4
|
// Implementation
|
|
5
5
|
export function Command(configOrName, schema) {
|
|
@@ -20,6 +20,7 @@ export function Command(configOrName, schema) {
|
|
|
20
20
|
throw new Error(`@Command '${config.command}': first parameter must be Player if parameters are present`);
|
|
21
21
|
}
|
|
22
22
|
const paramNames = getParameterNames(descriptor.value);
|
|
23
|
+
const defaultParams = getDefaultParameterIndices(descriptor.value);
|
|
23
24
|
const spreadIndices = getSpreadParameterIndices(descriptor.value);
|
|
24
25
|
const hasSpreadParam = spreadIndices.length > 0 && spreadIndices[spreadIndices.length - 1];
|
|
25
26
|
const metadata = {
|
|
@@ -30,6 +31,7 @@ export function Command(configOrName, schema) {
|
|
|
30
31
|
paramNames,
|
|
31
32
|
expectsPlayer,
|
|
32
33
|
hasSpreadParam,
|
|
34
|
+
defaultParams,
|
|
33
35
|
};
|
|
34
36
|
Reflect.defineMetadata(METADATA_KEYS.COMMAND, metadata, target, propertyKey);
|
|
35
37
|
};
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { NativeHandle } from 'src/runtime/core/nativehandle';
|
|
2
1
|
import { IEntityServer } from '../../../adapters/contracts/server/IEntityServer';
|
|
3
2
|
import { INpcLifecycleServer } from '../../../adapters/contracts/server/npc-lifecycle/INpcLifecycleServer';
|
|
4
3
|
import { IPedServer } from '../../../adapters/contracts/server/IPedServer';
|
|
@@ -6,6 +5,7 @@ import { Vector3 } from '../../../kernel/utils/vector3';
|
|
|
6
5
|
import { BaseEntity } from '../../core/entity';
|
|
7
6
|
import { Spatial } from '../../core/spatial';
|
|
8
7
|
import { SerializedNpcData } from '../types/npc.types';
|
|
8
|
+
import { NativeHandle } from '../../core';
|
|
9
9
|
export interface NpcAdapters {
|
|
10
10
|
entityServer: IEntityServer;
|
|
11
11
|
pedServer: IPedServer;
|
|
@@ -11,7 +11,7 @@ import { Spatial } from '../../core/spatial';
|
|
|
11
11
|
import { LinkedID } from '../types/linked-id';
|
|
12
12
|
import { PlayerSession } from '../types/player-session.types';
|
|
13
13
|
import { SerializedPlayerData } from '../types/core-exports.types';
|
|
14
|
-
import { NativeHandle } from '
|
|
14
|
+
import { NativeHandle } from '../../core';
|
|
15
15
|
/**
|
|
16
16
|
* Adapter bundle for player operations.
|
|
17
17
|
* Passed to Player instances by PlayerDirectory.
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { loggers } from '../../../kernel/logger';
|
|
2
2
|
import { BaseEntity } from '../../core/entity';
|
|
3
|
+
import { SYSTEM_EVENTS } from '../../shared/types/system-types';
|
|
3
4
|
/**
|
|
4
5
|
* Core-level representation of a connected player on the server.
|
|
5
6
|
*
|
|
@@ -30,10 +31,16 @@ export class Player extends BaseEntity {
|
|
|
30
31
|
this._position = adapters.playerInfo.getPlayerPosition(session.clientID);
|
|
31
32
|
}
|
|
32
33
|
getHeading() {
|
|
33
|
-
|
|
34
|
+
const ped = this.adapters.playerServer.getPed(this.clientID.toString());
|
|
35
|
+
if (!ped || ped === 0)
|
|
36
|
+
return 0;
|
|
37
|
+
return this.adapters.entityServer.getHeading(ped);
|
|
34
38
|
}
|
|
35
39
|
setHeading(heading) {
|
|
36
|
-
this.adapters.
|
|
40
|
+
const ped = this.adapters.playerServer.getPed(this.clientID.toString());
|
|
41
|
+
if (!ped || ped === 0)
|
|
42
|
+
return;
|
|
43
|
+
this.adapters.entityServer.setHeading(ped, heading);
|
|
37
44
|
}
|
|
38
45
|
getHandle() {
|
|
39
46
|
return this.clientID;
|
|
@@ -120,7 +127,7 @@ export class Player extends BaseEntity {
|
|
|
120
127
|
* @param type - Message type for styling
|
|
121
128
|
*/
|
|
122
129
|
send(message, type = 'chat') {
|
|
123
|
-
this.emit(
|
|
130
|
+
this.emit(SYSTEM_EVENTS.chat.send, message, type);
|
|
124
131
|
}
|
|
125
132
|
// ─────────────────────────────────────────────────────────────────
|
|
126
133
|
// Spawning / Teleporting
|
|
@@ -4,17 +4,21 @@ import { generateSchemaFromTypes } from '../system/schema-generator';
|
|
|
4
4
|
import { processTupleSchema } from '../../shared/helpers/process-tuple-schema';
|
|
5
5
|
export async function validateAndExecuteCommand(meta, player, args, handler) {
|
|
6
6
|
const paramNames = meta.expectsPlayer ? meta.paramNames.slice(1) : meta.paramNames;
|
|
7
|
+
const defaultParams = meta.expectsPlayer
|
|
8
|
+
? (meta.defaultParams ?? []).slice(1)
|
|
9
|
+
: (meta.defaultParams ?? []);
|
|
7
10
|
let schema = meta.schema;
|
|
8
11
|
if (!meta.expectsPlayer) {
|
|
9
12
|
if (args.length > 0) {
|
|
10
|
-
|
|
11
|
-
|
|
13
|
+
const usage = resolveCommandUsage(meta, paramNames, defaultParams);
|
|
14
|
+
throw new AppError('GAME:BAD_REQUEST', `Incorrect usage, use: ${usage}`, 'client', {
|
|
15
|
+
usage,
|
|
12
16
|
});
|
|
13
17
|
}
|
|
14
18
|
return await handler();
|
|
15
19
|
}
|
|
16
20
|
if (!schema) {
|
|
17
|
-
schema = generateSchemaFromTypes(meta.paramTypes);
|
|
21
|
+
schema = generateSchemaFromTypes(meta.paramTypes, meta.defaultParams);
|
|
18
22
|
if (!schema) {
|
|
19
23
|
if (paramNames.length > 0) {
|
|
20
24
|
throw new AppError('SCHEMA:MISMATCH', `Command '${meta.command}' has parameters ${paramNames.join(', ')} but no schema was provided.`, 'core');
|
|
@@ -39,8 +43,9 @@ export async function validateAndExecuteCommand(meta, player, args, handler) {
|
|
|
39
43
|
inputObj[paramNames[i]] = args[i];
|
|
40
44
|
}
|
|
41
45
|
const validated = await schema.parseAsync(inputObj).catch(() => {
|
|
42
|
-
|
|
43
|
-
|
|
46
|
+
const usage = resolveCommandUsage(meta, paramNames, defaultParams);
|
|
47
|
+
throw new AppError('GAME:BAD_REQUEST', `Incorrect usage, use: ${usage}`, 'client', {
|
|
48
|
+
usage,
|
|
44
49
|
});
|
|
45
50
|
});
|
|
46
51
|
const obj = validated;
|
|
@@ -51,8 +56,9 @@ export async function validateAndExecuteCommand(meta, player, args, handler) {
|
|
|
51
56
|
if (schema instanceof z.ZodTuple) {
|
|
52
57
|
const processedArgs = processTupleSchema(schema, args);
|
|
53
58
|
const validated = await schema.parseAsync(processedArgs).catch(() => {
|
|
54
|
-
|
|
55
|
-
|
|
59
|
+
const usage = resolveCommandUsage(meta, paramNames, defaultParams);
|
|
60
|
+
throw new AppError('GAME:BAD_REQUEST', `Incorrect usage, use: ${usage}`, 'client', {
|
|
61
|
+
usage,
|
|
56
62
|
});
|
|
57
63
|
});
|
|
58
64
|
const finalArgs = validated;
|
|
@@ -71,3 +77,10 @@ export async function validateAndExecuteCommand(meta, player, args, handler) {
|
|
|
71
77
|
// fallback
|
|
72
78
|
return await handler(player);
|
|
73
79
|
}
|
|
80
|
+
function resolveCommandUsage(meta, paramNames, defaultParams) {
|
|
81
|
+
if (meta.usage?.trim()) {
|
|
82
|
+
return meta.usage;
|
|
83
|
+
}
|
|
84
|
+
const renderedParams = paramNames.map((name, index) => defaultParams[index] ? `[${name}]` : `<${name}>`);
|
|
85
|
+
return `/${meta.command}${renderedParams.length > 0 ? ` ${renderedParams.join(' ')}` : ''}`;
|
|
86
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export declare function getParameterNames(func: (...args: any[]) => any): string[];
|
|
2
|
+
export declare function getDefaultParameterIndices(func: (...args: any[]) => any): boolean[];
|
|
2
3
|
/**
|
|
3
4
|
* Detects which parameter indices use the spread operator (...args).
|
|
4
5
|
* Returns an array of booleans where true means the parameter at that index is a spread parameter.
|
|
@@ -1,14 +1,10 @@
|
|
|
1
1
|
export function getParameterNames(func) {
|
|
2
|
-
|
|
3
|
-
.toString()
|
|
4
|
-
.replace(/\/\/.*$/gm, '')
|
|
5
|
-
.replace(/\/\*[\s\S]*?\*\//gm, '');
|
|
6
|
-
const args = stripped
|
|
7
|
-
.slice(stripped.indexOf('(') + 1, stripped.indexOf(')'))
|
|
8
|
-
.split(',')
|
|
2
|
+
return parseParameterTokens(func)
|
|
9
3
|
.map((arg) => arg.replace(/=[\s\S]*/, '').trim())
|
|
10
4
|
.filter(Boolean);
|
|
11
|
-
|
|
5
|
+
}
|
|
6
|
+
export function getDefaultParameterIndices(func) {
|
|
7
|
+
return parseParameterTokens(func).map((arg) => arg.includes('='));
|
|
12
8
|
}
|
|
13
9
|
/**
|
|
14
10
|
* Detects which parameter indices use the spread operator (...args).
|
|
@@ -26,3 +22,14 @@ export function getSpreadParameterIndices(func) {
|
|
|
26
22
|
.filter(Boolean);
|
|
27
23
|
return args.map((arg) => arg.startsWith('...'));
|
|
28
24
|
}
|
|
25
|
+
function parseParameterTokens(func) {
|
|
26
|
+
const stripped = func
|
|
27
|
+
.toString()
|
|
28
|
+
.replace(/\/\/.*$/gm, '')
|
|
29
|
+
.replace(/\/\*[\s\S]*?\*\//gm, '');
|
|
30
|
+
return stripped
|
|
31
|
+
.slice(stripped.indexOf('(') + 1, stripped.indexOf(')'))
|
|
32
|
+
.split(',')
|
|
33
|
+
.map((arg) => arg.trim())
|
|
34
|
+
.filter(Boolean);
|
|
35
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { EventsAPI } from '../../../../adapters/contracts/transport/events.api';
|
|
2
|
-
import { RGB } from '
|
|
2
|
+
import { RGB } from '../../../../kernel/utils';
|
|
3
3
|
import { Player } from '../../entities';
|
|
4
4
|
import { Channels } from '../../ports/channel.api-port';
|
|
5
5
|
import { IChannelValidator, ChannelMetadata, ChannelType } from '../../types';
|