@open-core/framework 1.0.1-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +373 -0
- package/README.md +350 -0
- package/dist/client/client-bootstrap.d.ts +1 -0
- package/dist/client/client-bootstrap.js +53 -0
- package/dist/client/client-container.d.ts +2 -0
- package/dist/client/client-container.js +6 -0
- package/dist/client/client-core.d.ts +18 -0
- package/dist/client/client-core.js +52 -0
- package/dist/client/decorators/controller.d.ts +3 -0
- package/dist/client/decorators/controller.js +14 -0
- package/dist/client/decorators/export.d.ts +7 -0
- package/dist/client/decorators/export.js +15 -0
- package/dist/client/decorators/gameEvent.d.ts +47 -0
- package/dist/client/decorators/gameEvent.js +54 -0
- package/dist/client/decorators/index.d.ts +10 -0
- package/dist/client/decorators/index.js +26 -0
- package/dist/client/decorators/interval.d.ts +7 -0
- package/dist/client/decorators/interval.js +15 -0
- package/dist/client/decorators/key.d.ts +2 -0
- package/dist/client/decorators/key.js +10 -0
- package/dist/client/decorators/localEvent.d.ts +7 -0
- package/dist/client/decorators/localEvent.js +15 -0
- package/dist/client/decorators/nui.d.ts +1 -0
- package/dist/client/decorators/nui.js +9 -0
- package/dist/client/decorators/onNet.d.ts +1 -0
- package/dist/client/decorators/onNet.js +9 -0
- package/dist/client/decorators/resourceLifecycle.d.ts +11 -0
- package/dist/client/decorators/resourceLifecycle.js +24 -0
- package/dist/client/decorators/tick.d.ts +1 -0
- package/dist/client/decorators/tick.js +9 -0
- package/dist/client/index.d.ts +6 -0
- package/dist/client/index.js +22 -0
- package/dist/client/loaders/exports.loader.d.ts +1 -0
- package/dist/client/loaders/exports.loader.js +13 -0
- package/dist/client/player/player.d.ts +262 -0
- package/dist/client/player/player.js +480 -0
- package/dist/client/player/player.loader.d.ts +1 -0
- package/dist/client/player/player.loader.js +22 -0
- package/dist/client/services/core/index.d.ts +1 -0
- package/dist/client/services/core/index.js +17 -0
- package/dist/client/services/core/spawn.service.d.ts +20 -0
- package/dist/client/services/core/spawn.service.js +143 -0
- package/dist/client/services/index.d.ts +4 -0
- package/dist/client/services/index.js +24 -0
- package/dist/client/services/streaming/index.d.ts +1 -0
- package/dist/client/services/streaming/index.js +17 -0
- package/dist/client/services/streaming/streaming.service.d.ts +165 -0
- package/dist/client/services/streaming/streaming.service.js +341 -0
- package/dist/client/services/ui/index.d.ts +3 -0
- package/dist/client/services/ui/index.js +19 -0
- package/dist/client/services/ui/notification.service.d.ts +76 -0
- package/dist/client/services/ui/notification.service.js +111 -0
- package/dist/client/services/ui/progress.service.d.ts +82 -0
- package/dist/client/services/ui/progress.service.js +210 -0
- package/dist/client/services/ui/textui.service.d.ts +82 -0
- package/dist/client/services/ui/textui.service.js +156 -0
- package/dist/client/services/world/blip.service.d.ts +112 -0
- package/dist/client/services/world/blip.service.js +215 -0
- package/dist/client/services/world/index.d.ts +4 -0
- package/dist/client/services/world/index.js +20 -0
- package/dist/client/services/world/marker.service.d.ts +94 -0
- package/dist/client/services/world/marker.service.js +153 -0
- package/dist/client/services/world/ped.service.d.ts +182 -0
- package/dist/client/services/world/ped.service.js +302 -0
- package/dist/client/services/world/vehicle.service.d.ts +168 -0
- package/dist/client/services/world/vehicle.service.js +296 -0
- package/dist/client/system/metadata-client.keys.d.ts +13 -0
- package/dist/client/system/metadata-client.keys.js +16 -0
- package/dist/client/system/processors/export.processor.d.ts +7 -0
- package/dist/client/system/processors/export.processor.js +39 -0
- package/dist/client/system/processors/gameEvent.processor.d.ts +10 -0
- package/dist/client/system/processors/gameEvent.processor.js +58 -0
- package/dist/client/system/processors/interval.processor.d.ts +7 -0
- package/dist/client/system/processors/interval.processor.js +43 -0
- package/dist/client/system/processors/key.processor.d.ts +8 -0
- package/dist/client/system/processors/key.processor.js +27 -0
- package/dist/client/system/processors/localEvent.processor.d.ts +7 -0
- package/dist/client/system/processors/localEvent.processor.js +38 -0
- package/dist/client/system/processors/netEvent.processor.d.ts +7 -0
- package/dist/client/system/processors/netEvent.processor.js +38 -0
- package/dist/client/system/processors/nui.processor.d.ts +7 -0
- package/dist/client/system/processors/nui.processor.js +40 -0
- package/dist/client/system/processors/resourceLifecycle.processor.d.ts +9 -0
- package/dist/client/system/processors/resourceLifecycle.processor.js +69 -0
- package/dist/client/system/processors/tick.processor.d.ts +5 -0
- package/dist/client/system/processors/tick.processor.js +37 -0
- package/dist/client/system/processors.register.d.ts +1 -0
- package/dist/client/system/processors.register.js +27 -0
- package/dist/client/types/game-events.d.ts +126 -0
- package/dist/client/types/game-events.js +83 -0
- package/dist/client/types/index.d.ts +1 -0
- package/dist/client/types/index.js +17 -0
- package/dist/client/ui-bridge.d.ts +116 -0
- package/dist/client/ui-bridge.js +201 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +46 -0
- package/dist/server/bootstrap.d.ts +16 -0
- package/dist/server/bootstrap.js +57 -0
- package/dist/server/bus/core-event-bus.d.ts +6 -0
- package/dist/server/bus/core-event-bus.js +31 -0
- package/dist/server/configs/api.config.d.ts +71 -0
- package/dist/server/configs/api.config.js +81 -0
- package/dist/server/configs/config.base.d.ts +63 -0
- package/dist/server/configs/config.base.js +64 -0
- package/dist/server/configs/index.d.ts +2 -0
- package/dist/server/configs/index.js +18 -0
- package/dist/server/container.d.ts +2 -0
- package/dist/server/container.js +6 -0
- package/dist/server/controllers/chat.controller.d.ts +10 -0
- package/dist/server/controllers/chat.controller.js +50 -0
- package/dist/server/controllers/command.controller.d.ts +7 -0
- package/dist/server/controllers/command.controller.js +47 -0
- package/dist/server/core.d.ts +1 -0
- package/dist/server/core.js +7 -0
- package/dist/server/database/adapters/oxmysql.adapter.d.ts +89 -0
- package/dist/server/database/adapters/oxmysql.adapter.js +149 -0
- package/dist/server/database/database.contract.d.ts +128 -0
- package/dist/server/database/database.contract.js +29 -0
- package/dist/server/database/database.service.d.ts +216 -0
- package/dist/server/database/database.service.js +301 -0
- package/dist/server/database/index.d.ts +53 -0
- package/dist/server/database/index.js +70 -0
- package/dist/server/database/types.d.ts +67 -0
- package/dist/server/database/types.js +7 -0
- package/dist/server/database.d.ts +7 -0
- package/dist/server/database.js +23 -0
- package/dist/server/decorators/bind.d.ts +2 -0
- package/dist/server/decorators/bind.js +15 -0
- package/dist/server/decorators/command.d.ts +19 -0
- package/dist/server/decorators/command.js +18 -0
- package/dist/server/decorators/controller.d.ts +3 -0
- package/dist/server/decorators/controller.js +14 -0
- package/dist/server/decorators/coreEvent.d.ts +2 -0
- package/dist/server/decorators/coreEvent.js +9 -0
- package/dist/server/decorators/export.d.ts +1 -0
- package/dist/server/decorators/export.js +9 -0
- package/dist/server/decorators/guard.d.ts +5 -0
- package/dist/server/decorators/guard.js +39 -0
- package/dist/server/decorators/index.d.ts +10 -0
- package/dist/server/decorators/index.js +26 -0
- package/dist/server/decorators/netEvent.d.ts +36 -0
- package/dist/server/decorators/netEvent.js +40 -0
- package/dist/server/decorators/onTick.d.ts +1 -0
- package/dist/server/decorators/onTick.js +9 -0
- package/dist/server/decorators/public.d.ts +16 -0
- package/dist/server/decorators/public.js +25 -0
- package/dist/server/decorators/requiresState.d.ts +55 -0
- package/dist/server/decorators/requiresState.js +62 -0
- package/dist/server/decorators/throttle.d.ts +9 -0
- package/dist/server/decorators/throttle.js +36 -0
- package/dist/server/decorators/utils.d.ts +7 -0
- package/dist/server/decorators/utils.js +13 -0
- package/dist/server/entities/index.d.ts +1 -0
- package/dist/server/entities/index.js +17 -0
- package/dist/server/entities/player.d.ts +157 -0
- package/dist/server/entities/player.js +217 -0
- package/dist/server/error-handler.d.ts +2 -0
- package/dist/server/error-handler.js +43 -0
- package/dist/server/index.d.ts +10 -0
- package/dist/server/index.js +29 -0
- package/dist/server/loaders/exports.loader.d.ts +0 -0
- package/dist/server/loaders/exports.loader.js +23 -0
- package/dist/server/loaders/playerSession.loader.d.ts +1 -0
- package/dist/server/loaders/playerSession.loader.js +42 -0
- package/dist/server/services/access-control.service.d.ts +56 -0
- package/dist/server/services/access-control.service.js +99 -0
- package/dist/server/services/chat.service.d.ts +7 -0
- package/dist/server/services/chat.service.js +31 -0
- package/dist/server/services/command.service.d.ts +15 -0
- package/dist/server/services/command.service.js +74 -0
- package/dist/server/services/config.service.d.ts +75 -0
- package/dist/server/services/config.service.js +116 -0
- package/dist/server/services/default/default-security.handler.d.ts +6 -0
- package/dist/server/services/default/default-security.handler.js +26 -0
- package/dist/server/services/http/http.service.d.ts +50 -0
- package/dist/server/services/http/http.service.js +126 -0
- package/dist/server/services/index.d.ts +10 -0
- package/dist/server/services/index.js +26 -0
- package/dist/server/services/parallel/index.d.ts +49 -0
- package/dist/server/services/parallel/index.js +67 -0
- package/dist/server/services/parallel/parallel-compute.service.d.ts +132 -0
- package/dist/server/services/parallel/parallel-compute.service.js +449 -0
- package/dist/server/services/parallel/types.d.ts +188 -0
- package/dist/server/services/parallel/types.js +7 -0
- package/dist/server/services/parallel/worker-pool.d.ts +83 -0
- package/dist/server/services/parallel/worker-pool.js +350 -0
- package/dist/server/services/parallel/worker.d.ts +19 -0
- package/dist/server/services/parallel/worker.js +49 -0
- package/dist/server/services/persistence.service.d.ts +59 -0
- package/dist/server/services/persistence.service.js +166 -0
- package/dist/server/services/player.service.d.ts +96 -0
- package/dist/server/services/player.service.js +132 -0
- package/dist/server/services/rate-limiter.service.d.ts +5 -0
- package/dist/server/services/rate-limiter.service.js +39 -0
- package/dist/server/services/registers.d.ts +1 -0
- package/dist/server/services/registers.js +18 -0
- package/dist/server/setup.d.ts +9 -0
- package/dist/server/setup.js +28 -0
- package/dist/server/system/metadata-server.keys.d.ts +9 -0
- package/dist/server/system/metadata-server.keys.js +12 -0
- package/dist/server/system/processors/command.processor.d.ts +9 -0
- package/dist/server/system/processors/command.processor.js +31 -0
- package/dist/server/system/processors/coreEvent.processor.d.ts +7 -0
- package/dist/server/system/processors/coreEvent.processor.js +38 -0
- package/dist/server/system/processors/export.processor.d.ts +7 -0
- package/dist/server/system/processors/export.processor.js +26 -0
- package/dist/server/system/processors/netEvent.processor.d.ts +11 -0
- package/dist/server/system/processors/netEvent.processor.js +100 -0
- package/dist/server/system/processors/tick.processor.d.ts +5 -0
- package/dist/server/system/processors/tick.processor.js +36 -0
- package/dist/server/system/processors.register.d.ts +1 -0
- package/dist/server/system/processors.register.js +21 -0
- package/dist/server/templates/admin/admin.controller-template.d.ts +10 -0
- package/dist/server/templates/admin/admin.controller-template.js +2 -0
- package/dist/server/templates/auth/auth-provider.contract.d.ts +58 -0
- package/dist/server/templates/auth/auth-provider.contract.js +23 -0
- package/dist/server/templates/index.d.ts +8 -0
- package/dist/server/templates/index.js +21 -0
- package/dist/server/templates/persistence/index.d.ts +30 -0
- package/dist/server/templates/persistence/index.js +34 -0
- package/dist/server/templates/persistence/player-persistence.contract.d.ts +86 -0
- package/dist/server/templates/persistence/player-persistence.contract.js +52 -0
- package/dist/server/templates/repository/index.d.ts +57 -0
- package/dist/server/templates/repository/index.js +61 -0
- package/dist/server/templates/repository/repository.contract.d.ts +224 -0
- package/dist/server/templates/repository/repository.contract.js +342 -0
- package/dist/server/templates/repository/repository.types.d.ts +51 -0
- package/dist/server/templates/repository/repository.types.js +7 -0
- package/dist/server/templates/security/permission.types.d.ts +32 -0
- package/dist/server/templates/security/permission.types.js +2 -0
- package/dist/server/templates/security/principal-provider.contract.d.ts +43 -0
- package/dist/server/templates/security/principal-provider.contract.js +19 -0
- package/dist/server/templates/security/security-handler.contract.d.ts +5 -0
- package/dist/server/templates/security/security-handler.contract.js +6 -0
- package/dist/server/types/core-events.d.ts +17 -0
- package/dist/server/types/core-events.js +2 -0
- package/dist/server/types/security.types.d.ts +7 -0
- package/dist/server/types/security.types.js +2 -0
- package/dist/shared/index.d.ts +1 -0
- package/dist/shared/index.js +17 -0
- package/dist/shared/logger/core-logger.d.ts +35 -0
- package/dist/shared/logger/core-logger.js +52 -0
- package/dist/shared/logger/index.d.ts +11 -0
- package/dist/shared/logger/index.js +26 -0
- package/dist/shared/logger/logger.config.d.ts +47 -0
- package/dist/shared/logger/logger.config.js +33 -0
- package/dist/shared/logger/logger.service.d.ts +161 -0
- package/dist/shared/logger/logger.service.js +279 -0
- package/dist/shared/logger/logger.types.d.ts +85 -0
- package/dist/shared/logger/logger.types.js +74 -0
- package/dist/shared/logger/transports/buffered.transport.d.ts +88 -0
- package/dist/shared/logger/transports/buffered.transport.js +174 -0
- package/dist/shared/logger/transports/console.transport.d.ts +37 -0
- package/dist/shared/logger/transports/console.transport.js +134 -0
- package/dist/shared/logger/transports/index.d.ts +3 -0
- package/dist/shared/logger/transports/index.js +19 -0
- package/dist/shared/logger/transports/transport.interface.d.ts +40 -0
- package/dist/shared/logger/transports/transport.interface.js +2 -0
- package/dist/system/class-constructor.d.ts +1 -0
- package/dist/system/class-constructor.js +2 -0
- package/dist/system/decorator-processor.d.ts +4 -0
- package/dist/system/decorator-processor.js +2 -0
- package/dist/system/metadata.scanner.d.ts +7 -0
- package/dist/system/metadata.scanner.js +45 -0
- package/dist/utils/errors.d.ts +14 -0
- package/dist/utils/errors.js +25 -0
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.js +20 -0
- package/dist/utils/result.d.ts +12 -0
- package/dist/utils/result.js +10 -0
- package/dist/utils/rgb.d.ts +5 -0
- package/dist/utils/rgb.js +2 -0
- package/dist/utils/vector3.d.ts +13 -0
- package/dist/utils/vector3.js +27 -0
- package/package.json +70 -0
package/README.md
ADDED
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
# OpenCore Framework
|
|
2
|
+
|
|
3
|
+
> **The robust TypeScript Engine for FiveM.**
|
|
4
|
+
> Built on strong OOP principles, Layered Architecture, and Security-first design.
|
|
5
|
+
> _Stop writing scripts; start engineering gameplay._
|
|
6
|
+
|
|
7
|
+
[](https://opensource.org/licenses/MPL-2.0)
|
|
8
|
+
[](https://github.com/newcore-network/opencore)
|
|
9
|
+

|
|
10
|
+

|
|
11
|
+

|
|
12
|
+
|
|
13
|
+
## 📋 Table of Contents
|
|
14
|
+
|
|
15
|
+
- [Why OpenCore?](#-why-opencore)
|
|
16
|
+
- [Installation](#-installation)
|
|
17
|
+
- [Quick Start](#-quick-start)
|
|
18
|
+
- [Security System](#️-security-system)
|
|
19
|
+
- [Architecture](#️-architecture)
|
|
20
|
+
- [Testing](#-testing)
|
|
21
|
+
- [Performance](#-performance--benchmarks)
|
|
22
|
+
- [Project Structure](#-project-structure)
|
|
23
|
+
- [Scripts](#-available-scripts)
|
|
24
|
+
- [License](#-license)
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## 🚀 Why OpenCore?
|
|
29
|
+
|
|
30
|
+
OpenCore transforms FiveM development from chaotic scripting into professional software engineering. Inspired by enterprise frameworks like **Spring Boot** and **NestJS**, it brings structure, security, and strict typing to your server.
|
|
31
|
+
|
|
32
|
+
### ✨ Key Features
|
|
33
|
+
|
|
34
|
+
- **🛡️ Security by Design:** Built-in Input Validation (**Zod**), Rate Limiting (`@Throttle`), and Access Control (`@Guard`).
|
|
35
|
+
- **🏗️ Decoupled Architecture:** Logic is separated into **Controllers**, **Services**, and **Entities**.
|
|
36
|
+
- **💉 Dependency Injection:** Full IoC container powered by `tsyringe`.
|
|
37
|
+
- **📝 Type-Safe:** No more guessing `source` types or argument structures.
|
|
38
|
+
- **📡 Event-Driven:** Powerful Event Bus for internal and network communication.
|
|
39
|
+
- **⚡ High Performance:** Sub-microsecond latencies, millions of ops/sec.
|
|
40
|
+
- **🧪 Fully Tested:** Comprehensive unit, integration, and load tests.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## 📦 Installation
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
pnpm add @open-core/framework reflect-metadata tsyringe zod uuid
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
> **Note:** Ensure you have `experimentalDecorators` and `emitDecoratorMetadata` enabled in your `tsconfig.json`.
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## ⚡ Quick Start
|
|
55
|
+
|
|
56
|
+
Define a Controller, validate inputs with Zod, and protect it with a Guard. Zero boilerplate.
|
|
57
|
+
|
|
58
|
+
**Server-side:**
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
import { Server } from '@open-core/framework/server'
|
|
62
|
+
import { z } from 'zod'
|
|
63
|
+
|
|
64
|
+
// 1. Define your Input Schema
|
|
65
|
+
const TransferSchema = z.tuple([
|
|
66
|
+
z.coerce.number().positive(), // Target ID
|
|
67
|
+
z.coerce.number().min(1).max(50000), // Amount
|
|
68
|
+
])
|
|
69
|
+
|
|
70
|
+
@Server.Controller()
|
|
71
|
+
export class BankController {
|
|
72
|
+
constructor(private readonly bankService: BankService) {}
|
|
73
|
+
|
|
74
|
+
@Server.Command({
|
|
75
|
+
name: 'transfer',
|
|
76
|
+
schema: TransferSchema,
|
|
77
|
+
usage: '/transfer [id] [amount]',
|
|
78
|
+
})
|
|
79
|
+
@Server.Guard({ rank: 1 }) // Must be at least Rank 1 (User)
|
|
80
|
+
@Server.Throttle(1, 2000) // Max 1 request per 2 seconds
|
|
81
|
+
async handleTransfer(player: Server.Player, args: z.infer<typeof TransferSchema>) {
|
|
82
|
+
const [targetId, amount] = args
|
|
83
|
+
|
|
84
|
+
// Logic is pure and type-safe
|
|
85
|
+
await this.bankService.transfer(player, targetId, amount)
|
|
86
|
+
|
|
87
|
+
player.emit('chat:message', `Successfully transferred $${amount}`)
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## 🛡️ Security System
|
|
95
|
+
|
|
96
|
+
OpenCore handles the dirty work so you can focus on gameplay.
|
|
97
|
+
|
|
98
|
+
### 1. Input Validation (`@Command`, `@OnNet`)
|
|
99
|
+
|
|
100
|
+
All network inputs are validated against Zod schemas before they reach your logic. Malformed packets are rejected automatically.
|
|
101
|
+
|
|
102
|
+
### 2. Access Control (`@Guard`)
|
|
103
|
+
|
|
104
|
+
Protect methods with granular permissions or hierarchical ranks:
|
|
105
|
+
|
|
106
|
+
```ts
|
|
107
|
+
@Server.Guard({ permission: 'admin.ban' })
|
|
108
|
+
@Server.Guard({ rank: 10 }) // Admin level
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### 3. Rate Limiting (`@Throttle`)
|
|
112
|
+
|
|
113
|
+
Prevent abuse with configurable rate limits:
|
|
114
|
+
|
|
115
|
+
```ts
|
|
116
|
+
@Server.Throttle(5, 10000) // 5 requests per 10 seconds
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### 4. State Management (`@RequiresState`)
|
|
120
|
+
|
|
121
|
+
Avoid "dead player exploits" or interaction glitches:
|
|
122
|
+
|
|
123
|
+
```ts
|
|
124
|
+
@Server.RequiresState({ missing: ['dead', 'cuffed'] })
|
|
125
|
+
openInventory(player: Server.Player) { ... }
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## 🏗️ Architecture
|
|
131
|
+
|
|
132
|
+
OpenCore follows a clean, layered architecture:
|
|
133
|
+
|
|
134
|
+
| Layer | Responsibility | Example |
|
|
135
|
+
| --------------- | ------------------------------------------------------------ | ---------------- |
|
|
136
|
+
| **Controllers** | Handle entry points (Commands, Events, NUI). Keep them thin. | `BankController` |
|
|
137
|
+
| **Services** | Contain business logic. Singletons injectable anywhere. | `BankService` |
|
|
138
|
+
| **Entities** | Wrappers around FiveM objects with rich APIs. | `Player` |
|
|
139
|
+
|
|
140
|
+
```
|
|
141
|
+
┌─────────────────────────────────────────────────────────┐
|
|
142
|
+
│ Client / FiveM │
|
|
143
|
+
└─────────────────────────┬───────────────────────────────┘
|
|
144
|
+
│
|
|
145
|
+
┌─────────────────────────▼───────────────────────────────┐
|
|
146
|
+
│ Controllers │
|
|
147
|
+
│ @Command @OnNet @NUI @GameEvent @OnTick │
|
|
148
|
+
└─────────────────────────┬───────────────────────────────┘
|
|
149
|
+
│
|
|
150
|
+
┌─────────────────────────▼───────────────────────────────┐
|
|
151
|
+
│ Security Layer (Middleware) │
|
|
152
|
+
│ @Guard @Throttle @RequiresState Zod Validation │
|
|
153
|
+
└─────────────────────────┬───────────────────────────────┘
|
|
154
|
+
│
|
|
155
|
+
┌─────────────────────────▼───────────────────────────────┐
|
|
156
|
+
│ Services │
|
|
157
|
+
│ Business Logic • PlayerService • BankService │
|
|
158
|
+
└─────────────────────────┬───────────────────────────────┘
|
|
159
|
+
│
|
|
160
|
+
┌─────────────────────────▼───────────────────────────────┐
|
|
161
|
+
│ Core Event Bus │
|
|
162
|
+
│ Internal Events • Cross-Service Communication │
|
|
163
|
+
└─────────────────────────────────────────────────────────┘
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## 🧪 Testing
|
|
169
|
+
|
|
170
|
+
OpenCore has a comprehensive testing suite using **Vitest**.
|
|
171
|
+
|
|
172
|
+
### Test Categories
|
|
173
|
+
|
|
174
|
+
| Category | Description | Command |
|
|
175
|
+
| --------------- | --------------------------------------- | ----------------------- |
|
|
176
|
+
| **Unit** | Individual components and decorators | `pnpm test:unit` |
|
|
177
|
+
| **Integration** | Component interactions and bootstrap | `pnpm test:integration` |
|
|
178
|
+
| **Load** | Performance under simulated player load | `pnpm bench:load` |
|
|
179
|
+
| **All Tests** | Run everything | `pnpm test` |
|
|
180
|
+
|
|
181
|
+
### Running Tests
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
# Run all tests
|
|
185
|
+
pnpm test
|
|
186
|
+
|
|
187
|
+
# Run specific test suites
|
|
188
|
+
pnpm test:unit
|
|
189
|
+
pnpm test:integration
|
|
190
|
+
|
|
191
|
+
# Watch mode for development
|
|
192
|
+
pnpm test:watch
|
|
193
|
+
|
|
194
|
+
# Generate coverage report
|
|
195
|
+
pnpm test:coverage
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Test Structure
|
|
199
|
+
|
|
200
|
+
```
|
|
201
|
+
tests/
|
|
202
|
+
├── unit/ # Unit tests
|
|
203
|
+
│ ├── server/
|
|
204
|
+
│ │ └── decorators/
|
|
205
|
+
│ │ ├── command.test.ts
|
|
206
|
+
│ │ ├── guard.test.ts
|
|
207
|
+
│ │ ├── throttle.test.ts
|
|
208
|
+
│ │ └── ...
|
|
209
|
+
│ └── utils/
|
|
210
|
+
├── integration/ # Integration tests
|
|
211
|
+
│ ├── client/
|
|
212
|
+
│ └── server/
|
|
213
|
+
├── mocks/ # FiveM mocks
|
|
214
|
+
│ └── citizenfx.ts
|
|
215
|
+
└── helpers/ # Test utilities
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### Coverage
|
|
219
|
+
|
|
220
|
+
All core decorators are **100% tested**:
|
|
221
|
+
|
|
222
|
+
- `@Command`, `@Guard`, `@Throttle`, `@OnNet`, `@OnTick`
|
|
223
|
+
- `@Controller`, `@Public`, `@Export`, `@CoreEvent`, `@Bind`
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
## ⚡ Performance & Benchmarks
|
|
228
|
+
|
|
229
|
+
OpenCore is built for performance. Our benchmark suite validates that the framework can handle production workloads with ease.
|
|
230
|
+
|
|
231
|
+
### Run Benchmarks
|
|
232
|
+
|
|
233
|
+
```bash
|
|
234
|
+
# Core component benchmarks (Tinybench)
|
|
235
|
+
pnpm bench:core
|
|
236
|
+
|
|
237
|
+
# Load benchmarks with player simulation (Vitest)
|
|
238
|
+
pnpm bench:load
|
|
239
|
+
|
|
240
|
+
# Full benchmark suite with reports
|
|
241
|
+
pnpm bench:all
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
### Latest Results (v0.6.0-beta.1)
|
|
245
|
+
|
|
246
|
+
#### Core Components
|
|
247
|
+
|
|
248
|
+
| Component | Operation | Throughput | Latency |
|
|
249
|
+
| ----------------- | ------------------ | ------------- | ------- |
|
|
250
|
+
| **DI Container** | Resolve service | 1.65M ops/sec | 0.61μs |
|
|
251
|
+
| **Zod** | Simple validation | 1.99M ops/sec | 0.50μs |
|
|
252
|
+
| **Zod** | Complex validation | 1.00M ops/sec | 1.00μs |
|
|
253
|
+
| **RateLimiter** | Key check | 2.56M ops/sec | 0.39μs |
|
|
254
|
+
| **AccessControl** | Permission check | 2.76M ops/sec | 0.36μs |
|
|
255
|
+
| **EventBus** | Emit event | 3.22M ops/sec | 0.31μs |
|
|
256
|
+
| **Decorators** | Define metadata | 5.48M ops/sec | 0.18μs |
|
|
257
|
+
|
|
258
|
+
#### Load Tests (500 Concurrent Players)
|
|
259
|
+
|
|
260
|
+
| Scenario | Throughput | p95 Latency | Error Rate |
|
|
261
|
+
| --------------------------- | --------------- | ----------- | ---------- |
|
|
262
|
+
| **Net Events (Simple)** | 92.59M ops/sec | 0.80μs | 0.00% |
|
|
263
|
+
| **Net Events (Validated)** | 11.47M ops/sec | 2.70μs | 0.00% |
|
|
264
|
+
| **Net Events (Concurrent)** | 1.61M ops/sec | 294.22μs | 0.00% |
|
|
265
|
+
| **Serialization (Large)** | 146.53K ops/sec | 951.11μs | 0.00% |
|
|
266
|
+
|
|
267
|
+
#### Key Performance Highlights
|
|
268
|
+
|
|
269
|
+
- ✅ **Zero error rate** across all load scenarios (10 → 500 players)
|
|
270
|
+
- ✅ **Sub-microsecond latency** for core operations
|
|
271
|
+
- ✅ **Excellent scalability** - handles 500+ concurrent players
|
|
272
|
+
- ✅ **Consistent p95/p99** - predictable latency behavior
|
|
273
|
+
|
|
274
|
+
> Full benchmark details available in [`benchmark/README.md`](./benchmark/README.md)
|
|
275
|
+
|
|
276
|
+
---
|
|
277
|
+
|
|
278
|
+
## 📁 Project Structure
|
|
279
|
+
|
|
280
|
+
```
|
|
281
|
+
opencore/
|
|
282
|
+
├── src/
|
|
283
|
+
│ ├── client/ # Client-side framework
|
|
284
|
+
│ │ ├── decorators/ # @OnNet, @Key, @Tick, @NUI, etc.
|
|
285
|
+
│ │ ├── services/ # Streaming, UI, World services
|
|
286
|
+
│ │ └── system/ # Processors and metadata
|
|
287
|
+
│ ├── server/ # Server-side framework
|
|
288
|
+
│ │ ├── decorators/ # @Command, @Guard, @Throttle, etc.
|
|
289
|
+
│ │ ├── services/ # Player, Command, RateLimiter, etc.
|
|
290
|
+
│ │ ├── entities/ # Player entity
|
|
291
|
+
│ │ └── bus/ # Core Event Bus
|
|
292
|
+
│ ├── shared/ # Shared utilities
|
|
293
|
+
│ │ └── logger/ # Logging system
|
|
294
|
+
│ └── system/ # Core system (MetadataScanner, DI)
|
|
295
|
+
├── tests/ # Test suites
|
|
296
|
+
│ ├── unit/
|
|
297
|
+
│ ├── integration/
|
|
298
|
+
│ └── mocks/
|
|
299
|
+
├── benchmark/ # Performance benchmarks
|
|
300
|
+
│ ├── core/ # Tinybench benchmarks
|
|
301
|
+
│ ├── load/ # Vitest load tests
|
|
302
|
+
│ └── reports/ # Generated reports
|
|
303
|
+
└── dist/ # Compiled output
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
---
|
|
307
|
+
|
|
308
|
+
## 📜 Available Scripts
|
|
309
|
+
|
|
310
|
+
| Script | Description |
|
|
311
|
+
| ----------------------- | -------------------------------- |
|
|
312
|
+
| `pnpm build` | Compile TypeScript to JavaScript |
|
|
313
|
+
| `pnpm watch` | Watch mode for development |
|
|
314
|
+
| `pnpm lint` | Run ESLint |
|
|
315
|
+
| `pnpm lint:fix` | Fix ESLint issues |
|
|
316
|
+
| `pnpm format` | Format code with Prettier |
|
|
317
|
+
| `pnpm test` | Run all tests |
|
|
318
|
+
| `pnpm test:unit` | Run unit tests only |
|
|
319
|
+
| `pnpm test:integration` | Run integration tests only |
|
|
320
|
+
| `pnpm test:coverage` | Generate coverage report |
|
|
321
|
+
| `pnpm bench` | Show benchmark options |
|
|
322
|
+
| `pnpm bench:core` | Run core benchmarks |
|
|
323
|
+
| `pnpm bench:load` | Run load benchmarks |
|
|
324
|
+
| `pnpm bench:all` | Run all benchmarks with reports |
|
|
325
|
+
|
|
326
|
+
---
|
|
327
|
+
|
|
328
|
+
## 🤝 Contributing
|
|
329
|
+
|
|
330
|
+
Contributions are welcome! Please ensure:
|
|
331
|
+
|
|
332
|
+
1. All tests pass (`pnpm test`)
|
|
333
|
+
2. Code is formatted (`pnpm format`)
|
|
334
|
+
3. No linting errors (`pnpm lint`)
|
|
335
|
+
4. New features include tests
|
|
336
|
+
|
|
337
|
+
---
|
|
338
|
+
|
|
339
|
+
## 📄 License
|
|
340
|
+
|
|
341
|
+
OpenCore is licensed under the **MPL-2.0**.
|
|
342
|
+
|
|
343
|
+
See [LICENSE](./LICENSE) for details.
|
|
344
|
+
|
|
345
|
+
---
|
|
346
|
+
|
|
347
|
+
<p align="center">
|
|
348
|
+
<strong>OpenCore Framework</strong><br>
|
|
349
|
+
<em>Stop scripting. Start engineering.</em>
|
|
350
|
+
</p>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function initClientCore(): Promise<void>;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.initClientCore = initClientCore;
|
|
4
|
+
const metadata_scanner_1 = require("../system/metadata.scanner");
|
|
5
|
+
const client_container_1 = require("./client-container");
|
|
6
|
+
const decorators_1 = require("./decorators");
|
|
7
|
+
const player_loader_1 = require("./player/player.loader");
|
|
8
|
+
const processors_register_1 = require("./system/processors.register");
|
|
9
|
+
const ui_bridge_1 = require("./ui-bridge");
|
|
10
|
+
// Services
|
|
11
|
+
const core_1 = require("./services/core");
|
|
12
|
+
const ui_1 = require("./services/ui");
|
|
13
|
+
const world_1 = require("./services/world");
|
|
14
|
+
const streaming_1 = require("./services/streaming");
|
|
15
|
+
const bootServices = [core_1.Spawner];
|
|
16
|
+
/**
|
|
17
|
+
* Basic setup for client, for configs, decorators, containers... etc
|
|
18
|
+
*/
|
|
19
|
+
function setSingletons() {
|
|
20
|
+
// Core services
|
|
21
|
+
client_container_1.di.registerSingleton(core_1.Spawner, core_1.Spawner);
|
|
22
|
+
// NUI
|
|
23
|
+
client_container_1.di.registerSingleton(ui_bridge_1.NuiBridge, ui_bridge_1.NuiBridge);
|
|
24
|
+
// UI services
|
|
25
|
+
client_container_1.di.registerSingleton(ui_1.NotificationService, ui_1.NotificationService);
|
|
26
|
+
client_container_1.di.registerSingleton(ui_1.TextUIService, ui_1.TextUIService);
|
|
27
|
+
client_container_1.di.registerSingleton(ui_1.ProgressService, ui_1.ProgressService);
|
|
28
|
+
// World services
|
|
29
|
+
client_container_1.di.registerSingleton(world_1.MarkerService, world_1.MarkerService);
|
|
30
|
+
client_container_1.di.registerSingleton(world_1.BlipService, world_1.BlipService);
|
|
31
|
+
client_container_1.di.registerSingleton(world_1.VehicleService, world_1.VehicleService);
|
|
32
|
+
client_container_1.di.registerSingleton(world_1.PedService, world_1.PedService);
|
|
33
|
+
// Streaming services
|
|
34
|
+
client_container_1.di.registerSingleton(streaming_1.StreamingService, streaming_1.StreamingService);
|
|
35
|
+
}
|
|
36
|
+
async function bootstraper() {
|
|
37
|
+
for (const Service of bootServices) {
|
|
38
|
+
const instance = client_container_1.di.resolve(Service);
|
|
39
|
+
if (typeof instance.init === 'function') {
|
|
40
|
+
await instance.init();
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
async function initClientCore() {
|
|
45
|
+
setSingletons();
|
|
46
|
+
// Register system processors
|
|
47
|
+
(0, processors_register_1.registerSystemClient)();
|
|
48
|
+
await bootstraper();
|
|
49
|
+
// Loaders
|
|
50
|
+
(0, player_loader_1.playerClientLoader)();
|
|
51
|
+
const scanner = client_container_1.di.resolve(metadata_scanner_1.MetadataScanner);
|
|
52
|
+
scanner.scan(decorators_1.clientControllerRegistry);
|
|
53
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { NuiBridge } from './ui-bridge';
|
|
2
|
+
import { Spawner } from './services/core';
|
|
3
|
+
import { NotificationService, TextUIService, ProgressService } from './services/ui';
|
|
4
|
+
import { MarkerService, BlipService, VehicleService, PedService } from './services/world';
|
|
5
|
+
import { StreamingService } from './services/streaming';
|
|
6
|
+
export declare function init(): Promise<void>;
|
|
7
|
+
export declare const services: {
|
|
8
|
+
readonly spawner: Spawner;
|
|
9
|
+
readonly nui: NuiBridge<Record<string, any>, Record<string, any>>;
|
|
10
|
+
readonly notifications: NotificationService;
|
|
11
|
+
readonly textUI: TextUIService;
|
|
12
|
+
readonly progress: ProgressService;
|
|
13
|
+
readonly markers: MarkerService;
|
|
14
|
+
readonly blips: BlipService;
|
|
15
|
+
readonly vehicles: VehicleService;
|
|
16
|
+
readonly peds: PedService;
|
|
17
|
+
readonly streaming: StreamingService;
|
|
18
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.services = void 0;
|
|
4
|
+
exports.init = init;
|
|
5
|
+
const client_bootstrap_1 = require("./client-bootstrap");
|
|
6
|
+
const client_container_1 = require("./client-container");
|
|
7
|
+
const ui_bridge_1 = require("./ui-bridge");
|
|
8
|
+
// Services
|
|
9
|
+
const core_1 = require("./services/core");
|
|
10
|
+
const ui_1 = require("./services/ui");
|
|
11
|
+
const world_1 = require("./services/world");
|
|
12
|
+
const streaming_1 = require("./services/streaming");
|
|
13
|
+
async function init() {
|
|
14
|
+
await (0, client_bootstrap_1.initClientCore)();
|
|
15
|
+
}
|
|
16
|
+
exports.services = {
|
|
17
|
+
// Core
|
|
18
|
+
get spawner() {
|
|
19
|
+
return client_container_1.di.resolve(core_1.Spawner);
|
|
20
|
+
},
|
|
21
|
+
// NUI
|
|
22
|
+
get nui() {
|
|
23
|
+
return client_container_1.di.resolve(ui_bridge_1.NuiBridge);
|
|
24
|
+
},
|
|
25
|
+
// UI
|
|
26
|
+
get notifications() {
|
|
27
|
+
return client_container_1.di.resolve(ui_1.NotificationService);
|
|
28
|
+
},
|
|
29
|
+
get textUI() {
|
|
30
|
+
return client_container_1.di.resolve(ui_1.TextUIService);
|
|
31
|
+
},
|
|
32
|
+
get progress() {
|
|
33
|
+
return client_container_1.di.resolve(ui_1.ProgressService);
|
|
34
|
+
},
|
|
35
|
+
// World
|
|
36
|
+
get markers() {
|
|
37
|
+
return client_container_1.di.resolve(world_1.MarkerService);
|
|
38
|
+
},
|
|
39
|
+
get blips() {
|
|
40
|
+
return client_container_1.di.resolve(world_1.BlipService);
|
|
41
|
+
},
|
|
42
|
+
get vehicles() {
|
|
43
|
+
return client_container_1.di.resolve(world_1.VehicleService);
|
|
44
|
+
},
|
|
45
|
+
get peds() {
|
|
46
|
+
return client_container_1.di.resolve(world_1.PedService);
|
|
47
|
+
},
|
|
48
|
+
// Streaming
|
|
49
|
+
get streaming() {
|
|
50
|
+
return client_container_1.di.resolve(streaming_1.StreamingService);
|
|
51
|
+
},
|
|
52
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.clientControllerRegistry = void 0;
|
|
4
|
+
exports.Controller = Controller;
|
|
5
|
+
const tsyringe_1 = require("tsyringe");
|
|
6
|
+
const metadata_client_keys_1 = require("../system/metadata-client.keys");
|
|
7
|
+
exports.clientControllerRegistry = [];
|
|
8
|
+
function Controller() {
|
|
9
|
+
return function (target) {
|
|
10
|
+
(0, tsyringe_1.injectable)()(target);
|
|
11
|
+
Reflect.defineMetadata(metadata_client_keys_1.METADATA_KEYS.CONTROLLER, { type: 'client' }, target);
|
|
12
|
+
exports.clientControllerRegistry.push(target);
|
|
13
|
+
};
|
|
14
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Decorator to expose a method as a client export.
|
|
3
|
+
* Other resources can call this via exports['resourceName']['exportName']()
|
|
4
|
+
*
|
|
5
|
+
* @param name - Optional custom export name. Defaults to method name.
|
|
6
|
+
*/
|
|
7
|
+
export declare function Export(name?: string): (target: any, propertyKey: string) => void;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Export = Export;
|
|
4
|
+
const metadata_client_keys_1 = require("../system/metadata-client.keys");
|
|
5
|
+
/**
|
|
6
|
+
* Decorator to expose a method as a client export.
|
|
7
|
+
* Other resources can call this via exports['resourceName']['exportName']()
|
|
8
|
+
*
|
|
9
|
+
* @param name - Optional custom export name. Defaults to method name.
|
|
10
|
+
*/
|
|
11
|
+
function Export(name) {
|
|
12
|
+
return (target, propertyKey) => {
|
|
13
|
+
Reflect.defineMetadata(metadata_client_keys_1.METADATA_KEYS.EXPORT, { exportName: name || propertyKey }, target, propertyKey);
|
|
14
|
+
};
|
|
15
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { GameEventName, GameEventMap } from '../types/game-events';
|
|
2
|
+
/**
|
|
3
|
+
* Decorator for handling native game events from the RAGE engine.
|
|
4
|
+
*
|
|
5
|
+
* These are low-level events triggered internally by GTA V.
|
|
6
|
+
* FiveM captures them via the 'gameEventTriggered' event.
|
|
7
|
+
*
|
|
8
|
+
* **Documentation:** https://docs.fivem.net/docs/game-references/game-events/
|
|
9
|
+
*
|
|
10
|
+
* ## Common Events:
|
|
11
|
+
*
|
|
12
|
+
* | Event | Description |
|
|
13
|
+
* |-------|-------------|
|
|
14
|
+
* | `CEventNetworkEntityDamage` | Entity receives damage |
|
|
15
|
+
* | `CEventNetworkPlayerEnteredVehicle` | Player enters vehicle |
|
|
16
|
+
* | `CEventNetworkPlayerLeftVehicle` | Player exits vehicle |
|
|
17
|
+
* | `CEventNetworkVehicleUndrivable` | Vehicle destroyed |
|
|
18
|
+
* | `CEventShockingSeenPedKilled` | Ped witnesses death |
|
|
19
|
+
* | `CEventGunShot` | Weapon fired |
|
|
20
|
+
*
|
|
21
|
+
* ## Usage:
|
|
22
|
+
*
|
|
23
|
+
* ```typescript
|
|
24
|
+
* @Controller()
|
|
25
|
+
* class CombatController {
|
|
26
|
+
* // Raw args (array)
|
|
27
|
+
* @OnGameEvent('CEventNetworkEntityDamage')
|
|
28
|
+
* onDamage(args: number[]) {
|
|
29
|
+
* const [victim, attacker] = args
|
|
30
|
+
* }
|
|
31
|
+
*
|
|
32
|
+
* // Or with auto-parsing (set autoParse: true)
|
|
33
|
+
* @OnGameEvent('CEventNetworkEntityDamage', { autoParse: true })
|
|
34
|
+
* onDamageParsed(data: EntityDamageEvent) {
|
|
35
|
+
* console.log(data.victim, data.attacker, data.victimDied)
|
|
36
|
+
* }
|
|
37
|
+
* }
|
|
38
|
+
* ```
|
|
39
|
+
*
|
|
40
|
+
* @param eventName - The native game event name (CEvent*)
|
|
41
|
+
* @param options - Optional configuration
|
|
42
|
+
*/
|
|
43
|
+
export declare function OnGameEvent<K extends GameEventName>(eventName: K, options?: {
|
|
44
|
+
autoParse?: boolean;
|
|
45
|
+
}): (target: any, propertyKey: string) => void;
|
|
46
|
+
export type { GameEventName, GameEventMap };
|
|
47
|
+
export type { EntityDamageEvent, PlayerEnteredVehicleEvent, PlayerLeftVehicleEvent, SeenPedKilledEvent, VehicleUndrivableEvent, GunShotEvent, } from '../types/game-events';
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OnGameEvent = OnGameEvent;
|
|
4
|
+
const metadata_client_keys_1 = require("../system/metadata-client.keys");
|
|
5
|
+
/**
|
|
6
|
+
* Decorator for handling native game events from the RAGE engine.
|
|
7
|
+
*
|
|
8
|
+
* These are low-level events triggered internally by GTA V.
|
|
9
|
+
* FiveM captures them via the 'gameEventTriggered' event.
|
|
10
|
+
*
|
|
11
|
+
* **Documentation:** https://docs.fivem.net/docs/game-references/game-events/
|
|
12
|
+
*
|
|
13
|
+
* ## Common Events:
|
|
14
|
+
*
|
|
15
|
+
* | Event | Description |
|
|
16
|
+
* |-------|-------------|
|
|
17
|
+
* | `CEventNetworkEntityDamage` | Entity receives damage |
|
|
18
|
+
* | `CEventNetworkPlayerEnteredVehicle` | Player enters vehicle |
|
|
19
|
+
* | `CEventNetworkPlayerLeftVehicle` | Player exits vehicle |
|
|
20
|
+
* | `CEventNetworkVehicleUndrivable` | Vehicle destroyed |
|
|
21
|
+
* | `CEventShockingSeenPedKilled` | Ped witnesses death |
|
|
22
|
+
* | `CEventGunShot` | Weapon fired |
|
|
23
|
+
*
|
|
24
|
+
* ## Usage:
|
|
25
|
+
*
|
|
26
|
+
* ```typescript
|
|
27
|
+
* @Controller()
|
|
28
|
+
* class CombatController {
|
|
29
|
+
* // Raw args (array)
|
|
30
|
+
* @OnGameEvent('CEventNetworkEntityDamage')
|
|
31
|
+
* onDamage(args: number[]) {
|
|
32
|
+
* const [victim, attacker] = args
|
|
33
|
+
* }
|
|
34
|
+
*
|
|
35
|
+
* // Or with auto-parsing (set autoParse: true)
|
|
36
|
+
* @OnGameEvent('CEventNetworkEntityDamage', { autoParse: true })
|
|
37
|
+
* onDamageParsed(data: EntityDamageEvent) {
|
|
38
|
+
* console.log(data.victim, data.attacker, data.victimDied)
|
|
39
|
+
* }
|
|
40
|
+
* }
|
|
41
|
+
* ```
|
|
42
|
+
*
|
|
43
|
+
* @param eventName - The native game event name (CEvent*)
|
|
44
|
+
* @param options - Optional configuration
|
|
45
|
+
*/
|
|
46
|
+
function OnGameEvent(eventName, options) {
|
|
47
|
+
return (target, propertyKey) => {
|
|
48
|
+
var _a;
|
|
49
|
+
Reflect.defineMetadata(metadata_client_keys_1.METADATA_KEYS.GAME_EVENT, {
|
|
50
|
+
eventName,
|
|
51
|
+
autoParse: (_a = options === null || options === void 0 ? void 0 : options.autoParse) !== null && _a !== void 0 ? _a : false,
|
|
52
|
+
}, target, propertyKey);
|
|
53
|
+
};
|
|
54
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export * from './controller';
|
|
2
|
+
export * from './key';
|
|
3
|
+
export * from './nui';
|
|
4
|
+
export * from './onNet';
|
|
5
|
+
export * from './tick';
|
|
6
|
+
export * from './localEvent';
|
|
7
|
+
export * from './interval';
|
|
8
|
+
export * from './export';
|
|
9
|
+
export * from './resourceLifecycle';
|
|
10
|
+
export * from './gameEvent';
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./controller"), exports);
|
|
18
|
+
__exportStar(require("./key"), exports);
|
|
19
|
+
__exportStar(require("./nui"), exports);
|
|
20
|
+
__exportStar(require("./onNet"), exports);
|
|
21
|
+
__exportStar(require("./tick"), exports);
|
|
22
|
+
__exportStar(require("./localEvent"), exports);
|
|
23
|
+
__exportStar(require("./interval"), exports);
|
|
24
|
+
__exportStar(require("./export"), exports);
|
|
25
|
+
__exportStar(require("./resourceLifecycle"), exports);
|
|
26
|
+
__exportStar(require("./gameEvent"), exports);
|