Esempio n. 1
0
void HPM_HP_load(void) {
	#include HPM_POINTS_INCLUDE
	int i, len = ARRAYLENGTH(HookingPoints), idx = 0;
	
	memset(&HPMHooks,0,sizeof(struct HPMHooksCore));
	
	hp_db = strdb_alloc(DB_OPT_BASE|DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA, HookingPointsLenMax);
	
	for(i = 0; i < len; i++) {
		struct HookingPointData *hpd = NULL;
		
		CREATE(hpd, struct HookingPointData, 1);
		
		memcpy(hpd, &HookingPoints[i], sizeof(struct HookingPointData));
		
		hpd->idx = idx;
		idx += 2;
		
		strdb_put(hp_db, HookingPoints[i].name, hpd);
		
		HPMHooks.data.total++;
	}
	
	#include HPM_SOURCES_INCLUDE
}
Esempio n. 2
0
bool channel_create(struct map_session_data *sd, const char* name, const char* pass, short type, short color, int op)
{
	struct channel_data *cd;
	int i = 0;

	if( !name || strlen(name) < 2 || strlen(name) >= NAME_LENGTH || name[0] != '#' )
	{
		if( sd ) clif_displaymessage(sd->fd, msg_txt(801));
		return false;
	}
	if( type == CHN_USER && !sd )
		return false; // Operator required for user channels
	if( sd && type == CHN_USER && (i = channel_slot_free(sd)) < 0 )
	{
		clif_displaymessage(sd->fd, msg_txt(800));
		return false;
	}
	if( (cd = (struct channel_data *)strdb_get(channel_db, name)) != NULL )
	{
		if( sd ) clif_displaymessage(sd->fd, msg_txt(802));
		return false; // Already exists
	}

	CREATE(cd, struct channel_data, 1);
	cd->channel_id = ++channel_counter;
	safestrncpy(cd->name, name, sizeof(cd->name));
	safestrncpy(cd->pass, pass, sizeof(cd->pass));
	cd->type = type;
	cd->color = channel_color[cap_value(color,0,38)];
	cd->users = 0;
	cd->op = 0;
	cd->users_db = idb_alloc(DB_OPT_BASE);

	if( type == CHN_USER )
	{
		char output[128];
		sprintf(output, msg_txt(803), cd->name, sd->status.name);
		
		sd->cd[i] = cd;
		cd->op = sd->bl.id;
		idb_put(cd->users_db, sd->bl.id, sd);
		cd->users++;
		clif_channel_message(cd, output, -1);
	}
	else if( type < CHN_USER )
	{
		server_channel[type] = cd; // Quick access to main channels
		ShowInfo("Channel System : New channel %s created.\n", cd->name);
	}
	else
		cd->op = op; // Server Channel

	strdb_put(channel_db, cd->name, cd);
	return true;
}
Esempio n. 3
0
/**
 * Create a channel
 * - Will then add it in the channel_db if the type is not map or ally
 * @param name: Channel name, can't be null
 * @param pass: Channel password, can be null
 * @param color: Display color
 * @param chantype: Channel type
 * @return NULL on failure or Channel on success
 */
struct Channel* channel_create(struct Channel *tmp_chan) {
	struct Channel* channel;

	if (!tmp_chan->name[0])
		return NULL;

	CREATE(channel, struct Channel, 1); //will exit on fail allocation
	//channel->id = tmp_chan->id;
	channel->users = idb_alloc(DB_OPT_BASE);
	channel->banned = idb_alloc(static_cast<DBOptions>(DB_OPT_BASE|DB_OPT_RELEASE_DATA) );
	channel->opt = tmp_chan->opt;
	channel->type = tmp_chan->type;
	channel->color = tmp_chan->color;
	safestrncpy(channel->name, tmp_chan->name, CHAN_NAME_LENGTH); // Store channel cname without '#'
	safestrncpy(channel->alias, tmp_chan->alias[0] ? tmp_chan->alias : tmp_chan->name, CHAN_NAME_LENGTH);
	if (!tmp_chan->pass[0])
		channel->pass[0] = '\0';
	else
		safestrncpy(channel->pass, tmp_chan->pass, CHAN_NAME_LENGTH);
	channel->msg_delay = tmp_chan->msg_delay;

