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 }
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; }
/** * 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; }
/** * 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; }
/** * 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); } }
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()