/** * Attempt to create a global channel from the channel config * @param chan: Channel list * @param tmp_chan: Temporary channel data * @param i: Index * @return True on success or false on failure */ bool channel_read_sub(config_setting_t *chan, struct Channel *tmp_chan, uint8 i) { config_setting_t *group_list = NULL; int delay = 1000, autojoin = 0, leave = 1, chat = 1, color_override = 0, self_notif = 1, join_notif = 0, leave_notif = 0; int type = CHAN_TYPE_PUBLIC, group_count = 0; const char *name = NULL, *password = NULL, *alias = NULL, *color_str = "Default", *type_str = NULL; if (tmp_chan == NULL) return false; if (!config_setting_lookup_string(chan, "name", &name)) { ShowError("Please input channel 'name' at '%s' line '%d'! Skipping...\n", chan->file, chan->line); return false; } if (config_setting_lookup_string(chan, "type", &type_str) && !script_get_constant(type_str, &type)) { ShowError("Invalid channel type %s at '%s' line '%d'! Skipping...\n", type_str, chan->file, chan->line); return false; } config_setting_lookup_string(chan, "password", &password); config_setting_lookup_string(chan, "alias", &alias); config_setting_lookup_string(chan, "color", &color_str); config_setting_lookup_int(chan, "delay", &delay); config_setting_lookup_bool(chan, "autojoin", &autojoin); config_setting_lookup_bool(chan, "leave", &leave); config_setting_lookup_bool(chan, "chat", &chat); config_setting_lookup_bool(chan, "color_override", &color_override); config_setting_lookup_bool(chan, "self_notif", &self_notif); config_setting_lookup_bool(chan, "join_notif", &join_notif); config_setting_lookup_bool(chan, "leave_notif", &leave_notif); safestrncpy(tmp_chan->name,name+1,sizeof(tmp_chan->name)); if (password) safestrncpy(tmp_chan->pass,password,sizeof(tmp_chan->pass)); else tmp_chan->pass[0] = '\0'; safestrncpy(tmp_chan->alias,alias?alias:name,sizeof(tmp_chan->alias)); tmp_chan->msg_delay = delay; tmp_chan->type = (enum Channel_Type)type; tmp_chan->color = channel_getColor(color_str); tmp_chan->opt = (autojoin ? CHAN_OPT_AUTOJOIN : 0) | (leave ? CHAN_OPT_CAN_LEAVE : 0) | (chat ? CHAN_OPT_CAN_CHAT : 0) | (color_override ? CHAN_OPT_COLOR_OVERRIDE : 0) | (self_notif ? CHAN_OPT_ANNOUNCE_SELF : 0) | (join_notif ? CHAN_OPT_ANNOUNCE_JOIN : 0) | (leave_notif ? CHAN_OPT_ANNOUNCE_LEAVE : 0); if ((group_list = config_setting_get_member(chan, "groupid")) && (group_count = config_setting_length(group_list)) > 0) { int j; CREATE(tmp_chan->groups, unsigned short, group_count); tmp_chan->group_count = group_count; for (j = 0; j < group_count; j++) { int groupid = config_setting_get_int_elem(group_list, j); tmp_chan->groups[j] = groupid; } }
/** Read item group data * Structure: GroupID,ItemID,Rate{,Amount,isMust,isAnnounced,Duration,GUID,isBound,isNamed} */ static void itemdb_read_itemgroup_sub(const char* filename, bool silent) { FILE *fp; int ln = 0, entries = 0; char line[1024]; if ((fp=fopen(filename,"r")) == NULL) { if(silent == 0) ShowError("Can't read %s\n", filename); return; } while (fgets(line,sizeof(line),fp)) { DBData data; int group_id = -1; unsigned int j, prob = 1; uint8 rand_group = 1; char *str[10], *p; struct s_item_group_random *random = NULL; struct s_item_group_db *group = NULL; struct s_item_group_entry entry; bool found = false; ln++; if (line[0] == '/' && line[1] == '/') continue; if (strstr(line,"import")) { char w1[16], w2[64]; if (sscanf(line,"%15[^:]: %63[^\r\n]",w1,w2) == 2 && strcmpi(w1,"import") == 0) { itemdb_read_itemgroup_sub(w2, 0); continue; } } memset(str,0,sizeof(str)); for (j = 0, p = line; j < 9 && p;j++) { str[j] = p; p = strchr(p,','); if (p) *p++=0; } if (str[0] == NULL) //Empty Group ID continue; if (j < 3) { if (j > 1) // Or else it barks on blank lines... ShowWarning("itemdb_read_itemgroup: Insufficient fields for entry at %s:%d\n", filename, ln); continue; } memset(&entry, 0, sizeof(entry)); entry.amount = 1; entry.bound = BOUND_NONE; // Checking group_id trim(str[0]); if (ISDIGIT(str[0][0])) group_id = atoi(str[0]); else // Try reads group id by const script_get_constant(trim(str[0]), &group_id); if (group_id < 0) { ShowWarning("itemdb_read_itemgroup: Invalid Group ID '%s' (%s:%d)\n", str[0], filename, ln); continue; } // Remove from DB if (strcmpi(str[1], "clear") == 0 && itemdb_group->remove(itemdb_group, db_ui2key(group_id), &data)) { itemdb_group_free(db_ui2key(group_id), &data, 0); ShowNotice("Item Group '%s' has been cleared.\n", str[0]); continue; } // Checking sub group prob = atoi(str[2]); if (str[4] != NULL) rand_group = atoi(str[4]); if (rand_group < 0 || rand_group > MAX_ITEMGROUP_RANDGROUP) { ShowWarning("itemdb_read_itemgroup: Invalid sub group '%d' for group '%s' in %s:%d\n", rand_group, str[0], filename, ln); continue; } if (rand_group != 0 && prob < 1) { ShowWarning("itemdb_read_itemgroup: Random item must has probability. Group '%s' in %s:%d\n", str[0], filename, ln); continue; } // Checking item trim(str[1]); if (ISDIGIT(str[1][0]) && ISDIGIT(str[1][1]) && itemdb_exists((entry.nameid = atoi(str[1])))) found = true; else { struct item_data *id = itemdb_searchname(str[1]); if (id) { entry.nameid = id->nameid; found = true; } } if (!found) { ShowWarning("itemdb_read_itemgroup: Non-existant item '%s' in %s:%d\n", str[1], filename, ln); continue; } if (str[3] != NULL) entry.amount = cap_value(atoi(str[3]),1,MAX_AMOUNT); if (str[5] != NULL) entry.isAnnounced= atoi(str[5]); if (str[6] != NULL) entry.duration = cap_value(atoi(str[6]),0,UINT16_MAX); #ifdef ENABLE_ITEM_GUID if (str[7] != NULL) entry.GUID = atoi(str[7]); #endif if (str[8] != NULL) entry.bound = cap_value(atoi(str[8]),BOUND_NONE,BOUND_MAX-1); if (str[9] != NULL) entry.isNamed = atoi(str[9]); if (!(group = (struct s_item_group_db *) uidb_get(itemdb_group, group_id))) { CREATE(group, struct s_item_group_db, 1); group->id = group_id; uidb_put(itemdb_group, group->id, group); } // Must item (rand_group == 0), place it here if (!rand_group) { RECREATE(group->must, struct s_item_group_entry, group->must_qty+1); group->must[group->must_qty++] = entry; // If 'must' item isn't set as random item, skip the next process if (!prob) { entries++; continue; } rand_group = 0; }
/** Read item group data * Structure: GroupID,ItemID,Rate{,Amount,isMust,isAnnounced,Duration,isNamed,isBound} */ static void itemdb_read_itemgroup_sub(const char* filename) { FILE *fp; int ln = 0, entries = 0; char line[1024]; if( (fp = fopen(filename, "r")) == NULL ) { ShowError("Can't read %s\n", filename); return; } while( fgets(line, sizeof(line), fp) ) { uint16 nameid; int j, group_id, prob = 1, amt = 1, rand_group = 1, announced = 0, dur = 0, named = 0, bound = 0; char *str[3], *p, w1[1024], w2[1024]; bool found = false; struct s_item_group_random *random; ln++; if( line[0] == '/' && line[1] == '/' ) continue; if( strstr(line, "import") ) { if( sscanf(line, "%[^:]: %[^\r\n]", w1, w2) == 2 && strcmpi(w1, "import") == 0 ) { itemdb_read_itemgroup_sub(w2); continue; } } memset(str, 0, sizeof(str)); for( j = 0, p = line; j < 3 && p; j++ ) { str[j] = p; if( j == 2 ) sscanf(str[j], "%d,%d,%d,%d,%d,%d,%d", &prob, &amt, &rand_group, &announced, &dur, &named, &bound); p = strchr(p, ','); if( p ) *p++ = 0; } if( str[0] == NULL ) continue; if( j < 3 ) { if( j > 1 ) //Or else it barks on blank lines... ShowWarning("itemdb_read_itemgroup: Insufficient fields for entry at %s:%d\n", filename, ln); continue; } //Checking group_id trim(str[0]); if( ISDIGIT(str[0][0]) ) group_id = atoi(str[0]); else //Try reads group id by const script_get_constant(trim(str[0]), &group_id); if( group_id < 1 || group_id >= MAX_ITEMGROUP ) { ShowWarning("itemdb_read_itemgroup: Cannot save '%s' because invalid group id or group db is overflow in %s:%d\n", str[0], filename, ln); continue; } //Checking sub group if( rand_group < 0 || rand_group > MAX_ITEMGROUP_RANDGROUP ) { ShowWarning("itemdb_read_itemgroup: Invalid sub group %d for group '%s' in %s:%d\n", rand_group, str[0], filename, ln); continue; } if( rand_group && prob < 1 ) { ShowWarning("itemdb_read_itemgroup: Invalid probaility for group '%s' sub: %d in %s:%d\n", str[0], rand_group, filename, ln); continue; } //Checking item trim(str[1]); if( ISDIGIT(str[1][0]) && itemdb_exists((nameid = atoi(str[1]))) ) found = true; else if( itemdb_searchname(str[1]) ) { found = true; nameid = itemdb_searchname(str[1])->nameid; } if( !found ) { ShowWarning("itemdb_read_itemgroup: Non-existant item '%s' in %s:%d\n", str[1], filename, ln); continue; } amt = cap_value(amt, 1, MAX_AMOUNT); dur = cap_value(dur, 0, UINT16_MAX); bound = cap_value(bound, 0, 4); //Must item (rand_group == 0), place it here if( !rand_group ) { uint16 idx = itemgroup_db[group_id].must_qty; if( !idx ) CREATE(itemgroup_db[group_id].must, struct s_item_group, 1); else RECREATE(itemgroup_db[group_id].must, struct s_item_group, idx + 1); itemgroup_db[group_id].must[idx].nameid = nameid; itemgroup_db[group_id].must[idx].amount = amt; itemgroup_db[group_id].must[idx].isAnnounced = announced; itemgroup_db[group_id].must[idx].duration = dur; itemgroup_db[group_id].must[idx].isNamed = named; itemgroup_db[group_id].must[idx].bound = bound; itemgroup_db[group_id].must_qty++; //If 'must' item isn't set as random item, skip the next process if( !prob ) { entries++; continue; } rand_group = 0; } else