Files
ox_lib/package/server/resource/addCommand/index.ts

136 lines
3.6 KiB
TypeScript
Raw Normal View History

2024-01-15 02:10:40 +01:00
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;
2024-01-15 02:10:40 +01:00
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 || !DoesPlayerExist(value.toString())) value = false;
2024-01-15 02:10:40 +01:00
break;
default:
value = arg;
break;
}
if (value === undefined && (!param.optional || (param.optional && arg))) {
2024-01-15 02:10:40 +01:00
return Citizen.trace(
`^1command '${raw.split(' ')[0] || raw}' received an invalid ${param.paramType} for argument ${index + 1} (${
2024-01-15 02:10:40 +01:00
param.name
}), received '${arg}'^0`
);
}
args[param.name] = value;
delete args[index];
return true;
});
return result ? args : undefined;
}
export function addCommand<T extends OxCommandArguments>(
2024-01-15 02:10:40 +01:00
commandName: string | string[],
cb: (source: number, args: T, raw: string) => Promise<any>,
2024-01-15 02:10:40 +01:00
properties?: OxCommandProperties
) {
const restricted = properties?.restricted;
const params = properties?.params;
if (params) {
params.forEach((param) => {
if (param.paramType)
2024-01-15 02:10:40 +01:00
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) as T | undefined;
if (!parsed) return;
2024-01-15 02:10:40 +01:00
cb(source, parsed, raw).catch((e) =>
Citizen.trace(`^1command '${raw.split(' ')[0] || raw}' failed to execute!^0\n${e.message}`)
);
2024-01-15 02:10:40 +01:00
};
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);
2024-01-15 02:10:40 +01:00
});
}
}
if (properties) {
properties.name = `/${commandName}`;
delete properties.restricted;
registeredCommmands.push(properties);
if (index !== numCommands && numCommands !== 1) properties = { ...properties };
2024-01-15 02:10:40 +01:00
if (shouldSendCommands) emitNet('chat:addSuggestions', -1, properties);
2024-01-15 02:10:40 +01:00
}
});
}