@armoury/fivem-framework-common 0.0.0-stage → 1.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/common/index.js +26 -0
- package/dist/cjs/decorators/command.decorator.js +37 -0
- package/dist/cjs/decorators/controller.decorator.js +9 -0
- package/dist/cjs/decorators/decorator.utils.js +43 -0
- package/dist/cjs/decorators/event-listener.decorator.js +64 -0
- package/dist/cjs/decorators/export.decorator.js +18 -0
- package/dist/cjs/decorators/index.js +16 -0
- package/dist/cjs/decorators/key-binding.decorator.js +29 -0
- package/dist/cjs/decorators/ui-listener.decorator.js +24 -0
- package/dist/cjs/shared/index.js +17 -0
- package/dist/cjs/shared/models/account.js +2 -0
- package/dist/cjs/shared/models/character.js +2 -0
- package/dist/cjs/shared/models/index.js +18 -0
- package/dist/cjs/utils/index.js +21 -0
- package/dist/cjs/utils/location-utils.js +9 -0
- package/dist/cjs/utils/string-formatter.js +29 -0
- package/dist/cjs/utils/utils.js +109 -0
- package/dist/esm/common/index.js +7 -0
- package/dist/esm/decorators/command.decorator.js +33 -0
- package/dist/esm/decorators/controller.decorator.js +6 -0
- package/dist/esm/decorators/decorator.utils.js +38 -0
- package/dist/esm/decorators/event-listener.decorator.js +59 -0
- package/dist/esm/decorators/export.decorator.js +14 -0
- package/dist/esm/decorators/index.js +6 -0
- package/dist/esm/decorators/key-binding.decorator.js +25 -0
- package/dist/esm/decorators/ui-listener.decorator.js +20 -0
- package/dist/esm/shared/index.js +1 -0
- package/dist/esm/shared/models/account.js +1 -0
- package/dist/esm/shared/models/character.js +1 -0
- package/dist/esm/shared/models/index.js +2 -0
- package/dist/esm/utils/index.js +3 -0
- package/dist/esm/utils/location-utils.js +5 -0
- package/dist/esm/utils/string-formatter.js +25 -0
- package/dist/esm/utils/utils.js +93 -0
- package/dist/types/common/index.d.ts +6 -0
- package/dist/types/decorators/command.decorator.d.ts +5 -0
- package/dist/types/decorators/controller.decorator.d.ts +1 -0
- package/dist/types/decorators/decorator.utils.d.ts +15 -0
- package/dist/types/decorators/event-listener.decorator.d.ts +15 -0
- package/dist/types/decorators/export.decorator.d.ts +2 -0
- package/dist/types/decorators/index.d.ts +6 -0
- package/dist/types/decorators/key-binding.decorator.d.ts +8 -0
- package/dist/types/decorators/ui-listener.decorator.d.ts +4 -0
- package/dist/types/shared/index.d.ts +1 -0
- package/dist/types/shared/models/account.d.ts +5 -0
- package/dist/types/shared/models/character.d.ts +4 -0
- package/dist/types/shared/models/index.d.ts +2 -0
- package/dist/types/utils/index.d.ts +3 -0
- package/dist/types/utils/location-utils.d.ts +3 -0
- package/dist/types/utils/string-formatter.d.ts +5 -0
- package/dist/types/utils/utils.d.ts +15 -0
- package/package.json +28 -5
- package/README.md +0 -3
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/// <reference path = "../ambient.declarations.d.ts" />
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
15
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
16
|
+
};
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.DecorationType = exports.Decorate = void 0;
|
|
19
|
+
require("reflect-metadata");
|
|
20
|
+
__exportStar(require("../shared"), exports);
|
|
21
|
+
__exportStar(require("../decorators"), exports);
|
|
22
|
+
var decorator_utils_1 = require("../decorators/decorator.utils");
|
|
23
|
+
Object.defineProperty(exports, "Decorate", { enumerable: true, get: function () { return decorator_utils_1.Decorate; } });
|
|
24
|
+
Object.defineProperty(exports, "DecorationType", { enumerable: true, get: function () { return decorator_utils_1.DecorationType; } });
|
|
25
|
+
__exportStar(require("../utils"), exports);
|
|
26
|
+
__exportStar(require("../utils/utils"), exports);
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Command = Command;
|
|
4
|
+
exports.Commands = Commands;
|
|
5
|
+
const decorator_utils_1 = require("./decorator.utils");
|
|
6
|
+
// TODO: adminLevelRequired is not supposed to be here. Move it to @armoury/fivem-gamemode
|
|
7
|
+
function Command(data) {
|
|
8
|
+
return function (target, propertyKey) {
|
|
9
|
+
Reflect.defineMetadata(`arm_command_${propertyKey}`, data, target);
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
function Commands(target, _prototype, providers) {
|
|
13
|
+
decorator_utils_1.DecoratorUtils.map(target, _prototype, providers !== null && providers !== void 0 ? providers : [])
|
|
14
|
+
.filter((mapping) => mapping.key.startsWith('arm_command_'))
|
|
15
|
+
.forEach((mapping) => {
|
|
16
|
+
var _a;
|
|
17
|
+
const rawCommandName = mapping.key.split('_').slice(2).join('_');
|
|
18
|
+
const keybinding = Reflect.getOwnMetadata('keybinding_' + rawCommandName, _prototype);
|
|
19
|
+
const commandName = `${keybinding ? '+' : ''}` + rawCommandName.toLowerCase() + (((_a = mapping.value) === null || _a === void 0 ? void 0 : _a.suffix) || '');
|
|
20
|
+
if (!Cfx.Client.IsDuplicityVersion()) {
|
|
21
|
+
Cfx.Client.RegisterCommand(commandName, (_source, args, _raw) => {
|
|
22
|
+
mapping.target[rawCommandName].apply(mapping.target, args);
|
|
23
|
+
}, false);
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
Cfx.Server.RegisterCommand(commandName, (source, args, _raw) => {
|
|
27
|
+
var _a, _b;
|
|
28
|
+
// TODO: This conditional is not generic enough. This conditional should actually check a function given through an injection token.
|
|
29
|
+
if (((_a = mapping.value) === null || _a === void 0 ? void 0 : _a.adminLevelRequired) && Number(Cfx.exports['authentication'].getPlayerInfo(source, 'adminLevel')) < ((_b = mapping.value) === null || _b === void 0 ? void 0 : _b.adminLevelRequired)) {
|
|
30
|
+
// TODO: Add error chat message OR some kind of visual notice here
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
mapping.target[rawCommandName].apply(mapping.target, [source, ...args]);
|
|
34
|
+
}, false);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// TODO: Re-add translation logic
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.Controller = Controller;
|
|
5
|
+
function Controller(data) {
|
|
6
|
+
return function (target) {
|
|
7
|
+
// Reflect.defineMetadata(`arm_export_${propertyKey}`, propertyKey, target);
|
|
8
|
+
};
|
|
9
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DecorationType = exports.DecoratorUtils = void 0;
|
|
4
|
+
exports.Decorate = Decorate;
|
|
5
|
+
const command_decorator_1 = require("./command.decorator");
|
|
6
|
+
const event_listener_decorator_1 = require("./event-listener.decorator");
|
|
7
|
+
const export_decorator_1 = require("./export.decorator");
|
|
8
|
+
const key_binding_decorator_1 = require("./key-binding.decorator");
|
|
9
|
+
const ui_listener_decorator_1 = require("./ui-listener.decorator");
|
|
10
|
+
class DecoratorUtils {
|
|
11
|
+
static map(target, _prototype, providers) {
|
|
12
|
+
return [
|
|
13
|
+
...Reflect.getOwnMetadataKeys(_prototype)
|
|
14
|
+
.map((key) => ({ key, target, value: Reflect.getOwnMetadata(key, _prototype) })),
|
|
15
|
+
...providers
|
|
16
|
+
? providers.map((provider) => Reflect.getMetadataKeys(provider)
|
|
17
|
+
.map((key) => ({
|
|
18
|
+
key,
|
|
19
|
+
target: provider,
|
|
20
|
+
value: Reflect.getMetadata(key, provider)
|
|
21
|
+
}))).flat()
|
|
22
|
+
: []
|
|
23
|
+
];
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
exports.DecoratorUtils = DecoratorUtils;
|
|
27
|
+
function Decorate(instance, _prototype, providers, decorationType = DecorationType.SERVER) {
|
|
28
|
+
const relevantProvidersForClass = Object.values(instance)
|
|
29
|
+
.filter((provider) => typeof provider === 'object'
|
|
30
|
+
&& Reflect.getMetadataKeys(provider).some((key) => key.startsWith('arm_')));
|
|
31
|
+
(0, command_decorator_1.Commands)(instance, _prototype, relevantProvidersForClass);
|
|
32
|
+
(0, event_listener_decorator_1.EventListeners)(instance, _prototype, relevantProvidersForClass);
|
|
33
|
+
(0, export_decorator_1.Exports)(instance, _prototype, relevantProvidersForClass);
|
|
34
|
+
(0, key_binding_decorator_1.KeyBindings)(instance, _prototype, relevantProvidersForClass);
|
|
35
|
+
if (decorationType === DecorationType.CLIENT) {
|
|
36
|
+
(0, ui_listener_decorator_1.UIListeners)(instance, _prototype, relevantProvidersForClass);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
var DecorationType;
|
|
40
|
+
(function (DecorationType) {
|
|
41
|
+
DecorationType[DecorationType["SERVER"] = 0] = "SERVER";
|
|
42
|
+
DecorationType[DecorationType["CLIENT"] = 1] = "CLIENT";
|
|
43
|
+
})(DecorationType || (exports.DecorationType = DecorationType = {}));
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFAULT_EVENTS = exports.EVENT_DIRECTIONS = void 0;
|
|
4
|
+
exports.EventListener = EventListener;
|
|
5
|
+
exports.EventListeners = EventListeners;
|
|
6
|
+
const decorator_utils_1 = require("./decorator.utils");
|
|
7
|
+
function EventListener(data) {
|
|
8
|
+
return function (target, propertyKey) {
|
|
9
|
+
const eventName = (exports.DEFAULT_EVENTS[propertyKey] || (data === null || data === void 0 ? void 0 : data.eventName));
|
|
10
|
+
const direction = (data === null || data === void 0 ? void 0 : data.direction) || EVENT_DIRECTIONS.CLIENT_TO_SERVER;
|
|
11
|
+
const type = (data === null || data === void 0 ? void 0 : data.type) || 'default';
|
|
12
|
+
Reflect.defineMetadata(`arm_eventListener_${propertyKey}`, { eventName, direction, type }, target);
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
function EventListeners(target, _prototype, providers) {
|
|
16
|
+
decorator_utils_1.DecoratorUtils.map(target, _prototype, providers !== null && providers !== void 0 ? providers : [])
|
|
17
|
+
.filter((mapping) => mapping.key.startsWith('arm_eventListener_'))
|
|
18
|
+
.forEach((mapping) => {
|
|
19
|
+
const { eventName, direction, type } = mapping.value;
|
|
20
|
+
const func = mapping.key.split('_').slice(2).join('_');
|
|
21
|
+
if (type === 'ui') {
|
|
22
|
+
Cfx.Client.RegisterNuiCallbackType(eventName);
|
|
23
|
+
Cfx.Client.on('__cfx_nui:' + eventName, (data, cb) => {
|
|
24
|
+
mapping.target[func].call(mapping.target, data);
|
|
25
|
+
cb('ok');
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
switch (direction) {
|
|
30
|
+
case EVENT_DIRECTIONS.CLIENT_TO_CLIENT: {
|
|
31
|
+
Cfx.Client.on(eventName, mapping.target[func].bind(mapping.target));
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
default: {
|
|
35
|
+
Cfx.Server.onNet(eventName, mapping.target[func].bind(mapping.target));
|
|
36
|
+
break;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
var EVENT_DIRECTIONS;
|
|
43
|
+
(function (EVENT_DIRECTIONS) {
|
|
44
|
+
EVENT_DIRECTIONS[EVENT_DIRECTIONS["SERVER_TO_SERVER"] = 0] = "SERVER_TO_SERVER";
|
|
45
|
+
EVENT_DIRECTIONS[EVENT_DIRECTIONS["SERVER_TO_CLIENT"] = 1] = "SERVER_TO_CLIENT";
|
|
46
|
+
EVENT_DIRECTIONS[EVENT_DIRECTIONS["CLIENT_TO_SERVER"] = 2] = "CLIENT_TO_SERVER";
|
|
47
|
+
EVENT_DIRECTIONS[EVENT_DIRECTIONS["CLIENT_TO_CLIENT"] = 3] = "CLIENT_TO_CLIENT";
|
|
48
|
+
})(EVENT_DIRECTIONS || (exports.EVENT_DIRECTIONS = EVENT_DIRECTIONS = {}));
|
|
49
|
+
// TODO: Refactor this, so resources can add to it
|
|
50
|
+
exports.DEFAULT_EVENTS = {
|
|
51
|
+
onAccountAuthenticate: 'authentication:account-success',
|
|
52
|
+
onPlayerConnect: 'playerJoining',
|
|
53
|
+
onPlayerDeath: 'armoury:onPlayerDeath',
|
|
54
|
+
onPlayerAuthenticate: 'authentication:player-authenticated',
|
|
55
|
+
onPlayerLogout: 'armoury:player-logout',
|
|
56
|
+
onPlayerDisconnect: 'playerDropped',
|
|
57
|
+
onResourceStop: 'onResourceStop',
|
|
58
|
+
onContextMenuItemPressed: 'armoury-overlay:context-menu-item-pressed',
|
|
59
|
+
onPlayerEnterVehicle: 'armoury:onPlayerEnterVehicle',
|
|
60
|
+
onPlayerExitVehicle: 'armoury:onPlayerExitVehicle',
|
|
61
|
+
onPlayerClientsidedCacheLoaded: 'armoury:player-resource-cache-loaded',
|
|
62
|
+
onPlayerStartTowVehicle: 'armoury:onPlayerStartTowVehicle',
|
|
63
|
+
onPlayerStopTowVehicle: 'armoury:onPlayerStopTowVehicle',
|
|
64
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Export = Export;
|
|
4
|
+
exports.Exports = Exports;
|
|
5
|
+
const decorator_utils_1 = require("./decorator.utils");
|
|
6
|
+
function Export() {
|
|
7
|
+
return function (target, propertyKey) {
|
|
8
|
+
Reflect.defineMetadata(`arm_export_${propertyKey}`, propertyKey, target);
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
function Exports(target, _prototype, providers) {
|
|
12
|
+
decorator_utils_1.DecoratorUtils.map(target, _prototype, providers !== null && providers !== void 0 ? providers : [])
|
|
13
|
+
.filter((mapping) => mapping.key.startsWith('arm_export_'))
|
|
14
|
+
.forEach((mapping) => {
|
|
15
|
+
const exportName = mapping.key.split('_').slice(2).join('_');
|
|
16
|
+
Cfx.exports(exportName, mapping.target[exportName].bind(mapping.target));
|
|
17
|
+
});
|
|
18
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.UIListener = exports.KeyBinding = exports.Export = exports.EVENT_DIRECTIONS = exports.EventListener = exports.Controller = exports.Command = void 0;
|
|
4
|
+
var command_decorator_1 = require("./command.decorator");
|
|
5
|
+
Object.defineProperty(exports, "Command", { enumerable: true, get: function () { return command_decorator_1.Command; } });
|
|
6
|
+
var controller_decorator_1 = require("./controller.decorator");
|
|
7
|
+
Object.defineProperty(exports, "Controller", { enumerable: true, get: function () { return controller_decorator_1.Controller; } });
|
|
8
|
+
var event_listener_decorator_1 = require("./event-listener.decorator");
|
|
9
|
+
Object.defineProperty(exports, "EventListener", { enumerable: true, get: function () { return event_listener_decorator_1.EventListener; } });
|
|
10
|
+
Object.defineProperty(exports, "EVENT_DIRECTIONS", { enumerable: true, get: function () { return event_listener_decorator_1.EVENT_DIRECTIONS; } });
|
|
11
|
+
var export_decorator_1 = require("./export.decorator");
|
|
12
|
+
Object.defineProperty(exports, "Export", { enumerable: true, get: function () { return export_decorator_1.Export; } });
|
|
13
|
+
var key_binding_decorator_1 = require("./key-binding.decorator");
|
|
14
|
+
Object.defineProperty(exports, "KeyBinding", { enumerable: true, get: function () { return key_binding_decorator_1.KeyBinding; } });
|
|
15
|
+
var ui_listener_decorator_1 = require("./ui-listener.decorator");
|
|
16
|
+
Object.defineProperty(exports, "UIListener", { enumerable: true, get: function () { return ui_listener_decorator_1.UIListener; } });
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.KeyBinding = KeyBinding;
|
|
4
|
+
exports.KeyBindings = KeyBindings;
|
|
5
|
+
const decorator_utils_1 = require("./decorator.utils");
|
|
6
|
+
function KeyBinding(data) {
|
|
7
|
+
return function (target, propertyKey) {
|
|
8
|
+
Reflect.defineMetadata(`arm_keybinding_${propertyKey}`, {
|
|
9
|
+
command: data.command,
|
|
10
|
+
description: data.description,
|
|
11
|
+
defaultMapper: data.defaultMapper,
|
|
12
|
+
key: data.key
|
|
13
|
+
}, target);
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
function KeyBindings(target, _prototype, providers) {
|
|
17
|
+
decorator_utils_1.DecoratorUtils.map(target, _prototype, providers !== null && providers !== void 0 ? providers : [])
|
|
18
|
+
.filter((mapping) => mapping.key.startsWith('arm_keybinding_'))
|
|
19
|
+
.forEach((mapping) => {
|
|
20
|
+
var _a, _b, _c, _d;
|
|
21
|
+
const keybindingName = mapping.key.split('_').slice(2).join('_');
|
|
22
|
+
const command = ((_a = mapping.value) === null || _a === void 0 ? void 0 : _a.command) || keybindingName;
|
|
23
|
+
if (!command) {
|
|
24
|
+
console.error(`Could not find any relevant command for key binding ${keybindingName}`);
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
Cfx.Client.RegisterKeyMapping(`+${command.toLowerCase()}`, (_b = mapping.value) === null || _b === void 0 ? void 0 : _b.description, (_c = mapping.value) === null || _c === void 0 ? void 0 : _c.defaultMapper, (_d = mapping.value) === null || _d === void 0 ? void 0 : _d.key);
|
|
28
|
+
});
|
|
29
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.UIListener = UIListener;
|
|
4
|
+
exports.UIListeners = UIListeners;
|
|
5
|
+
const decorator_utils_1 = require("./decorator.utils");
|
|
6
|
+
function UIListener(data) {
|
|
7
|
+
return function (target, propertyKey) {
|
|
8
|
+
const eventName = (data === null || data === void 0 ? void 0 : data.eventName) || propertyKey;
|
|
9
|
+
Reflect.defineMetadata(`arm_uiListener_${propertyKey}`, { eventName }, target);
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
function UIListeners(target, _prototype, providers) {
|
|
13
|
+
decorator_utils_1.DecoratorUtils.map(target, _prototype, providers !== null && providers !== void 0 ? providers : [])
|
|
14
|
+
.filter((mapping) => mapping.key.startsWith('arm_uiListener_'))
|
|
15
|
+
.forEach((mapping) => {
|
|
16
|
+
const { eventName } = mapping.value;
|
|
17
|
+
const func = mapping.key.split('_').slice(2).join('_');
|
|
18
|
+
Cfx.Client.RegisterNuiCallbackType(eventName);
|
|
19
|
+
Cfx.Client.on('__cfx_nui:' + eventName, (data, cb) => {
|
|
20
|
+
mapping.target[func].call(mapping.target, data);
|
|
21
|
+
cb('ok');
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
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("./models"), exports);
|
|
@@ -0,0 +1,18 @@
|
|
|
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("./account"), exports);
|
|
18
|
+
__exportStar(require("./character"), exports);
|
|
@@ -0,0 +1,21 @@
|
|
|
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
|
+
exports.Delay = void 0;
|
|
18
|
+
__exportStar(require("./string-formatter"), exports);
|
|
19
|
+
__exportStar(require("./location-utils"), exports);
|
|
20
|
+
var utils_1 = require("./utils");
|
|
21
|
+
Object.defineProperty(exports, "Delay", { enumerable: true, get: function () { return utils_1.Delay; } });
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LocationUtils = void 0;
|
|
4
|
+
class LocationUtils {
|
|
5
|
+
static distance(fromX, fromY, fromZ, toX, toY, toZ) {
|
|
6
|
+
return Math.hypot(toX - fromX, toY - fromY, toZ - fromZ);
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
exports.LocationUtils = LocationUtils;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.StringFormatter = void 0;
|
|
4
|
+
const suffixes = ['k', 'M', 'G', 'T', 'P', 'E'];
|
|
5
|
+
class StringFormatter {
|
|
6
|
+
static numberWithCommas(num) {
|
|
7
|
+
return num.toString().replace(new RegExp('\\B(?=(\\d{3})+(?!\\d))', 'g'), ",");
|
|
8
|
+
}
|
|
9
|
+
static phone(phone) {
|
|
10
|
+
const filteredValue = phone.toString().replace('-', '');
|
|
11
|
+
if (filteredValue.length > 3) {
|
|
12
|
+
return `${filteredValue.substring(0, 3)}-${filteredValue.substring(3)}`;
|
|
13
|
+
}
|
|
14
|
+
return phone.toString();
|
|
15
|
+
}
|
|
16
|
+
static thousands(input, args) {
|
|
17
|
+
let isNegative = input < 0;
|
|
18
|
+
input = Math.abs(input);
|
|
19
|
+
if (Number.isNaN(input)) {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
if (input < 1000) {
|
|
23
|
+
return input;
|
|
24
|
+
}
|
|
25
|
+
const exp = Math.floor(Math.log(input) / Math.log(1000));
|
|
26
|
+
return ((isNegative ? '-' : '') + (input / Math.pow(1000, exp)).toFixed(args) + suffixes[exp - 1]);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
exports.StringFormatter = StringFormatter;
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isJSON = exports.numberWithCommas = exports.waitUntilThenDo = exports.isPlayerInRangeOfPoint = exports.isPlayerInArea = exports.Delay = exports.toTitleCase = exports.fromThousandsString = exports.toThousandsString = exports.phoneFormatted = exports.isPositionIn2DArea = exports.getRandomPositionInsideArea = exports.calculateDistanceInKm = exports.calculateDistance = void 0;
|
|
4
|
+
const Delay = (ms) => new Promise(res => setTimeout(res, ms));
|
|
5
|
+
exports.Delay = Delay;
|
|
6
|
+
const isPlayerInArea = (playerPosX, playerPosY, playerPosZ, areaMinX, areaMinY, areaMinZ, areaMaxX, areaMaxY, areaMaxZ) => {
|
|
7
|
+
return playerPosX >= areaMinX && playerPosX <= areaMaxX && playerPosY >= areaMinY && playerPosY <= areaMaxY && playerPosZ >= areaMinZ && playerPosZ <= areaMaxZ;
|
|
8
|
+
};
|
|
9
|
+
exports.isPlayerInArea = isPlayerInArea;
|
|
10
|
+
const isPlayerInRangeOfPoint = (playerPosX, playerPosY, playerPosZ, pointX, pointY, pointZ, range) => {
|
|
11
|
+
return (0, exports.calculateDistance)([playerPosX, playerPosY, playerPosZ, pointX, pointY, pointZ]) <= range;
|
|
12
|
+
};
|
|
13
|
+
exports.isPlayerInRangeOfPoint = isPlayerInRangeOfPoint;
|
|
14
|
+
const waitUntilThenDo = async (condition, func) => {
|
|
15
|
+
let attempts = 0;
|
|
16
|
+
while (!condition()) {
|
|
17
|
+
if (attempts > 50) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
await Delay(10);
|
|
21
|
+
}
|
|
22
|
+
func();
|
|
23
|
+
};
|
|
24
|
+
exports.waitUntilThenDo = waitUntilThenDo;
|
|
25
|
+
const calculateDistance = (pos) => {
|
|
26
|
+
var a = pos[3] - pos[0];
|
|
27
|
+
var b = pos[4] - pos[1];
|
|
28
|
+
var c = pos[5] - pos[2];
|
|
29
|
+
return Math.hypot(a, b, c);
|
|
30
|
+
};
|
|
31
|
+
exports.calculateDistance = calculateDistance;
|
|
32
|
+
const calculateDistanceInKm = (pos) => {
|
|
33
|
+
var a = pos[3] - pos[0];
|
|
34
|
+
var b = pos[4] - pos[1];
|
|
35
|
+
var c = pos[5] - pos[2];
|
|
36
|
+
return Math.hypot(a, b, c) * 0.004;
|
|
37
|
+
};
|
|
38
|
+
exports.calculateDistanceInKm = calculateDistanceInKm;
|
|
39
|
+
const getRandomPositionInsideArea = (x1, x2, y1, y2) => {
|
|
40
|
+
const sortedXs = [x1, x2].sort((current, previous) => current <= previous ? -1 : 1);
|
|
41
|
+
const sortedYs = [y1, y2].sort((current, previous) => current <= previous ? -1 : 1);
|
|
42
|
+
const [lowestX, highestX] = [sortedXs[0], sortedXs.slice(-1)[0]];
|
|
43
|
+
const [lowestY, highestY] = [sortedYs[0], sortedYs.slice(-1)[0]];
|
|
44
|
+
return [lowestX + (Math.random() * (highestX - lowestX)), lowestY + (Math.random() * (highestY - lowestY))];
|
|
45
|
+
};
|
|
46
|
+
exports.getRandomPositionInsideArea = getRandomPositionInsideArea;
|
|
47
|
+
const isPositionIn2DArea = (x, y, x1, x2, y1, y2) => {
|
|
48
|
+
const sortedXs = [x1, x2].sort((current, previous) => current <= previous ? -1 : 1);
|
|
49
|
+
const sortedYs = [y1, y2].sort((current, previous) => current <= previous ? -1 : 1);
|
|
50
|
+
const [lowestX, highestX] = [sortedXs[0], sortedXs.slice(-1)[0]];
|
|
51
|
+
const [lowestY, highestY] = [sortedYs[0], sortedYs.slice(-1)[0]];
|
|
52
|
+
return x >= lowestX && x <= highestX && y >= lowestY && y <= highestY;
|
|
53
|
+
};
|
|
54
|
+
exports.isPositionIn2DArea = isPositionIn2DArea;
|
|
55
|
+
const numberWithCommas = (x) => {
|
|
56
|
+
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
57
|
+
};
|
|
58
|
+
exports.numberWithCommas = numberWithCommas;
|
|
59
|
+
const isJSON = (str) => {
|
|
60
|
+
if (/^\s*$/.test(str))
|
|
61
|
+
return false;
|
|
62
|
+
str = str.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@');
|
|
63
|
+
str = str.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']');
|
|
64
|
+
str = str.replace(/(?:^|:|,)(?:\s*\[)+/g, '');
|
|
65
|
+
return (/^[\],:{}\s]*$/).test(str);
|
|
66
|
+
};
|
|
67
|
+
exports.isJSON = isJSON;
|
|
68
|
+
const phoneFormatted = (phone) => {
|
|
69
|
+
const filteredValue = phone.toString().replace('-', '');
|
|
70
|
+
if (filteredValue.length > 3) {
|
|
71
|
+
return `${filteredValue.substring(0, 3)}-${filteredValue.substring(3)}`;
|
|
72
|
+
}
|
|
73
|
+
return phone.toString();
|
|
74
|
+
};
|
|
75
|
+
exports.phoneFormatted = phoneFormatted;
|
|
76
|
+
const suffixes = ['k', 'M', 'G', 'T', 'P', 'E'];
|
|
77
|
+
const toThousandsString = (input, args) => {
|
|
78
|
+
let isNegative = input < 0;
|
|
79
|
+
input = Math.abs(input);
|
|
80
|
+
if (Number.isNaN(input)) {
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
if (input < 1000) {
|
|
84
|
+
return input;
|
|
85
|
+
}
|
|
86
|
+
const exp = Math.floor(Math.log(input) / Math.log(1000));
|
|
87
|
+
return ((isNegative ? '-' : '') + (input / Math.pow(1000, exp)).toFixed(args) + suffixes[exp - 1]);
|
|
88
|
+
};
|
|
89
|
+
exports.toThousandsString = toThousandsString;
|
|
90
|
+
const fromThousandsString = (input) => {
|
|
91
|
+
var _a;
|
|
92
|
+
const existingSuffix = (input.match(/[a-zA-Z]/) || []).pop() || '';
|
|
93
|
+
if (!existingSuffix) {
|
|
94
|
+
return Number(input);
|
|
95
|
+
}
|
|
96
|
+
const existingNumber = Number((_a = input.match(/\d+/)) === null || _a === void 0 ? void 0 : _a[0]);
|
|
97
|
+
return (existingNumber *
|
|
98
|
+
Math.pow(1000, 1 +
|
|
99
|
+
suffixes
|
|
100
|
+
.map((suffix) => suffix.toLowerCase())
|
|
101
|
+
.indexOf(existingSuffix.toLowerCase())));
|
|
102
|
+
};
|
|
103
|
+
exports.fromThousandsString = fromThousandsString;
|
|
104
|
+
const toTitleCase = (str) => {
|
|
105
|
+
return str.replace(/\w\S*/g, function (txt) {
|
|
106
|
+
return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
|
|
107
|
+
});
|
|
108
|
+
};
|
|
109
|
+
exports.toTitleCase = toTitleCase;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/// <reference path = "../ambient.declarations.d.ts" />
|
|
2
|
+
import 'reflect-metadata';
|
|
3
|
+
export * from '../shared';
|
|
4
|
+
export * from '../decorators';
|
|
5
|
+
export { Decorate, DecorationType } from '../decorators/decorator.utils';
|
|
6
|
+
export * from '../utils';
|
|
7
|
+
export * from '../utils/utils';
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { DecoratorUtils } from "./decorator.utils";
|
|
2
|
+
// TODO: adminLevelRequired is not supposed to be here. Move it to @armoury/fivem-gamemode
|
|
3
|
+
export function Command(data) {
|
|
4
|
+
return function (target, propertyKey) {
|
|
5
|
+
Reflect.defineMetadata(`arm_command_${propertyKey}`, data, target);
|
|
6
|
+
};
|
|
7
|
+
}
|
|
8
|
+
export function Commands(target, _prototype, providers) {
|
|
9
|
+
DecoratorUtils.map(target, _prototype, providers !== null && providers !== void 0 ? providers : [])
|
|
10
|
+
.filter((mapping) => mapping.key.startsWith('arm_command_'))
|
|
11
|
+
.forEach((mapping) => {
|
|
12
|
+
var _a;
|
|
13
|
+
const rawCommandName = mapping.key.split('_').slice(2).join('_');
|
|
14
|
+
const keybinding = Reflect.getOwnMetadata('keybinding_' + rawCommandName, _prototype);
|
|
15
|
+
const commandName = `${keybinding ? '+' : ''}` + rawCommandName.toLowerCase() + (((_a = mapping.value) === null || _a === void 0 ? void 0 : _a.suffix) || '');
|
|
16
|
+
if (!Cfx.Client.IsDuplicityVersion()) {
|
|
17
|
+
Cfx.Client.RegisterCommand(commandName, (_source, args, _raw) => {
|
|
18
|
+
mapping.target[rawCommandName].apply(mapping.target, args);
|
|
19
|
+
}, false);
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
Cfx.Server.RegisterCommand(commandName, (source, args, _raw) => {
|
|
23
|
+
var _a, _b;
|
|
24
|
+
// TODO: This conditional is not generic enough. This conditional should actually check a function given through an injection token.
|
|
25
|
+
if (((_a = mapping.value) === null || _a === void 0 ? void 0 : _a.adminLevelRequired) && Number(Cfx.exports['authentication'].getPlayerInfo(source, 'adminLevel')) < ((_b = mapping.value) === null || _b === void 0 ? void 0 : _b.adminLevelRequired)) {
|
|
26
|
+
// TODO: Add error chat message OR some kind of visual notice here
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
mapping.target[rawCommandName].apply(mapping.target, [source, ...args]);
|
|
30
|
+
}, false);
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Commands } from "./command.decorator";
|
|
2
|
+
import { EventListeners } from "./event-listener.decorator";
|
|
3
|
+
import { Exports } from "./export.decorator";
|
|
4
|
+
import { KeyBindings } from "./key-binding.decorator";
|
|
5
|
+
import { UIListeners } from "./ui-listener.decorator";
|
|
6
|
+
export class DecoratorUtils {
|
|
7
|
+
static map(target, _prototype, providers) {
|
|
8
|
+
return [
|
|
9
|
+
...Reflect.getOwnMetadataKeys(_prototype)
|
|
10
|
+
.map((key) => ({ key, target, value: Reflect.getOwnMetadata(key, _prototype) })),
|
|
11
|
+
...providers
|
|
12
|
+
? providers.map((provider) => Reflect.getMetadataKeys(provider)
|
|
13
|
+
.map((key) => ({
|
|
14
|
+
key,
|
|
15
|
+
target: provider,
|
|
16
|
+
value: Reflect.getMetadata(key, provider)
|
|
17
|
+
}))).flat()
|
|
18
|
+
: []
|
|
19
|
+
];
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
export function Decorate(instance, _prototype, providers, decorationType = DecorationType.SERVER) {
|
|
23
|
+
const relevantProvidersForClass = Object.values(instance)
|
|
24
|
+
.filter((provider) => typeof provider === 'object'
|
|
25
|
+
&& Reflect.getMetadataKeys(provider).some((key) => key.startsWith('arm_')));
|
|
26
|
+
Commands(instance, _prototype, relevantProvidersForClass);
|
|
27
|
+
EventListeners(instance, _prototype, relevantProvidersForClass);
|
|
28
|
+
Exports(instance, _prototype, relevantProvidersForClass);
|
|
29
|
+
KeyBindings(instance, _prototype, relevantProvidersForClass);
|
|
30
|
+
if (decorationType === DecorationType.CLIENT) {
|
|
31
|
+
UIListeners(instance, _prototype, relevantProvidersForClass);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
export var DecorationType;
|
|
35
|
+
(function (DecorationType) {
|
|
36
|
+
DecorationType[DecorationType["SERVER"] = 0] = "SERVER";
|
|
37
|
+
DecorationType[DecorationType["CLIENT"] = 1] = "CLIENT";
|
|
38
|
+
})(DecorationType || (DecorationType = {}));
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { DecoratorUtils } from "./decorator.utils";
|
|
2
|
+
export function EventListener(data) {
|
|
3
|
+
return function (target, propertyKey) {
|
|
4
|
+
const eventName = (DEFAULT_EVENTS[propertyKey] || (data === null || data === void 0 ? void 0 : data.eventName));
|
|
5
|
+
const direction = (data === null || data === void 0 ? void 0 : data.direction) || EVENT_DIRECTIONS.CLIENT_TO_SERVER;
|
|
6
|
+
const type = (data === null || data === void 0 ? void 0 : data.type) || 'default';
|
|
7
|
+
Reflect.defineMetadata(`arm_eventListener_${propertyKey}`, { eventName, direction, type }, target);
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
export function EventListeners(target, _prototype, providers) {
|
|
11
|
+
DecoratorUtils.map(target, _prototype, providers !== null && providers !== void 0 ? providers : [])
|
|
12
|
+
.filter((mapping) => mapping.key.startsWith('arm_eventListener_'))
|
|
13
|
+
.forEach((mapping) => {
|
|
14
|
+
const { eventName, direction, type } = mapping.value;
|
|
15
|
+
const func = mapping.key.split('_').slice(2).join('_');
|
|
16
|
+
if (type === 'ui') {
|
|
17
|
+
Cfx.Client.RegisterNuiCallbackType(eventName);
|
|
18
|
+
Cfx.Client.on('__cfx_nui:' + eventName, (data, cb) => {
|
|
19
|
+
mapping.target[func].call(mapping.target, data);
|
|
20
|
+
cb('ok');
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
switch (direction) {
|
|
25
|
+
case EVENT_DIRECTIONS.CLIENT_TO_CLIENT: {
|
|
26
|
+
Cfx.Client.on(eventName, mapping.target[func].bind(mapping.target));
|
|
27
|
+
break;
|
|
28
|
+
}
|
|
29
|
+
default: {
|
|
30
|
+
Cfx.Server.onNet(eventName, mapping.target[func].bind(mapping.target));
|
|
31
|
+
break;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
export var EVENT_DIRECTIONS;
|
|
38
|
+
(function (EVENT_DIRECTIONS) {
|
|
39
|
+
EVENT_DIRECTIONS[EVENT_DIRECTIONS["SERVER_TO_SERVER"] = 0] = "SERVER_TO_SERVER";
|
|
40
|
+
EVENT_DIRECTIONS[EVENT_DIRECTIONS["SERVER_TO_CLIENT"] = 1] = "SERVER_TO_CLIENT";
|
|
41
|
+
EVENT_DIRECTIONS[EVENT_DIRECTIONS["CLIENT_TO_SERVER"] = 2] = "CLIENT_TO_SERVER";
|
|
42
|
+
EVENT_DIRECTIONS[EVENT_DIRECTIONS["CLIENT_TO_CLIENT"] = 3] = "CLIENT_TO_CLIENT";
|
|
43
|
+
})(EVENT_DIRECTIONS || (EVENT_DIRECTIONS = {}));
|
|
44
|
+
// TODO: Refactor this, so resources can add to it
|
|
45
|
+
export const DEFAULT_EVENTS = {
|
|
46
|
+
onAccountAuthenticate: 'authentication:account-success',
|
|
47
|
+
onPlayerConnect: 'playerJoining',
|
|
48
|
+
onPlayerDeath: 'armoury:onPlayerDeath',
|
|
49
|
+
onPlayerAuthenticate: 'authentication:player-authenticated',
|
|
50
|
+
onPlayerLogout: 'armoury:player-logout',
|
|
51
|
+
onPlayerDisconnect: 'playerDropped',
|
|
52
|
+
onResourceStop: 'onResourceStop',
|
|
53
|
+
onContextMenuItemPressed: 'armoury-overlay:context-menu-item-pressed',
|
|
54
|
+
onPlayerEnterVehicle: 'armoury:onPlayerEnterVehicle',
|
|
55
|
+
onPlayerExitVehicle: 'armoury:onPlayerExitVehicle',
|
|
56
|
+
onPlayerClientsidedCacheLoaded: 'armoury:player-resource-cache-loaded',
|
|
57
|
+
onPlayerStartTowVehicle: 'armoury:onPlayerStartTowVehicle',
|
|
58
|
+
onPlayerStopTowVehicle: 'armoury:onPlayerStopTowVehicle',
|
|
59
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { DecoratorUtils } from "./decorator.utils";
|
|
2
|
+
export function Export() {
|
|
3
|
+
return function (target, propertyKey) {
|
|
4
|
+
Reflect.defineMetadata(`arm_export_${propertyKey}`, propertyKey, target);
|
|
5
|
+
};
|
|
6
|
+
}
|
|
7
|
+
export function Exports(target, _prototype, providers) {
|
|
8
|
+
DecoratorUtils.map(target, _prototype, providers !== null && providers !== void 0 ? providers : [])
|
|
9
|
+
.filter((mapping) => mapping.key.startsWith('arm_export_'))
|
|
10
|
+
.forEach((mapping) => {
|
|
11
|
+
const exportName = mapping.key.split('_').slice(2).join('_');
|
|
12
|
+
Cfx.exports(exportName, mapping.target[exportName].bind(mapping.target));
|
|
13
|
+
});
|
|
14
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { Command } from './command.decorator';
|
|
2
|
+
export { Controller } from './controller.decorator';
|
|
3
|
+
export { EventListener, EVENT_DIRECTIONS } from './event-listener.decorator';
|
|
4
|
+
export { Export } from './export.decorator';
|
|
5
|
+
export { KeyBinding } from './key-binding.decorator';
|
|
6
|
+
export { UIListener } from './ui-listener.decorator';
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { DecoratorUtils } from "./decorator.utils";
|
|
2
|
+
export function KeyBinding(data) {
|
|
3
|
+
return function (target, propertyKey) {
|
|
4
|
+
Reflect.defineMetadata(`arm_keybinding_${propertyKey}`, {
|
|
5
|
+
command: data.command,
|
|
6
|
+
description: data.description,
|
|
7
|
+
defaultMapper: data.defaultMapper,
|
|
8
|
+
key: data.key
|
|
9
|
+
}, target);
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
export function KeyBindings(target, _prototype, providers) {
|
|
13
|
+
DecoratorUtils.map(target, _prototype, providers !== null && providers !== void 0 ? providers : [])
|
|
14
|
+
.filter((mapping) => mapping.key.startsWith('arm_keybinding_'))
|
|
15
|
+
.forEach((mapping) => {
|
|
16
|
+
var _a, _b, _c, _d;
|
|
17
|
+
const keybindingName = mapping.key.split('_').slice(2).join('_');
|
|
18
|
+
const command = ((_a = mapping.value) === null || _a === void 0 ? void 0 : _a.command) || keybindingName;
|
|
19
|
+
if (!command) {
|
|
20
|
+
console.error(`Could not find any relevant command for key binding ${keybindingName}`);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
Cfx.Client.RegisterKeyMapping(`+${command.toLowerCase()}`, (_b = mapping.value) === null || _b === void 0 ? void 0 : _b.description, (_c = mapping.value) === null || _c === void 0 ? void 0 : _c.defaultMapper, (_d = mapping.value) === null || _d === void 0 ? void 0 : _d.key);
|
|
24
|
+
});
|
|
25
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { DecoratorUtils } from "./decorator.utils";
|
|
2
|
+
export function UIListener(data) {
|
|
3
|
+
return function (target, propertyKey) {
|
|
4
|
+
const eventName = (data === null || data === void 0 ? void 0 : data.eventName) || propertyKey;
|
|
5
|
+
Reflect.defineMetadata(`arm_uiListener_${propertyKey}`, { eventName }, target);
|
|
6
|
+
};
|
|
7
|
+
}
|
|
8
|
+
export function UIListeners(target, _prototype, providers) {
|
|
9
|
+
DecoratorUtils.map(target, _prototype, providers !== null && providers !== void 0 ? providers : [])
|
|
10
|
+
.filter((mapping) => mapping.key.startsWith('arm_uiListener_'))
|
|
11
|
+
.forEach((mapping) => {
|
|
12
|
+
const { eventName } = mapping.value;
|
|
13
|
+
const func = mapping.key.split('_').slice(2).join('_');
|
|
14
|
+
Cfx.Client.RegisterNuiCallbackType(eventName);
|
|
15
|
+
Cfx.Client.on('__cfx_nui:' + eventName, (data, cb) => {
|
|
16
|
+
mapping.target[func].call(mapping.target, data);
|
|
17
|
+
cb('ok');
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './models';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
const suffixes = ['k', 'M', 'G', 'T', 'P', 'E'];
|
|
2
|
+
export class StringFormatter {
|
|
3
|
+
static numberWithCommas(num) {
|
|
4
|
+
return num.toString().replace(new RegExp('\\B(?=(\\d{3})+(?!\\d))', 'g'), ",");
|
|
5
|
+
}
|
|
6
|
+
static phone(phone) {
|
|
7
|
+
const filteredValue = phone.toString().replace('-', '');
|
|
8
|
+
if (filteredValue.length > 3) {
|
|
9
|
+
return `${filteredValue.substring(0, 3)}-${filteredValue.substring(3)}`;
|
|
10
|
+
}
|
|
11
|
+
return phone.toString();
|
|
12
|
+
}
|
|
13
|
+
static thousands(input, args) {
|
|
14
|
+
let isNegative = input < 0;
|
|
15
|
+
input = Math.abs(input);
|
|
16
|
+
if (Number.isNaN(input)) {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
if (input < 1000) {
|
|
20
|
+
return input;
|
|
21
|
+
}
|
|
22
|
+
const exp = Math.floor(Math.log(input) / Math.log(1000));
|
|
23
|
+
return ((isNegative ? '-' : '') + (input / Math.pow(1000, exp)).toFixed(args) + suffixes[exp - 1]);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
const Delay = (ms) => new Promise(res => setTimeout(res, ms));
|
|
2
|
+
const isPlayerInArea = (playerPosX, playerPosY, playerPosZ, areaMinX, areaMinY, areaMinZ, areaMaxX, areaMaxY, areaMaxZ) => {
|
|
3
|
+
return playerPosX >= areaMinX && playerPosX <= areaMaxX && playerPosY >= areaMinY && playerPosY <= areaMaxY && playerPosZ >= areaMinZ && playerPosZ <= areaMaxZ;
|
|
4
|
+
};
|
|
5
|
+
const isPlayerInRangeOfPoint = (playerPosX, playerPosY, playerPosZ, pointX, pointY, pointZ, range) => {
|
|
6
|
+
return calculateDistance([playerPosX, playerPosY, playerPosZ, pointX, pointY, pointZ]) <= range;
|
|
7
|
+
};
|
|
8
|
+
const waitUntilThenDo = async (condition, func) => {
|
|
9
|
+
let attempts = 0;
|
|
10
|
+
while (!condition()) {
|
|
11
|
+
if (attempts > 50) {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
await Delay(10);
|
|
15
|
+
}
|
|
16
|
+
func();
|
|
17
|
+
};
|
|
18
|
+
export const calculateDistance = (pos) => {
|
|
19
|
+
var a = pos[3] - pos[0];
|
|
20
|
+
var b = pos[4] - pos[1];
|
|
21
|
+
var c = pos[5] - pos[2];
|
|
22
|
+
return Math.hypot(a, b, c);
|
|
23
|
+
};
|
|
24
|
+
export const calculateDistanceInKm = (pos) => {
|
|
25
|
+
var a = pos[3] - pos[0];
|
|
26
|
+
var b = pos[4] - pos[1];
|
|
27
|
+
var c = pos[5] - pos[2];
|
|
28
|
+
return Math.hypot(a, b, c) * 0.004;
|
|
29
|
+
};
|
|
30
|
+
export const getRandomPositionInsideArea = (x1, x2, y1, y2) => {
|
|
31
|
+
const sortedXs = [x1, x2].sort((current, previous) => current <= previous ? -1 : 1);
|
|
32
|
+
const sortedYs = [y1, y2].sort((current, previous) => current <= previous ? -1 : 1);
|
|
33
|
+
const [lowestX, highestX] = [sortedXs[0], sortedXs.slice(-1)[0]];
|
|
34
|
+
const [lowestY, highestY] = [sortedYs[0], sortedYs.slice(-1)[0]];
|
|
35
|
+
return [lowestX + (Math.random() * (highestX - lowestX)), lowestY + (Math.random() * (highestY - lowestY))];
|
|
36
|
+
};
|
|
37
|
+
export const isPositionIn2DArea = (x, y, x1, x2, y1, y2) => {
|
|
38
|
+
const sortedXs = [x1, x2].sort((current, previous) => current <= previous ? -1 : 1);
|
|
39
|
+
const sortedYs = [y1, y2].sort((current, previous) => current <= previous ? -1 : 1);
|
|
40
|
+
const [lowestX, highestX] = [sortedXs[0], sortedXs.slice(-1)[0]];
|
|
41
|
+
const [lowestY, highestY] = [sortedYs[0], sortedYs.slice(-1)[0]];
|
|
42
|
+
return x >= lowestX && x <= highestX && y >= lowestY && y <= highestY;
|
|
43
|
+
};
|
|
44
|
+
const numberWithCommas = (x) => {
|
|
45
|
+
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
46
|
+
};
|
|
47
|
+
const isJSON = (str) => {
|
|
48
|
+
if (/^\s*$/.test(str))
|
|
49
|
+
return false;
|
|
50
|
+
str = str.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@');
|
|
51
|
+
str = str.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']');
|
|
52
|
+
str = str.replace(/(?:^|:|,)(?:\s*\[)+/g, '');
|
|
53
|
+
return (/^[\],:{}\s]*$/).test(str);
|
|
54
|
+
};
|
|
55
|
+
export const phoneFormatted = (phone) => {
|
|
56
|
+
const filteredValue = phone.toString().replace('-', '');
|
|
57
|
+
if (filteredValue.length > 3) {
|
|
58
|
+
return `${filteredValue.substring(0, 3)}-${filteredValue.substring(3)}`;
|
|
59
|
+
}
|
|
60
|
+
return phone.toString();
|
|
61
|
+
};
|
|
62
|
+
const suffixes = ['k', 'M', 'G', 'T', 'P', 'E'];
|
|
63
|
+
export const toThousandsString = (input, args) => {
|
|
64
|
+
let isNegative = input < 0;
|
|
65
|
+
input = Math.abs(input);
|
|
66
|
+
if (Number.isNaN(input)) {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
if (input < 1000) {
|
|
70
|
+
return input;
|
|
71
|
+
}
|
|
72
|
+
const exp = Math.floor(Math.log(input) / Math.log(1000));
|
|
73
|
+
return ((isNegative ? '-' : '') + (input / Math.pow(1000, exp)).toFixed(args) + suffixes[exp - 1]);
|
|
74
|
+
};
|
|
75
|
+
export const fromThousandsString = (input) => {
|
|
76
|
+
var _a;
|
|
77
|
+
const existingSuffix = (input.match(/[a-zA-Z]/) || []).pop() || '';
|
|
78
|
+
if (!existingSuffix) {
|
|
79
|
+
return Number(input);
|
|
80
|
+
}
|
|
81
|
+
const existingNumber = Number((_a = input.match(/\d+/)) === null || _a === void 0 ? void 0 : _a[0]);
|
|
82
|
+
return (existingNumber *
|
|
83
|
+
Math.pow(1000, 1 +
|
|
84
|
+
suffixes
|
|
85
|
+
.map((suffix) => suffix.toLowerCase())
|
|
86
|
+
.indexOf(existingSuffix.toLowerCase())));
|
|
87
|
+
};
|
|
88
|
+
export const toTitleCase = (str) => {
|
|
89
|
+
return str.replace(/\w\S*/g, function (txt) {
|
|
90
|
+
return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
|
|
91
|
+
});
|
|
92
|
+
};
|
|
93
|
+
export { Delay, isPlayerInArea, isPlayerInRangeOfPoint, waitUntilThenDo, numberWithCommas, isJSON };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function Controller(data?: any): (target: any) => void;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Provider } from "injection-js";
|
|
2
|
+
export declare class DecoratorUtils {
|
|
3
|
+
static map(target: any, _prototype: any, providers: Object[]): {
|
|
4
|
+
key: any;
|
|
5
|
+
target: any;
|
|
6
|
+
value: any;
|
|
7
|
+
}[];
|
|
8
|
+
}
|
|
9
|
+
export declare function Decorate<T extends {
|
|
10
|
+
new (...args: any[]): any;
|
|
11
|
+
} & Provider>(instance: T, _prototype: any, providers: Provider[], decorationType?: DecorationType): void;
|
|
12
|
+
export declare enum DecorationType {
|
|
13
|
+
SERVER = 0,
|
|
14
|
+
CLIENT = 1
|
|
15
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export declare function EventListener(data?: {
|
|
2
|
+
eventName?: string;
|
|
3
|
+
direction?: EVENT_DIRECTIONS;
|
|
4
|
+
type?: 'ui' | 'default';
|
|
5
|
+
}): (target: any, propertyKey: string) => void;
|
|
6
|
+
export declare function EventListeners(target: any, _prototype: any, providers?: Object[]): void;
|
|
7
|
+
export declare enum EVENT_DIRECTIONS {
|
|
8
|
+
SERVER_TO_SERVER = 0,
|
|
9
|
+
SERVER_TO_CLIENT = 1,
|
|
10
|
+
CLIENT_TO_SERVER = 2,
|
|
11
|
+
CLIENT_TO_CLIENT = 3
|
|
12
|
+
}
|
|
13
|
+
export declare const DEFAULT_EVENTS: {
|
|
14
|
+
[key: string]: string;
|
|
15
|
+
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { Command } from './command.decorator';
|
|
2
|
+
export { Controller } from './controller.decorator';
|
|
3
|
+
export { EventListener, EVENT_DIRECTIONS } from './event-listener.decorator';
|
|
4
|
+
export { Export } from './export.decorator';
|
|
5
|
+
export { KeyBinding } from './key-binding.decorator';
|
|
6
|
+
export { UIListener } from './ui-listener.decorator';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare function KeyBinding(data: {
|
|
2
|
+
command?: string;
|
|
3
|
+
description: string;
|
|
4
|
+
defaultMapper: KeyBindingType;
|
|
5
|
+
key: string;
|
|
6
|
+
}): (target: any, propertyKey: string) => void;
|
|
7
|
+
export declare function KeyBindings(target: any, _prototype: any, providers?: Object[]): void;
|
|
8
|
+
export type KeyBindingType = 'digitalbutton_axis' | 'game_controlled' | 'joystick_axis' | 'joystick_axis_negative' | 'joystick_axis_positive' | 'joystick_button' | 'joystick_iaxis' | 'joystick_pov' | 'joystick_pov_axis' | 'keyboard' | 'mkb_axis' | 'mouse_absoluteaxis' | 'mouse_button' | 'mouse_buttonany' | 'mouse_centeredaxis' | 'mouse_relativeaxis' | 'mouse_scaledaxis' | 'mouse_normalized' | 'mouse_wheel' | 'pad_analogbutton' | 'pad_axis' | 'pad_debugbutton' | 'pad_digitalbutton' | 'pad_digitalbuttonany' | 'touchpad_absolute_axis' | 'touchpad_centered_axis';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './models';
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
declare const Delay: (ms: number) => Promise<unknown>;
|
|
2
|
+
declare const isPlayerInArea: (playerPosX: number, playerPosY: number, playerPosZ: number, areaMinX: number, areaMinY: number, areaMinZ: number, areaMaxX: number, areaMaxY: number, areaMaxZ: number) => boolean;
|
|
3
|
+
declare const isPlayerInRangeOfPoint: (playerPosX: number, playerPosY: number, playerPosZ: number, pointX: number, pointY: number, pointZ: number, range: number) => boolean;
|
|
4
|
+
declare const waitUntilThenDo: (condition: Function, func: Function) => Promise<void>;
|
|
5
|
+
export declare const calculateDistance: (pos: number[]) => number;
|
|
6
|
+
export declare const calculateDistanceInKm: (pos: number[]) => number;
|
|
7
|
+
export declare const getRandomPositionInsideArea: (x1: number, x2: number, y1: number, y2: number) => [number, number];
|
|
8
|
+
export declare const isPositionIn2DArea: (x: number, y: number, x1: number, x2: number, y1: number, y2: number) => boolean;
|
|
9
|
+
declare const numberWithCommas: (x: number) => string;
|
|
10
|
+
declare const isJSON: (str: string) => boolean;
|
|
11
|
+
export declare const phoneFormatted: (phone: number) => string;
|
|
12
|
+
export declare const toThousandsString: (input: number, args?: number) => string | number | null;
|
|
13
|
+
export declare const fromThousandsString: (input: string) => number;
|
|
14
|
+
export declare const toTitleCase: (str: string) => string;
|
|
15
|
+
export { Delay, isPlayerInArea, isPlayerInRangeOfPoint, waitUntilThenDo, numberWithCommas, isJSON };
|
package/package.json
CHANGED
|
@@ -1,6 +1,29 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@armoury/fivem-framework-common",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
1
|
+
{
|
|
2
|
+
"name": "@armoury/fivem-framework-common",
|
|
3
|
+
"version": "1.0.8",
|
|
4
|
+
"description": "Shared APIs for the Armoury FiveM framework",
|
|
5
|
+
"main": "dist/cjs/common/index.js",
|
|
6
|
+
"module": "dist/esm/common/index.js",
|
|
7
|
+
"types": "dist/types/common/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/types/common/index.d.ts",
|
|
11
|
+
"import": "./dist/esm/common/index.js",
|
|
12
|
+
"require": "./dist/cjs/common/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": ["dist"],
|
|
16
|
+
"scripts": {
|
|
17
|
+
"build": "npm run build:cjs && npm run build:esm && npm run build:types",
|
|
18
|
+
"build:cjs": "tsc -p tsconfig.cjs.json",
|
|
19
|
+
"build:esm": "tsc -p tsconfig.esm.json",
|
|
20
|
+
"build:types": "tsc -p tsconfig.types.json"
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"injection-js": "^2.4.0",
|
|
24
|
+
"reflect-metadata": "^0.2.1"
|
|
25
|
+
},
|
|
26
|
+
"publishConfig": {
|
|
27
|
+
"access": "public"
|
|
28
|
+
}
|
|
6
29
|
}
|
package/README.md
DELETED