Exemplo n.º 1
0
/*==========================================
 * Initialize / Finalize
 *------------------------------------------
 */
static int itemdb_final_sub (DBKey key,void *data,va_list ap)
{
	int flag;
	struct item_data *id = (struct item_data *)data;

	flag = va_arg(ap, int);
	if (id->script)
	{
		script_free_code(id->script);
		id->script = NULL;
	}
	if (id->equip_script)
	{
		script_free_code(id->equip_script);
		id->equip_script = NULL;
	}
	if (id->unequip_script)
	{
		script_free_code(id->unequip_script);
		id->unequip_script = NULL;
	}
	// Whether to clear the item data (exception: do not clear the dummy item data
	if (flag && id != &dummy_item) 
		aFree(id);

	return 0;
}
Exemplo n.º 2
0
/*==========================================
 *
 *------------------------------------------
 */
static int itemdb_final(void *key,void *data,va_list ap)
{
	struct item_data *id;

	nullpo_retr(0, id = (struct item_data *)data);

	if(id->use_script)
		script_free_code(id->use_script);
	if(id->equip_script)
		script_free_code(id->equip_script);
	aFree(id);

	return 0;
}
Exemplo n.º 3
0
void do_final_itemdb(void)
{
	item_db->destroy(item_db, itemdb_final_sub, 1);
	if (dummy_item.script) {
		script_free_code(dummy_item.script);
		dummy_item.script = NULL;
	}
	if (dummy_item.equip_script) {
		script_free_code(dummy_item.equip_script);
		dummy_item.equip_script = NULL;
	}
	if (dummy_item.unequip_script) {
		script_free_code(dummy_item.unequip_script);
		dummy_item.unequip_script = NULL;
	}
}
Exemplo n.º 4
0
/// Destroys the item_data.
static void destroy_item_data(struct item_data* self, int free_self)
{
	if( self == NULL )
		return;
	// free scripts
	if( self->script )
		script_free_code(self->script);
	if( self->equip_script )
		script_free_code(self->equip_script);
	if( self->unequip_script )
		script_free_code(self->unequip_script);
#if defined(DEBUG)
	// trash item
	memset(self, 0xDD, sizeof(struct item_data));
#endif
	// free self
	if( free_self )
		aFree(self);
}
Exemplo n.º 5
0
/*==========================================
 * アイテムデータベースの読み込み
 *------------------------------------------
 */