	switch (channel->type) {
		case CHAN_TYPE_MAP:
			channel->m = tmp_chan->m;
			break;
		case CHAN_TYPE_ALLY:
			channel->gid = tmp_chan->gid;
			break;
		case CHAN_TYPE_PRIVATE:
			channel->char_id = tmp_chan->char_id;
		default:
			strdb_put(channel_db, channel->name, channel);
			break;
	}

	if (battle_config.etc_log)
		ShowInfo("Create channel %s alias %s type=%d, owner=%d/%d/%d\n",channel->name,channel->alias,channel->type,channel->char_id,channel->m,channel->gid);

	return channel;
}
Esempio n. 4
0
/**
 * Creates a chat channel.
 *
 * If the channel type isn't HCS_TYPE_MAP or HCS_TYPE_ALLY, the channel is added to the channel->db.
 *
 * @param type The channel type.
 * @param name The channel name.
 * @param color The channel chat color.
 * @return A pointer to the created channel.
 */
struct channel_data *channel_create(enum channel_types type, const char *name, unsigned char color)
{
	struct channel_data *chan;

	if (!name)
		return NULL;

	CREATE(chan, struct channel_data, 1);
	chan->users = idb_alloc(DB_OPT_BASE);
	safestrncpy(chan->name, name, HCS_NAME_LENGTH);
	chan->color = color;

	chan->options = HCS_OPT_BASE;
	chan->banned = NULL;

	chan->msg_delay = 0;

	chan->type = type;
	if (chan->type != HCS_TYPE_MAP && chan->type != HCS_TYPE_ALLY)
		strdb_put(channel->db, chan->name, chan);
	return chan;
}
Esempio n. 5
0
/**
 * Loads group configuration from config file into memory.
 * @private
 */
