mirror of
https://github.com/CommunityOx/ox_lib.git
synced 2026-08-16 22:46:03 +01:00
feat(package): addCommand (#482)
This commit is contained in:
140
package/server/resource/addCommand/index.ts
Normal file
140
package/server/resource/addCommand/index.ts
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
import { addAce } from '../acl';
|
||||||
|
|
||||||
|
type OxCommandArguments = Record<string | number, string | number | boolean>;
|
||||||
|
|
||||||
|
interface OxCommandParams {
|
||||||
|
name: string;
|
||||||
|
help?: string;
|
||||||
|
paramType?: 'number' | 'playerId' | 'string';
|
||||||
|
optional?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface OxCommandProperties {
|
||||||
|
name?: string;
|
||||||
|
help?: string;
|
||||||
|
params?: OxCommandParams[];
|
||||||
|
restricted?: boolean | string | string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
const registeredCommmands: OxCommandProperties[] = [];
|
||||||
|
let shouldSendCommands = false;
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
shouldSendCommands = true;
|
||||||
|
emitNet('chat:addSuggestions', -1, registeredCommmands);
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
on('playerJoining', (source: number) => {
|
||||||
|
emitNet('chat:addSuggestions', source, registeredCommmands);
|
||||||
|
});
|
||||||
|
|
||||||
|
function parseArguments(
|
||||||
|
source: number,
|
||||||
|
args: OxCommandArguments,
|
||||||
|
raw: string,
|
||||||
|
params?: OxCommandParams[]
|
||||||
|
): OxCommandArguments | undefined {
|
||||||
|
if (!params) { return args; }
|
||||||
|
|
||||||
|
const result = params.every((param, index) => {
|
||||||
|
const arg = args[index];
|
||||||
|
let value;
|
||||||
|
|
||||||
|
switch (param.paramType) {
|
||||||
|
case 'number':
|
||||||
|
value = +arg;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'string':
|
||||||
|
value = !Number(arg) ? arg : false;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'playerId':
|
||||||
|
value = arg === 'me' ? source : +arg;
|
||||||
|
if (!value || !GetPlayerGuid(value.toString())) {
|
||||||
|
value = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
value = arg;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!value && (!param.optional || (param.optional && arg))) {
|
||||||
|
return Citizen.trace(
|
||||||
|
`^1command '${raw.split(' ') || raw}' received an invalid ${param.paramType} for argument ${index} (${
|
||||||
|
param.name
|
||||||
|
}), received '${arg}'^0`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
args[param.name] = value;
|
||||||
|
delete args[index];
|
||||||
|
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
return result ? args : undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function addCommand(
|
||||||
|
commandName: string | string[],
|
||||||
|
cb: (source: number, args: object, raw: string) => any,
|
||||||
|
properties?: OxCommandProperties
|
||||||
|
) {
|
||||||
|
const restricted = properties?.restricted;
|
||||||
|
const params = properties?.params;
|
||||||
|
|
||||||
|
if (params) {
|
||||||
|
params.forEach((param) => {
|
||||||
|
if (param.paramType) {
|
||||||
|
param.help = param.help ? `${param.help} (type: ${param.paramType})` : `(type: ${param.paramType})`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const commands = typeof commandName !== 'object' ? [commandName] : commandName;
|
||||||
|
const numCommands = commands.length;
|
||||||
|
|
||||||
|
const commandHandler = (source: number, args: OxCommandArguments, raw: string) => {
|
||||||
|
const parsed = parseArguments(source, args, raw, params);
|
||||||
|
if (!parsed) { return; }
|
||||||
|
|
||||||
|
cb(source, parsed, raw);
|
||||||
|
};
|
||||||
|
|
||||||
|
commands.forEach((commandName, index) => {
|
||||||
|
RegisterCommand(commandName, commandHandler, restricted ? true : false);
|
||||||
|
|
||||||
|
if (restricted) {
|
||||||
|
const ace = `command.${commandName}`;
|
||||||
|
const restrictedType = typeof restricted;
|
||||||
|
|
||||||
|
if (restrictedType === 'string' && !IsPrincipalAceAllowed(restricted as string, ace)) {
|
||||||
|
addAce(restricted as string, ace, true);
|
||||||
|
} else if (restrictedType === 'object') {
|
||||||
|
const _restricted = restricted as string[];
|
||||||
|
_restricted.forEach((principal) => {
|
||||||
|
if (!IsPrincipalAceAllowed(principal, ace)) {
|
||||||
|
addAce(principal as string, ace, true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (properties) {
|
||||||
|
properties.name = `/${commandName}`;
|
||||||
|
delete properties.restricted;
|
||||||
|
registeredCommmands.push(properties);
|
||||||
|
|
||||||
|
if (index !== numCommands && numCommands !== 1) {
|
||||||
|
properties = { ...properties };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shouldSendCommands) {
|
||||||
|
emitNet('chat:addSuggestions', -1, properties);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -2,3 +2,4 @@ export * from './acl';
|
|||||||
export * from './locale';
|
export * from './locale';
|
||||||
export * from './callback';
|
export * from './callback';
|
||||||
export * from './version';
|
export * from './version';
|
||||||
|
export * from './addCommand';
|
||||||
Reference in New Issue
Block a user