rock-mod 0.20.0 → 0.21.0
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/client/RockMod.d.ts +1 -1
- package/dist/client/RockMod.js +4 -0
- package/dist/client/entities/ccmp/camera/CCMPCamera.d.ts +24 -0
- package/dist/client/entities/ccmp/camera/CCMPCamera.js +58 -0
- package/dist/client/entities/ccmp/camera/CCMPCameraManager.d.ts +16 -0
- package/dist/client/entities/ccmp/camera/CCMPCameraManager.js +50 -0
- package/dist/client/entities/ccmp/ped/CCMPPed.d.ts +65 -0
- package/dist/client/entities/ccmp/ped/CCMPPed.js +185 -0
- package/dist/client/entities/ccmp/ped/CCMPPedsManager.d.ts +20 -0
- package/dist/client/entities/ccmp/ped/CCMPPedsManager.js +105 -0
- package/dist/client/entities/ccmp/player/CCMPPlayer.d.ts +112 -0
- package/dist/client/entities/ccmp/player/CCMPPlayer.js +332 -0
- package/dist/client/entities/ccmp/player/CCMPPlayersManager.d.ts +84 -0
- package/dist/client/entities/ccmp/player/CCMPPlayersManager.js +318 -0
- package/dist/client/entities/ccmp/vehicle/CCMPVehiclesManager.d.ts +64 -0
- package/dist/client/entities/ccmp/vehicle/CCMPVehiclesManager.js +105 -0
- package/dist/client/entities/common/entity/IEntity.d.ts +3 -0
- package/dist/client/entities/ragemp/entity/RageEntity.d.ts +3 -0
- package/dist/client/entities/ragemp/entity/RageEntity.js +11 -0
- package/dist/client/factories/ccmp/CCMPManagersFactory.d.ts +46 -0
- package/dist/client/factories/ccmp/CCMPManagersFactory.js +149 -0
- package/dist/client/factories/ccmp/createNotImplementedProxy.d.ts +1 -0
- package/dist/client/factories/ccmp/createNotImplementedProxy.js +24 -0
- package/dist/client/game/ccmp/browser/CCMPBrowserManager.d.ts +22 -0
- package/dist/client/game/ccmp/browser/CCMPBrowserManager.js +66 -0
- package/dist/client/game/ccmp/chat/CCMPChatManager.d.ts +26 -0
- package/dist/client/game/ccmp/chat/CCMPChatManager.js +41 -0
- package/dist/client/game/ccmp/controls/CCMPControlsManager.d.ts +33 -0
- package/dist/client/game/ccmp/controls/CCMPControlsManager.js +47 -0
- package/dist/client/game/ccmp/cursor/CCMPCursorManager.d.ts +6 -0
- package/dist/client/game/ccmp/cursor/CCMPCursorManager.js +15 -0
- package/dist/client/game/ccmp/gameplay/CCMPGameplayManager.d.ts +6 -0
- package/dist/client/game/ccmp/gameplay/CCMPGameplayManager.js +10 -0
- package/dist/client/game/ccmp/graphics/CCMPGraphicsManager.d.ts +58 -0
- package/dist/client/game/ccmp/graphics/CCMPGraphicsManager.js +112 -0
- package/dist/client/game/ccmp/gui/CCMPGuiManager.d.ts +5 -0
- package/dist/client/game/ccmp/gui/CCMPGuiManager.js +17 -0
- package/dist/client/game/ccmp/keys/CCMPKeysManager.d.ts +41 -0
- package/dist/client/game/ccmp/keys/CCMPKeysManager.js +94 -0
- package/dist/client/game/ccmp/nametags/CCMPNametagsManager.d.ts +4 -0
- package/dist/client/game/ccmp/nametags/CCMPNametagsManager.js +6 -0
- package/dist/client/game/ccmp/native/CCMPNativeCallerManager.d.ts +74 -0
- package/dist/client/game/ccmp/native/CCMPNativeCallerManager.js +129 -0
- package/dist/client/game/ccmp/native/_generated/nativeDispatch.d.ts +5 -0
- package/dist/client/game/ccmp/native/_generated/nativeDispatch.js +8123 -0
- package/dist/client/game/ccmp/object/CCMPGameObjectManager.d.ts +4 -0
- package/dist/client/game/ccmp/object/CCMPGameObjectManager.js +6 -0
- package/dist/client/game/ccmp/pathfind/CCMPPathfindManager.d.ts +26 -0
- package/dist/client/game/ccmp/pathfind/CCMPPathfindManager.js +31 -0
- package/dist/client/game/ccmp/raycasting/CCMPRaycastingManager.d.ts +10 -0
- package/dist/client/game/ccmp/raycasting/CCMPRaycastingManager.js +46 -0
- package/dist/client/game/ccmp/storage/CCMPStorageManager.d.ts +25 -0
- package/dist/client/game/ccmp/storage/CCMPStorageManager.js +46 -0
- package/dist/client/game/ccmp/streaming/CCMPStreamingManager.d.ts +17 -0
- package/dist/client/game/ccmp/streaming/CCMPStreamingManager.js +41 -0
- package/dist/client/game/ccmp/ui/CCMPUiManager.d.ts +41 -0
- package/dist/client/game/ccmp/ui/CCMPUiManager.js +69 -0
- package/dist/client/game/ccmp/zone/CCMPZoneManager.d.ts +19 -0
- package/dist/client/game/ccmp/zone/CCMPZoneManager.js +20 -0
- package/dist/client/game/common/browser/IBrowserManager.d.ts +7 -0
- package/dist/client/game/common/chat/IChatManager.d.ts +1 -0
- package/dist/client/game/common/controls/IControlsManager.d.ts +3 -0
- package/dist/client/game/common/graphics/IGraphicsManager.d.ts +17 -0
- package/dist/client/game/common/streaming/IStreamingManager.d.ts +2 -0
- package/dist/client/game/ragemp/browser/RageBrowserManager.d.ts +2 -1
- package/dist/client/game/ragemp/browser/RageBrowserManager.js +30 -1
- package/dist/client/game/ragemp/chat/RageChatManager.d.ts +1 -0
- package/dist/client/game/ragemp/chat/RageChatManager.js +3 -0
- package/dist/client/game/ragemp/controls/RageControlsManager.d.ts +3 -0
- package/dist/client/game/ragemp/controls/RageControlsManager.js +9 -0
- package/dist/client/game/ragemp/graphics/RageGraphicsManager.d.ts +5 -1
- package/dist/client/game/ragemp/graphics/RageGraphicsManager.js +12 -0
- package/dist/client/game/ragemp/streaming/RageStreamingManager.d.ts +2 -0
- package/dist/client/game/ragemp/streaming/RageStreamingManager.js +6 -0
- package/dist/client/net/ccmp/CCMPConsoleForwarder.d.ts +11 -0
- package/dist/client/net/ccmp/CCMPConsoleForwarder.js +153 -0
- package/dist/client/net/ccmp/CCMPNetManager.d.ts +23 -0
- package/dist/client/net/ccmp/CCMPNetManager.js +55 -0
- package/dist/client/net/ccmp/dataHandler/CCMPDataHandler.d.ts +23 -0
- package/dist/client/net/ccmp/dataHandler/CCMPDataHandler.js +43 -0
- package/dist/client/net/ccmp/events/CCMPEventsBridge.d.ts +14 -0
- package/dist/client/net/ccmp/events/CCMPEventsBridge.js +19 -0
- package/dist/client/net/ccmp/events/CCMPEventsManager.d.ts +72 -0
- package/dist/client/net/ccmp/events/CCMPEventsManager.js +177 -0
- package/dist/client/net/ccmp/events/CCMPInProcessEmitter.d.ts +45 -0
- package/dist/client/net/ccmp/events/CCMPInProcessEmitter.js +133 -0
- package/dist/client/net/ccmp/events/CCMPRenderTicker.d.ts +18 -0
- package/dist/client/net/ccmp/events/CCMPRenderTicker.js +74 -0
- package/dist/client/net/ccmp/events/CCMPSyncedMetaBridge.d.ts +24 -0
- package/dist/client/net/ccmp/events/CCMPSyncedMetaBridge.js +35 -0
- package/dist/client/net/ccmp/rpc/CCMPRPCManager.d.ts +22 -0
- package/dist/client/net/ccmp/rpc/CCMPRPCManager.js +31 -0
- package/dist/client/net/common/events/types.d.ts +3 -1
- package/dist/client/net/common/events/types.js +1 -0
- package/dist/client/utils/ccmp/CCMPUtilsManager.d.ts +18 -0
- package/dist/client/utils/ccmp/CCMPUtilsManager.js +20 -0
- package/dist/server/RockMod.d.ts +1 -1
- package/dist/server/RockMod.js +4 -0
- package/dist/server/entities/ccmp/baseObject/CCMPBaseObject.d.ts +8 -0
- package/dist/server/entities/ccmp/baseObject/CCMPBaseObject.js +21 -0
- package/dist/server/entities/ccmp/baseObject/CCMPBaseObjectsIterator.d.ts +8 -0
- package/dist/server/entities/ccmp/baseObject/CCMPBaseObjectsIterator.js +16 -0
- package/dist/server/entities/ccmp/baseObject/CCMPBaseObjectsManager.d.ts +19 -0
- package/dist/server/entities/ccmp/baseObject/CCMPBaseObjectsManager.js +49 -0
- package/dist/server/entities/ccmp/blip/CCMPBlip.d.ts +34 -0
- package/dist/server/entities/ccmp/blip/CCMPBlip.js +80 -0
- package/dist/server/entities/ccmp/blip/CCMPBlipsManager.d.ts +9 -0
- package/dist/server/entities/ccmp/blip/CCMPBlipsManager.js +33 -0
- package/dist/server/entities/ccmp/colshape/CCMPCircleColshape.d.ts +7 -0
- package/dist/server/entities/ccmp/colshape/CCMPCircleColshape.js +10 -0
- package/dist/server/entities/ccmp/colshape/CCMPColshape.d.ts +23 -0
- package/dist/server/entities/ccmp/colshape/CCMPColshape.js +47 -0
- package/dist/server/entities/ccmp/colshape/CCMPColshapesManager.d.ts +28 -0
- package/dist/server/entities/ccmp/colshape/CCMPColshapesManager.js +108 -0
- package/dist/server/entities/ccmp/colshape/CCMPCuboidColshape.d.ts +7 -0
- package/dist/server/entities/ccmp/colshape/CCMPCuboidColshape.js +10 -0
- package/dist/server/entities/ccmp/colshape/CCMPCylinderColshape.d.ts +7 -0
- package/dist/server/entities/ccmp/colshape/CCMPCylinderColshape.js +10 -0
- package/dist/server/entities/ccmp/colshape/CCMPRectangleColshape.d.ts +7 -0
- package/dist/server/entities/ccmp/colshape/CCMPRectangleColshape.js +10 -0
- package/dist/server/entities/ccmp/colshape/CCMPSphereColshape.d.ts +7 -0
- package/dist/server/entities/ccmp/colshape/CCMPSphereColshape.js +10 -0
- package/dist/server/entities/ccmp/entity/CCMPEntitiesManager.d.ts +8 -0
- package/dist/server/entities/ccmp/entity/CCMPEntitiesManager.js +10 -0
- package/dist/server/entities/ccmp/entity/CCMPEntity.d.ts +13 -0
- package/dist/server/entities/ccmp/entity/CCMPEntity.js +28 -0
- package/dist/server/entities/ccmp/marker/CCMPMarker.d.ts +32 -0
- package/dist/server/entities/ccmp/marker/CCMPMarker.js +79 -0
- package/dist/server/entities/ccmp/marker/CCMPMarkersManager.d.ts +9 -0
- package/dist/server/entities/ccmp/marker/CCMPMarkersManager.js +30 -0
- package/dist/server/entities/ccmp/object/CCMPObject.d.ts +48 -0
- package/dist/server/entities/ccmp/object/CCMPObject.js +70 -0
- package/dist/server/entities/ccmp/object/CCMPObjectsManager.d.ts +9 -0
- package/dist/server/entities/ccmp/object/CCMPObjectsManager.js +28 -0
- package/dist/server/entities/ccmp/ped/CCMPPed.d.ts +33 -0
- package/dist/server/entities/ccmp/ped/CCMPPed.js +82 -0
- package/dist/server/entities/ccmp/ped/CCMPPedsManager.d.ts +9 -0
- package/dist/server/entities/ccmp/ped/CCMPPedsManager.js +28 -0
- package/dist/server/entities/ccmp/player/CCMPPlayer.d.ts +65 -0
- package/dist/server/entities/ccmp/player/CCMPPlayer.js +180 -0
- package/dist/server/entities/ccmp/player/CCMPPlayersManager.d.ts +12 -0
- package/dist/server/entities/ccmp/player/CCMPPlayersManager.js +66 -0
- package/dist/server/entities/ccmp/vehicle/CCMPVehicle.d.ts +58 -0
- package/dist/server/entities/ccmp/vehicle/CCMPVehicle.js +161 -0
- package/dist/server/entities/ccmp/vehicle/CCMPVehiclesManager.d.ts +9 -0
- package/dist/server/entities/ccmp/vehicle/CCMPVehiclesManager.js +31 -0
- package/dist/server/entities/ccmp/worldObject/CCMPWorldObject.d.ts +9 -0
- package/dist/server/entities/ccmp/worldObject/CCMPWorldObject.js +7 -0
- package/dist/server/entities/ccmp/worldObject/CCMPWorldObjectsIterator.d.ts +10 -0
- package/dist/server/entities/ccmp/worldObject/CCMPWorldObjectsIterator.js +40 -0
- package/dist/server/entities/ccmp/worldObject/CCMPWorldObjectsManager.d.ts +11 -0
- package/dist/server/entities/ccmp/worldObject/CCMPWorldObjectsManager.js +16 -0
- package/dist/server/entities/mock/player/MockPlayersManager.js +2 -1
- package/dist/server/factories/ccmp/CCMPManagersFactory.d.ts +23 -0
- package/dist/server/factories/ccmp/CCMPManagersFactory.js +46 -0
- package/dist/server/net/ccmp/CCMPNetManager.d.ts +19 -0
- package/dist/server/net/ccmp/CCMPNetManager.js +112 -0
- package/dist/server/net/ccmp/events/CCMPEventsManager.d.ts +17 -0
- package/dist/server/net/ccmp/events/CCMPEventsManager.js +54 -0
- package/dist/server/net/ccmp/rpc/CCMPRPCManager.d.ts +8 -0
- package/dist/server/net/ccmp/rpc/CCMPRPCManager.js +18 -0
- package/dist/server/net/common/events/types.d.ts +2 -0
- package/dist/server/net/common/events/types.js +1 -0
- package/dist/server/utils/ccmp/CCMPUtilsManager.d.ts +4 -0
- package/dist/server/utils/ccmp/CCMPUtilsManager.js +9 -0
- package/dist/server/world/ccmp/CCMPWorldManager.d.ts +10 -0
- package/dist/server/world/ccmp/CCMPWorldManager.js +24 -0
- package/package.json +3 -1
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
const RENDER_EVENT = "rm::render";
|
|
2
|
+
const RENDER_LISTENER_WARN_THRESHOLD_MS = 10;
|
|
3
|
+
function getCCMPCallbackProfiler() {
|
|
4
|
+
return globalThis;
|
|
5
|
+
}
|
|
6
|
+
function profileLabel(event) {
|
|
7
|
+
return `rm internal "${event}"`;
|
|
8
|
+
}
|
|
9
|
+
function captureRegistrationSite() {
|
|
10
|
+
var _a;
|
|
11
|
+
const stack = String((_a = new Error().stack) !== null && _a !== void 0 ? _a : "");
|
|
12
|
+
const lines = stack
|
|
13
|
+
.split("\n")
|
|
14
|
+
.map((line) => line.trim())
|
|
15
|
+
.filter(Boolean);
|
|
16
|
+
for (const line of lines) {
|
|
17
|
+
if (line === "Error" ||
|
|
18
|
+
line.includes("captureRegistrationSite") ||
|
|
19
|
+
line.includes("CCMPInProcessEmitter") ||
|
|
20
|
+
line.includes("getCCMPCallbackProfiler") ||
|
|
21
|
+
line.includes("profileLabel")) {
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
return line.replace(/^at\s+/, "");
|
|
25
|
+
}
|
|
26
|
+
return "<unknown>";
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Тонкий внутренний event bus.
|
|
30
|
+
*
|
|
31
|
+
* RageMP даёт `mp.events.call(name, ...args)` для локальной шины поверх своего
|
|
32
|
+
* движка событий. У CCMP нативной внутренней шины нет — её роль выполняет этот
|
|
33
|
+
* класс. Используется только из `CCMPEventsManager` для `onInternal` /
|
|
34
|
+
* `offInternal` / `emitInternal` и из `CCMPEventsBridge` для синтезированных
|
|
35
|
+
* `rm::*` событий.
|
|
36
|
+
*
|
|
37
|
+
* Поддерживает "sticky" events (см. `emitSticky`) для one-shot lifecycle-
|
|
38
|
+
* сигналов (например `rm::playerReady`), которые могут эмититься до того,
|
|
39
|
+
* как поздние подписчики из DI-цепочки геймода успели зарегистрироваться.
|
|
40
|
+
* Sticky-кэш гарантирует, что любой `on()`-вызов после `emitSticky` получит
|
|
41
|
+
* последнее значение synchronously.
|
|
42
|
+
*/
|
|
43
|
+
export class CCMPInProcessEmitter {
|
|
44
|
+
constructor() {
|
|
45
|
+
this._listeners = new Map();
|
|
46
|
+
/** Кэш аргументов для sticky-events. См. `emitSticky` / `on`. */
|
|
47
|
+
this._stickyCache = new Map();
|
|
48
|
+
}
|
|
49
|
+
on(event, listener) {
|
|
50
|
+
var _a, _b;
|
|
51
|
+
let bucket = this._listeners.get(event);
|
|
52
|
+
if (!bucket) {
|
|
53
|
+
bucket = new Set();
|
|
54
|
+
this._listeners.set(event, bucket);
|
|
55
|
+
}
|
|
56
|
+
bucket.add(listener);
|
|
57
|
+
(_b = (_a = getCCMPCallbackProfiler()).__ccmp_registerCallbackProfile) === null || _b === void 0 ? void 0 : _b.call(_a, profileLabel(event), listener, captureRegistrationSite());
|
|
58
|
+
// Sticky replay: если событие уже было эмитнуто как sticky — сразу
|
|
59
|
+
// воспроизводим последнее значение новому подписчику. Это решает гонку
|
|
60
|
+
// "CCMPEventsBridge эмитит rm::playerReady до того, как геймод-адаптер
|
|
61
|
+
// успел подписаться" — типично для async DI-bootstrap'а.
|
|
62
|
+
const sticky = this._stickyCache.get(event);
|
|
63
|
+
if (sticky !== undefined) {
|
|
64
|
+
try {
|
|
65
|
+
this._callListener(event, listener, sticky);
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
console.error(`[CCMPInProcessEmitter] sticky replay "${event}" failed for new subscriber:`, error);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
off(event, listener) {
|
|
73
|
+
const bucket = this._listeners.get(event);
|
|
74
|
+
if (!bucket) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
if (listener) {
|
|
78
|
+
bucket.delete(listener);
|
|
79
|
+
if (bucket.size === 0) {
|
|
80
|
+
this._listeners.delete(event);
|
|
81
|
+
}
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
this._listeners.delete(event);
|
|
85
|
+
}
|
|
86
|
+
emit(event, ...args) {
|
|
87
|
+
const bucket = this._listeners.get(event);
|
|
88
|
+
if (!bucket || bucket.size === 0) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
// Копия на случай, если хендлер изменит реестр во время итерации.
|
|
92
|
+
for (const listener of [...bucket]) {
|
|
93
|
+
try {
|
|
94
|
+
this._callListener(event, listener, args);
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
console.error(`[CCMPInProcessEmitter] listener "${event}" failed:`, error);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Как `emit`, но дополнительно кэширует args, чтобы любой будущий
|
|
103
|
+
* `on(event, listener)` сразу получил воспроизведение последнего значения.
|
|
104
|
+
*
|
|
105
|
+
* Использовать только для one-shot lifecycle-событий (`rm::playerReady` и
|
|
106
|
+
* т.п.), где "позднее" подписавшийся обработчик всё равно должен получить
|
|
107
|
+
* сигнал. Для регулярных событий (`rm::playerConnected` на каждого нового
|
|
108
|
+
* игрока) sticky-кэш приведёт к нежелательному поведению — используйте
|
|
109
|
+
* обычный `emit`.
|
|
110
|
+
*
|
|
111
|
+
* Кэш переписывается на каждый последующий вызов с тем же event'ом, так
|
|
112
|
+
* что подписчики получат последнее значение, не цепочку историй.
|
|
113
|
+
*/
|
|
114
|
+
emitSticky(event, ...args) {
|
|
115
|
+
this._stickyCache.set(event, args);
|
|
116
|
+
this.emit(event, ...args);
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Удаляет sticky-кэш для события. Полезно на disconnect/reset, чтобы
|
|
120
|
+
* новые подписчики не получили устаревший local-player-stub.
|
|
121
|
+
*/
|
|
122
|
+
clearSticky(event) {
|
|
123
|
+
this._stickyCache.delete(event);
|
|
124
|
+
}
|
|
125
|
+
_callListener(event, listener, args) {
|
|
126
|
+
const profiler = getCCMPCallbackProfiler().__ccmp_profileCallback;
|
|
127
|
+
if (profiler) {
|
|
128
|
+
profiler(profileLabel(event), listener, args, event === RENDER_EVENT ? RENDER_LISTENER_WARN_THRESHOLD_MS : undefined);
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
listener(...args);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type CCMPEventsManager } from "./CCMPEventsManager";
|
|
2
|
+
/**
|
|
3
|
+
* Per-frame событие `rm::render` под CCMP.
|
|
4
|
+
*
|
|
5
|
+
* У RageMP клиента есть нативный raw-event `render`, на котором завязаны
|
|
6
|
+
* декораторы `@Render` и `@Interval` в геймоде. Современный CCMP runtime
|
|
7
|
+
* эмитит coalesced native `ccmp.on("render")` из game loop; используем его,
|
|
8
|
+
* чтобы render не зависел от JS timer pump и не копился в очереди.
|
|
9
|
+
*
|
|
10
|
+
* `setInterval` остаётся только fallback'ом для старых runtime.
|
|
11
|
+
*/
|
|
12
|
+
export declare class CCMPRenderTicker {
|
|
13
|
+
private _emitter;
|
|
14
|
+
private _handle;
|
|
15
|
+
private _nativeRenderRegistered;
|
|
16
|
+
start(emitter: CCMPEventsManager): void;
|
|
17
|
+
stop(): void;
|
|
18
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { ClientInternalEventName } from "../../common/events/types";
|
|
2
|
+
const TARGET_FPS = 60;
|
|
3
|
+
const TICK_INTERVAL_MS = Math.floor(1000 / TARGET_FPS);
|
|
4
|
+
/**
|
|
5
|
+
* Достаём `setInterval` из global scope не вызывая ReferenceError.
|
|
6
|
+
*
|
|
7
|
+
* Под bare deno_core просто `setInterval` бросает `ReferenceError: setInterval
|
|
8
|
+
* is not defined` ещё до того как мы можем проверить `typeof`. `globalThis`
|
|
9
|
+
* безопасен — обращение к несуществующему свойству даёт `undefined`.
|
|
10
|
+
*/
|
|
11
|
+
function getSetInterval() {
|
|
12
|
+
const fn = globalThis.setInterval;
|
|
13
|
+
return typeof fn === "function" ? fn : null;
|
|
14
|
+
}
|
|
15
|
+
function getClearInterval() {
|
|
16
|
+
const fn = globalThis.clearInterval;
|
|
17
|
+
return typeof fn === "function" ? fn : null;
|
|
18
|
+
}
|
|
19
|
+
function getNativeRenderEventSource() {
|
|
20
|
+
const maybeCcmp = globalThis.ccmp;
|
|
21
|
+
return typeof (maybeCcmp === null || maybeCcmp === void 0 ? void 0 : maybeCcmp.on) === "function" ? maybeCcmp : null;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Per-frame событие `rm::render` под CCMP.
|
|
25
|
+
*
|
|
26
|
+
* У RageMP клиента есть нативный raw-event `render`, на котором завязаны
|
|
27
|
+
* декораторы `@Render` и `@Interval` в геймоде. Современный CCMP runtime
|
|
28
|
+
* эмитит coalesced native `ccmp.on("render")` из game loop; используем его,
|
|
29
|
+
* чтобы render не зависел от JS timer pump и не копился в очереди.
|
|
30
|
+
*
|
|
31
|
+
* `setInterval` остаётся только fallback'ом для старых runtime.
|
|
32
|
+
*/
|
|
33
|
+
export class CCMPRenderTicker {
|
|
34
|
+
constructor() {
|
|
35
|
+
this._emitter = null;
|
|
36
|
+
this._handle = null;
|
|
37
|
+
this._nativeRenderRegistered = false;
|
|
38
|
+
}
|
|
39
|
+
start(emitter) {
|
|
40
|
+
var _a;
|
|
41
|
+
this._emitter = emitter;
|
|
42
|
+
const nativeRender = getNativeRenderEventSource();
|
|
43
|
+
if (nativeRender) {
|
|
44
|
+
if (!this._nativeRenderRegistered) {
|
|
45
|
+
this._nativeRenderRegistered = true;
|
|
46
|
+
(_a = nativeRender.on) === null || _a === void 0 ? void 0 : _a.call(nativeRender, "render", () => {
|
|
47
|
+
var _a;
|
|
48
|
+
(_a = this._emitter) === null || _a === void 0 ? void 0 : _a.emitInternal(ClientInternalEventName.Render);
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
if (this._handle !== null)
|
|
54
|
+
return;
|
|
55
|
+
const setIntervalFn = getSetInterval();
|
|
56
|
+
if (!setIntervalFn) {
|
|
57
|
+
console.warn('[CCMPRenderTicker] native `ccmp.on("render")` and `setInterval` are unavailable. ' +
|
|
58
|
+
"`rm::render` will not be emitted.");
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
this._handle = setIntervalFn(() => {
|
|
62
|
+
var _a;
|
|
63
|
+
(_a = this._emitter) === null || _a === void 0 ? void 0 : _a.emitInternal(ClientInternalEventName.Render);
|
|
64
|
+
}, TICK_INTERVAL_MS);
|
|
65
|
+
}
|
|
66
|
+
stop() {
|
|
67
|
+
if (this._handle !== null) {
|
|
68
|
+
const clearIntervalFn = getClearInterval();
|
|
69
|
+
clearIntervalFn === null || clearIntervalFn === void 0 ? void 0 : clearIntervalFn(this._handle);
|
|
70
|
+
this._handle = null;
|
|
71
|
+
}
|
|
72
|
+
this._emitter = null;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type CCMPPlayersManager } from "../../../entities/ccmp/player/CCMPPlayersManager";
|
|
2
|
+
import { type CCMPEventsManager } from "./CCMPEventsManager";
|
|
3
|
+
/**
|
|
4
|
+
* Переводит нативное CCMP-событие `streamSyncedMetaChange` в internal-bus
|
|
5
|
+
* `rm::syncedMetaChange`.
|
|
6
|
+
*
|
|
7
|
+
* Вынесено в отдельный класс от `CCMPEventsBridge` из-за порядка
|
|
8
|
+
* инстанцирования: bridge'у нужна ссылка на `CCMPPlayersManager` чтобы
|
|
9
|
+
* резолвить `payload.entityId → CCMPPlayer`, а players manager создаётся
|
|
10
|
+
* в `CCMPManagersFactory` **после** `CCMPNetManager` (внутри которого
|
|
11
|
+
* живёт `CCMPEventsBridge`). Поэтому этот bridge создаётся вторым
|
|
12
|
+
* шагом из `createPlayersManager`, когда обе зависимости уже доступны.
|
|
13
|
+
*
|
|
14
|
+
* Сейчас обслуживается только `entityType === Player` (=0) — на клиенте
|
|
15
|
+
* rock-mod-CCMP других сущностей пока нет. Остальные типы тихо
|
|
16
|
+
* игнорируем (snapshot прилетает на каждом stream-in, для несуществующих
|
|
17
|
+
* на клиенте сущностей это нормально).
|
|
18
|
+
*/
|
|
19
|
+
export declare class CCMPSyncedMetaBridge {
|
|
20
|
+
private readonly _events;
|
|
21
|
+
private readonly _playersManager;
|
|
22
|
+
constructor(events: CCMPEventsManager, playersManager: CCMPPlayersManager);
|
|
23
|
+
register(): void;
|
|
24
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { ClientInternalEventName } from "../../common/events/types";
|
|
2
|
+
/**
|
|
3
|
+
* Переводит нативное CCMP-событие `streamSyncedMetaChange` в internal-bus
|
|
4
|
+
* `rm::syncedMetaChange`.
|
|
5
|
+
*
|
|
6
|
+
* Вынесено в отдельный класс от `CCMPEventsBridge` из-за порядка
|
|
7
|
+
* инстанцирования: bridge'у нужна ссылка на `CCMPPlayersManager` чтобы
|
|
8
|
+
* резолвить `payload.entityId → CCMPPlayer`, а players manager создаётся
|
|
9
|
+
* в `CCMPManagersFactory` **после** `CCMPNetManager` (внутри которого
|
|
10
|
+
* живёт `CCMPEventsBridge`). Поэтому этот bridge создаётся вторым
|
|
11
|
+
* шагом из `createPlayersManager`, когда обе зависимости уже доступны.
|
|
12
|
+
*
|
|
13
|
+
* Сейчас обслуживается только `entityType === Player` (=0) — на клиенте
|
|
14
|
+
* rock-mod-CCMP других сущностей пока нет. Остальные типы тихо
|
|
15
|
+
* игнорируем (snapshot прилетает на каждом stream-in, для несуществующих
|
|
16
|
+
* на клиенте сущностей это нормально).
|
|
17
|
+
*/
|
|
18
|
+
export class CCMPSyncedMetaBridge {
|
|
19
|
+
constructor(events, playersManager) {
|
|
20
|
+
this._events = events;
|
|
21
|
+
this._playersManager = playersManager;
|
|
22
|
+
}
|
|
23
|
+
register() {
|
|
24
|
+
ccmp.on("streamSyncedMetaChange", (payload) => {
|
|
25
|
+
if (payload.entityType !== ccmp.entities.ENTITY_TYPE.Player) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const player = this._playersManager.findByRemoteId(payload.entityId);
|
|
29
|
+
if (!player) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
this._events.emitInternal(ClientInternalEventName.SyncedMetaChange, player, payload.key, payload.newValue, payload.oldValue);
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type IRPCManager } from "../../common/rpc/IRPCManager";
|
|
2
|
+
import { type IClientRPCList, type IServerRPCList } from "../../../../shared/net/common/rpc/types";
|
|
3
|
+
type UIHandler = (...args: unknown[]) => unknown;
|
|
4
|
+
/**
|
|
5
|
+
* CCMP implementation of the rock-mod client RPC registry.
|
|
6
|
+
*
|
|
7
|
+
* The current gamemod routes UI RPC through the event bridge:
|
|
8
|
+
* `window.ccmp.emitClient(...)` -> `ccmp.on(...)` -> NetworkRPCService.
|
|
9
|
+
* `register` therefore keeps the same public contract as RageMP's
|
|
10
|
+
* `mp.events.addProc` without emitting noisy startup warnings.
|
|
11
|
+
*
|
|
12
|
+
* Native client->server RPC is still intentionally unsupported here. The
|
|
13
|
+
* gamemod uses its correlation-id protocol over `net.events` for that path.
|
|
14
|
+
*/
|
|
15
|
+
export declare class CCMPRPCManager implements IRPCManager {
|
|
16
|
+
private readonly _uiHandlers;
|
|
17
|
+
register<K extends keyof IClientRPCList>(rpcName: K, handler: (...args: Parameters<IClientRPCList[K]>) => ReturnType<IClientRPCList[K]>): void;
|
|
18
|
+
unregister<K extends keyof IClientRPCList>(rpcName: K): void;
|
|
19
|
+
emitServer<K extends keyof IServerRPCList>(rpcName: K, ...args: Parameters<IServerRPCList[K]>): Promise<ReturnType<IServerRPCList[K]>>;
|
|
20
|
+
getHandler(name: string): UIHandler | undefined;
|
|
21
|
+
}
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CCMP implementation of the rock-mod client RPC registry.
|
|
3
|
+
*
|
|
4
|
+
* The current gamemod routes UI RPC through the event bridge:
|
|
5
|
+
* `window.ccmp.emitClient(...)` -> `ccmp.on(...)` -> NetworkRPCService.
|
|
6
|
+
* `register` therefore keeps the same public contract as RageMP's
|
|
7
|
+
* `mp.events.addProc` without emitting noisy startup warnings.
|
|
8
|
+
*
|
|
9
|
+
* Native client->server RPC is still intentionally unsupported here. The
|
|
10
|
+
* gamemod uses its correlation-id protocol over `net.events` for that path.
|
|
11
|
+
*/
|
|
12
|
+
export class CCMPRPCManager {
|
|
13
|
+
constructor() {
|
|
14
|
+
this._uiHandlers = new Map();
|
|
15
|
+
}
|
|
16
|
+
register(rpcName, handler) {
|
|
17
|
+
this._uiHandlers.set(String(rpcName), handler);
|
|
18
|
+
}
|
|
19
|
+
unregister(rpcName) {
|
|
20
|
+
this._uiHandlers.delete(String(rpcName));
|
|
21
|
+
}
|
|
22
|
+
emitServer(rpcName, ...args) {
|
|
23
|
+
void args;
|
|
24
|
+
return Promise.reject(new Error(`CCMPRPCManager.emitServer(${String(rpcName)}): native client→server ` +
|
|
25
|
+
`RPC не реализован под CCMP. Используй net.events с собственным ` +
|
|
26
|
+
`correlationId-протоколом (как делает rock-mod-rpc-caller.adapter).`));
|
|
27
|
+
}
|
|
28
|
+
getHandler(name) {
|
|
29
|
+
return this._uiHandlers.get(name);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -15,7 +15,8 @@ export declare enum ClientInternalEventName {
|
|
|
15
15
|
PlayerSpawn = "rm::playerSpawn",
|
|
16
16
|
PlayerWeaponShot = "rm::playerWeaponShot",
|
|
17
17
|
Render = "rm::render",
|
|
18
|
-
Click = "rm::click"
|
|
18
|
+
Click = "rm::click",
|
|
19
|
+
SyncedMetaChange = "rm::syncedMetaChange"
|
|
19
20
|
}
|
|
20
21
|
export interface IClickOptions {
|
|
21
22
|
absoluteX: number;
|
|
@@ -43,4 +44,5 @@ export interface IClientInternalEvents {
|
|
|
43
44
|
[ClientInternalEventName.PlayerWeaponShot]: () => void;
|
|
44
45
|
[ClientInternalEventName.Render]: () => void;
|
|
45
46
|
[ClientInternalEventName.Click]: (options: IClickOptions) => void;
|
|
47
|
+
[ClientInternalEventName.SyncedMetaChange]: (entity: IEntity, key: string, value: unknown, oldValue: unknown) => void;
|
|
46
48
|
}
|
|
@@ -15,4 +15,5 @@ export var ClientInternalEventName;
|
|
|
15
15
|
ClientInternalEventName["PlayerWeaponShot"] = "rm::playerWeaponShot";
|
|
16
16
|
ClientInternalEventName["Render"] = "rm::render";
|
|
17
17
|
ClientInternalEventName["Click"] = "rm::click";
|
|
18
|
+
ClientInternalEventName["SyncedMetaChange"] = "rm::syncedMetaChange";
|
|
18
19
|
})(ClientInternalEventName || (ClientInternalEventName = {}));
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type IUtilsManager } from "../common/IUtilsManager";
|
|
2
|
+
/**
|
|
3
|
+
* Реализация `IUtilsManager` под CCMP.
|
|
4
|
+
*
|
|
5
|
+
* `hash(value)` — обёртка вокруг `ccmp.natives.misc.getHashKey(value)`,
|
|
6
|
+
* который вызывает GTA V натив `GET_HASH_KEY` (joaat). Алгоритм идентичен
|
|
7
|
+
* RageMP'шному `mp.game.joaat(value)`, так что результат бит-в-бит совпадает —
|
|
8
|
+
* хеши моделей/нативов из shared-кода (`@shared/common/enums/Model`,
|
|
9
|
+
* `WeaponHash.*`, etc.) валидны в обеих интеграциях.
|
|
10
|
+
*
|
|
11
|
+
* **Hot path:** `hash(weaponName)` вызывается каждый render-tick из
|
|
12
|
+
* `WeaponAmmoDisplayService.renderAmmo` для резолва hash'а текущего оружия.
|
|
13
|
+
* Это синхронный V8-op без аллокаций, стоимость — единицы микросекунд. JS-side
|
|
14
|
+
* кешировать не нужно: натив сам кеширует на стороне Rust-рантайма.
|
|
15
|
+
*/
|
|
16
|
+
export declare class CCMPUtilsManager implements IUtilsManager {
|
|
17
|
+
hash(value: string): number;
|
|
18
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/// <reference types="@classic-mp/types/client" />
|
|
2
|
+
/**
|
|
3
|
+
* Реализация `IUtilsManager` под CCMP.
|
|
4
|
+
*
|
|
5
|
+
* `hash(value)` — обёртка вокруг `ccmp.natives.misc.getHashKey(value)`,
|
|
6
|
+
* который вызывает GTA V натив `GET_HASH_KEY` (joaat). Алгоритм идентичен
|
|
7
|
+
* RageMP'шному `mp.game.joaat(value)`, так что результат бит-в-бит совпадает —
|
|
8
|
+
* хеши моделей/нативов из shared-кода (`@shared/common/enums/Model`,
|
|
9
|
+
* `WeaponHash.*`, etc.) валидны в обеих интеграциях.
|
|
10
|
+
*
|
|
11
|
+
* **Hot path:** `hash(weaponName)` вызывается каждый render-tick из
|
|
12
|
+
* `WeaponAmmoDisplayService.renderAmmo` для резолва hash'а текущего оружия.
|
|
13
|
+
* Это синхронный V8-op без аллокаций, стоимость — единицы микросекунд. JS-side
|
|
14
|
+
* кешировать не нужно: натив сам кеширует на стороне Rust-рантайма.
|
|
15
|
+
*/
|
|
16
|
+
export class CCMPUtilsManager {
|
|
17
|
+
hash(value) {
|
|
18
|
+
return ccmp.natives.misc.getHashKey(value);
|
|
19
|
+
}
|
|
20
|
+
}
|
package/dist/server/RockMod.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { type IBlipsManager, type IColshapesManager, type IMarkersManager, type
|
|
|
3
3
|
import { type IUtilsManager } from "./utils";
|
|
4
4
|
import { type IManagersFactory } from "./factories/common/IManagersFactory";
|
|
5
5
|
import { type IWorldManager } from "./world";
|
|
6
|
-
type MultiplayerType = "RageMP" | "AltV" | "Mock";
|
|
6
|
+
type MultiplayerType = "RageMP" | "AltV" | "Mock" | "CCMP";
|
|
7
7
|
export interface RockModOptions {
|
|
8
8
|
multiplayer: MultiplayerType;
|
|
9
9
|
}
|
package/dist/server/RockMod.js
CHANGED
|
@@ -55,6 +55,10 @@ class RockMod {
|
|
|
55
55
|
const { MockManagersFactory } = await Promise.resolve().then(() => __importStar(require("./factories/mock/MockManagersFactory")));
|
|
56
56
|
return new MockManagersFactory();
|
|
57
57
|
}
|
|
58
|
+
case "CCMP": {
|
|
59
|
+
const { CCMPManagersFactory } = await Promise.resolve().then(() => __importStar(require("./factories/ccmp/CCMPManagersFactory")));
|
|
60
|
+
return new CCMPManagersFactory();
|
|
61
|
+
}
|
|
58
62
|
}
|
|
59
63
|
}
|
|
60
64
|
_net;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type IBaseObject } from "../../common/baseObject/IBaseObject";
|
|
2
|
+
import { type BaseObjectType } from "../../../../shared";
|
|
3
|
+
export declare abstract class CCMPBaseObject implements IBaseObject {
|
|
4
|
+
get id(): number;
|
|
5
|
+
get type(): BaseObjectType;
|
|
6
|
+
get isExists(): boolean;
|
|
7
|
+
destroy(): void;
|
|
8
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CCMPBaseObject = void 0;
|
|
4
|
+
const notImplemented = (name) => {
|
|
5
|
+
throw new Error(`Not implemented yet: ${name}`);
|
|
6
|
+
};
|
|
7
|
+
class CCMPBaseObject {
|
|
8
|
+
get id() {
|
|
9
|
+
return notImplemented("CCMPBaseObject.id");
|
|
10
|
+
}
|
|
11
|
+
get type() {
|
|
12
|
+
return notImplemented("CCMPBaseObject.type");
|
|
13
|
+
}
|
|
14
|
+
get isExists() {
|
|
15
|
+
return notImplemented("CCMPBaseObject.isExists");
|
|
16
|
+
}
|
|
17
|
+
destroy() {
|
|
18
|
+
notImplemented("CCMPBaseObject.destroy");
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
exports.CCMPBaseObject = CCMPBaseObject;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type IBaseObjectsIterator } from "../../common/baseObject/IBaseObjectsIterator";
|
|
2
|
+
import { type CCMPBaseObject } from "./CCMPBaseObject";
|
|
3
|
+
export declare class CCMPBaseObjectsIterator<T extends CCMPBaseObject> implements IBaseObjectsIterator<T> {
|
|
4
|
+
private readonly _baseObjects;
|
|
5
|
+
constructor(baseObjects: ReadonlyMap<number, T>);
|
|
6
|
+
protected get baseObjects(): ReadonlyMap<number, T>;
|
|
7
|
+
all(): IterableIterator<T>;
|
|
8
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CCMPBaseObjectsIterator = void 0;
|
|
4
|
+
class CCMPBaseObjectsIterator {
|
|
5
|
+
_baseObjects;
|
|
6
|
+
constructor(baseObjects) {
|
|
7
|
+
this._baseObjects = baseObjects;
|
|
8
|
+
}
|
|
9
|
+
get baseObjects() {
|
|
10
|
+
return this._baseObjects;
|
|
11
|
+
}
|
|
12
|
+
all() {
|
|
13
|
+
return this._baseObjects.values();
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
exports.CCMPBaseObjectsIterator = CCMPBaseObjectsIterator;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type IBaseObjectsManager, type IBaseObjectsManagerOptions } from "../../common/baseObject/IBaseObjectsManager";
|
|
2
|
+
import { type CCMPBaseObject } from "./CCMPBaseObject";
|
|
3
|
+
import { CCMPBaseObjectsIterator } from "./CCMPBaseObjectsIterator";
|
|
4
|
+
import { type BaseObjectType } from "../../../../shared";
|
|
5
|
+
export interface ICCMPBaseObjectsManagerOptions extends IBaseObjectsManagerOptions {
|
|
6
|
+
}
|
|
7
|
+
export declare abstract class CCMPBaseObjectsManager<T extends CCMPBaseObject> implements IBaseObjectsManager<T> {
|
|
8
|
+
private readonly _baseObjects;
|
|
9
|
+
private readonly _baseObjectsType;
|
|
10
|
+
protected readonly _iterator: CCMPBaseObjectsIterator<T>;
|
|
11
|
+
protected get baseObjects(): ReadonlyMap<number, T>;
|
|
12
|
+
protected get baseObjectsType(): `${BaseObjectType}`;
|
|
13
|
+
get iterator(): CCMPBaseObjectsIterator<T>;
|
|
14
|
+
protected constructor(options: ICCMPBaseObjectsManagerOptions);
|
|
15
|
+
getByID(id: number): T;
|
|
16
|
+
findByID(id: number): T | null;
|
|
17
|
+
protected registerBaseObject(baseObject: T): void;
|
|
18
|
+
protected unregisterBaseObject(baseObject: T): void;
|
|
19
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CCMPBaseObjectsManager = void 0;
|
|
4
|
+
const CCMPBaseObjectsIterator_1 = require("./CCMPBaseObjectsIterator");
|
|
5
|
+
class CCMPBaseObjectsManager {
|
|
6
|
+
_baseObjects;
|
|
7
|
+
_baseObjectsType;
|
|
8
|
+
_iterator;
|
|
9
|
+
get baseObjects() {
|
|
10
|
+
return this._baseObjects;
|
|
11
|
+
}
|
|
12
|
+
get baseObjectsType() {
|
|
13
|
+
return this._baseObjectsType;
|
|
14
|
+
}
|
|
15
|
+
get iterator() {
|
|
16
|
+
return this._iterator;
|
|
17
|
+
}
|
|
18
|
+
constructor(options) {
|
|
19
|
+
this._baseObjects = new Map();
|
|
20
|
+
this._baseObjectsType = options.baseObjectsType;
|
|
21
|
+
this._iterator = new CCMPBaseObjectsIterator_1.CCMPBaseObjectsIterator(this._baseObjects);
|
|
22
|
+
}
|
|
23
|
+
getByID(id) {
|
|
24
|
+
const baseObject = this.findByID(id);
|
|
25
|
+
if (!baseObject) {
|
|
26
|
+
throw new Error(`BaseObject [${this._baseObjectsType}] with id ${id} not found`);
|
|
27
|
+
}
|
|
28
|
+
return baseObject;
|
|
29
|
+
}
|
|
30
|
+
findByID(id) {
|
|
31
|
+
return this._baseObjects.get(id) ?? null;
|
|
32
|
+
}
|
|
33
|
+
registerBaseObject(baseObject) {
|
|
34
|
+
if (this._baseObjects.has(baseObject.id)) {
|
|
35
|
+
throw new Error(`BaseObject [${this._baseObjectsType}] with id ${baseObject.id} already exists`);
|
|
36
|
+
}
|
|
37
|
+
this._baseObjects.set(baseObject.id, baseObject);
|
|
38
|
+
// TODO: emit ServerInternalEventName.EntityCreated and broadcast EntityCreated DTO
|
|
39
|
+
// through net.events once CCMPEventsManager is implemented (parity with RageBaseObjectsManager).
|
|
40
|
+
}
|
|
41
|
+
unregisterBaseObject(baseObject) {
|
|
42
|
+
if (!this._baseObjects.delete(baseObject.id)) {
|
|
43
|
+
throw new Error(`BaseObject [${this._baseObjectsType}] with id ${baseObject.id} not found`);
|
|
44
|
+
}
|
|
45
|
+
// TODO: emit ServerInternalEventName.EntityDestroyed and broadcast EntityDestroyed DTO
|
|
46
|
+
// through net.events once CCMPEventsManager is implemented.
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
exports.CCMPBaseObjectsManager = CCMPBaseObjectsManager;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { CCMPWorldObject } from "../worldObject/CCMPWorldObject";
|
|
2
|
+
import { type IBlip } from "../../common/blip/IBlip";
|
|
3
|
+
import { BaseObjectType, type IBlipColor, type IBlipSprite } from "../../../../shared";
|
|
4
|
+
import { type IVector3D } from "../../../../shared/common/utils/math/Vectors";
|
|
5
|
+
import type { Blip as CcmpBlip } from "@classic-mp/types/server";
|
|
6
|
+
export interface ICCMPBlipOptions {
|
|
7
|
+
ccmpBlip: CcmpBlip;
|
|
8
|
+
onDestroy: (blip: CCMPBlip) => void;
|
|
9
|
+
}
|
|
10
|
+
export declare class CCMPBlip extends CCMPWorldObject implements IBlip {
|
|
11
|
+
private readonly _ccmpBlip;
|
|
12
|
+
private readonly _onDestroy;
|
|
13
|
+
get id(): number;
|
|
14
|
+
get type(): BaseObjectType;
|
|
15
|
+
get isExists(): boolean;
|
|
16
|
+
get position(): IVector3D;
|
|
17
|
+
get dimension(): number;
|
|
18
|
+
get name(): string;
|
|
19
|
+
get sprite(): IBlipSprite;
|
|
20
|
+
get color(): number;
|
|
21
|
+
get alpha(): number;
|
|
22
|
+
get scale(): number;
|
|
23
|
+
get drawDistance(): number;
|
|
24
|
+
get shortRange(): boolean;
|
|
25
|
+
get rotation(): number;
|
|
26
|
+
constructor(options: ICCMPBlipOptions);
|
|
27
|
+
destroy(): void;
|
|
28
|
+
setPosition(value: IVector3D): void;
|
|
29
|
+
setDimension(value: number): void;
|
|
30
|
+
setName(value: string): void;
|
|
31
|
+
setSprite(value: IBlipSprite): void;
|
|
32
|
+
setColor(value: IBlipColor): void;
|
|
33
|
+
setAlpha(value: number): void;
|
|
34
|
+
}
|