static void read_config(void)
{
	config_setting_t *groups = NULL;
	const char *config_filename = "conf/groups.conf"; // FIXME hardcoded name
	int group_count = 0;
	
	if (conf_read_file(&pc_group_config, config_filename))
		return;

	groups = config_lookup(&pc_group_config, "groups");

	if (groups != NULL) {
		GroupSettings *group_settings = NULL;
		DBIterator *iter = NULL;
		int i, loop = 0;

		group_count = config_setting_length(groups);
		for (i = 0; i < group_count; ++i) {
			int id = 0, level = 0;
			const char *groupname = NULL;
			int log_commands = 0;
			config_setting_t *group = config_setting_get_elem(groups, i);

			if (!config_setting_lookup_int(group, "id", &id)) {
				ShowConfigWarning(group, "pc_groups:read_config: \"groups\" list member #%d has undefined id, removing...", i);
				config_setting_remove_elem(groups, i);
				--i;
				--group_count;
				continue;
			}

			if (id2group(id) != NULL) {
				ShowConfigWarning(group, "pc_groups:read_config: duplicate group id %d, removing...", i);
				config_setting_remove_elem(groups, i);
				--i;
				--group_count;
				continue;
			}

			config_setting_lookup_int(group, "level", &level);
			config_setting_lookup_bool(group, "log_commands", &log_commands);

			if (!config_setting_lookup_string(group, "name", &groupname)) {
				char temp[20];
				config_setting_t *name = NULL;
				snprintf(temp, sizeof(temp), "Group %d", id);
				if ((name = config_setting_add(group, "name", CONFIG_TYPE_STRING)) == NULL ||
				    !config_setting_set_string(name, temp)) {
					ShowError("pc_groups:read_config: failed to set missing group name, id=%d, skipping... (%s:%d)\n",
					          id, config_setting_source_file(group), config_setting_source_line(group));
					continue;
				}
				config_setting_lookup_string(group, "name", &groupname); // Retrieve the pointer
			}

			if (name2group(groupname) != NULL) {
				ShowConfigWarning(group, "pc_groups:read_config: duplicate group name %s, removing...", groupname);
				config_setting_remove_elem(groups, i);
				--i;
				--group_count;
				continue;
			}

			CREATE(group_settings, GroupSettings, 1);
			group_settings->id = id;
			group_settings->level = level;
			group_settings->name = groupname;
			group_settings->log_commands = (bool)log_commands;
			group_settings->inherit = config_setting_get_member(group, "inherit");
			group_settings->commands = config_setting_get_member(group, "commands");
			group_settings->permissions = config_setting_get_member(group, "permissions");
			group_settings->inheritance_done = false;
			group_settings->root = group;
			group_settings->group_pos = i;

			strdb_put(pc_groupname_db, groupname, group_settings);
			idb_put(pc_group_db, id, group_settings);
			
		}
		group_count = config_setting_length(groups); // Save number of groups
		
		// Check if all commands and permissions exist
		iter = db_iterator(pc_group_db);
		for (group_settings = dbi_first(iter); dbi_exists(iter); group_settings = dbi_next(iter)) {
			config_setting_t *commands = group_settings->commands, *permissions = group_settings->permissions;
			int count = 0, j;

			// Make sure there is "commands" group
			if (commands == NULL)
				commands = group_settings->commands = config_setting_add(group_settings->root, "commands", CONFIG_TYPE_GROUP);
			count = config_setting_length(commands);

			for (j = 0; j < count; ++j) {
				config_setting_t *command = config_setting_get_elem(commands, j);
				const char *name = config_setting_name(command);
				if (!atcommand_exists(name)) {
					ShowConfigWarning(command, "pc_groups:read_config: non-existent command name '%s', removing...", name);
					config_setting_remove(commands, name);
					--j;
					--count;
				}
			}

			// Make sure there is "permissions" group
			if (permissions == NULL)
				permissions = group_settings->permissions = config_setting_add(group_settings->root, "permissions", CONFIG_TYPE_GROUP);
			count = config_setting_length(permissions);

			for(j = 0; j < count; ++j) {
				config_setting_t *permission = config_setting_get_elem(permissions, j);
				const char *name = config_setting_name(permission);
				int p;

				ARR_FIND(0, ARRAYLENGTH(pc_g_permission_name), p, strcmp(pc_g_permission_name[p].name, name) == 0);
				if (p == ARRAYLENGTH(pc_g_permission_name)) {
					ShowConfigWarning(permission, "pc_groups:read_config: non-existent permission name '%s', removing...", name);
					config_setting_remove(permissions, name);
					--p;
					--count;
				}
			}
		}
		dbi_destroy(iter);

		// Apply inheritance
		i = 0; // counter for processed groups
		while (i < group_count) {
			iter = db_iterator(pc_group_db);
			for (group_settings = dbi_first(iter); dbi_exists(iter); group_settings = dbi_next(iter)) {
				config_setting_t *inherit = NULL,
				                 *commands = group_settings->commands,
					             *permissions = group_settings->permissions;
				int j, inherit_count = 0, done = 0;
				
				if (group_settings->inheritance_done) // group already processed
					continue; 

				if ((inherit = group_settings->inherit) == NULL ||
				    (inherit_count = config_setting_length(inherit)) <= 0) { // this group does not inherit from others
					++i;
					group_settings->inheritance_done = true;
					continue;
				}
				
				for (j = 0; j < inherit_count; ++j) {
					GroupSettings *inherited_group = NULL;
					const char *groupname = config_setting_get_string_elem(inherit, j);

					if (groupname == NULL) {
						ShowConfigWarning(inherit, "pc_groups:read_config: \"inherit\" array member #%d is not a name, removing...", j);
						config_setting_remove_elem(inherit,j);
						continue;
					}
					if ((inherited_group = name2group(groupname)) == NULL) {
						ShowConfigWarning(inherit, "pc_groups:read_config: non-existent group name \"%s\", removing...", groupname);
						config_setting_remove_elem(inherit,j);
						continue;
					}
					if (!inherited_group->inheritance_done)
						continue; // we need to do that group first

					// Copy settings (commands/permissions) that are not defined yet
					if (inherited_group->commands != NULL) {
						int l = 0, commands_count = config_setting_length(inherited_group->commands);
						for (l = 0; l < commands_count; ++l)
							config_setting_copy(commands, config_setting_get_elem(inherited_group->commands, l));
					}

					if (inherited_group->permissions != NULL) {
						int l = 0, permissions_count = config_setting_length(inherited_group->permissions);
						for (l = 0; l < permissions_count; ++l)
							config_setting_copy(permissions, config_setting_get_elem(inherited_group->permissions, l));
					}

					++done; // copied commands and permissions from one of inherited groups
				}
				
				if (done == inherit_count) { // copied commands from all of inherited groups
					++i;
					group_settings->inheritance_done = true; // we're done with this group
				}
			}
			dbi_destroy(iter);

			if (++loop > group_count) {
				ShowWarning("pc_groups:read_config: Could not process inheritance rules, check your config '%s' for cycles...\n",
				            config_filename);
				break;
			}
		} // while(i < group_count)

		// Pack permissions into GroupSettings.e_permissions for faster checking
		iter = db_iterator(pc_group_db);
		for (group_settings = dbi_first(iter); dbi_exists(iter); group_settings = dbi_next(iter)) {
			config_setting_t *permissions = group_settings->permissions;
			int c, count = config_setting_length(permissions);

			for (c = 0; c < count; ++c) {
				config_setting_t *perm = config_setting_get_elem(permissions, c);
				const char *name = config_setting_name(perm);
				int val = config_setting_get_bool(perm);
				int j;

				if (val == 0) // does not have this permission
					continue;
				ARR_FIND(0, ARRAYLENGTH(pc_g_permission_name), j, strcmp(pc_g_permission_name[j].name, name) == 0);
				group_settings->e_permissions |= pc_g_permission_name[j].permission;
			}
		}
		dbi_destroy(iter);
	}

	ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' groups in '"CL_WHITE"%s"CL_RESET"'.\n", group_count, config_filename);

	
	if( ( pc_group_max = group_count ) ) {
		DBIterator *iter = db_iterator(pc_group_db);
		GroupSettings *group_settings = NULL;
		int* group_ids = aMalloc( pc_group_max * sizeof(int) );
		int i = 0;
		for (group_settings = dbi_first(iter); dbi_exists(iter); group_settings = dbi_next(iter)) {
			group_ids[i++] = group_settings->id;
		}
		
		atcommand_db_load_groups(group_ids);
		
		aFree(group_ids);
		
		dbi_destroy(iter);
	}
}
Esempio n. 6
0
static bool configParse(raconf inst,  const char *fileName){
	FILE *fp;
	char line[4096];
	char currentSection[SECTION_LEN];
	char *p;
	char c;
	int linecnt;
	size_t linelen;
	size_t currentSection_len;
	
	fp = fopen(fileName, "r");
	if(fp == NULL){
		ShowError("configParse: cannot open '%s' for reading.\n", fileName);
		return false;
	}
	

	// Start with empty section:
	currentSection[0] = '\0';
	currentSection_len = 0;
	
	// 	
	linecnt = 0;
	while(1){
		linecnt++;
		
		if(fgets(line, sizeof(line), fp) != line)
			break;

		linelen = strlen(line);
		p = line;
		
		// Skip whitespaces from beginning (space and tab)
		_line_begin_skip_whities:
		c = *p;
		if(c == ' ' || c == '\t'){
			p++; 
			linelen--;
			goto _line_begin_skip_whities;
		}
		
		// Remove linebreaks as (cr or lf) and whitespaces from line end!
		_line_end_skip_whities_and_breaks:
		c = p[linelen-1];
		if(c == '\r' || c == '\n' || c == ' ' || c == '\t'){
			p[--linelen] = '\0';
			goto _line_end_skip_whities_and_breaks;
		}
		
		// Empty line? 
		// or line starts with comment (commented out)?
		if(linelen == 0 || (p[0] == '/' && p[1] == '/') || p[0] == ';')
			continue;
		
		// Variable names can contain:
		// A-Za-z-_.0-9
		//
		// Sections start with [ .. ] (INI Style)
		//
		c = *p;
		
		// check what we have.. :)
		if(c == '['){ // got section!
			// Got Section!
			// Search for ] 
			char *start = (p+1);
			
			while(1){
				++p;
				c = *p;
				
				if(c == '\0'){
					ShowError("Syntax Error: unterminated Section name in %s:%u (expected ']')\n", fileName, linecnt);
					fclose(fp);
					return false;
				}else if(c == ']'){ // closing backet (section name termination)
					if( (p - start + 1) > (sizeof(currentSection) ) ){
						ShowError("Syntax Error: Section name in %s:%u is too large (max Supported length: %u chars)\n", fileName, linecnt, sizeof(currentSection)-1);
						fclose(fp);
						return false;
					}
					
					// Set section!
					*p = '\0'; // add termination here.
					memcpy(currentSection, start, (p-start)+1 ); // we'll copy \0, too! (we replaced the ] backet with \0.)
					currentSection_len = (p-start);
					
					break;
					
				}else if( (c >= '0' && c <= '9') || (c == '-') || (c == ' ') || (c == '_') || (c == '.') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ){
					// skip .. (allowed char / specifier)
					continue;
				}else{
					ShowError("Syntax Error: Invalid Character '%c' in %s:%u (offset %u) for Section name.\n", c, fileName, linecnt, (p-line));
					fclose(fp);
					return false;
				}
				
			}//endwhile: parse section name 
			
		
		}else if( (c >= '0' && c <= '9') || (c == '-') || (c == '_') || (c == '.') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ){
			// Got variable! 
			// Search for '=' or ':' wich termiantes the name 
			char *start = p;
			char *valuestart = NULL;
			size_t start_len;
						
			while(1){
				++p;
				c = *p;
				
				if(c == '\0'){
					ShowError("Syntax Error: unterminated Variable name in %s:%u\n", fileName, linecnt);
					fclose(fp);
					return false;
				}else if( (c == '=') || (c == ':') ){
					// got name termination
					
					*p = '\0'; // Terminate it so  (start) will hold the pointer to the name.
					
					break;
					
				}else if( (c >= '0' && c <= '9') || (c == '-') || (c == '_') || (c == '.') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ){
					// skip .. allowed char 
					continue;
				}else{
					ShowError("Syntax Error: Invalid Character '%c' in %s:%u (offset %u) for Variable name.\n", c, fileName, linecnt, (p-line));
					fclose(fp);
					return false;
				}
				
			}//endwhile: parse var name			
			
			start_len = (p-start);
			if(start_len >= VARNAME_LEN){
				ShowError("%s:%u Variable length exceeds limit of %u Characters.\n", fileName, linecnt, VARNAME_LEN-1);
				fclose(fp);
				return false;
			}else if(start_len == 0){
				ShowError("%s:%u Empty Variable name is not allowed.\n", fileName, linecnt);
				fclose(fp);
				return false;
			}
			
			
			valuestart = (p+1); 
			
			
			// Skip whitespace from begin of value (tab and space)
			_skip_value_begin_whities:
			c = *valuestart; 
			if(c == ' ' || c == '\t'){
				valuestart++;
				goto _skip_value_begin_whities;
			}
			
			// Scan for value termination, 
			// wich can be \0  or  comment start (// or ; (INI) )
			//
			p = valuestart;
			while(1){
				c = *p;
				if(c == '\0'){
					// Terminated by line end.
					break;
				}else if(c == '/' && p[1] == '/'){
					// terminated by c++ style comment.
					*p = '\0';
					break;
				}else if(c == ';'){
					// terminated by ini style comment.
					*p = '\0';
					break;
				}
				
				p++;
			}//endwhile: search var value end.
						
			
			// Strip whitespaces from end of value.
			if(valuestart != p){ // not empty!
				p--;
				_strip_value_end_whities: 
				c = *p;
				if(c == ' ' || c == '\t'){
					*p = '\0';
					p--;
					goto _strip_value_end_whities;
				}
				p++;
			}					
			
			
			// Buildin Hook:
			if( stricmp(start, "import") == 0){
				if( configParse(inst, valuestart) != true){
					ShowError("%s:%u - Import of '%s' failed!\n", fileName, linecnt, valuestart);
				}
			}else{
				// put it to db.
				struct conf_value *v, *o;
				char key[ (SECTION_LEN+VARNAME_LEN+1+1) ]; //+1 for delimiter, +1 for termination.
				size_t section_len;
				
				if(*currentSection == '\0'){ // empty / none
					strncpy(key, "<unnamed>",9);
					section_len = 9;
				}else{
					strncpy(key, currentSection, currentSection_len);
					section_len = currentSection_len;
				}
				
				key[section_len] = '.'; // Delim
				
				strncpy(&key[section_len+1],  start, start_len);
				
				key[section_len + start_len + 1] = '\0'; 

				
				v = makeValue(key, valuestart, (p-valuestart) );				
				
				// Try to get the old one before
				o = strdb_get(inst->db, key);
				if(o != NULL){
					strdb_remove(inst->db, key);
					aFree(o); //			
				}
				
				strdb_put( inst->db, key,  v);
			}								
			
			
		}else{
			ShowError("Syntax Error: unexpected Character '%c' in %s:%u (offset %u)\n", c, fileName, linecnt, (p-line) );
			fclose(fp);
			return false;
		}
		
		
		
	}
	
	
	
	fclose(fp);
	return true;
}//end: configParse()