All pastes #439131 Raw Edit

YSI_commands 0.1.4

public cpp v1 · immutable
·published 2007-04-14 01:37 UTC
rendered paste body
/*----------------------------------------------------------------------------*-					=============================					YAdmin system - Commands Core					=============================	Runs commands registered with the system and calls the required functions.	Also handles alternate names and prefixes.  Theory based very loosely on dcmd.Changelog:	14/04/07:		Updated header documentation with more than changelog/functions.	13/04/07:		Added function documentation.		Added wrapped functions for e_COMM_FLAG values missing them.		Added header function list.	12/04/07:		Added command removal.	11/04/07:		Changed system slightly to handle names and alt names separately.  Still need		a better way of ignoring names when alt names are used.	10/04/07:		First version.Functions:	Public:		Command_Add - Adds a command to the array for processing.		Command_Remove - Removes a command.	Core:		Command_Process - Called from OnPlayerCommandText to process entered commands.		Command_Parse - Sorts added commands into a binary tree.	Stock:		Command_SetDisconnectReturn - Sets the return value for unconnected players.		Command_UseShortCuts - Toggles use of per-player command shortcuts.		Command_SetDeniedReturn - Sets the return value for denied use commands.		Command_UseDeniedMessage - Toggles the use of an error message for denied.		Command_UseAltNames - Toggles the use of ini defined alternate names.		Command_UsePrefix - Toggles the use of a global prefix.		Command_UseSpace - Toggles the use of a space between prefix and command.		Command_SetAltName - Sets the alternate name of a function.		Command_SetPrefix - Sets the pfexix to be typed.	Static:		Command_SetSorted - Marks the binary tree as sorted.		Command_FindSlow - Finds a function by linear search of function name.		Command_FindFunc - Finds a function by binary search of function name.		Command_FindAlt - Finds a function by binary search of alternate name.		Command_Find - Finds a function from entered text.		Command_Prefix - Checks the entered prefix.		Command_Hash - Hashes a word for command hashing.	Inline:		Command_Command - Not used, constructor.		Command_IsCleared - Checks a player is cleared to use a command.		Command_DisconnectReturn - Gets the return value for disconnected players.		Command_UsingShortCuts - Checks if short cuts are being used.		Command_DeniedReturn - Gets the return value for prohibited commands.		Command_DeniedMessage - Checks if a level error message should be sent.		Command_IsSorted - Checks if the binary tree has been initialised.		Command_UsingAltNames - Checks if alt names are being used.		Command_UsingPrefix - Checks if the prefix is being used.		Command_UsingSpace - Checks if the space option is being used.		Command_CallFunction - Calls the required function.Definitions:	MAX_COMMAND_LENGTH - The maximum length of a command string.	COMMAND_NOT_FOUND - Indicates that a searched for string is not a function.Enums:	e_COMM_FLAG - Bit mappings for command options.	E_COMMANDS - Structure of the array holding the string data.Macros:	Command_(%1) - Forwards and declares a standard command for calling.	ycmd(%1) - Adds a command to the array (wrapper for Command_Add).Tags:	e_COMM_FLAG - Flag type.Variables:	Global:		-	Static:		g_sCommands - Holds all the textual data of the commands.		g_sSearchTree - Tree of hashes for function names.		g_sAltTree - Tree of hashes for alternate names.		g_sPrefix - The command prefix.		g_sPrefixLength - Length of the prefix.		g_sCommandIndex - Pointer to the next free index in the function array.		g_sAltCount - The number of commands with altnames.		g_sCommandFlags - Bit array of command options.-*----------------------------------------------------------------------------*/#define MAX_COMMAND_LENGTH	16#define COMMAND_NOT_FOUND	-1enum e_COMM_FLAG (<<= 1){	e_COMM_FLAG_SORTED = 1,	e_COMM_FLAG_PERMISSION_WARN,	e_COMM_FLAG_USE_ALTNAMES,	e_COMM_FLAG_PERMISSION_RET,	e_COMM_FLAG_USE_PREFIX,	e_COMM_FLAG_USE_SPACE,	e_COMM_FLAG_USE_SHORTCUTS,	e_COMM_FLAG_DISCONNECT}enum E_COMMANDS{	E_COMMANDS_FUNCTION[MAX_COMMAND_LENGTH],	E_COMMANDS_ALTNAME[MAX_COMMAND_LENGTH],	E_COMMANDS_FUNCNAME[MAX_COMMAND_LENGTH + 5]}forward Command_Add(funcname[]);forward Command_Remove(funcname[]);static	g_sCommands[MAX_COMMANDS][E_COMMANDS],	Bintree:g_sSearchTree[MAX_COMMANDS][E_BINTREE_TREE],	Bintree:g_sAltTree[MAX_COMMANDS][E_BINTREE_TREE],	g_sPrefix[MAX_COMMAND_LENGTH],	g_sPrefixLength,	g_sCommandIndex,	g_sAltCount,	e_COMM_FLAG:g_sCommandFlags;#define Command_(%1) \	forward ycmd_%1(playerid, params[], help); \	public ycmd_%1(playerid, params[], help)	#define ycmd(%1) \	CallRemoteFunction("Command_Add", "s", (%1))/*----------------------------------------------------------------------------*-Function:	Command_CommandParams:	-Return:	-Notes:	--*----------------------------------------------------------------------------*/#define Command_Command()/*----------------------------------------------------------------------------*-Function:	Command_IsClearedParams:	playerid - Player to check for.	command - Command to check for.Return:	TRUENotes:	Not implemented yet.-*----------------------------------------------------------------------------*/#define Command_IsCleared(%1,%2) \	TRUE/*----------------------------------------------------------------------------*-Function:	Command_DisconnectReturnParams:	-Return:	e_COMM_FLAG_DISCONNECTNotes:	--*----------------------------------------------------------------------------*/#define Command_DisconnectReturn() \	(g_sCommandFlags & e_COMM_FLAG_DISCONNECT)/*----------------------------------------------------------------------------*-Function:	Command_SetDisconnectReturnParams:	set - 1/0.Return:	-Notes:	--*----------------------------------------------------------------------------*/stock Command_SetDisconnectReturn(set){	if (set) g_sCommandFlags |= e_COMM_FLAG_DISCONNECT;	else g_sCommandFlags &= ~e_COMM_FLAG_USE_DISCONNECT;}/*----------------------------------------------------------------------------*-Function:	Command_UsingShortCutsParams:	-Return:	e_COMM_FLAG_USE_SHORTCUTSNotes:	--*----------------------------------------------------------------------------*/#define Command_UsingShortCuts() \	(g_sCommandFlags & e_COMM_FLAG_USE_SHORTCUTS)/*----------------------------------------------------------------------------*-Function:	Command_UseShortCutsParams:	set - true/false.Return:	-Notes:	--*----------------------------------------------------------------------------*/stock Command_UseShortCuts(set){	if (set) g_sCommandFlags |= e_COMM_FLAG_USE_SHORTCUTS;	else g_sCommandFlags &= ~e_COMM_FLAG_USE_SHORTCUTS;}/*----------------------------------------------------------------------------*-Function:	Command_DeniedReturnParams:	-Return:	e_COMM_FLAG_PERMISSION_RETNotes:	--*----------------------------------------------------------------------------*/#define Command_DeniedReturn() \	(g_sCommandFlags & e_COMM_FLAG_PERMISSION_RET)/*----------------------------------------------------------------------------*-Function:	Command_SetDeniedReturnParams:	set - 1/0.Return:	-Notes:	--*----------------------------------------------------------------------------*/stock Command_SetDeniedReturn(set){	if (set) g_sCommandFlags |= e_COMM_FLAG_PERMISSION_RET;	else g_sCommandFlags &= ~e_COMM_FLAG_USE_PERMISSION_RET;}/*----------------------------------------------------------------------------*-Function:	Command_DeniedMessageParams:	-Return:	e_COMM_FLAG_PERMISSION_WARNNotes:	--*----------------------------------------------------------------------------*/#define Command_DeniedMessage() \	(g_sCommandFlags & e_COMM_FLAG_PERMISSION_WARN)/*----------------------------------------------------------------------------*-Function:	Command_UseDeniedMessageParams:	set - true/false.Return:	-Notes:	--*----------------------------------------------------------------------------*/stock Command_UseDeniedMessage(set){	if (set) g_sCommandFlags |= e_COMM_FLAG_PERMISSION_WARN;	else g_sCommandFlags &= ~e_COMM_FLAG_PERMISSION_WARN;}/*----------------------------------------------------------------------------*-Function:	Command_IsSortedParams:	-Return:	e_COMM_FLAG_SORTEDNotes:	--*----------------------------------------------------------------------------*/#define Command_IsSorted() \	(g_sCommandFlags & e_COMM_FLAG_SORTED)/*----------------------------------------------------------------------------*-Function:	Command_SetSortedParams:	set - true/false.Return:	-Notes:	--*----------------------------------------------------------------------------*/static Command_SetSorted(set){	if (set) g_sCommandFlags |= e_COMM_FLAG_SORTED;	else g_sCommandFlags &= ~e_COMM_FLAG_SORTED;}/*----------------------------------------------------------------------------*-Function:	Command_UsingAltNamesParams:	-Return:	e_COMM_FLAG_USE_ALTNAMESNotes:	--*----------------------------------------------------------------------------*/#define Command_UsingAltNames() \	(g_sCommandFlags & e_COMM_FLAG_USE_ALTNAMES)/*----------------------------------------------------------------------------*-Function:	Command_UseAltNamesParams:	set - true/false.Return:	-Notes:	--*----------------------------------------------------------------------------*/stock Command_UseAltNames(set){	if (set) g_sCommandFlags |= e_COMM_FLAG_USE_ALTNAMES;	else g_sCommandFlags &= ~e_COMM_FLAG_USE_ALTNAMES;}/*----------------------------------------------------------------------------*-Function:	Command_UsingPrefixParams:	-Return:	e_COMM_FLAG_USE_PREFIXNotes:	--*----------------------------------------------------------------------------*/#define Command_UsingPrefix() \	(g_sCommandFlags & e_COMM_FLAG_USE_PREFIX)/*----------------------------------------------------------------------------*-Function:	Command_UsePrefixParams:	set - true/false.Return:	-Notes:	--*----------------------------------------------------------------------------*/stock Command_UsePrefix(set){	if (set) g_sCommandFlags |= e_COMM_FLAG_USE_PREFIX;	else g_sCommandFlags &= ~e_COMM_FLAG_USE_PREFIX;}/*----------------------------------------------------------------------------*-Function:	Command_UsingSpaceParams:	-Return:	e_COMM_FLAG_USE_SPACENotes:	--*----------------------------------------------------------------------------*/#define Command_UsingSpace() \	(g_sCommandFlags & e_COMM_FLAG_USE_SPACE)/*----------------------------------------------------------------------------*-Function:	Command_UseSpaceParams:	set - true/false.Return:	-Notes:	--*----------------------------------------------------------------------------*/stock Command_UseSpace(set){	if (set) g_sCommandFlags |= e_COMM_FLAG_USE_SPACE;	else g_sCommandFlags &= ~e_COMM_FLAG_USE_SPACE;}/*----------------------------------------------------------------------------*-Function:	Command_CallFunctionParams:	command - Function index to call.	playerid - playeris parameter.	params[] - params[] parameter.	help - help parameter.Return:	CallRemoteFunctionNotes:	--*----------------------------------------------------------------------------*/#define Command_CallFunction(%1,%2,%3,%4) \	CallRemoteFunction(g_sCommands[(%1)][E_COMMANDS_FUNCNAME], "isi", (%2), (%3), (%4))/*----------------------------------------------------------------------------*-Function:	Command_AddParams:	funcname[] - The function to add to the array.Return:	-Notes:	If the list of commands have already been sorted into the binary tree the	new commands will be appended, otherwise they will just be added to the	array.-*----------------------------------------------------------------------------*/public Command_Add(funcname[]){	if (g_sCommandIndex >= MAX_COMMANDS) return;	strcpy(g_sCommands[g_sCommandIndex][E_COMMANDS_FUNCTION], strtolower(funcname));	strcpy(g_sCommands[g_sCommandIndex][E_COMMANDS_FUNCNAME], strcat2("ycmd_", strtolower(funcname)));	if (Command_IsSorted())	{		new			data[E_BINTREE_INPUT],			index;		data[E_BINTREE_INPUT_VALUE] = Command_Hash(funcname, index);		data[E_BINTREE_INPUT_POINTER] = g_sCommandIndex;		Bintree_Add(g_sSearchTree, data, g_sCommandIndex, sizeof (g_sSearchTree));	}	g_sCommandIndex++;}/*----------------------------------------------------------------------------*-Function:	Command_ParseParams:	-Return:	-Notes:	Sorts the commands into the binary tree.-*----------------------------------------------------------------------------*/Command_Parse(){	if (Command_IsSorted()) return;	new		funcData[MAX_COMMANDS][E_BINTREE_INPUT],		altData[MAX_COMMANDS][E_BINTREE_INPUT],		j;	for (new i = 0; i < g_sCommandIndex; i++)	{		funcData[i][E_BINTREE_INPUT_VALUE] = bernstein(g_sCommands[i][E_COMMANDS_FUNCTION]);		funcData[i][E_BINTREE_INPUT_POINTER] = i;		if (g_sCommands[i][E_COMMANDS_ALTNAME][0])		{			altData[j][E_BINTREE_INPUT_VALUE] = bernstein(g_sCommands[i][E_COMMANDS_ALTNAME]);			altData[j][E_BINTREE_INPUT_POINTER] = i;			j++;		}	}	g_sAltCount = j;	Bintree_Generate(g_sSearchTree, funcData, g_sCommandIndex);	Bintree_Generate(g_sAltTree, altData, g_sAltCount);	Command_SetSorted(1);}/*----------------------------------------------------------------------------*-Function:	Command_FindSlowParams:	funcname[] - Function to find.Return:	-Notes:	Searches through the array for function linearly - used to set altnames	before the data has been sorted.-*----------------------------------------------------------------------------*/static Command_FindSlow(funcname[]){	for (new i = 0; i < g_sCommandIndex; i++)	{		if (!strcmp(g_sCommands[i][E_COMMANDS_FUNCTION], funcname, true)) return i;	}	return COMMAND_NOT_FOUND;}/*----------------------------------------------------------------------------*-Function:	Command_SetAltNameParams:	funcname[] - Function to set the alternate name for.	altname[] - The new name.Return:	-Notes:	--*----------------------------------------------------------------------------*/stock Command_SetAltName(funcname[], altname[]){	new		pointer;	if (!Command_IsSorted())	{		if ((pointer = Command_FindSlow(funcname)) == COMMAND_NOT_FOUND) return;	}	else	{		new			index;		if ((pointer = Command_FindFunc(funcname, Command_Hash(funcname, index), index)) == COMMAND_NOT_FOUND) return;		if (g_sCommands[pointer][E_COMMANDS_ALTNAME][0])		{			index = 0;			new				pointer2 = Command_FindAlt(g_sCommands[pointer][E_COMMANDS_ALTNAME], Command_Hash(g_sCommands[pointer][E_COMMANDS_ALTNAME], index), index);			if (pointer2 != BINTREE_NOT_FOUND)			{				g_sAltCount = Bintree_Delete(g_sAltTree, pointer2, g_sAltCount);			}		}		index = 0;		new			data[E_BINTREE_INPUT];		data[E_BINTREE_INPUT_VALUE] = Command_Hash(altname, index);		data[E_BINTREE_INPUT_POINTER] = pointer;		g_sAltCount = Bintree_Add(g_sAltTree, data, g_sAltCount, sizeof (g_sAltTree));	}	strcpy(g_sCommands[pointer][E_COMMANDS_ALTNAME], strtolower(altname));}/*----------------------------------------------------------------------------*-Function:	Command_SetPrefixParams:	prefix[] - The new prefix.Return:	-Notes:	--*----------------------------------------------------------------------------*/stock Command_SetPrefix(prefix[]){	strcpy(g_sPrefix, prefix);	g_sPrefixLength = strlen(prefix);}/*----------------------------------------------------------------------------*-Function:	Command_FindFuncParams:	data[] - Function name to find.	value - Hash of function name.	length - Length of name.	&ret - Variable to store leaf to.Return:	Position in functions array or COMMAND_NOT_FOUND.Notes:	--*----------------------------------------------------------------------------*/static Command_FindFunc(data[], value, length, &ret = 0){	new		leaf,		pointer;	while ((pointer = Bintree_FindValue(g_sSearchTree, value, leaf, ret)) != BINTREE_NOT_FOUND)	{		if (!strcmp(g_sCommands[pointer][E_COMMANDS_FUNCTION], data, true, length)) return pointer;	}	return COMMAND_NOT_FOUND;}/*----------------------------------------------------------------------------*-Function:	Command_FindFuncParams:	data[] - Altname to find.	value - Hash of altname.	length - Length of name.	&ret - Variable to store leaf to.Return:	Position in functions array or COMMAND_NOT_FOUND.Notes:	--*----------------------------------------------------------------------------*/static Command_FindAlt(data[], value, length, &ret = 0){	new		leaf,		pointer;	while ((pointer = Bintree_FindValue(g_sAltTree, value, leaf, ret)) != BINTREE_NOT_FOUND)	{		if (!strcmp(g_sCommands[pointer][E_COMMANDS_ALTNAME], data, true, length)) return pointer;	}	return COMMAND_NOT_FOUND;}/*----------------------------------------------------------------------------*-Function:	Command_FindParams:	data[] - string from OnPlayerCommandText to search for.	&index - Variable to store end of Return:	Command index or COMMAND_NOT_FOUND.Notes:	--*----------------------------------------------------------------------------*/static Command_Find(data[], &index){	new		pointer,		start = index,		length = index,		value = Command_Hash(data, index);	length = index - length;	if (Command_UsingAltNames() && (pointer = Command_FindAlt(data[start], value, length)) != COMMAND_NOT_FOUND) return pointer;	if ((pointer = Command_FindFunc(data[start], value, length)) != COMMAND_NOT_FOUND && (!Command_UsingAltNames() || !g_sCommands[pointer][E_COMMANDS_ALTNAME][0])) return pointer;	return COMMAND_NOT_FOUND;}/*----------------------------------------------------------------------------*-Function:	Command_RemoveParams:	funcname[] - Function to removeReturn:	-Notes:	Don't use before the bintree has been sorted or the function will fail.-*----------------------------------------------------------------------------*/public Command_Remove(funcname[]){	new		pointer,		leaf;	if ((pointer = Command_FindFunc(funcname, Command_Hash(funcname), strlen(funcname), leaf)) == COMMAND_NOT_FOUND) return;	g_sCommandIndex = Bintree_Delete(g_sSearchTree, leaf, g_sCommandIndex);	Bintree_UpdatePointers(g_sSearchTree, pointer, g_sCommandIndex);	new		pointer2,		altname[MAX_COMMAND_LENGTH];	strcpy(altname, g_sCommands[pointer][E_COMMANDS_ALTNAME]);	while ((pointer2 = pointer + 1) <= g_sCommandIndex)	{		strcpy(g_sCommands[pointer][E_COMMANDS_FUNCTION], g_sCommands[pointer2][E_COMMANDS_FUNCTION]);		strcpy(g_sCommands[pointer][E_COMMANDS_ALTNAME], g_sCommands[pointer2][E_COMMANDS_ALTNAME]);		strcpy(g_sCommands[pointer][E_COMMANDS_FUNCNAME], g_sCommands[pointer2][E_COMMANDS_FUNCNAME]);		pointer++;	}	if (altname[0])	{		if ((pointer = Command_FindAlt(altname, Command_Hash(altname), strlen(altname), leaf)) == COMMAND_NOT_FOUND) return;		g_sAltCount = Bintree_Delete(g_sAltTree, leaf, g_sAltCount);		Bintree_UpdatePointers(g_sAltTree, pointer, g_sAltCount);	}}/*----------------------------------------------------------------------------*-Function:	Command_PrefixParams:	cmdtext[] - Text from OnPlayerCommandText.	&index - Variable to store end of prefix to.Return:	true/false.Notes:	Checks the player has entered the required command prefix with optional	trailing space.-*----------------------------------------------------------------------------*/static Command_Prefix(cmdtext[], &index){	if (Command_UsingPrefix())	{		if (strcmp(cmdtext[index], g_sPrefix, true, g_sPrefixLength)) return 0;		index += g_sPrefixLength;		if (Command_UsingSpace())		{			new				ret;			while (cmdtext[index] && cmdtext[index] == ' ')			{				ret = 1;				index++;			}			return ret;		}	}	return 1;}/*----------------------------------------------------------------------------*-Function:	Command_ProcessParams:	playerid - Player who entered the command.	cmdtext[] - Text entered.	help - Called from the help commmand or OnPlayerCommandText.Return:	true - success or hidden fail, false - fail.Notes:	--*----------------------------------------------------------------------------*/Command_Process(playerid, cmdtext[], help = 0){	if (!IsPlayerConnected(playerid)) return Command_DisconnectReturn();	if (!help && Command_UsingShortCuts() && (!cmdtext[2] || cmdtext[2] == ' '))	{		new			cmdname[MAX_COMMAND_LENGTH];		Player_FindShortCut(playerid, cmdtext[1], cmdname);		if (cmdname[0])		{			return CallRemoteFunction("OnPlayerCommandText", "is", playerid, strcat2(cmdname, cmdtext[2]));		}	}	new		index = 1,		command = Command_Find(cmdtext, index);	if (!help && !Command_Prefix(cmdtext, index)) return 0;	if (command == COMMAND_NOT_FOUND) return 0;	if (Command_IsCleared(playerid, command))	{		if (index < strlen(cmdtext)) return Command_CallFunction(command, playerid, cmdtext[index], help);		return Command_CallFunction(command, playerid, NULL, help);	}	if (Command_DeniedMessage()) SendClientMessage2(playerid, COLOR_WARN, "TEXT_MAIN_BLEVEL");	return Command_DeniedReturn();}/*----------------------------------------------------------------------------*-Function:	Command_HashParams:	command[] - Command text to hash.	&index - Start point and variable to store end point to.Return:	hash value.Notes:	Based on the bernstein function but only hashes one word, space delimited.-*----------------------------------------------------------------------------*/static Command_Hash(command[], &index = 0){	new		hash = -1,		j;	while ((j = command[index++]) && j != ' ') hash = hash * 33 + chrtolower(j);	while (command[index] == ' ') index++; index--;	return hash;}