@armoury/fivem-framework-server 0.0.0-stage → 1.0.7

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 (129) hide show
  1. package/dist/cjs/decorators/command.decorator.js +37 -0
  2. package/dist/cjs/decorators/controller.decorator.js +9 -0
  3. package/dist/cjs/decorators/decorator.utils.js +43 -0
  4. package/dist/cjs/decorators/event-listener.decorator.js +64 -0
  5. package/dist/cjs/decorators/export.decorator.js +18 -0
  6. package/dist/cjs/decorators/index.js +16 -0
  7. package/dist/cjs/decorators/key-binding.decorator.js +29 -0
  8. package/dist/cjs/decorators/ui-listener.decorator.js +24 -0
  9. package/dist/cjs/server/entity-controllers/server-entity-entrance.controller.js +28 -0
  10. package/dist/cjs/server/index.js +82 -0
  11. package/dist/cjs/server/models/create-vehicle.enums.js +8 -0
  12. package/dist/cjs/server/models/index.js +17 -0
  13. package/dist/cjs/server/models/session/base-items/array.session-item.js +60 -0
  14. package/dist/cjs/server/models/session/base-items/index.js +17 -0
  15. package/dist/cjs/server/models/session/index.js +19 -0
  16. package/dist/cjs/server/models/session/session-item.model.js +19 -0
  17. package/dist/cjs/server/models/session/session.model.js +2 -0
  18. package/dist/cjs/server/server-db-dependent.controller.js +227 -0
  19. package/dist/cjs/server/server.base.js +32 -0
  20. package/dist/cjs/server/server.controller.js +83 -0
  21. package/dist/cjs/server/server.entities.js +57 -0
  22. package/dist/cjs/server/services/index.js +21 -0
  23. package/dist/cjs/server/services/server-enterable-database.service.js +37 -0
  24. package/dist/cjs/server/services/server-resource-database.service.js +242 -0
  25. package/dist/cjs/server/services/server-translate.service.js +54 -0
  26. package/dist/cjs/server/services/server-virtual-worlds.service.js +62 -0
  27. package/dist/cjs/server/services/session/default-entities/character.entity.js +31 -0
  28. package/dist/cjs/server/services/session/default-entities/index.js +24 -0
  29. package/dist/cjs/server/services/session/default-entities/session-account-id.js +10 -0
  30. package/dist/cjs/server/services/session/default-entities/session-cash.js +10 -0
  31. package/dist/cjs/server/services/session/default-entities/session-hours-played.js +16 -0
  32. package/dist/cjs/server/services/session/default-entities/session-id.js +10 -0
  33. package/dist/cjs/server/services/session/default-entities/session-language.js +10 -0
  34. package/dist/cjs/server/services/session/default-entities/session-last-location.js +19 -0
  35. package/dist/cjs/server/services/session/default-entities/session-name.js +10 -0
  36. package/dist/cjs/server/services/session/index.js +17 -0
  37. package/dist/cjs/server/services/session/server-session.service.js +271 -0
  38. package/dist/cjs/shared/index.js +17 -0
  39. package/dist/cjs/shared/models/account.js +2 -0
  40. package/dist/cjs/shared/models/character.js +2 -0
  41. package/dist/cjs/shared/models/index.js +18 -0
  42. package/dist/cjs/utils/utils.js +109 -0
  43. package/dist/esm/decorators/command.decorator.js +33 -0
  44. package/dist/esm/decorators/controller.decorator.js +6 -0
  45. package/dist/esm/decorators/decorator.utils.js +38 -0
  46. package/dist/esm/decorators/event-listener.decorator.js +59 -0
  47. package/dist/esm/decorators/export.decorator.js +14 -0
  48. package/dist/esm/decorators/index.js +6 -0
  49. package/dist/esm/decorators/key-binding.decorator.js +25 -0
  50. package/dist/esm/decorators/ui-listener.decorator.js +20 -0
  51. package/dist/esm/server/entity-controllers/server-entity-entrance.controller.js +24 -0
  52. package/dist/esm/server/index.js +64 -0
  53. package/dist/esm/server/models/create-vehicle.enums.js +5 -0
  54. package/dist/esm/server/models/index.js +1 -0
  55. package/dist/esm/server/models/session/base-items/array.session-item.js +56 -0
  56. package/dist/esm/server/models/session/base-items/index.js +1 -0
  57. package/dist/esm/server/models/session/index.js +3 -0
  58. package/dist/esm/server/models/session/session-item.model.js +15 -0
  59. package/dist/esm/server/models/session/session.model.js +1 -0
  60. package/dist/esm/server/server-db-dependent.controller.js +224 -0
  61. package/dist/esm/server/server.base.js +28 -0
  62. package/dist/esm/server/server.controller.js +80 -0
  63. package/dist/esm/server/server.entities.js +54 -0
  64. package/dist/esm/server/services/index.js +5 -0
  65. package/dist/esm/server/services/server-enterable-database.service.js +34 -0
  66. package/dist/esm/server/services/server-resource-database.service.js +239 -0
  67. package/dist/esm/server/services/server-translate.service.js +51 -0
  68. package/dist/esm/server/services/server-virtual-worlds.service.js +59 -0
  69. package/dist/esm/server/services/session/default-entities/character.entity.js +28 -0
  70. package/dist/esm/server/services/session/default-entities/index.js +8 -0
  71. package/dist/esm/server/services/session/default-entities/session-account-id.js +6 -0
  72. package/dist/esm/server/services/session/default-entities/session-cash.js +6 -0
  73. package/dist/esm/server/services/session/default-entities/session-hours-played.js +12 -0
  74. package/dist/esm/server/services/session/default-entities/session-id.js +6 -0
  75. package/dist/esm/server/services/session/default-entities/session-language.js +6 -0
  76. package/dist/esm/server/services/session/default-entities/session-last-location.js +15 -0
  77. package/dist/esm/server/services/session/default-entities/session-name.js +6 -0
  78. package/dist/esm/server/services/session/index.js +1 -0
  79. package/dist/esm/server/services/session/server-session.service.js +268 -0
  80. package/dist/esm/shared/index.js +1 -0
  81. package/dist/esm/shared/models/account.js +1 -0
  82. package/dist/esm/shared/models/character.js +1 -0
  83. package/dist/esm/shared/models/index.js +2 -0
  84. package/dist/esm/utils/utils.js +93 -0
  85. package/dist/types/ambient.declarations.d.ts +62840 -0
  86. package/dist/types/decorators/command.decorator.d.ts +5 -0
  87. package/dist/types/decorators/controller.decorator.d.ts +1 -0
  88. package/dist/types/decorators/decorator.utils.d.ts +15 -0
  89. package/dist/types/decorators/event-listener.decorator.d.ts +15 -0
  90. package/dist/types/decorators/export.decorator.d.ts +2 -0
  91. package/dist/types/decorators/index.d.ts +6 -0
  92. package/dist/types/decorators/key-binding.decorator.d.ts +8 -0
  93. package/dist/types/decorators/ui-listener.decorator.d.ts +4 -0
  94. package/dist/types/server/entity-controllers/server-entity-entrance.controller.d.ts +14 -0
  95. package/dist/types/server/index.d.ts +23 -0
  96. package/dist/types/server/models/create-vehicle.enums.d.ts +3 -0
  97. package/dist/types/server/models/index.d.ts +1 -0
  98. package/dist/types/server/models/session/base-items/array.session-item.d.ts +13 -0
  99. package/dist/types/server/models/session/base-items/index.d.ts +1 -0
  100. package/dist/types/server/models/session/index.d.ts +3 -0
  101. package/dist/types/server/models/session/session-item.model.d.ts +22 -0
  102. package/dist/types/server/models/session/session.model.d.ts +4 -0
  103. package/dist/types/server/server-db-dependent.controller.d.ts +29 -0
  104. package/dist/types/server/server.base.d.ts +7 -0
  105. package/dist/types/server/server.controller.d.ts +20 -0
  106. package/dist/types/server/server.entities.d.ts +13 -0
  107. package/dist/types/server/services/index.d.ts +5 -0
  108. package/dist/types/server/services/server-enterable-database.service.d.ts +14 -0
  109. package/dist/types/server/services/server-resource-database.service.d.ts +37 -0
  110. package/dist/types/server/services/server-translate.service.d.ts +12 -0
  111. package/dist/types/server/services/server-virtual-worlds.service.d.ts +15 -0
  112. package/dist/types/server/services/session/default-entities/character.entity.d.ts +5 -0
  113. package/dist/types/server/services/session/default-entities/index.d.ts +8 -0
  114. package/dist/types/server/services/session/default-entities/session-account-id.d.ts +4 -0
  115. package/dist/types/server/services/session/default-entities/session-cash.d.ts +4 -0
  116. package/dist/types/server/services/session/default-entities/session-hours-played.d.ts +5 -0
  117. package/dist/types/server/services/session/default-entities/session-id.d.ts +4 -0
  118. package/dist/types/server/services/session/default-entities/session-language.d.ts +4 -0
  119. package/dist/types/server/services/session/default-entities/session-last-location.d.ts +6 -0
  120. package/dist/types/server/services/session/default-entities/session-name.d.ts +4 -0
  121. package/dist/types/server/services/session/index.d.ts +1 -0
  122. package/dist/types/server/services/session/server-session.service.d.ts +70 -0
  123. package/dist/types/shared/index.d.ts +1 -0
  124. package/dist/types/shared/models/account.d.ts +5 -0
  125. package/dist/types/shared/models/character.d.ts +4 -0
  126. package/dist/types/shared/models/index.d.ts +2 -0
  127. package/dist/types/utils/utils.d.ts +15 -0
  128. package/package.json +32 -5
  129. package/README.md +0 -3