static int itemdb_readdb(void)
{
	FILE *fp;
	char line[1024];
	int ln=0,lines=0;
	int nameid,j;
	char *str[32],*p,*np;
	struct item_data *id;
	int i=0;
	char *filename[]={ "item_db.txt","item_db2.txt" };

	for(i=0;i<2;i++){
		sprintf(line, "%s/%s", db_path, filename[i]);
		fp=fopen(line,"r");
		if(fp==NULL){
			if(i>0)
				continue;
			ShowFatalError("can't read %s\n",line);
			exit(1);
		}

		lines=0;
		while(fgets(line,1020,fp)){
			lines++;
			if(line[0]=='/' && line[1]=='/')
				continue;
			memset(str,0,sizeof(str));
			for(j=0,np=p=line;j<19 && p;j++){
				str[j]=p;
				p=strchr(p,',');
				if(p){ *p++=0; np=p; }
			}
			if(str[0]==NULL)
				continue;

			nameid=atoi(str[0]);
			if(nameid<=0)
				continue;
			if (j < 19)
			{	//Crash-fix on broken item lines. [Skotlex]
				ShowWarning("Reading %s: Insufficient fields for item with id %d, skipping.\n", filename[i], nameid);
				continue;
			}
			ln++;

			//ID,Name,Jname,Type,Price,Sell,Weight,ATK,DEF,Range,Slot,Job,Job Upper,Gender,Loc,wLV,eLV,refineable,View
			id=itemdb_load(nameid);
			strncpy(id->name, str[1], ITEM_NAME_LENGTH-1);
			strncpy(id->jname, str[2], ITEM_NAME_LENGTH-1);
			id->type=atoi(str[3]);
			if (id->type == IT_DELAYCONSUME)
			{	//Items that are consumed upon target confirmation
				//(yggdrasil leaf, spells & pet lures) [Skotlex]
				id->type = IT_USABLE;
				id->flag.delay_consume=1;
			}

			{
				int buy = atoi(str[4]), sell = atoi(str[5]);
				// if buying price > selling price * 2 consider it valid and don't change it [celest]
				if (buy && sell && buy > sell*2){
					id->value_buy = buy;
					id->value_sell = sell;
				} else {
					// buy≠sell*2 は item_value_db.txt で指定してください。
					if (sell) {		// sell値を優先とする
						id->value_buy = sell*2;
						id->value_sell = sell;
					} else {
						id->value_buy = buy;
						id->value_sell = buy/2;
					}
				}
				// check for bad prices that can possibly cause exploits
				if (id->value_buy*75/100 < id->value_sell*124/100) {
					ShowWarning ("Item %s [%d] buying:%d < selling:%d\n",
						id->name, id->nameid, id->value_buy*75/100, id->value_sell*124/100);
				}
			}
			id->weight=atoi(str[6]);
			id->atk=atoi(str[7]);
			id->def=atoi(str[8]);
			id->range=atoi(str[9]);
			id->slot=atoi(str[10]);
			if (id->slot > MAX_SLOTS)
			{
				ShowWarning("itemdb_readdb: Item %d (%s) specifies %d slots, but the server only supports up to %d\n", nameid, id->jname, id->slot, MAX_SLOTS);
				id->slot = MAX_SLOTS;
			}
			itemdb_jobid2mapid(id->class_base, (unsigned int)strtoul(str[11],NULL,0));
			id->class_upper = atoi(str[12]);
			id->sex	= atoi(str[13]);
			if(id->equip != atoi(str[14])){
				id->equip=atoi(str[14]);
			}
			if (!id->equip && itemdb_isequip2(id))
			{
				ShowWarning("Item %d (%s) is an equipment with no equip-field! Making it an etc item.\n", nameid, id->jname);
				id->type = 3;
			}
			id->wlv=atoi(str[15]);
			id->elv=atoi(str[16]);
			id->flag.no_refine = atoi(str[17])?0:1;	//If the refine column is 1, no_refine is 0
			id->look=atoi(str[18]);
			id->flag.available=1;
			id->flag.value_notdc=0;
			id->flag.value_notoc=0;
			id->view_id=0;
			id->sex = itemdb_gendercheck(id); //Apply gender filtering.

			if (id->script) {
				script_free_code(id->script);
				id->script=NULL;
			}
			if (id->equip_script) {
				script_free_code(id->equip_script);
				id->equip_script=NULL;
			}
			if (id->unequip_script) {
				script_free_code(id->unequip_script);
				id->unequip_script=NULL;
			}

			if((p=strchr(np,'{'))==NULL)
				continue;
			
			str[19] = p; //Script
			np = strchr(p,'}');

			while (np && np[1] && np[1] != ',')
				np = strchr(np+1,'}'); //Jump close brackets until the next field is found.
			if (!np || !np[1]) {
				//Couldn't find the end of the script field.
				id->script = parse_script(str[19],filename[i],lines,0);
				continue;
			}
			np[1] = '\0'; //Set end of script
			id->script = parse_script(str[19],filename[i],lines,0);
			np+=2; //Skip to next field

			if(!np || (p=strchr(np,'{'))==NULL)
				continue;

			str[20] = p; //Equip Script
			np = strchr(p,'}');

			while (np && np[1] && np[1] != ',')
				np = strchr(np+1,'}'); //Jump close brackets until the next field is found.
			if (!np || !np[1]) {
				//Couldn't find the end of the script field.
				id->equip_script = parse_script(str[20],filename[i],lines,0);
				continue;
			}

			np[1] = '\0'; //Set end of script
			id->equip_script = parse_script(str[20],filename[i],lines,0);
			np+=2; //Skip comma, to next field

			if(!np || (p=strchr(np,'{'))==NULL)
				continue;
			//Unequip script, last column.
			id->unequip_script = parse_script(p,filename[i],lines,0);
		}
		fclose(fp);
		if (ln > 0) {
			ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n",ln,filename[i]);
		}
		ln=0;	// reset to 0
	}
	return 0;
}
Exemplo n.º 6
0
/*======================================
* SQL
*===================================
*/
static int itemdb_read_sqldb(void)
{
	unsigned short nameid;
	struct item_data *id;
	char script[65535 + 2 + 1]; // Maximum length of MySQL TEXT type (65535) + 2 bytes for curly brackets + 1 byte for terminator
	char *item_db_name[] = { item_db_db, item_db2_db };
	long unsigned int ln = 0;
	int i;	

	// ----------

	for (i = 0; i < 2; i++) {
		sprintf(tmp_sql, "SELECT * FROM `%s`", item_db_name[i]);

		// Execute the query; if the query execution succeeded...
		if (mysql_query(&mmysql_handle, tmp_sql) == 0) {
			sql_res = mysql_store_result(&mmysql_handle);

			// If the storage of the query result succeeded...
			if (sql_res) {
				// Parse each row in the query result into sql_row
				while ((sql_row = mysql_fetch_row(sql_res)))
				{	/*Table structure is:
					00  id
					01  name_english
					02  name_japanese
					03  type
					04  price_buy
					05  price_sell
					06  weight
					07  attack
					08  defence
					09  range
					10  slots
					11  equip_jobs
					12  equip_upper
					13  equip_genders
					14  equip_locations
					15  weapon_level
					16  equip_level
					17  refineable
					18  view
					19  script
					20  equip_script
					21  unequip_script
					*/
					nameid = atoi(sql_row[0]);

					// If the identifier is not within the valid range, process the next row
					if (nameid == 0)
						continue;

					ln++;

					// ----------
					id = itemdb_load(nameid);
					
					strncpy(id->name, sql_row[1], ITEM_NAME_LENGTH-1);
					strncpy(id->jname, sql_row[2], ITEM_NAME_LENGTH-1);

					id->type = atoi(sql_row[3]);
					if (id->type == IT_DELAYCONSUME)
					{	//Items that are consumed upon target confirmation
						//(yggdrasil leaf, spells & pet lures) [Skotlex]
						id->type = IT_USABLE;
						id->flag.delay_consume=1;
					} else //In case of an itemdb reload and the item type changed.
						id->flag.delay_consume=0;

					// If price_buy is not NULL and price_sell is not NULL...
					if ((sql_row[4] != NULL) && (sql_row[5] != NULL)) {
						id->value_buy = atoi(sql_row[4]);
						id->value_sell = atoi(sql_row[5]);
					}
					// If price_buy is not NULL and price_sell is NULL...
					else if ((sql_row[4] != NULL) && (sql_row[5] == NULL)) {
						id->value_buy = atoi(sql_row[4]);
						id->value_sell = atoi(sql_row[4]) / 2;
					}
					// If price_buy is NULL and price_sell is not NULL...
					else if ((sql_row[4] == NULL) && (sql_row[5] != NULL)) {
						id->value_buy = atoi(sql_row[5]) * 2;
						id->value_sell = atoi(sql_row[5]);
					}
					// If price_buy is NULL and price_sell is NULL...
					if ((sql_row[4] == NULL) && (sql_row[5] == NULL)) {
						id->value_buy = 0;
						id->value_sell = 0;
					}

					id->weight	= atoi(sql_row[6]);
					id->atk		= (sql_row[7] != NULL) ? atoi(sql_row[7]) : 0;
					id->def		= (sql_row[8] != NULL) ? atoi(sql_row[8]) : 0;
					id->range	= (sql_row[9] != NULL) ? atoi(sql_row[9]) : 0;
					id->slot	= (sql_row[10] != NULL) ? atoi(sql_row[10]) : 0;
					if (id->slot > MAX_SLOTS)
					{
						ShowWarning("itemdb_read_sqldb: Item %d (%s) specifies %d slots, but the server only supports up to %d\n", nameid, id->jname, id->slot, MAX_SLOTS);
						id->slot = MAX_SLOTS;
					}
					itemdb_jobid2mapid(id->class_base, (sql_row[11] != NULL) ? (unsigned int)strtoul(sql_row[11], NULL, 0) : 0);
					id->class_upper= (sql_row[12] != NULL) ? atoi(sql_row[12]) : 0;
					id->sex		= (sql_row[13] != NULL) ? atoi(sql_row[13]) : 0;
					id->equip	= (sql_row[14] != NULL) ? atoi(sql_row[14]) : 0;
					if (!id->equip && itemdb_isequip2(id))
					{
						ShowWarning("Item %d (%s) is an equipment with no equip-field! Making it an etc item.\n", nameid, id->jname);
						id->type = 3;
					}
					id->wlv		= (sql_row[15] != NULL) ? atoi(sql_row[15]) : 0;
					id->elv		= (sql_row[16] != NULL)	? atoi(sql_row[16]) : 0;
					id->flag.no_refine = (sql_row[17] == NULL || atoi(sql_row[17]) == 1)?0:1;
					id->look	= (sql_row[18] != NULL) ? atoi(sql_row[18]) : 0;
					id->view_id	= 0;
					id->sex = itemdb_gendercheck(id); //Apply gender filtering.

					// ----------
					
					if (id->script)
						script_free_code(id->script);
					if (sql_row[19] != NULL) {
						if (sql_row[19][0] == '{')
							id->script = parse_script(sql_row[19],item_db_name[i], ln, 0);
						else {
							sprintf(script, "{%s}", sql_row[19]);
							id->script = parse_script(script, item_db_name[i], ln, 0);
						}
					} else id->script = NULL;
	
					if (id->equip_script)
						script_free_code(id->equip_script);
					if (sql_row[20] != NULL) {
						if (sql_row[20][0] == '{')
							id->equip_script = parse_script(sql_row[20], item_db_name[i], ln, 0);
						else {
							sprintf(script, "{%s}", sql_row[20]);
							id->equip_script = parse_script(script, item_db_name[i], ln, 0);
						}
					} else id->equip_script = NULL;
	
					if (id->unequip_script)
						script_free_code(id->unequip_script);
					if (sql_row[21] != NULL) {
						if (sql_row[21][0] == '{')
							id->unequip_script = parse_script(sql_row[21],item_db_name[i], ln, 0);
						else {
							sprintf(script, "{%s}", sql_row[21]);
							id->unequip_script = parse_script(script, item_db_name[i], ln, 0);
						}
					} else id->unequip_script = NULL;
				
					// ----------

					id->flag.available	= 1;
					id->flag.value_notdc	= 0;
					id->flag.value_notoc	= 0;
				}

				ShowStatus("Done reading '"CL_WHITE"%lu"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", ln, item_db_name[i]);
				ln = 0;
			} else {
				ShowSQL("DB error (%s) - %s\n",item_db_name[i], mysql_error(&mmysql_handle));
				ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
			}

			// Free the query result
			mysql_free_result(sql_res);
		} else {
			ShowSQL("DB error (%s) - %s\n",item_db_name[i], mysql_error(&mmysql_handle));
			ShowDebug("at %s:%d - %s\n", __FILE__,__LINE__,tmp_sql);
		}
	}

	return 0;
}
Exemplo n.º 7
0
/*==========================================
 * processes one itemdb entry
 *------------------------------------------*/
static bool itemdb_parse_dbrow(char** str, const char* source, int line, int scriptopt)
{
	/*
		+----+--------------+---------------+------+-----------+------------+--------+--------+---------+-------+-------+------------+-------------+---------------+-----------------+--------------+-------------+------------+------+--------+--------------+----------------+
		| 00 |      01      |       02      |  03  |     04    |     05     |   06   |   07   |    08   |   09  |   10  |     11     |      12     |       13      |        14       |      15      |      16     |     17     |  18  |   19   |      20      |        21      |
		+----+--------------+---------------+------+-----------+------------+--------+--------+---------+-------+-------+------------+-------------+---------------+-----------------+--------------+-------------+------------+------+--------+--------------+----------------+
		| id | name_english | name_japanese | type | price_buy | price_sell | weight | attack | defence | range | slots | equip_jobs | equip_upper | equip_genders | equip_locations | weapon_level | equip_level | refineable | view | script | equip_script | unequip_script |
		+----+--------------+---------------+------+-----------+------------+--------+--------+---------+-------+-------+------------+-------------+---------------+-----------------+--------------+-------------+------------+------+--------+--------------+----------------+
	*/
	int nameid;
	struct item_data* id;
	
	nameid = atoi(str[0]);
	if( nameid <= 0 )
	{
		ShowWarning("itemdb_parse_dbrow: Invalid id %d in line %d of \"%s\", skipping.\n", nameid, line, source);
		return false;
	}

	//ID,Name,Jname,Type,Price,Sell,Weight,ATK,DEF,Range,Slot,Job,Job Upper,Gender,Loc,wLV,eLV,refineable,View
	id = itemdb_load(nameid);
	safestrncpy(id->name, str[1], sizeof(id->name));
	safestrncpy(id->jname, str[2], sizeof(id->jname));

	id->type = atoi(str[3]);

	if( id->type < 0 || id->type == IT_UNKNOWN || id->type == IT_UNKNOWN2 || ( id->type > IT_DELAYCONSUME && id->type < IT_THROWWEAPON ) || id->type >= IT_MAX )
	{// catch invalid item types
		ShowWarning("itemdb_parse_dbrow: Invalid item type %d for item %d. IT_ETC will be used.\n", id->type, nameid);
		id->type = IT_ETC;
	}

	if (id->type == IT_DELAYCONSUME)
	{	//Items that are consumed only after target confirmation
		id->type = IT_USABLE;
		id->flag.delay_consume = 1;
	} else //In case of an itemdb reload and the item type changed.
		id->flag.delay_consume = 0;

	//When a particular price is not given, we should base it off the other one
	//(it is important to make a distinction between 'no price' and 0z)
	if ( str[4][0] )
		id->value_buy = atoi(str[4]);
	else
		id->value_buy = atoi(str[5]) * 2;

	if ( str[5][0] )
		id->value_sell = atoi(str[5]);
	else
		id->value_sell = id->value_buy / 2;
	/* 
	if ( !str[4][0] && !str[5][0])
	{  
		ShowWarning("itemdb_parse_dbrow: No buying/selling price defined for item %d (%s), using 20/10z\n",       nameid, id->jname);
		id->value_buy = 20;
		id->value_sell = 10;
	} else
	*/
	if (id->value_buy/124. < id->value_sell/75.)
		ShowWarning("itemdb_parse_dbrow: Buying/Selling [%d/%d] price of item %d (%s) allows Zeny making exploit  through buying/selling at discounted/overcharged prices!\n",
			id->value_buy, id->value_sell, nameid, id->jname);

	id->weight = atoi(str[6]);
#if REMODE
	itemdb_re_split_atoi(str[7],&id->atk,&id->matk);
#else
	id->atk = atoi(str[7]);
#endif
	id->def = atoi(str[8]);
	id->range = atoi(str[9]);
	id->slot = atoi(str[10]);

	if (id->slot > MAX_SLOTS)
	{
		ShowWarning("itemdb_parse_dbrow: Item %d (%s) specifies %d slots, but the server only supports up to %d. Using %d slots.\n", nameid, id->jname, id->slot, MAX_SLOTS, MAX_SLOTS);
		id->slot = MAX_SLOTS;
	}

	itemdb_jobid2mapid(id->class_base, (unsigned int)strtoul(str[11],NULL,0));
	id->class_upper = atoi(str[12]);
	id->sex	= atoi(str[13]);
	id->equip = atoi(str[14]);

	if (!id->equip && itemdb_isequip2(id))
	{
		ShowWarning("Item %d (%s) is an equipment with no equip-field! Making it an etc item.\n", nameid, id->jname);
		id->type = IT_ETC;
	}

	id->wlv = atoi(str[15]);
	id->elv = atoi(str[16]);
	id->flag.no_refine = atoi(str[17]) ? 0 : 1; //FIXME: verify this
	id->look = atoi(str[18]);

	id->flag.available = 1;
	id->view_id = 0;
	id->sex = itemdb_gendercheck(id); //Apply gender filtering.

	if (id->script)
	{
		script_free_code(id->script);
		id->script = NULL;
	}
	if (id->equip_script)
	{
		script_free_code(id->equip_script);
		id->equip_script = NULL;
	}
	if (id->unequip_script)
	{
		script_free_code(id->unequip_script);
		id->unequip_script = NULL;
	}

	if (*str[19])
		id->script = parse_script(str[19], source, line, scriptopt);
	if (*str[20])
		id->equip_script = parse_script(str[20], source, line, scriptopt);
	if (*str[21])
		id->unequip_script = parse_script(str[21], source, line, scriptopt);

	return true;
}
Exemplo n.º 8
0
/*==========================================
 * アイテムデータベースの読み込み
 *------------------------------------------
 */
static int itemdb_read_itemdb(void)
{
	FILE *fp;
	char line[4096];
	int ln=0,lines=0;
	int nameid,j;
	char *str[32],*p,*np;
	struct item_data *id;
	struct script_code *script = NULL;
	int i=0;
	const char *filename[] = {
		"db/item_db.txt",
#ifdef PRE_RENEWAL
		"db/pre/item_db_pre.txt",
#endif
		"db/addon/item_db_add.txt"
	};
	const char *filename2;

	for(i = 0; i < sizeof(filename)/sizeof(filename[0]); i++) {
		fp = fopen(filename[i], "r");
		if(fp == NULL) {
			if(i > 0)
				continue;
			printf("itemdb_read_itemdb: open [%s] failed !\n", filename[i]);
			continue;
		}
		lines=ln=0;
		while(fgets(line,sizeof(line),fp)){
			lines++;
			if(line[0] == '\0' || line[0] == '\r' || line[0] == '\n')
				continue;
			if(line[0]=='/' && line[1]=='/')
				continue;
			memset(str,0,sizeof(str));
			for(j=0,np=p=line;j<18 && p;j++){
				str[j]=p;
				p=strchr(p,',');
				if(p){ *p++=0; np=p; }
			}
			if(str[0] == NULL)
				continue;

			nameid = atoi(str[0]);
			if(nameid <= 0)
				continue;
			ln++;

			//ID,Name,Jname,Type,Price,Sell,Weight,ATK,DEF,Range,Slot,Job,Gender,Loc,wLV,eLV,View,Refine
			id = itemdb_search(nameid);
			strncpy(id->name,str[1],48);
			strncpy(id->jname,str[2],48);
			id->type = atoi(str[3]);
			// buy≠sell*2 は item_value_db.txt で指定してください。
			if(atoi(str[5])) {		// sell値を優先とする
				id->value_buy  = atoi(str[5])*2;
				id->value_sell = atoi(str[5]);
			} else {
				id->value_buy  = atoi(str[4]);
				id->value_sell = atoi(str[4])/2;
			}
			id->weight = atoi(str[6]);
			itemdb_split_atoi(str[7],&id->atk,&id->matk);
			itemdb_split_atoi(str[8],&id->def,&id->mdef);
			id->range  = atoi(str[9]);
			id->slot = atoi(str[10]);
			if(id->slot < 0 || id->slot > 4) {
				id->slot = 0;
			}
			id->class_ = (unsigned int)strtoul(str[11],NULL,0);
			id->sex    = atoi(str[12]);
			if(id->equip != atoi(str[13])) {
				id->equip = atoi(str[13]);
			}
			id->wlv = atoi(str[14]);
			if(id->wlv < 0 || id->wlv > MAX_WEAPON_LEVEL) {
				id->wlv = 0;
			}
			id->elv              = atoi(str[15]);
			id->look             = atoi(str[16]);
			id->refine           = atoi(str[17]);
			id->flag.available   = 1;
			id->flag.value_notdc = 0;
			id->flag.value_notoc = 0;
			id->flag.pet_egg     = 0;
			id->flag.pet_acce    = 0;
			id->view_id          = 0;
			id->group            = 0;
			id->delay            = 0;
			id->upper            = 0;
			id->zone             = 0;

			// force \0 terminal
			id->name[47]  = '\0';
			id->jname[47] = '\0';

			if((p = strchr(np, '{')) == NULL)
				continue;

			np = parse_script_line_end(p, filename[i], lines);
			if(!np)
				continue;

			if(id->use_script) {
				script_free_code(id->use_script);
			}
			script = parse_script(p, filename[i], lines);
			id->use_script = (script_is_error(script))? NULL: script;

			np++;
			if(*np != ',')
				continue;

			if((p = strchr(np + 1, '{')) == NULL)
				continue;

			np = parse_script_line_end(p, filename[i], lines);
			if(!np)
				continue;

			if(id->equip_script) {
				script_free_code(id->equip_script);
			}
			script = parse_script(p, filename[i], lines);
			id->equip_script = (script_is_error(script))? NULL: script;
		}
		fclose(fp);
		printf("read %s done (count=%d)\n",filename[i],ln);
	}

	filename2 = "db/item_db2.txt";
	fp = fopen(filename2, "r");
	if(fp == NULL) {
		printf("itemdb_read_itemdb: open [%s] failed !\n", filename2);
		return 0;
	}
	ln=0;
	while(fgets(line,sizeof(line),fp)){
		if(line[0] == '\0' || line[0] == '\r' || line[0] == '\n')
			continue;
		if(line[0]=='/' && line[1]=='/')
			continue;
		memset(str,0,sizeof(str));
		for(j=0,np=p=line;j<11 && p;j++){
			str[j]=p;
			p=strchr(p,',');
			if(p){ *p++=0; np=p; }
		}
		if(str[0] == NULL)
			continue;

		nameid = atoi(str[0]);
		if(nameid <= 0 || !(id = itemdb_exists(nameid)))
			continue;

		ln++;
		id->upper            = atoi(str[1]);
		id->zone             = atoi(str[2]);
		id->flag.dropable    = (atoi(str[3]) == 0)? 0: 1;
		id->flag.sellable    = (atoi(str[4]) == 0)? 0: 1;
		id->flag.storageable = (atoi(str[5]) == 0)? 0: 1;
		id->flag.guildstorageable = (atoi(str[6]) == 0)? 0: 1;
		id->flag.cartable    = (atoi(str[7]) == 0)? 0: 1;
		id->delay            = atoi(str[8]);
		id->flag.buyingable  = (atoi(str[9]) == 0)? 0: 1;
		id->flag.nonconsume  = (atoi(str[10]) == 0)? 0: 1;
	}
	fclose(fp);
	printf("read %s (count=%d)\n", filename2, ln);

	filename2 = "db/item_arrowtype.txt",
	fp = fopen(filename2, "r");
	if(fp == NULL){
		printf("itemdb_read_itemdb: open [%s] failed !\n", filename2);
		return 0;
	}
	while(fgets(line,sizeof(line),fp)){
		if(line[0] == '\0' || line[0] == '\r' || line[0] == '\n')
			continue;
		if(line[0]=='/' && line[1]=='/')
			continue;
		memset(str,0,sizeof(str));
		for(j=0,np=p=line;j<4 && p;j++){
			str[j]=p;
			p=strchr(p,',');
			if(p){ *p++=0; np=p; }
		}
		if(str[0] == NULL || str[3] == NULL)
			continue;

		nameid = atoi(str[0]);
		if(nameid <= 0 || !(id = itemdb_exists(nameid)))
			continue;
		//ID,Name,Jname,type
		id->arrow_type = atoi(str[3]);
	}
	fclose(fp);
	printf("read %s done\n", filename2);

	filename2 = "db/item_cardtype.txt";
	fp = fopen(filename2, "r");
	if(fp == NULL) {
		printf("itemdb_read_itemdb: open [%s] failed !\n", filename2);
		return 0;
	}
	while(fgets(line,sizeof(line),fp)){
		if(line[0] == '\0' || line[0] == '\r' || line[0] == '\n')
			continue;
		if(line[0]=='/' && line[1]=='/')
			continue;
		memset(str,0,sizeof(str));
		for(j=0,np=p=line;j<4 && p;j++){
			str[j]=p;
			p=strchr(p,',');
			if(p){ *p++=0; np=p; }
		}
		if(str[0] == NULL || str[3] == NULL)
			continue;

		nameid = atoi(str[0]);
		if(nameid <= 0 || !(id = itemdb_exists(nameid)))
			continue;
		//ID,Name,Jname,type
		id->card_type = atoi(str[3]);
	}
	fclose(fp);
	printf("read %s done\n", filename2);

	filename2 = "db/item_group_db.txt";
	fp = fopen(filename2, "r");
	if(fp == NULL) {
		printf("itemdb_read_itemdb: open [%s] failed !\n", filename2);
		return 0;
	}
	while(fgets(line,sizeof(line),fp)) {
		int group_id;

		if(line[0] == '\0' || line[0] == '\r' || line[0] == '\n')
			continue;
		if(line[0]=='/' && line[1]=='/')
			continue;
		memset(str,0,sizeof(str));
		for(j=0,np=p=line;j<4 && p;j++){
			str[j]=p;
			p=strchr(p,',');
			if(p){ *p++=0; np=p; }
		}
		if(str[0] == NULL || str[3] == NULL)
			continue;

		nameid = atoi(str[0]);
		if(nameid <= 0 || !(id = itemdb_exists(nameid)))
			continue;

		//ID,Name,Jname,Group
		group_id = atoi(str[3]);
		if(group_id >= MAX_ITEMGROUP) {
			printf("item_group: invalid group id(%d) ID %d\n", group_id, nameid);
			continue;
		}
		id->group = group_id;
	}
	fclose(fp);
	printf("read %s done\n", filename2);
	return 0;
}