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,41 @@
|
|
|
1
|
+
import { type IKeysManager } from "../../common/keys/IKeysManager";
|
|
2
|
+
type KeyHandler = () => void;
|
|
3
|
+
/**
|
|
4
|
+
* Реализация `IKeysManager` поверх нативных CCMP-событий `keyDown`/`keyUp`.
|
|
5
|
+
*
|
|
6
|
+
* Контрактные тонкости (зеркало RageMP `mp.keys.bind`):
|
|
7
|
+
* - `keyHold = false` → handler срабатывает на **нажатие** (`keyDown`).
|
|
8
|
+
* - `keyHold = true` → handler срабатывает на **отпускание** (`keyUp`).
|
|
9
|
+
* Несмотря на название параметра, это НЕ "только когда зажато",
|
|
10
|
+
* это "при отпускании после нажатия". См. RageMP wiki.
|
|
11
|
+
*
|
|
12
|
+
* Архитектура:
|
|
13
|
+
* - Делаем **одну** глобальную подписку на `ccmp.on('keyDown')` и одну
|
|
14
|
+
* на `keyUp` в конструкторе. Дальше сами роутим по `key`-коду через
|
|
15
|
+
* `Map<key, { down: Set, up: Set }>`. Это намного эффективнее, чем
|
|
16
|
+
* регистрировать новый `ccmp.on` на каждый `bind`, и убирает проблему
|
|
17
|
+
* отсутствующего у CCMP `ccmp.off` (наш dispatcher остаётся в силе,
|
|
18
|
+
* меняется только содержимое внутреннего реестра).
|
|
19
|
+
* - Параллельно ведём `_pressedKeys: Set<number>` — текущее состояние,
|
|
20
|
+
* чтобы `isDown`/`isUp` отвечали синхронно (у CCMP нет API запроса
|
|
21
|
+
* состояния клавиши).
|
|
22
|
+
*
|
|
23
|
+
* Auto-repeat: если CCMP-клиент эмитит `keyDown` повторно при удержании
|
|
24
|
+
* (как WM_KEYDOWN auto-repeat), то и наши `down`-handler'ы будут срабатывать
|
|
25
|
+
* повторно — это зеркало RageMP-поведения. Не маскируем намеренно: gamemod-
|
|
26
|
+
* консьюмеры писались под такую семантику.
|
|
27
|
+
*
|
|
28
|
+
* Snapshot при диспатче (`[...binding.down]`) защищает от модификации Set
|
|
29
|
+
* из handler'а — `bind`/`unbind` внутри callback'а не ломают текущую итерацию.
|
|
30
|
+
*/
|
|
31
|
+
export declare class CCMPKeysManager implements IKeysManager {
|
|
32
|
+
private readonly _pressedKeys;
|
|
33
|
+
private readonly _bindings;
|
|
34
|
+
constructor();
|
|
35
|
+
isDown(key: number): boolean;
|
|
36
|
+
isUp(key: number): boolean;
|
|
37
|
+
bind(key: number, keyHold: boolean, handler: KeyHandler): void;
|
|
38
|
+
unbind(key: number, keyHold: boolean, handler?: KeyHandler): void;
|
|
39
|
+
private _dispatch;
|
|
40
|
+
}
|
|
41
|
+
export {};
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/// <reference types="@classic-mp/types/client" />
|
|
2
|
+
/**
|
|
3
|
+
* Реализация `IKeysManager` поверх нативных CCMP-событий `keyDown`/`keyUp`.
|
|
4
|
+
*
|
|
5
|
+
* Контрактные тонкости (зеркало RageMP `mp.keys.bind`):
|
|
6
|
+
* - `keyHold = false` → handler срабатывает на **нажатие** (`keyDown`).
|
|
7
|
+
* - `keyHold = true` → handler срабатывает на **отпускание** (`keyUp`).
|
|
8
|
+
* Несмотря на название параметра, это НЕ "только когда зажато",
|
|
9
|
+
* это "при отпускании после нажатия". См. RageMP wiki.
|
|
10
|
+
*
|
|
11
|
+
* Архитектура:
|
|
12
|
+
* - Делаем **одну** глобальную подписку на `ccmp.on('keyDown')` и одну
|
|
13
|
+
* на `keyUp` в конструкторе. Дальше сами роутим по `key`-коду через
|
|
14
|
+
* `Map<key, { down: Set, up: Set }>`. Это намного эффективнее, чем
|
|
15
|
+
* регистрировать новый `ccmp.on` на каждый `bind`, и убирает проблему
|
|
16
|
+
* отсутствующего у CCMP `ccmp.off` (наш dispatcher остаётся в силе,
|
|
17
|
+
* меняется только содержимое внутреннего реестра).
|
|
18
|
+
* - Параллельно ведём `_pressedKeys: Set<number>` — текущее состояние,
|
|
19
|
+
* чтобы `isDown`/`isUp` отвечали синхронно (у CCMP нет API запроса
|
|
20
|
+
* состояния клавиши).
|
|
21
|
+
*
|
|
22
|
+
* Auto-repeat: если CCMP-клиент эмитит `keyDown` повторно при удержании
|
|
23
|
+
* (как WM_KEYDOWN auto-repeat), то и наши `down`-handler'ы будут срабатывать
|
|
24
|
+
* повторно — это зеркало RageMP-поведения. Не маскируем намеренно: gamemod-
|
|
25
|
+
* консьюмеры писались под такую семантику.
|
|
26
|
+
*
|
|
27
|
+
* Snapshot при диспатче (`[...binding.down]`) защищает от модификации Set
|
|
28
|
+
* из handler'а — `bind`/`unbind` внутри callback'а не ломают текущую итерацию.
|
|
29
|
+
*/
|
|
30
|
+
export class CCMPKeysManager {
|
|
31
|
+
constructor() {
|
|
32
|
+
this._pressedKeys = new Set();
|
|
33
|
+
this._bindings = new Map();
|
|
34
|
+
ccmp.on("keyDown", (key) => {
|
|
35
|
+
this._pressedKeys.add(key);
|
|
36
|
+
this._dispatch(key, "down");
|
|
37
|
+
});
|
|
38
|
+
ccmp.on("keyUp", (key) => {
|
|
39
|
+
this._pressedKeys.delete(key);
|
|
40
|
+
this._dispatch(key, "up");
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
isDown(key) {
|
|
44
|
+
return this._pressedKeys.has(key);
|
|
45
|
+
}
|
|
46
|
+
isUp(key) {
|
|
47
|
+
return !this._pressedKeys.has(key);
|
|
48
|
+
}
|
|
49
|
+
bind(key, keyHold, handler) {
|
|
50
|
+
let binding = this._bindings.get(key);
|
|
51
|
+
if (!binding) {
|
|
52
|
+
binding = { down: new Set(), up: new Set() };
|
|
53
|
+
this._bindings.set(key, binding);
|
|
54
|
+
}
|
|
55
|
+
(keyHold ? binding.up : binding.down).add(handler);
|
|
56
|
+
}
|
|
57
|
+
unbind(key, keyHold, handler) {
|
|
58
|
+
const binding = this._bindings.get(key);
|
|
59
|
+
if (!binding) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
const set = keyHold ? binding.up : binding.down;
|
|
63
|
+
if (handler === undefined) {
|
|
64
|
+
// RageMP-семантика: без handler — удаляем все подписки на (key, keyHold).
|
|
65
|
+
set.clear();
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
set.delete(handler);
|
|
69
|
+
}
|
|
70
|
+
if (binding.down.size === 0 && binding.up.size === 0) {
|
|
71
|
+
this._bindings.delete(key);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
_dispatch(key, phase) {
|
|
75
|
+
const binding = this._bindings.get(key);
|
|
76
|
+
if (!binding) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
const handlers = phase === "down" ? binding.down : binding.up;
|
|
80
|
+
if (handlers.size === 0) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
// Snapshot: handler может вызвать bind/unbind, мы не должны ломать
|
|
84
|
+
// итерацию по Set.
|
|
85
|
+
for (const handler of [...handlers]) {
|
|
86
|
+
try {
|
|
87
|
+
handler();
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
console.error(`[CCMPKeysManager] ${phase}-handler for key ${key} threw:`, error);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { type INativeCallerManager } from "../../common/native/INativeCallerManager";
|
|
2
|
+
/**
|
|
3
|
+
* Реализация `INativeCallerManager` под CCMP — полноценный generic dispatch
|
|
4
|
+
* GTA V-нативов по hex-хэшу.
|
|
5
|
+
*
|
|
6
|
+
* ### Архитектура
|
|
7
|
+
*
|
|
8
|
+
* **Таблица hash→method** генерируется на build-time скриптом
|
|
9
|
+
* `scripts/generate-native-dispatch.mjs` из alloc8or-format nativedb
|
|
10
|
+
* (`scripts/data/natives.json`, ~6649 натов). Output:
|
|
11
|
+
* `_generated/nativeDispatch.ts`. Каждая запись — `{ns: "<ccmp-namespace>",
|
|
12
|
+
* methods: ["<camelMethod1>", "<camelMethod2-fallback>"]}`, где `methods[]`
|
|
13
|
+
* содержит канонический имя натива + все `old_names` алиасы (нужно потому
|
|
14
|
+
* что CCMP-биндинги могут использовать либо новое каноническое, либо
|
|
15
|
+
* легаси-имя в зависимости от момента генерации `@classic-mp/types`).
|
|
16
|
+
*
|
|
17
|
+
* **Runtime resolve**: при первом вызове `callNative(hash, ...args)`:
|
|
18
|
+
* 1. Lookup в `NATIVE_DISPATCH[hash.toLowerCase()]` → `{ns, methods[]}`.
|
|
19
|
+
* 2. `ccmp.natives[ns]` — берём namespace-объект.
|
|
20
|
+
* 3. Перебираем `methods[]` в порядке: для первой существующей функции —
|
|
21
|
+
* биндим `[nsObj, fn]` в `_resolved` кэш.
|
|
22
|
+
* 4. Зовём с args через `fn.apply(nsObj, args)`.
|
|
23
|
+
* 5. Адаптируем return-shape (см. ниже).
|
|
24
|
+
*
|
|
25
|
+
* Lookup-кэш `_resolved` — Map с hash-ключом, чтобы не дёргать
|
|
26
|
+
* `NATIVE_DISPATCH[]` + `_resolve()` на каждый вызов (multiple natives
|
|
27
|
+
* вызываются на каждый render-tick).
|
|
28
|
+
*
|
|
29
|
+
* ### Адаптация return-shape (CCMP → RageMP-конвенция)
|
|
30
|
+
*
|
|
31
|
+
* CCMP-нативы для multi-return значений возвращают **объект** с именованными
|
|
32
|
+
* полями (например, `getGameplayCamCoord()` → `{x, y, z}`). Геймод (написанный
|
|
33
|
+
* под RageMP-конвенцию) ожидает **массив-кортеж** (`[x, y, z]`).
|
|
34
|
+
*
|
|
35
|
+
* Generic `_adaptResult`:
|
|
36
|
+
* - `boolean` (top-level) → `0` или `1` (RageMP'шный native-bool протокол:
|
|
37
|
+
* `mp.game.invoke(boolNative)` возвращает число).
|
|
38
|
+
* - Object с string-keys → `Object.values(obj)` (порядок гарантирован ES2015
|
|
39
|
+
* insertion-order для non-integer keys; CCMP-типы декларируют поля в
|
|
40
|
+
* каноническом порядке).
|
|
41
|
+
* - Nested object внутри tuple → рекурсивно тоже `Object.values()`
|
|
42
|
+
* (для нативов вроде `getShapeTestResult` с nested `endcoords: {x,y,z}`).
|
|
43
|
+
* - Bool **внутри** объекта/tuple → не конвертим (нужен для tuple-полей
|
|
44
|
+
* типа `[bool, x, y]` где геймод-тип честно ожидает boolean).
|
|
45
|
+
* - Primitives / arrays / null → passthrough.
|
|
46
|
+
*
|
|
47
|
+
* ### Hot path
|
|
48
|
+
*
|
|
49
|
+
* `callNative` вызывается из render-tick consumer'ов: `HudController`
|
|
50
|
+
* (drawBlip), `CameraIdleController.onInterval`, `VehicleIndicatorService`,
|
|
51
|
+
* `PolygonZoneRenderer`, `ScriptedMarker`, `ConeDebugRenderer`. После прогрева
|
|
52
|
+
* `_resolved`-кэша — один Map.get + `fn.apply` + adapt-проход. Адапт — линейный
|
|
53
|
+
* по числу полей возврата (обычно ≤ 5), стоимость незначительная.
|
|
54
|
+
*
|
|
55
|
+
* ### Ошибки
|
|
56
|
+
*
|
|
57
|
+
* - **Hash не в DB**: натив отсутствует в nativedb. Throws с подсказкой
|
|
58
|
+
* "обновите scripts/data/natives.json" — обычно случается для свежих
|
|
59
|
+
* build-specific натов, не вошедших в last-snapshot базы.
|
|
60
|
+
* - **Namespace не в `ccmp.natives`**: CCMP-runtime версия не имеет такого
|
|
61
|
+
* namespace'а. Throws с указанием ns.
|
|
62
|
+
* - **Все method-кандидаты отсутствуют в namespace'е**: CCMP-биндинг не
|
|
63
|
+
* экспонирует ни одного из known-имён. Throws с перечислением кандидатов.
|
|
64
|
+
*/
|
|
65
|
+
export declare class CCMPNativeCallerManager implements INativeCallerManager {
|
|
66
|
+
private readonly _resolved;
|
|
67
|
+
callNative(hash: string, ...args: unknown[]): unknown;
|
|
68
|
+
private _resolve;
|
|
69
|
+
/**
|
|
70
|
+
* Конвертация CCMP object-return → RageMP tuple-return.
|
|
71
|
+
* См. block-комментарий класса (Адаптация return-shape).
|
|
72
|
+
*/
|
|
73
|
+
private static _adaptResult;
|
|
74
|
+
}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/// <reference types="@classic-mp/types/client" />
|
|
2
|
+
import { NATIVE_DISPATCH } from "./_generated/nativeDispatch";
|
|
3
|
+
/**
|
|
4
|
+
* Реализация `INativeCallerManager` под CCMP — полноценный generic dispatch
|
|
5
|
+
* GTA V-нативов по hex-хэшу.
|
|
6
|
+
*
|
|
7
|
+
* ### Архитектура
|
|
8
|
+
*
|
|
9
|
+
* **Таблица hash→method** генерируется на build-time скриптом
|
|
10
|
+
* `scripts/generate-native-dispatch.mjs` из alloc8or-format nativedb
|
|
11
|
+
* (`scripts/data/natives.json`, ~6649 натов). Output:
|
|
12
|
+
* `_generated/nativeDispatch.ts`. Каждая запись — `{ns: "<ccmp-namespace>",
|
|
13
|
+
* methods: ["<camelMethod1>", "<camelMethod2-fallback>"]}`, где `methods[]`
|
|
14
|
+
* содержит канонический имя натива + все `old_names` алиасы (нужно потому
|
|
15
|
+
* что CCMP-биндинги могут использовать либо новое каноническое, либо
|
|
16
|
+
* легаси-имя в зависимости от момента генерации `@classic-mp/types`).
|
|
17
|
+
*
|
|
18
|
+
* **Runtime resolve**: при первом вызове `callNative(hash, ...args)`:
|
|
19
|
+
* 1. Lookup в `NATIVE_DISPATCH[hash.toLowerCase()]` → `{ns, methods[]}`.
|
|
20
|
+
* 2. `ccmp.natives[ns]` — берём namespace-объект.
|
|
21
|
+
* 3. Перебираем `methods[]` в порядке: для первой существующей функции —
|
|
22
|
+
* биндим `[nsObj, fn]` в `_resolved` кэш.
|
|
23
|
+
* 4. Зовём с args через `fn.apply(nsObj, args)`.
|
|
24
|
+
* 5. Адаптируем return-shape (см. ниже).
|
|
25
|
+
*
|
|
26
|
+
* Lookup-кэш `_resolved` — Map с hash-ключом, чтобы не дёргать
|
|
27
|
+
* `NATIVE_DISPATCH[]` + `_resolve()` на каждый вызов (multiple natives
|
|
28
|
+
* вызываются на каждый render-tick).
|
|
29
|
+
*
|
|
30
|
+
* ### Адаптация return-shape (CCMP → RageMP-конвенция)
|
|
31
|
+
*
|
|
32
|
+
* CCMP-нативы для multi-return значений возвращают **объект** с именованными
|
|
33
|
+
* полями (например, `getGameplayCamCoord()` → `{x, y, z}`). Геймод (написанный
|
|
34
|
+
* под RageMP-конвенцию) ожидает **массив-кортеж** (`[x, y, z]`).
|
|
35
|
+
*
|
|
36
|
+
* Generic `_adaptResult`:
|
|
37
|
+
* - `boolean` (top-level) → `0` или `1` (RageMP'шный native-bool протокол:
|
|
38
|
+
* `mp.game.invoke(boolNative)` возвращает число).
|
|
39
|
+
* - Object с string-keys → `Object.values(obj)` (порядок гарантирован ES2015
|
|
40
|
+
* insertion-order для non-integer keys; CCMP-типы декларируют поля в
|
|
41
|
+
* каноническом порядке).
|
|
42
|
+
* - Nested object внутри tuple → рекурсивно тоже `Object.values()`
|
|
43
|
+
* (для нативов вроде `getShapeTestResult` с nested `endcoords: {x,y,z}`).
|
|
44
|
+
* - Bool **внутри** объекта/tuple → не конвертим (нужен для tuple-полей
|
|
45
|
+
* типа `[bool, x, y]` где геймод-тип честно ожидает boolean).
|
|
46
|
+
* - Primitives / arrays / null → passthrough.
|
|
47
|
+
*
|
|
48
|
+
* ### Hot path
|
|
49
|
+
*
|
|
50
|
+
* `callNative` вызывается из render-tick consumer'ов: `HudController`
|
|
51
|
+
* (drawBlip), `CameraIdleController.onInterval`, `VehicleIndicatorService`,
|
|
52
|
+
* `PolygonZoneRenderer`, `ScriptedMarker`, `ConeDebugRenderer`. После прогрева
|
|
53
|
+
* `_resolved`-кэша — один Map.get + `fn.apply` + adapt-проход. Адапт — линейный
|
|
54
|
+
* по числу полей возврата (обычно ≤ 5), стоимость незначительная.
|
|
55
|
+
*
|
|
56
|
+
* ### Ошибки
|
|
57
|
+
*
|
|
58
|
+
* - **Hash не в DB**: натив отсутствует в nativedb. Throws с подсказкой
|
|
59
|
+
* "обновите scripts/data/natives.json" — обычно случается для свежих
|
|
60
|
+
* build-specific натов, не вошедших в last-snapshot базы.
|
|
61
|
+
* - **Namespace не в `ccmp.natives`**: CCMP-runtime версия не имеет такого
|
|
62
|
+
* namespace'а. Throws с указанием ns.
|
|
63
|
+
* - **Все method-кандидаты отсутствуют в namespace'е**: CCMP-биндинг не
|
|
64
|
+
* экспонирует ни одного из known-имён. Throws с перечислением кандидатов.
|
|
65
|
+
*/
|
|
66
|
+
export class CCMPNativeCallerManager {
|
|
67
|
+
constructor() {
|
|
68
|
+
this._resolved = new Map();
|
|
69
|
+
}
|
|
70
|
+
callNative(hash, ...args) {
|
|
71
|
+
const key = hash.toLowerCase();
|
|
72
|
+
let resolved = this._resolved.get(key);
|
|
73
|
+
if (!resolved) {
|
|
74
|
+
resolved = this._resolve(key, hash);
|
|
75
|
+
this._resolved.set(key, resolved);
|
|
76
|
+
}
|
|
77
|
+
const [nsObj, fn] = resolved;
|
|
78
|
+
const result = fn.apply(nsObj, args);
|
|
79
|
+
return CCMPNativeCallerManager._adaptResult(result);
|
|
80
|
+
}
|
|
81
|
+
_resolve(key, originalHash) {
|
|
82
|
+
const entry = NATIVE_DISPATCH[key];
|
|
83
|
+
if (!entry) {
|
|
84
|
+
throw new Error(`CCMPNativeCallerManager.callNative: native hash "${originalHash}" не найден ` +
|
|
85
|
+
"в nativedb (scripts/data/natives.json). Если натив был добавлен недавно " +
|
|
86
|
+
"— обновите snapshot из CCMP-проекта и перезапустите " +
|
|
87
|
+
"`node scripts/generate-native-dispatch.mjs`.");
|
|
88
|
+
}
|
|
89
|
+
const natives = ccmp.natives;
|
|
90
|
+
const nsObj = natives[entry.ns];
|
|
91
|
+
if (!nsObj) {
|
|
92
|
+
throw new Error(`CCMPNativeCallerManager.callNative: native hash "${originalHash}" — namespace ` +
|
|
93
|
+
`"ccmp.natives.${entry.ns}" отсутствует в runtime. Возможно, версия CCMP ` +
|
|
94
|
+
"не соответствует версии nativedb.");
|
|
95
|
+
}
|
|
96
|
+
for (const method of entry.methods) {
|
|
97
|
+
const fn = nsObj[method];
|
|
98
|
+
if (typeof fn === "function") {
|
|
99
|
+
return [nsObj, fn];
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
throw new Error(`CCMPNativeCallerManager.callNative: native hash "${originalHash}" — ни один ` +
|
|
103
|
+
`из method-кандидатов [${entry.methods.join(", ")}] не существует в ` +
|
|
104
|
+
`ccmp.natives.${entry.ns}. CCMP-биндинг не экспонирует этот натив; ` +
|
|
105
|
+
"при необходимости — пропатчить @classic-mp/types или маппинг в nativedb.");
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Конвертация CCMP object-return → RageMP tuple-return.
|
|
109
|
+
* См. block-комментарий класса (Адаптация return-shape).
|
|
110
|
+
*/
|
|
111
|
+
static _adaptResult(r) {
|
|
112
|
+
if (typeof r === "boolean") {
|
|
113
|
+
// Top-level boolean → RageMP-конвенция 0/1.
|
|
114
|
+
return r ? 1 : 0;
|
|
115
|
+
}
|
|
116
|
+
if (r === null || typeof r !== "object" || Array.isArray(r)) {
|
|
117
|
+
return r;
|
|
118
|
+
}
|
|
119
|
+
// Object: flatten в tuple через Object.values, recursively для nested objects.
|
|
120
|
+
// Booleans внутри объекта НЕ конвертим — геймод-типы могут честно ожидать bool
|
|
121
|
+
// в multi-return tuple-полях.
|
|
122
|
+
return Object.values(r).map((v) => {
|
|
123
|
+
if (v !== null && typeof v === "object" && !Array.isArray(v)) {
|
|
124
|
+
return Object.values(v);
|
|
125
|
+
}
|
|
126
|
+
return v;
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
}
|