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.
Files changed (168) hide show
  1. package/dist/client/RockMod.d.ts +1 -1
  2. package/dist/client/RockMod.js +4 -0
  3. package/dist/client/entities/ccmp/camera/CCMPCamera.d.ts +24 -0
  4. package/dist/client/entities/ccmp/camera/CCMPCamera.js +58 -0
  5. package/dist/client/entities/ccmp/camera/CCMPCameraManager.d.ts +16 -0
  6. package/dist/client/entities/ccmp/camera/CCMPCameraManager.js +50 -0
  7. package/dist/client/entities/ccmp/ped/CCMPPed.d.ts +65 -0
  8. package/dist/client/entities/ccmp/ped/CCMPPed.js +185 -0
  9. package/dist/client/entities/ccmp/ped/CCMPPedsManager.d.ts +20 -0
  10. package/dist/client/entities/ccmp/ped/CCMPPedsManager.js +105 -0
  11. package/dist/client/entities/ccmp/player/CCMPPlayer.d.ts +112 -0
  12. package/dist/client/entities/ccmp/player/CCMPPlayer.js +332 -0
  13. package/dist/client/entities/ccmp/player/CCMPPlayersManager.d.ts +84 -0
  14. package/dist/client/entities/ccmp/player/CCMPPlayersManager.js +318 -0
  15. package/dist/client/entities/ccmp/vehicle/CCMPVehiclesManager.d.ts +64 -0
  16. package/dist/client/entities/ccmp/vehicle/CCMPVehiclesManager.js +105 -0
  17. package/dist/client/entities/common/entity/IEntity.d.ts +3 -0
  18. package/dist/client/entities/ragemp/entity/RageEntity.d.ts +3 -0
  19. package/dist/client/entities/ragemp/entity/RageEntity.js +11 -0
  20. package/dist/client/factories/ccmp/CCMPManagersFactory.d.ts +46 -0
  21. package/dist/client/factories/ccmp/CCMPManagersFactory.js +149 -0
  22. package/dist/client/factories/ccmp/createNotImplementedProxy.d.ts +1 -0
  23. package/dist/client/factories/ccmp/createNotImplementedProxy.js +24 -0
  24. package/dist/client/game/ccmp/browser/CCMPBrowserManager.d.ts +22 -0
  25. package/dist/client/game/ccmp/browser/CCMPBrowserManager.js +66 -0
  26. package/dist/client/game/ccmp/chat/CCMPChatManager.d.ts +26 -0
  27. package/dist/client/game/ccmp/chat/CCMPChatManager.js +41 -0
  28. package/dist/client/game/ccmp/controls/CCMPControlsManager.d.ts +33 -0
  29. package/dist/client/game/ccmp/controls/CCMPControlsManager.js +47 -0
  30. package/dist/client/game/ccmp/cursor/CCMPCursorManager.d.ts +6 -0
  31. package/dist/client/game/ccmp/cursor/CCMPCursorManager.js +15 -0
  32. package/dist/client/game/ccmp/gameplay/CCMPGameplayManager.d.ts +6 -0
  33. package/dist/client/game/ccmp/gameplay/CCMPGameplayManager.js +10 -0
  34. package/dist/client/game/ccmp/graphics/CCMPGraphicsManager.d.ts +58 -0
  35. package/dist/client/game/ccmp/graphics/CCMPGraphicsManager.js +112 -0
  36. package/dist/client/game/ccmp/gui/CCMPGuiManager.d.ts +5 -0
  37. package/dist/client/game/ccmp/gui/CCMPGuiManager.js +17 -0
  38. package/dist/client/game/ccmp/keys/CCMPKeysManager.d.ts +41 -0
  39. package/dist/client/game/ccmp/keys/CCMPKeysManager.js +94 -0
  40. package/dist/client/game/ccmp/nametags/CCMPNametagsManager.d.ts +4 -0
  41. package/dist/client/game/ccmp/nametags/CCMPNametagsManager.js +6 -0
  42. package/dist/client/game/ccmp/native/CCMPNativeCallerManager.d.ts +74 -0
  43. package/dist/client/game/ccmp/native/CCMPNativeCallerManager.js +129 -0
  44. package/dist/client/game/ccmp/native/_generated/nativeDispatch.d.ts +5 -0
  45. package/dist/client/game/ccmp/native/_generated/nativeDispatch.js +8123 -0
  46. package/dist/client/game/ccmp/object/CCMPGameObjectManager.d.ts +4 -0
  47. package/dist/client/game/ccmp/object/CCMPGameObjectManager.js +6 -0
  48. package/dist/client/game/ccmp/pathfind/CCMPPathfindManager.d.ts +26 -0
  49. package/dist/client/game/ccmp/pathfind/CCMPPathfindManager.js +31 -0
  50. package/dist/client/game/ccmp/raycasting/CCMPRaycastingManager.d.ts +10 -0
  51. package/dist/client/game/ccmp/raycasting/CCMPRaycastingManager.js +46 -0
  52. package/dist/client/game/ccmp/storage/CCMPStorageManager.d.ts +25 -0
  53. package/dist/client/game/ccmp/storage/CCMPStorageManager.js +46 -0
  54. package/dist/client/game/ccmp/streaming/CCMPStreamingManager.d.ts +17 -0
  55. package/dist/client/game/ccmp/streaming/CCMPStreamingManager.js +41 -0
  56. package/dist/client/game/ccmp/ui/CCMPUiManager.d.ts +41 -0
  57. package/dist/client/game/ccmp/ui/CCMPUiManager.js +69 -0
  58. package/dist/client/game/ccmp/zone/CCMPZoneManager.d.ts +19 -0
  59. package/dist/client/game/ccmp/zone/CCMPZoneManager.js +20 -0
  60. package/dist/client/game/common/browser/IBrowserManager.d.ts +7 -0
  61. package/dist/client/game/common/chat/IChatManager.d.ts +1 -0
  62. package/dist/client/game/common/controls/IControlsManager.d.ts +3 -0
  63. package/dist/client/game/common/graphics/IGraphicsManager.d.ts +17 -0
  64. package/dist/client/game/common/streaming/IStreamingManager.d.ts +2 -0
  65. package/dist/client/game/ragemp/browser/RageBrowserManager.d.ts +2 -1
  66. package/dist/client/game/ragemp/browser/RageBrowserManager.js +30 -1
  67. package/dist/client/game/ragemp/chat/RageChatManager.d.ts +1 -0
  68. package/dist/client/game/ragemp/chat/RageChatManager.js +3 -0
  69. package/dist/client/game/ragemp/controls/RageControlsManager.d.ts +3 -0
  70. package/dist/client/game/ragemp/controls/RageControlsManager.js +9 -0
  71. package/dist/client/game/ragemp/graphics/RageGraphicsManager.d.ts +5 -1
  72. package/dist/client/game/ragemp/graphics/RageGraphicsManager.js +12 -0
  73. package/dist/client/game/ragemp/streaming/RageStreamingManager.d.ts +2 -0
  74. package/dist/client/game/ragemp/streaming/RageStreamingManager.js +6 -0
  75. package/dist/client/net/ccmp/CCMPConsoleForwarder.d.ts +11 -0
  76. package/dist/client/net/ccmp/CCMPConsoleForwarder.js +153 -0
  77. package/dist/client/net/ccmp/CCMPNetManager.d.ts +23 -0
  78. package/dist/client/net/ccmp/CCMPNetManager.js +55 -0
  79. package/dist/client/net/ccmp/dataHandler/CCMPDataHandler.d.ts +23 -0
  80. package/dist/client/net/ccmp/dataHandler/CCMPDataHandler.js +43 -0
  81. package/dist/client/net/ccmp/events/CCMPEventsBridge.d.ts +14 -0
  82. package/dist/client/net/ccmp/events/CCMPEventsBridge.js +19 -0
  83. package/dist/client/net/ccmp/events/CCMPEventsManager.d.ts +72 -0
  84. package/dist/client/net/ccmp/events/CCMPEventsManager.js +177 -0
  85. package/dist/client/net/ccmp/events/CCMPInProcessEmitter.d.ts +45 -0
  86. package/dist/client/net/ccmp/events/CCMPInProcessEmitter.js +133 -0
  87. package/dist/client/net/ccmp/events/CCMPRenderTicker.d.ts +18 -0
  88. package/dist/client/net/ccmp/events/CCMPRenderTicker.js +74 -0
  89. package/dist/client/net/ccmp/events/CCMPSyncedMetaBridge.d.ts +24 -0
  90. package/dist/client/net/ccmp/events/CCMPSyncedMetaBridge.js +35 -0
  91. package/dist/client/net/ccmp/rpc/CCMPRPCManager.d.ts +22 -0
  92. package/dist/client/net/ccmp/rpc/CCMPRPCManager.js +31 -0
  93. package/dist/client/net/common/events/types.d.ts +3 -1
  94. package/dist/client/net/common/events/types.js +1 -0
  95. package/dist/client/utils/ccmp/CCMPUtilsManager.d.ts +18 -0
  96. package/dist/client/utils/ccmp/CCMPUtilsManager.js +20 -0
  97. package/dist/server/RockMod.d.ts +1 -1
  98. package/dist/server/RockMod.js +4 -0
  99. package/dist/server/entities/ccmp/baseObject/CCMPBaseObject.d.ts +8 -0
  100. package/dist/server/entities/ccmp/baseObject/CCMPBaseObject.js +21 -0
  101. package/dist/server/entities/ccmp/baseObject/CCMPBaseObjectsIterator.d.ts +8 -0
  102. package/dist/server/entities/ccmp/baseObject/CCMPBaseObjectsIterator.js +16 -0
  103. package/dist/server/entities/ccmp/baseObject/CCMPBaseObjectsManager.d.ts +19 -0
  104. package/dist/server/entities/ccmp/baseObject/CCMPBaseObjectsManager.js +49 -0
  105. package/dist/server/entities/ccmp/blip/CCMPBlip.d.ts +34 -0
  106. package/dist/server/entities/ccmp/blip/CCMPBlip.js +80 -0
  107. package/dist/server/entities/ccmp/blip/CCMPBlipsManager.d.ts +9 -0
  108. package/dist/server/entities/ccmp/blip/CCMPBlipsManager.js +33 -0
  109. package/dist/server/entities/ccmp/colshape/CCMPCircleColshape.d.ts +7 -0
  110. package/dist/server/entities/ccmp/colshape/CCMPCircleColshape.js +10 -0
  111. package/dist/server/entities/ccmp/colshape/CCMPColshape.d.ts +23 -0
  112. package/dist/server/entities/ccmp/colshape/CCMPColshape.js +47 -0
  113. package/dist/server/entities/ccmp/colshape/CCMPColshapesManager.d.ts +28 -0
  114. package/dist/server/entities/ccmp/colshape/CCMPColshapesManager.js +108 -0
  115. package/dist/server/entities/ccmp/colshape/CCMPCuboidColshape.d.ts +7 -0
  116. package/dist/server/entities/ccmp/colshape/CCMPCuboidColshape.js +10 -0
  117. package/dist/server/entities/ccmp/colshape/CCMPCylinderColshape.d.ts +7 -0
  118. package/dist/server/entities/ccmp/colshape/CCMPCylinderColshape.js +10 -0
  119. package/dist/server/entities/ccmp/colshape/CCMPRectangleColshape.d.ts +7 -0
  120. package/dist/server/entities/ccmp/colshape/CCMPRectangleColshape.js +10 -0
  121. package/dist/server/entities/ccmp/colshape/CCMPSphereColshape.d.ts +7 -0
  122. package/dist/server/entities/ccmp/colshape/CCMPSphereColshape.js +10 -0
  123. package/dist/server/entities/ccmp/entity/CCMPEntitiesManager.d.ts +8 -0
  124. package/dist/server/entities/ccmp/entity/CCMPEntitiesManager.js +10 -0
  125. package/dist/server/entities/ccmp/entity/CCMPEntity.d.ts +13 -0
  126. package/dist/server/entities/ccmp/entity/CCMPEntity.js +28 -0
  127. package/dist/server/entities/ccmp/marker/CCMPMarker.d.ts +32 -0
  128. package/dist/server/entities/ccmp/marker/CCMPMarker.js +79 -0
  129. package/dist/server/entities/ccmp/marker/CCMPMarkersManager.d.ts +9 -0
  130. package/dist/server/entities/ccmp/marker/CCMPMarkersManager.js +30 -0
  131. package/dist/server/entities/ccmp/object/CCMPObject.d.ts +48 -0
  132. package/dist/server/entities/ccmp/object/CCMPObject.js +70 -0
  133. package/dist/server/entities/ccmp/object/CCMPObjectsManager.d.ts +9 -0
  134. package/dist/server/entities/ccmp/object/CCMPObjectsManager.js +28 -0
  135. package/dist/server/entities/ccmp/ped/CCMPPed.d.ts +33 -0
  136. package/dist/server/entities/ccmp/ped/CCMPPed.js +82 -0
  137. package/dist/server/entities/ccmp/ped/CCMPPedsManager.d.ts +9 -0
  138. package/dist/server/entities/ccmp/ped/CCMPPedsManager.js +28 -0
  139. package/dist/server/entities/ccmp/player/CCMPPlayer.d.ts +65 -0
  140. package/dist/server/entities/ccmp/player/CCMPPlayer.js +180 -0
  141. package/dist/server/entities/ccmp/player/CCMPPlayersManager.d.ts +12 -0
  142. package/dist/server/entities/ccmp/player/CCMPPlayersManager.js +66 -0
  143. package/dist/server/entities/ccmp/vehicle/CCMPVehicle.d.ts +58 -0
  144. package/dist/server/entities/ccmp/vehicle/CCMPVehicle.js +161 -0
  145. package/dist/server/entities/ccmp/vehicle/CCMPVehiclesManager.d.ts +9 -0
  146. package/dist/server/entities/ccmp/vehicle/CCMPVehiclesManager.js +31 -0
  147. package/dist/server/entities/ccmp/worldObject/CCMPWorldObject.d.ts +9 -0
  148. package/dist/server/entities/ccmp/worldObject/CCMPWorldObject.js +7 -0
  149. package/dist/server/entities/ccmp/worldObject/CCMPWorldObjectsIterator.d.ts +10 -0
  150. package/dist/server/entities/ccmp/worldObject/CCMPWorldObjectsIterator.js +40 -0
  151. package/dist/server/entities/ccmp/worldObject/CCMPWorldObjectsManager.d.ts +11 -0
  152. package/dist/server/entities/ccmp/worldObject/CCMPWorldObjectsManager.js +16 -0
  153. package/dist/server/entities/mock/player/MockPlayersManager.js +2 -1
  154. package/dist/server/factories/ccmp/CCMPManagersFactory.d.ts +23 -0
  155. package/dist/server/factories/ccmp/CCMPManagersFactory.js +46 -0
  156. package/dist/server/net/ccmp/CCMPNetManager.d.ts +19 -0
  157. package/dist/server/net/ccmp/CCMPNetManager.js +112 -0
  158. package/dist/server/net/ccmp/events/CCMPEventsManager.d.ts +17 -0
  159. package/dist/server/net/ccmp/events/CCMPEventsManager.js +54 -0
  160. package/dist/server/net/ccmp/rpc/CCMPRPCManager.d.ts +8 -0
  161. package/dist/server/net/ccmp/rpc/CCMPRPCManager.js +18 -0
  162. package/dist/server/net/common/events/types.d.ts +2 -0
  163. package/dist/server/net/common/events/types.js +1 -0
  164. package/dist/server/utils/ccmp/CCMPUtilsManager.d.ts +4 -0
  165. package/dist/server/utils/ccmp/CCMPUtilsManager.js +9 -0
  166. package/dist/server/world/ccmp/CCMPWorldManager.d.ts +10 -0
  167. package/dist/server/world/ccmp/CCMPWorldManager.js +24 -0
  168. 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,4 @@
1
+ import { type INametagsManager } from "../../common/nametags/INametagsManager";
2
+ export declare class CCMPNametagsManager implements INametagsManager {
3
+ setEnabled(enabled: boolean): void;
4
+ }
@@ -0,0 +1,6 @@
1
+ /// <reference types="@classic-mp/types/client" />
2
+ export class CCMPNametagsManager {
3
+ setEnabled(enabled) {
4
+ ccmp.nametags.setEnabled(enabled);
5
+ }
6
+ }
@@ -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
+ }
@@ -0,0 +1,5 @@
1
+ export interface NativeDispatchEntry {
2
+ readonly ns: string;
3
+ readonly methods: readonly string[];
4
+ }
5
+ export declare const NATIVE_DISPATCH: Readonly<Record<string, NativeDispatchEntry>>;