mirror of
https://github.com/CommunityOx/ox_lib.git
synced 2026-08-17 06:56:03 +01:00
141 lines
3.5 KiB
TypeScript
141 lines
3.5 KiB
TypeScript
|
|
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);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
});
|
||
|
|
}
|