@@ -0,0 +1,24 @@
1
+ // TODO: Remove
2
+ import { isPlayerInRangeOfPoint } from '@armoury/fivem-framework-common';
3
+ import { ServerDBDependentController } from '../server-db-dependent.controller';
4
+ export class ServerEntityWithEntranceController extends ServerDBDependentController {
5
+ getClosestEntityOfSameTypeToPlayer(player) {
6
+ return this.getClosestEntityOfSameTypeExitToPlayer(player) || this.getClosestEntityOfSameTypeEntranceToPlayer(player);
7
+ }
8
+ getClosestEntityOfSameTypeEntranceToPlayer(source) {
9
+ // TODO: Replace here to actually get the closest, not the first one in the range
10
+ const playerPosition = Cfx.Server.GetEntityCoords(Cfx.Server.GetPlayerPed(Cfx.source.toString()) /*, true*/);
11
+ const entity = this.entities.find((_entity) => isPlayerInRangeOfPoint(playerPosition[0], playerPosition[1], playerPosition[2], _entity.entranceX, _entity.entranceY, _entity.entranceZ, 3.0));
12
+ return entity || null;
13
+ }
14
+ getClosestEntityOfSameTypeExitToPlayer(source) {
15
+ const virtualWorld = this.getPlayerVirtualWorld(source) || 0;
16
+ const entity = this.getEntityByDBId(virtualWorld);
17
+ const playerPosition = Cfx.Server.GetEntityCoords(Cfx.Server.GetPlayerPed(Cfx.source.toString()) /*, true*/);
18
+ // TODO: Replace here to actually get the closest, not the first one in the range
19
+ if (entity && isPlayerInRangeOfPoint(playerPosition[0], playerPosition[1], playerPosition[2], entity.exitX, entity.exitY, entity.exitZ, 3.0)) {
20
+ return entity;
21
+ }
22
+ return null;
23
+ }
24
+ }
@@ -0,0 +1,64 @@
1
+ /// <reference path = "../ambient.declarations.d.ts" />
2
+ import 'reflect-metadata';
3
+ import { MikroORM } from '@mikro-orm/core';
4
+ import { ReflectiveInjector } from 'injection-js';
5
+ import { Character, SessionAccountId, SessionCash, SessionHoursPlayed, SessionId, SessionLanguage, SessionLastLocation, SessionName } from './services/session/default-entities';
6
+ import { Decorate } from '@armoury/fivem-framework-common';
7
+ export const SERVER_PROVIDERS = [
8
+ {
9
+ provide: 'sessionItems',
10
+ useValue: new SessionId(),
11
+ multi: true,
12
+ },
13
+ {
14
+ provide: 'sessionItems',
15
+ useValue: new SessionAccountId(),
16
+ multi: true,
17
+ },
18
+ {
19
+ provide: 'sessionItems',
20
+ useValue: new SessionName(),
21
+ multi: true,
22
+ },
23
+ {
24
+ provide: 'sessionItems',
25
+ useValue: new SessionCash(),
26
+ multi: true,
27
+ },
28
+ {
29
+ provide: 'sessionItems',
30
+ useValue: new SessionHoursPlayed(),
31
+ multi: true,
32
+ },
33
+ {
34
+ provide: 'sessionItems',
35
+ useValue: new SessionLastLocation(),
36
+ multi: true,
37
+ },
38
+ {
39
+ provide: 'sessionItems',
40
+ useValue: new SessionLanguage(),
41
+ multi: true,
42
+ },
43
+ ];
44
+ export async function Server_Init(_class, ...providers) {
45
+ var _a;
46
+ const database = (_a = Cfx.Server.GetConvar('mysql_connection_string', '').split(';')
47
+ .find((item) => item.startsWith('database='))) === null || _a === void 0 ? void 0 : _a.split('=').slice(-1)[0];
48
+ const test = await MikroORM.init({
49
+ baseDir: __dirname + '/../..',
50
+ entities: [Character],
51
+ // entitiesTs: ['./src/**/*.entity.ts'],
52
+ dbName: database,
53
+ discovery: { disableDynamicFileAccess: true }
54
+ });
55
+ console.log('mikro-orm is', test);
56
+ const mainInjector = ReflectiveInjector.resolveAndCreate(SERVER_PROVIDERS);
57
+ const injector = ReflectiveInjector.resolveAndCreate([...providers, _class], mainInjector);
58
+ const instance = injector.get(_class);
59
+ Decorate(instance, _class.prototype, [...SERVER_PROVIDERS, ...providers]);
60
+ return instance;
61
+ }
62
+ export * from './services';
63
+ export * from './models';
64
+ export * from '@armoury/fivem-framework-common';
@@ -0,0 +1,5 @@
1
+ export var CREATE_VEHICLE_EVENT_TYPE;
2
+ (function (CREATE_VEHICLE_EVENT_TYPE) {
3
+ CREATE_VEHICLE_EVENT_TYPE[CREATE_VEHICLE_EVENT_TYPE["ATTACH_TRAILER"] = 0] = "ATTACH_TRAILER";
4
+ })(CREATE_VEHICLE_EVENT_TYPE || (CREATE_VEHICLE_EVENT_TYPE = {}));
5
+ ;
@@ -0,0 +1 @@
1
+ export * from './session';
@@ -0,0 +1,56 @@
1
+ import { SessionItem } from "../session-item.model";
2
+ export class ArraySessionItem extends SessionItem {
3
+ constructor(name, value, critical = false, tableName, syncedProperties) {
4
+ super(name, value, critical);
5
+ this.tableName = tableName;
6
+ this.syncedProperties = syncedProperties;
7
+ if (!this.syncedProperties.length) {
8
+ this.syncedProperties.push({ name: 'value', type: 'varchar(256)' });
9
+ }
10
+ this.syncedProperties = [
11
+ ...DEFAULT_PROPERTIES,
12
+ ...syncedProperties
13
+ ];
14
+ this.setup();
15
+ }
16
+ async load(accountId, characterId) {
17
+ return await Cfx.exports['oxmysql'].query_async(`SELECT * FROM ${this.tableName} WHERE id=? AND accountId=?`, [characterId, accountId]);
18
+ }
19
+ async save(accountId, characterId, value) {
20
+ const columns = this.syncedProperties.map((prop) => prop.name).join(',');
21
+ const keys = value.map(() => `(${new Array(columns.length).fill(0).map(() => '?').join(', ')})`).join(', ');
22
+ const values = new Array(value.length).fill(0).map((_, valueIndex) => this.syncedProperties.map((prop) => {
23
+ if (prop.name === 'accountId') {
24
+ return accountId;
25
+ }
26
+ if (prop.name === 'characterId') {
27
+ return characterId;
28
+ }
29
+ return value[valueIndex][prop.name];
30
+ }))
31
+ .flat();
32
+ await Cfx.exports['oxmysql'].query_async(`DELETE FROM \`${this.tableName}\` WHERE accountId = ? AND characterId = ?`, [accountId, characterId]);
33
+ await Cfx.exports['oxmysql'].insert_async(`INSERT INTO \`${this.tableName}\` (${columns}) VALUES ${keys}`, values);
34
+ }
35
+ async setup() {
36
+ var _a;
37
+ const database = (_a = Cfx.Server.GetConvar('mysql_connection_string', '').split(';')
38
+ .find((item) => item.startsWith('database='))) === null || _a === void 0 ? void 0 : _a.split('=').slice(-1)[0];
39
+ const result = await Cfx.exports['oxmysql'].single_async(`SELECT EXISTS (
40
+ SELECT 1
41
+ FROM information_schema.tables
42
+ WHERE table_schema = '${database}'
43
+ AND table_name = '${this.tableName}'
44
+ ) AS table_exists;`);
45
+ if (!result.table_exists) {
46
+ // TODO: Create table
47
+ }
48
+ else {
49
+ // TODO: Do migrations
50
+ }
51
+ }
52
+ }
53
+ const DEFAULT_PROPERTIES = [
54
+ { name: 'accountId', type: 'int(11)' },
55
+ { name: 'characterId', type: 'int(11)' },
56
+ ];
@@ -0,0 +1 @@
1
+ export * from './array.session-item';
@@ -0,0 +1,3 @@
1
+ export * from './base-items';
2
+ export * from './session-item.model';
3
+ export * from './session.model';
@@ -0,0 +1,15 @@
1
+ export class SessionItem {
2
+ constructor(name, defaultValue, critical = false) {
3
+ this.name = name;
4
+ this.defaultValue = defaultValue;
5
+ this.critical = critical;
6
+ }
7
+ load(_accountId, _characterId, bruteValue) {
8
+ return Promise.resolve(!Number.isNaN(Number(bruteValue))
9
+ ? Number(bruteValue)
10
+ : bruteValue);
11
+ }
12
+ compute(_playerId, originalValue) {
13
+ return originalValue;
14
+ }
15
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,224 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ // TODO: Remove
11
+ import { ServerController } from "./server.controller";
12
+ import { isJSON, Controller, EventListener, Export } from '@armoury/fivem-framework-common';
13
+ let ServerDBDependentController = class ServerDBDependentController extends ServerController {
14
+ get entities() {
15
+ return this._entities;
16
+ }
17
+ get cachedProperties() {
18
+ return this._cachedProperties;
19
+ }
20
+ get playerToEntityBindings() {
21
+ return this._playerToEntityBindings;
22
+ }
23
+ constructor(dbTableName, loadAllAtStart = false) {
24
+ super();
25
+ this.dbTableName = dbTableName;
26
+ this._entities = [];
27
+ this._cachedProperties = [];
28
+ this._playerToEntityBindings = new Map();
29
+ this.computeTableProperties();
30
+ if (loadAllAtStart) {
31
+ this.loadDBEntities();
32
+ }
33
+ }
34
+ getEntities() {
35
+ return this._entities;
36
+ }
37
+ createEntity(entity, forceId) {
38
+ return (async () => {
39
+ try {
40
+ let entityProperties = this.getEntityProperties(entity);
41
+ let entityValues = this.getEntityPropertiesValues(entity, entityProperties);
42
+ if (forceId) {
43
+ entityProperties = ['id', ...entityProperties];
44
+ entityValues = [forceId.toString(), ...entityValues];
45
+ }
46
+ const id = await Cfx.exports['oxmysql'].insert_async(`INSERT INTO \`${this.dbTableName}\` (${entityProperties.join(', ')}) VALUES (${Array(entityProperties.length).fill('?').join(', ')})`, entityValues);
47
+ const createdEntity = Object.assign(Object.assign({}, entity), { id: forceId || id });
48
+ this._entities.push(createdEntity);
49
+ this.syncWithClients();
50
+ return createdEntity;
51
+ }
52
+ catch (error) {
53
+ console.log(error);
54
+ return null;
55
+ }
56
+ })();
57
+ }
58
+ removeEntity(entity) {
59
+ return (async () => {
60
+ try {
61
+ const result = await Cfx.exports['oxmysql'].query_async(`DELETE FROM \`${this.dbTableName}\` WHERE id = ?`, [entity.id]);
62
+ this._entities = this._entities.filter((_entity) => _entity.id !== entity.id);
63
+ this.syncWithClients();
64
+ return !!result;
65
+ }
66
+ catch (error) {
67
+ console.log(error);
68
+ return false;
69
+ }
70
+ })();
71
+ }
72
+ saveDBEntityAsync(id) {
73
+ return (async () => {
74
+ try {
75
+ const entity = this.getEntityByDBId(id);
76
+ if (!entity)
77
+ return false;
78
+ const updateKeys = this.getEntityProperties(entity);
79
+ const updateValues = this.getEntityPropertiesValues(entity, updateKeys);
80
+ const concatString = ' = ?, ';
81
+ const result = await Cfx.exports['oxmysql'].update_async(`UPDATE \`${this.dbTableName}\` SET ${updateKeys.join(concatString).concat(concatString).slice(0, -2)} WHERE id = ?`, [...updateValues, entity.id]);
82
+ if (result) {
83
+ this.syncWithClients();
84
+ }
85
+ return result > 0;
86
+ }
87
+ catch (error) {
88
+ console.log(error);
89
+ return false;
90
+ }
91
+ })();
92
+ }
93
+ getEntityByDBId(id) {
94
+ return this._entities.find((_entity) => _entity.id === id);
95
+ }
96
+ async loadDBEntityFor(value, key = 'id', bindTo) {
97
+ const result = (await Cfx.exports['oxmysql'].query_async(`SELECT * FROM \`${this.dbTableName}\` WHERE ${key} = ?`, [value])).map((resultItem) => {
98
+ Object.keys(resultItem).forEach((property) => {
99
+ resultItem[property] = JSON.parse(isJSON(resultItem[property].toString()) ? resultItem[property] : `"${resultItem[property]}"`, function (_k, v) {
100
+ return (typeof v === "object" || isNaN(v)) ? v : Number(v);
101
+ });
102
+ });
103
+ return resultItem;
104
+ });
105
+ if (result === null || result === void 0 ? void 0 : result.length) {
106
+ result.forEach((entity) => {
107
+ this._entities.push(entity);
108
+ if (bindTo) {
109
+ this.bindEntityToPlayerByEntityId(entity.id, bindTo);
110
+ }
111
+ });
112
+ setTimeout(() => { this.syncWithClients(); }, 2000);
113
+ return ((result === null || result === void 0 ? void 0 : result.length) > 1 ? result : result[0]);
114
+ }
115
+ return null;
116
+ }
117
+ async loadDBEntities() {
118
+ const result = (await Cfx.exports['oxmysql'].query_async(`SELECT * FROM \`${this.dbTableName}\``, [])).map((resultItem) => {
119
+ Object.keys(resultItem).forEach((property) => {
120
+ resultItem[property] = JSON.parse(isJSON(resultItem[property].toString()) ? resultItem[property] : `"${resultItem[property]}"`, function (_k, v) {
121
+ return (typeof v === "object" || isNaN(v)) ? v : Number(v);
122
+ });
123
+ });
124
+ return resultItem;
125
+ });
126
+ if (result === null || result === void 0 ? void 0 : result.length) {
127
+ this._entities = result;
128
+ setTimeout(() => { this.syncWithClients(); }, 2000);
129
+ }
130
+ return this._entities;
131
+ }
132
+ getEntityProperties(entity) {
133
+ const keys = [];
134
+ for (let key in entity) {
135
+ if (key !== 'id' && (!this._cachedProperties.length || this._cachedProperties.includes(key))) {
136
+ keys.push(key);
137
+ }
138
+ }
139
+ return keys;
140
+ }
141
+ getEntityPropertiesValues(entity, properties) {
142
+ return properties.map((key) => {
143
+ if (Array.isArray(entity[key]) || typeof (entity[key]) === 'object') {
144
+ return JSON.stringify(entity[key]);
145
+ }
146
+ return entity[key].toString();
147
+ });
148
+ }
149
+ syncWithClients(client) {
150
+ // TODO: Probable performance issue cause. Entity updates should be sent to clients only for a specific property, so they don't need to wipe ALL data and rewrite it back.
151
+ Cfx.Server.TriggerClientEvent(`${Cfx.Server.GetCurrentResourceName()}:db-send-entities`, client || -1, this.entities);
152
+ }
153
+ bindEntityToPlayer(entity, playerId) {
154
+ if (this.entities.includes(entity)) {
155
+ this.bindEntityToPlayerByEntityId(entity.id, playerId);
156
+ }
157
+ }
158
+ bindEntityToPlayerByEntityId(id, playerId) {
159
+ const entityExists = this._entities.some((entity) => entity.id === id);
160
+ if (entityExists) {
161
+ if (this._playerToEntityBindings.has(playerId)) {
162
+ this._playerToEntityBindings.set(playerId, [...this._playerToEntityBindings.get(playerId), id]);
163
+ }
164
+ else {
165
+ this._playerToEntityBindings.set(playerId, [id]);
166
+ }
167
+ }
168
+ }
169
+ onBoundEntityDestroyed(_entity, _boundPlayer) { }
170
+ onPlayerAuthenticate(playerId, _player) {
171
+ if (this._entities.length) {
172
+ this.syncWithClients(playerId);
173
+ }
174
+ }
175
+ onPlayerDisconnect() {
176
+ if (this._playerToEntityBindings.has(Cfx.source)) {
177
+ const bindings = (this._playerToEntityBindings.has(Cfx.source)
178
+ ? this._playerToEntityBindings.get(Cfx.source)
179
+ : []);
180
+ bindings.forEach((entityId) => {
181
+ const entityBoundToPlayer = this._entities.find((entity) => entity.id === entityId);
182
+ if (entityBoundToPlayer) {
183
+ this.onBoundEntityDestroyed(entityBoundToPlayer, Cfx.source);
184
+ this._entities.splice(this._entities.indexOf(entityBoundToPlayer), 1);
185
+ }
186
+ });
187
+ this._playerToEntityBindings.delete(Cfx.source);
188
+ }
189
+ }
190
+ async computeTableProperties() {
191
+ const result = await Cfx.exports['oxmysql'].query_async(`DESCRIBE ${this.dbTableName}`, []);
192
+ if (result) {
193
+ result.forEach((sqlStructureObject) => {
194
+ this._cachedProperties.push(sqlStructureObject.Field);
195
+ });
196
+ }
197
+ else {
198
+ console.error(`[SQL ERROR:] computeTableProperties for ${Cfx.Server.GetCurrentResourceName()} did not work.`);
199
+ }
200
+ }
201
+ };
202
+ __decorate([
203
+ Export(),
204
+ __metadata("design:type", Function),
205
+ __metadata("design:paramtypes", []),
206
+ __metadata("design:returntype", Array)
207
+ ], ServerDBDependentController.prototype, "getEntities", null);
208
+ __decorate([
209
+ EventListener(),
210
+ __metadata("design:type", Function),
211
+ __metadata("design:paramtypes", [Number, Object]),
212
+ __metadata("design:returntype", void 0)
213
+ ], ServerDBDependentController.prototype, "onPlayerAuthenticate", null);
214
+ __decorate([
215
+ EventListener(),
216
+ __metadata("design:type", Function),
217
+ __metadata("design:paramtypes", []),
218
+ __metadata("design:returntype", void 0)
219
+ ], ServerDBDependentController.prototype, "onPlayerDisconnect", null);
220
+ ServerDBDependentController = __decorate([
221
+ Controller(),
222
+ __metadata("design:paramtypes", [String, Boolean])
223
+ ], ServerDBDependentController);
224
+ export { ServerDBDependentController };
@@ -0,0 +1,28 @@
1
+ // TODO: Remove
2
+ export class ServerBase {
3
+ constructor() {
4
+ this.routingBucketCondition = (source, routingBucket) => true;
5
+ this.assignServerBaseListeners();
6
+ }
7
+ // TODO: Remove this. We have created a brand new cool decorator for this
8
+ RegisterAdminCommand(commandName, adminLevelRequired, handlerFunction, restricted) {
9
+ Cfx.Server.RegisterCommand(commandName, (source, args, _raw) => {
10
+ if (Number(Cfx.exports['authentication'].getPlayerInfo(source, 'adminLevel')) < adminLevelRequired) {
11
+ // TODO: Add error chat message OR some kind of visual notice here
12
+ return;
13
+ }
14
+ handlerFunction(source, args, _raw);
15
+ }, restricted);
16
+ }
17
+ assignServerBaseListeners() {
18
+ Cfx.Server.onNet(`${Cfx.Server.GetCurrentResourceName()}:set-client-routing-bucket`, (source, routingBucket) => {
19
+ if (this.routingBucketCondition(source, routingBucket)) {
20
+ Cfx.Server.SetEntityRoutingBucket(source, routingBucket);
21
+ }
22
+ });
23
+ }
24
+ setRoutingBucket(playerId, routingBucket) {
25
+ Cfx.Server.SetEntityRoutingBucket(Cfx.Server.GetPlayerPed(playerId.toString()), routingBucket);
26
+ Cfx.Server.TriggerClientEvent(`${Cfx.Server.GetCurrentResourceName()}:set-routing-bucket`, playerId, routingBucket);
27
+ }
28
+ }
@@ -0,0 +1,80 @@
1
+ // TODO: Remove
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ import { Controller, EventListener } from '@armoury/fivem-framework-common';
12
+ import { ServerEntities } from "./server.entities";
13
+ let ServerController = class ServerController extends ServerEntities {
14
+ constructor() {
15
+ super(...arguments);
16
+ this._translationLanguage = 'en';
17
+ this._clientsidedResourceMap = new Map();
18
+ }
19
+ get translationLanguage() {
20
+ return this._translationLanguage;
21
+ }
22
+ get clientsidedResourceMap() {
23
+ return this._clientsidedResourceMap;
24
+ }
25
+ getPlayerClientsidedCacheKey(playerId, key) {
26
+ if (this._clientsidedResourceMap.has(playerId)) {
27
+ const metadataObject = this._clientsidedResourceMap.get(playerId);
28
+ if (metadataObject[key]) {
29
+ return metadataObject[key];
30
+ }
31
+ }
32
+ return null;
33
+ }
34
+ updatePlayerClientsidedCacheKey(playerId, key, value) {
35
+ const currentPlayerClientsidedResourceMapValue = this._clientsidedResourceMap.has(playerId)
36
+ ? this._clientsidedResourceMap.get(playerId) || {}
37
+ : {};
38
+ currentPlayerClientsidedResourceMapValue[key] = value;
39
+ this._clientsidedResourceMap.set(playerId, currentPlayerClientsidedResourceMapValue);
40
+ Cfx.Server.TriggerClientEvent('armoury-overlay:update-resource-metadata', playerId, Cfx.Server.GetCurrentResourceName(), key, value);
41
+ }
42
+ onPlayerClientsidedCacheLoaded(metadataObject) {
43
+ if (metadataObject[Cfx.Server.GetCurrentResourceName()]) {
44
+ this._clientsidedResourceMap.set(Cfx.source, metadataObject[Cfx.Server.GetCurrentResourceName()]);
45
+ }
46
+ }
47
+ onPlayerDisconnect() {
48
+ if (this._clientsidedResourceMap.has(Cfx.source)) {
49
+ this._clientsidedResourceMap.delete(Cfx.source);
50
+ }
51
+ }
52
+ translate(key, params) {
53
+ let content = this.translationFile[this._translationLanguage][key];
54
+ if (params) {
55
+ Object.keys(params).forEach((param) => {
56
+ content = content.replace(`{${param}}`, params[param]);
57
+ });
58
+ }
59
+ return content;
60
+ }
61
+ setTranslationLanguage(language) {
62
+ this._translationLanguage = language;
63
+ }
64
+ };
65
+ __decorate([
66
+ EventListener(),
67
+ __metadata("design:type", Function),
68
+ __metadata("design:paramtypes", [Object]),
69
+ __metadata("design:returntype", void 0)
70
+ ], ServerController.prototype, "onPlayerClientsidedCacheLoaded", null);
71
+ __decorate([
72
+ EventListener(),
73
+ __metadata("design:type", Function),
74
+ __metadata("design:paramtypes", []),
75
+ __metadata("design:returntype", void 0)
76
+ ], ServerController.prototype, "onPlayerDisconnect", null);
77
+ ServerController = __decorate([
78
+ Controller()
79
+ ], ServerController);
80
+ export { ServerController };
@@ -0,0 +1,54 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ // TODO: Remove
11
+ import { Controller, EventListener } from '@armoury/fivem-framework-common';
12
+ import { ServerBase } from './server.base';
13
+ let ServerEntities = class ServerEntities extends ServerBase {
14
+ constructor() {
15
+ super(...arguments);
16
+ // Probable performance issue? Maybe calling the export so many times when changing the virtual world is too costly?
17
+ this._virtualWorldsWithPlayers = new Map();
18
+ }
19
+ /** This only counts virtual worlds related to the resource! If another resource changes the virtual world of the player, this resource won't know it! */
20
+ get virtualWorldsWithPlayers() {
21
+ return this._virtualWorldsWithPlayers;
22
+ }
23
+ onPlayerEnteredScope(data) {
24
+ Cfx.Server.TriggerClientEvent(`${Cfx.Server.GetCurrentResourceName()}:refresh-virtual-world`, data.for);
25
+ }
26
+ setPlayerVirtualWorld(playerId, virtualWorld) {
27
+ const currentPlayerVirtualWorld = this.getPlayerVirtualWorld(playerId);
28
+ if (!isNaN(currentPlayerVirtualWorld)) {
29
+ this._virtualWorldsWithPlayers.set(currentPlayerVirtualWorld, (this._virtualWorldsWithPlayers.has(currentPlayerVirtualWorld) ? this._virtualWorldsWithPlayers.get(currentPlayerVirtualWorld) : []).filter((_playerId) => _playerId !== playerId));
30
+ }
31
+ const newPlayersInVirtualWorld = [
32
+ ...(this._virtualWorldsWithPlayers.has(virtualWorld) ? this._virtualWorldsWithPlayers.get(virtualWorld) : []),
33
+ playerId
34
+ ];
35
+ this._virtualWorldsWithPlayers.set(virtualWorld, newPlayersInVirtualWorld);
36
+ Cfx.exports['authentication'].setPlayerInfo(playerId, 'virtualWorld', virtualWorld);
37
+ }
38
+ getPlayerVirtualWorld(playerId) {
39
+ return Math.max(0, Number(Cfx.exports['authentication'].getPlayerInfo(playerId, 'virtualWorld')));
40
+ }
41
+ removeClientsideVehicles() {
42
+ Cfx.Server.TriggerClientEvent(`${Cfx.Server.GetCurrentResourceName()}:ARM_remove-vehicles`, -1);
43
+ }
44
+ };
45
+ __decorate([
46
+ EventListener({ eventName: 'playerEnteredScope' }),
47
+ __metadata("design:type", Function),
48
+ __metadata("design:paramtypes", [Object]),
49
+ __metadata("design:returntype", void 0)
50
+ ], ServerEntities.prototype, "onPlayerEnteredScope", null);
51
+ ServerEntities = __decorate([
52
+ Controller()
53
+ ], ServerEntities);
54
+ export { ServerEntities };
@@ -0,0 +1,5 @@
1
+ export * from './server-resource-database.service';
2
+ export * from './server-enterable-database.service';
3
+ export * from './server-virtual-worlds.service';
4
+ export * from './server-translate.service';
5
+ export * from './session';
@@ -0,0 +1,34 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { Injectable } from "injection-js";
8
+ import { ServerResourceDatabase } from "./server-resource-database.service";
9
+ import { isPlayerInRangeOfPoint } from '@armoury/fivem-framework-common';
10
+ let ServerEnterableDatabase = class ServerEnterableDatabase extends ServerResourceDatabase {
11
+ getClosestToPlayer(player) {
12
+ return this.getClosestExitToPlayer(player) || this.getClosestEntranceToPlayer(player);
13
+ }
14
+ getClosestEntranceToPlayer(source) {
15
+ // TODO: Replace here to actually get the closest, not the first one in the range
16
+ const playerPosition = Cfx.Server.GetEntityCoords(Cfx.Server.GetPlayerPed(source.toString()));
17
+ const entity = this.entities.find((_entity) => isPlayerInRangeOfPoint(playerPosition[0], playerPosition[1], playerPosition[2], _entity.entranceX, _entity.entranceY, _entity.entranceZ, 3.0));
18
+ return entity || null;
19
+ }
20
+ getClosestExitToPlayer(source) {
21
+ const virtualWorld = Math.max(0, Number(Cfx.exports['authentication'].getPlayerInfo(source, 'virtualWorld')));
22
+ const entity = this.getEntityByDBId(virtualWorld);
23
+ const playerPosition = Cfx.Server.GetEntityCoords(Cfx.Server.GetPlayerPed(source.toString()));
24
+ // TODO: Replace here to actually get the closest, not the first one in the range
25
+ if (entity && isPlayerInRangeOfPoint(playerPosition[0], playerPosition[1], playerPosition[2], entity.exitX, entity.exitY, entity.exitZ, 3.0)) {
26
+ return entity;
27
+ }
28
+ return null;
29
+ }
30
+ };
31
+ ServerEnterableDatabase = __decorate([
32
+ Injectable()
33
+ ], ServerEnterableDatabase);
34
+ export { ServerEnterableDatabase };