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

141 lines
3.5 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; }
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);
}
}
});
}