Exemplo n.º 1
0
/**
 * @brief Add a new command to the script interface
 * @param[in] cmd_name The name the command is available via script interface
 * @param[in] function The function pointer
 * @param[in] desc A usually(?) one-line description of what the cmd does
 * @sa Cmd_RemoveCommand
 */
void Cmd_AddCommand (const char *cmd_name, xcommand_t function, const char *desc)
{
	cmd_function_t *cmd;
	unsigned int hash;

	if (!cmd_name || !cmd_name[0])
		return;

	/* fail if the command is a variable name */
	if (Cvar_GetString(cmd_name)[0]) {
		Com_Printf("Cmd_AddCommand: %s already defined as a var\n", cmd_name);
		return;
	}

	/* fail if the command already exists */
	hash = Com_HashKey(cmd_name, CMD_HASH_SIZE);
	for (cmd = cmd_functions_hash[hash]; cmd; cmd = cmd->hash_next) {
		if (Q_streq(cmd_name, cmd->name)) {
			Com_DPrintf(DEBUG_COMMANDS, "Cmd_AddCommand: %s already defined\n", cmd_name);
			return;
		}
	}

	cmd = (cmd_function_t *)Mem_PoolAlloc(sizeof(*cmd), com_cmdSysPool, 0);
	cmd->name = cmd_name;
	cmd->description = desc;
	cmd->function = function;
	cmd->completeParam = NULL;
	HASH_Add(cmd_functions_hash, cmd, hash);
	cmd->next = cmd_functions;
	cmd_functions = cmd;
}
Exemplo n.º 2
0
/**
 * @brief Init or return a cvar
 * @param[in] var_name The cvar name
 * @param[in] var_value The standard cvar value (will be set if the cvar doesn't exist)
 * @param[in] flags CVAR_USERINFO, CVAR_LATCH, CVAR_SERVERINFO, CVAR_ARCHIVE and so on
 * @param[in] desc This is a short description of the cvar (see console command cvarlist)
 * @note CVAR_ARCHIVE: Cvar will be saved to config.cfg when game shuts down - and
 * will be reloaded when game starts up the next time
 * @note CVAR_LATCH: Latched cvars will be updated at the next map load
 * @note CVAR_SERVERINFO: This cvar will be send in the server info response strings (server browser)
 * @note CVAR_NOSET: This cvar can not be set from the commandline
 * @note CVAR_USERINFO: This cvar will be added to the userinfo string when changed (network synced)
 * @note CVAR_DEVELOPER: Only changeable if we are in development mode
 * If the variable already exists, the value will not be set
 * The flags will be or'ed in if the variable exists.
 */
cvar_t* Cvar_GetOrCreate (const char* var_name, const char* var_value, int flags, const char* desc)
{
	const unsigned hash = Com_HashKey(var_name, CVAR_HASH_SIZE);

	if (flags & (CVAR_USERINFO | CVAR_SERVERINFO)) {
		if (!Cvar_InfoValidate(var_name)) {
			Com_Printf("invalid info cvar name\n");
			return nullptr;
		}
	}

	if (cvar_t* const var = Cvar_FindVar(var_name)) {
		if (!var->defaultString && (flags & CVAR_CHEAT))
			var->defaultString = Mem_PoolStrDup(var_value, com_cvarSysPool, 0);
		var->flags |= flags;
		if (desc) {
			Mem_Free(var->description);
			var->description = Mem_PoolStrDup(desc, com_cvarSysPool, 0);
		}
		return var;
	}

	if (!var_value)
		return nullptr;

	if (flags & (CVAR_USERINFO | CVAR_SERVERINFO)) {
		if (!Cvar_InfoValidate(var_value)) {
			Com_Printf("invalid info cvar value '%s' of cvar '%s'\n", var_value, var_name);
			return nullptr;
		}
	}

	cvar_t* const var = Mem_PoolAllocType(cvar_t, com_cvarSysPool);
	var->name = Mem_PoolStrDup(var_name, com_cvarSysPool, 0);
	var->string = Mem_PoolStrDup(var_value, com_cvarSysPool, 0);
	var->oldString = nullptr;
	var->modified = true;
	var->value = atof(var->string);
	var->integer = atoi(var->string);
	if (desc)
		var->description = Mem_PoolStrDup(desc, com_cvarSysPool, 0);

	HASH_Add(cvarVarsHash, var, hash);
	/* link the variable in */
	var->next = cvarVars;
	cvarVars = var;
	if (var->next)
		var->next->prev = var;

	var->flags = flags;
	if (var->flags & CVAR_CHEAT)
		var->defaultString = Mem_PoolStrDup(var_value, com_cvarSysPool, 0);

	for (CvarListeners::iterator i = cvarListeners.begin(); i != cvarListeners.end(); ++i) {
		(*i)->onCreate(var);
	}

	return var;
}
Exemplo n.º 3
0
static void CL_ParseMessageID (const char* name, const char** text)
{
	/* get it's body */
	const char* token = Com_Parse(text);
	if (!*text || *token != '{') {
		Com_Printf("CL_ParseMessageID: msgid \"%s\" without body ignored\n", name);
		return;
	}

	/* search for game types with same name */
	int i;
	for (i = 0; i < numMsgIDs; i++)
		if (Q_streq(token, msgIDs[i].id))
			break;

	if (i == numMsgIDs) {
		msgid_t* msgid = &msgIDs[numMsgIDs++];

		if (numMsgIDs >= MAX_MSGIDS)
			Sys_Error("CL_ParseMessageID: MAX_MSGIDS exceeded");

		OBJZERO(*msgid);
		msgid->id = Mem_PoolStrDup(name, cl_msgidPool, 0);
		const unsigned int hash = Com_HashKey(msgid->id, MAX_MSGIDHASH);
		HASH_Add(msgIDHash, msgid, hash);

		do {
			const char* errhead = "CL_ParseMessageID: unexpected end of file (msgid ";
			token = Com_EParse(text, errhead, name);
			if (!*text)
				break;
			if (*token == '}')
				break;
			if (Q_streq(token, "text")) {
				/* found a definition */
				token = Com_EParse(text, errhead, name, msgIDText, MSGIDSIZE);
				if (!*text)
					break;
				if (token[0] == '_')
					token++;
				if (token[0] != '\0')
					msgid->text = _(token);
				else
					msgid->text = token;
				if (msgid->text == token) {
					msgid->text = Mem_PoolStrDup(token, cl_msgidPool, 0);
					Com_Printf("no translation for %s\n", msgid->id);
				}
			}
		} while (*text);
	} else {
		Com_Printf("CL_ParseMessageID: msgid \"%s\" with same already exists - ignore the second one\n", name);
		Com_SkipBlock(text);
	}
}