Exemplo n.º 1
0
/*==========================================
 * カードイラストのリソース名前テーブルを読み込む
 *------------------------------------------
 */
static int itemdb_read_cardillustnametable(void)
{
	char *buf,*p;
	int s;

	buf = grfio_reads("data\\num2cardillustnametable.txt", &s);

	if (buf == NULL)
		return -1;

	buf[s] = 0;
	p = buf;
	while(p - buf < s) {
		int nameid;
		char buf2[64];

		if (sscanf(p, "%d#%[^#]#", &nameid, buf2) == 2) {
			strcat(buf2, ".bmp");
			memset(itemdb_search(nameid)->cardillustname, 0, sizeof(itemdb_search(nameid)->cardillustname));
			strncpy(itemdb_search(nameid)->cardillustname, buf2, 64);
//			printf("%d %s\n", nameid, itemdb_search(nameid)->cardillustname);
		}

		p = strchr(p,10);
		if(!p)
			break;
		p++;
	}
	FREE(buf);

	printf("File '" CL_WHITE "data\\num2cardillustnametable.txt" CL_RESET "' readed.\n");

	return 0;
}
Exemplo n.º 2
0
static int storage_comp_item_by_type(const void *_i1, const void *_i2)
{
	struct item *i1 = (struct item *)_i1;
	struct item *i2 = (struct item *)_i2;
	struct item_data *data1, *data2;

	if(i1->nameid == 0 || i2->nameid == 0) {
		// 末尾に集めるので反転
		return i2->nameid - i1->nameid;
	}

	data1 = itemdb_search(i1->nameid);
	data2 = itemdb_search(i2->nameid);

	if(data1->type > data2->type)
		return 1;
	if(data1->type < data2->type)
		return -1;

	// 武器・防具ならLOCでソート
	if(itemdb_isarmor(data1->nameid) || itemdb_isweapon(data1->nameid)) {
		if(data1->equip > data2->equip)
			return 1;
		if(data1->equip < data2->equip)
			return -1;
	}

	// 最後はアイテムIDでソート
	if(data1->nameid > data2->nameid)
		return 1;
	if(data1->nameid < data2->nameid)
		return -1;

	return 0;
}
Exemplo n.º 3
0
/*==========================================
 * カードイラストのリソース名前テーブルを読み込む
 *------------------------------------------
 */
static int itemdb_read_cardillustnametable(void)
{
	char *buf,*p;
	int s;

	buf=(char *) grfio_reads("data\\num2cardillustnametable.txt",&s);

	if(buf==NULL)
		return -1;

	buf[s]=0;
	for(p=buf;p-buf<s;){
		int nameid;
		char buf2[64];

		if(	sscanf(p,"%d#%[^#]#",&nameid,buf2)==2 ){
			strcat(buf2,".bmp");
			memcpy(itemdb_search(nameid)->cardillustname,buf2,64);
		}
		
		p=strchr(p,10);
		if(!p) break;
		p++;
	}
	aFree(buf);
	ShowStatus("Done reading '"CL_WHITE"%s"CL_RESET"'.\n","data\\num2cardillustnametable.txt");

	return 0;
}
Exemplo n.º 4
0
/*==========================================
 *
 *------------------------------------------
 */
static int itemdb_read_itemslottable(void)
{
	char *buf, *p;
	int s;

	buf = (char *)grfio_reads("data\\itemslottable.txt", &s);
	if (buf == NULL)
		return -1;
	buf[s] = 0;
	for (p = buf; p - buf < s; ) {
		int nameid, equip;
		struct item_data* item;
		sscanf(p, "%d#%d#", &nameid, &equip);
		item = itemdb_search(nameid);
		if (item && itemdb_isequip2(item))			
			item->equip = equip;
		p = strchr(p, 10);
		if(!p) break;
		p++;
		p=strchr(p, 10);
		if(!p) break;
		p++;
	}
	aFree(buf);
	ShowStatus("Done reading '"CL_WHITE"%s"CL_RESET"'.\n","data\\itemslottable.txt");

	return 0;
}
Exemplo n.º 5
0
/*==========================================
 *
 *------------------------------------------
 */
static int itemdb_read_itemslotcounttable(void) {
	char *buf,*p;
	int s;

	buf = grfio_reads("data\\itemslotcounttable.txt", &s);
	if (buf == NULL)
		return -1;

	buf[s] = 0;
	p = buf;
	while(p - buf < s) {
		int nameid, slot;
		sscanf(p, "%d#%d#", &nameid, &slot);
		itemdb_search(nameid)->slot = slot;
		p = strchr(p, 10);
		if (!p)
			break;
		p++;
		p = strchr(p, 10);
		if (!p)
			break;
		p++;
	}
	FREE(buf);

	printf("File '" CL_WHITE "data\\itemslotcounttable.txt" CL_RESET "' readed.\n");

	return 0;
}
Exemplo n.º 6
0
/*==========================================
 * カードイラストのリソース名前テーブルを読み込む
 *------------------------------------------
 */
static int itemdb_read_cardillustnametable(void)
{
	char *buf,*p;
	int s;

	buf = (char *)grfio_reads("data\\num2cardillustnametable.txt",&s);

	if(buf == NULL)
		return -1;

	buf[s] = 0;
	for(p=buf; p-buf<s; ) {
		int nameid;
		char buf2[128];

		if(sscanf(p,"%d#%127[^#]#",&nameid,buf2) == 2) {
			buf2[59] = '\0';	// force \0
			strcat(buf2,".bmp");
			memcpy(itemdb_search(nameid)->cardillustname,buf2,64);
		}

		p=strchr(p,'\n');
		if(!p) break;
		p++;
	}
	aFree(buf);
	printf("read data\\num2cardillustnametable.txt done.\n");

	return 0;
}
Exemplo n.º 7
0
/*==========================================
 *
 *------------------------------------------
 */
static int itemdb_read_itemslottable(void) {
	char *buf,*p;
	int s;

	buf = grfio_reads("data\\itemslottable.txt", &s);
	if (buf == NULL)
		return -1;

	buf[s] = 0;
	p = buf;
	while(p - buf < s) {
		int nameid, equip;
		struct item_data* item;
		sscanf(p, "%d#%d#", &nameid, &equip);
		// fix unuseable cards
		item = itemdb_search(nameid);
		if (item && itemdb_isequip2(item))
			item->equip = equip;
		p = strchr(p, 10);
		if(!p)
			break;
		p++;
		p = strchr(p, 10);
		if (!p)
			break;
		p++;
	}
	FREE(buf);

	printf("File '" CL_WHITE "data\\itemslottable.txt" CL_RESET "' readed.\n");

	return 0;
}
Exemplo n.º 8
0
/*==========================================
 *
 *------------------------------------------
 */
static int itemdb_read_itemslottable(void)
{
	char *buf,*p;
	int s;

	buf = (char *)grfio_read("data\\itemslottable.txt");
	if(buf == NULL)
		return -1;
	s = grfio_size("data\\itemslottable.txt");

	buf[s] = 0;
	for(p=buf; p-buf<s; ) {
		int nameid,equip;
		sscanf(p,"%d#%d#",&nameid,&equip);
		itemdb_search(nameid)->equip = equip;
		p=strchr(p,'\n');
		if(!p) break;
		p++;
		p=strchr(p,'\n');
		if(!p) break;
		p++;
	}
	aFree(buf);

	return 0;
}
Exemplo n.º 9
0
int itemdb_isrestricted(struct item* item, int gmlv, int gmlv2, int (*func)(struct item_data*, int, int))
{
	struct item_data* item_data = itemdb_search(item->nameid);
	int i;

	if (!func(item_data, gmlv, gmlv2))
		return 0;
	
	if(item_data->slot == 0 || itemdb_isspecial(item->card[0]))
		return 1;
	
	for(i = 0; i < item_data->slot; i++) {
		if (!item->card[i]) continue;
		if (!func(itemdb_search(item->card[i]), gmlv, gmlv2))
			return 0;
	}
	return 1;
}
Exemplo n.º 10
0
int guild_storage_additem(struct map_session_data* sd, struct guild_storage* stor, struct item* item_data, int amount)
{
	struct item_data *data;
	int i;

	nullpo_retr(1, sd);
	nullpo_retr(1, stor);
	nullpo_retr(1, item_data);

	if(item_data->nameid <= 0 || amount <= 0)
		return 1;

	data = itemdb_search(item_data->nameid);

	if( !itemdb_canguildstore(item_data, pc_isGM(sd)) || item_data->expire_time || item_data->bound )
	{	//Check if item is storable. [Skotlex]
		clif_displaymessage (sd->fd, msg_txt(264));
		return 1;
	}

	if( sd->state.secure_items )
	{
		clif_displaymessage(sd->fd, "You can't store items on Guild Storage. Blocked with @security");
		return 1;
	}

	if(itemdb_isstackable2(data)){ //Stackable
		for(i=0;i<MAX_GUILD_STORAGE;i++){
			if(compare_item(&stor->items[i], item_data)) {
				if(stor->items[i].amount+amount > MAX_AMOUNT)
					return 1;
				stor->items[i].amount+=amount;
				clif_storageitemadded(sd,&stor->items[i],i,amount);
				stor->dirty = 1;
				if(log_config.enable_logs&0x1000)
					log_pick_pc(sd, "G", item_data->nameid, -amount, item_data, 0);
				return 0;
			}
		}
	}
	//Add item
	for(i=0;i<MAX_GUILD_STORAGE && stor->items[i].nameid;i++);
	
	if(i>=MAX_GUILD_STORAGE)
		return 1;
	
	memcpy(&stor->items[i],item_data,sizeof(stor->items[0]));
	stor->items[i].amount=amount;
	stor->storage_amount++;
	clif_storageitemadded(sd,&stor->items[i],i,amount);
	clif_updateguildstorageamount(sd,stor->storage_amount);
	stor->dirty = 1;
	if(log_config.enable_logs&0x1000)
		log_pick_pc(sd, "G", item_data->nameid, -amount, item_data, item_data->serial );
	return 0;
}
Exemplo n.º 11
0
void itemdb_reload(void)
{
	struct s_mapiterator* iter;
	struct map_session_data* sd;

	int i,d,k;
	
	// clear the previous itemdb data
	for( i = 0; i < ARRAYLENGTH(itemdb_array); ++i )
		if( itemdb_array[i] )
			destroy_item_data(itemdb_array[i], 1);

	itemdb_other->clear(itemdb_other, itemdb_final_sub);

	memset(itemdb_array, 0, sizeof(itemdb_array));
	
	// read new data
	itemdb_read();
	
	//Epoque's awesome @reloaditemdb fix - thanks! [Ind]
	//- Fixes the need of a @reloadmobdb after a @reloaditemdb to re-link monster drop data
	for( i = 0; i < MAX_MOB_DB; i++ ) {
		struct mob_db *entry;
		if( !((i < 1324 || i > 1363) && (i < 1938 || i > 1946)) )
			continue;
		entry = mob_db(i);
		for(d = 0; d < MAX_MOB_DROP; d++) {
			struct item_data *id;
			if( !entry->dropitem[d].nameid )
				continue;
			id = itemdb_search(entry->dropitem[d].nameid);

			for (k = 0; k < MAX_SEARCH; k++) {
				if (id->mob[k].chance <= entry->dropitem[d].p)
					break;
			}

			if (k == MAX_SEARCH)
				continue;
			
			if (id->mob[k].id != i)
				memmove(&id->mob[k+1], &id->mob[k], (MAX_SEARCH-k-1)*sizeof(id->mob[0]));
			id->mob[k].chance = entry->dropitem[d].p;
			id->mob[k].id = i;
		}
	}

	// readjust itemdb pointer cache for each player
	iter = mapit_geteachpc();
	for( sd = (struct map_session_data*)mapit_first(iter); mapit_exists(iter); sd = (struct map_session_data*)mapit_next(iter) )
	{
		memset(sd->item_delay, 0, sizeof(sd->item_delay));  // reset item delays
		pc_setinventorydata(sd);
	}
	mapit_free(iter);
}
Exemplo n.º 12
0
/**
 * Make a player add an item to his storage
 * @param sd : player
 * @param item_data : item to add
 * @param amount : quantity of items
 * @return 0:success, 1:failed
 */
static int storage_additem(struct map_session_data* sd, struct item* item_data, int amount)
{
	struct storage_data* stor = &sd->status.storage;
	struct item_data *data;
	int i;

	if( item_data->nameid == 0 || amount <= 0 )
		return 1;

	data = itemdb_search(item_data->nameid);

	if( data->stack.storage && amount > data->stack.amount )
	{// item stack limitation
		return 1;
	}

	if( !itemdb_canstore(item_data, pc_get_group_level(sd)) )
	{	//Check if item is storable. [Skotlex]
		clif_displaymessage (sd->fd, msg_txt(sd,264));
		return 1;
	}

	if( (item_data->bound > BOUND_ACCOUNT) && !pc_can_give_bounded_items(sd) ) {
		clif_displaymessage(sd->fd, msg_txt(sd,294));
		return 1;
	}

	if( itemdb_isstackable2(data) )
	{//Stackable
		for( i = 0; i < sd->storage_size; i++ )
		{
			if( compare_item(&stor->items[i], item_data) )
			{// existing items found, stack them
				if( amount > MAX_AMOUNT - stor->items[i].amount || ( data->stack.storage && amount > data->stack.amount - stor->items[i].amount ) )
					return 1;
				stor->items[i].amount += amount;
				clif_storageitemadded(sd,&stor->items[i],i,amount);
				return 0;
			}
		}
	}

	// find free slot
	ARR_FIND( 0, sd->storage_size, i, stor->items[i].nameid == 0 );
	if( i >= sd->storage_size )
		return 1;

	// add item to slot
	memcpy(&stor->items[i],item_data,sizeof(stor->items[0]));
	stor->storage_amount++;
	stor->items[i].amount = amount;
	clif_storageitemadded(sd,&stor->items[i],i,amount);
	clif_updatestorageamount(sd, stor->storage_amount, sd->storage_size);

	return 0;
}
Exemplo n.º 13
0
/**
 * Attempt to add an item in guild storage, then refresh it
 * @param sd : player attempting to open the guild_storage
 * @param stor : guild_storage
 * @param item_data : item to add
 * @param amount : number of item to add
 * @return 0 : success, 1 : fail
 */
char guild_storage_additem(struct map_session_data* sd, struct guild_storage* stor, struct item* item_data, int amount)
{
	struct item_data *data;
	int i;

	nullpo_retr(1, sd);
	nullpo_retr(1, stor);
	nullpo_retr(1, item_data);

	if(item_data->nameid == 0 || amount <= 0)
		return 1;

	data = itemdb_search(item_data->nameid);

	if( data->stack.guildstorage && amount > data->stack.amount )
	{// item stack limitation
		return 1;
	}

	if( !itemdb_canguildstore(item_data, pc_get_group_level(sd)) || item_data->expire_time )
	{	//Check if item is storable. [Skotlex]
		clif_displaymessage (sd->fd, msg_txt(sd,264));
		return 1;
	}

	if( (item_data->bound == BOUND_ACCOUNT || item_data->bound > BOUND_GUILD) && !pc_can_give_bounded_items(sd) ) {
		clif_displaymessage(sd->fd, msg_txt(sd,294));
		return 1;
	}

	if(itemdb_isstackable2(data)){ //Stackable
		for(i=0;i<MAX_GUILD_STORAGE;i++){
			if(compare_item(&stor->items[i], item_data)) {
				if( amount > MAX_AMOUNT - stor->items[i].amount || ( data->stack.guildstorage && amount > data->stack.amount - stor->items[i].amount ) )
					return 1;
				stor->items[i].amount+=amount;
				clif_storageitemadded(sd,&stor->items[i],i,amount);
				stor->dirty = 1;
				return 0;
			}
		}
	}
	//Add item
	for(i=0;i<MAX_GUILD_STORAGE && stor->items[i].nameid;i++);

	if(i>=MAX_GUILD_STORAGE)
		return 1;

	memcpy(&stor->items[i],item_data,sizeof(stor->items[0]));
	stor->items[i].amount=amount;
	stor->storage_amount++;
	clif_storageitemadded(sd,&stor->items[i],i,amount);
	clif_updatestorageamount(sd, stor->storage_amount, MAX_GUILD_STORAGE);
	stor->dirty = 1;
	return 0;
}
Exemplo n.º 14
0
/*==========================================
 * Internal add-item function.
 *------------------------------------------*/
static int storage_additem(struct map_session_data* sd, struct item* item_data, int amount, int flag)
{
	struct storage_data* stor = &sd->status.storage;
	struct item_data *data;
	int i;

	if( item_data->nameid <= 0 || amount <= 0 )
		return 1;
	
	data = itemdb_search(item_data->nameid);

	if( !itemdb_canstore(item_data, pc_isGM(sd)) )
	{	//Check if item is storable. [Skotlex]
		clif_displaymessage (sd->fd, msg_txt(264));
		return 1;
	}
	
	if( itemdb_isstackable2(data) )
	{//Stackable
		for( i = 0; i < MAX_STORAGE; i++ )
		{
			if( compare_item(&stor->items[i], item_data) )
			{// existing items found, stack them
				if( amount > MAX_AMOUNT - stor->items[i].amount )
					return 1;
				stor->items[i].amount += amount;
				if( flag ) clif_storageitemadded(sd,&stor->items[i],i,amount);
				if(log_config.enable_logs&0x800)
					log_pick_pc(sd, "R", item_data->nameid, -amount, item_data, 0);
				return 0;
			}
		}
	}

	// find free slot
	ARR_FIND( 0, MAX_STORAGE, i, stor->items[i].nameid == 0 );
	if( i >= MAX_STORAGE )
		return 1;

	// add item to slot
	memcpy(&stor->items[i],item_data,sizeof(stor->items[0]));
	stor->storage_amount++;
	stor->items[i].amount = amount;
	if( flag )
	{
		clif_storageitemadded(sd,&stor->items[i],i,amount);
		clif_updatestorageamount(sd,stor->storage_amount);
	}
	if(log_config.enable_logs&0x800)
		log_pick_pc(sd, "R", item_data->nameid, -amount, item_data, item_data->serial );

	return 0;
}
Exemplo n.º 15
0
/*==========================================
 * アイテムの名前テーブルを読み込む
 *------------------------------------------
 */
static int itemdb_read_itemnametable(void)
{
	char *buf,*p;
	int s;

	buf = grfio_reads("data\\idnum2itemdisplaynametable.txt",&s);

	if (buf == NULL)
		return -1;

	buf[s] = 0;
	p = buf;
	while(p - buf < s) {
		int nameid;
		char buf2[64];

		if (sscanf(p, "%d#%[^#]#", &nameid, buf2) == 2) {

#ifdef ITEMDB_OVERRIDE_NAME_VERBOSE
			if (itemdb_exists(nameid) &&
			    strncmp(itemdb_search(nameid)->jname, buf2, 24) != 0) {
				printf("[override] %d %s => %s\n", nameid, itemdb_search(nameid)->jname, buf2);
			}
#endif

			memset(itemdb_search(nameid)->jname, 0, sizeof(itemdb_search(nameid)->jname));
			strncpy(itemdb_search(nameid)->jname, buf2, 24);
		}

		p = strchr(p, 10);
		if (!p)
			break;
		p++;
	}
	FREE(buf);

	printf("File '" CL_WHITE "data\\idnum2itemdisplaynametable.txt" CL_RESET "' readed.\n");

	return 0;
}
Exemplo n.º 16
0
/*==========================================
 * ギルド倉庫へアイテム追加
 *------------------------------------------
 */
static int storage_guild_additem(struct map_session_data *sd,struct guild_storage *stor,struct item *item_data,int amount)
{
	struct item_data *data;
	int i;

	nullpo_retr(1, sd);
	nullpo_retr(1, stor);
	nullpo_retr(1, item_data);

	if(item_data->nameid <= 0 || amount <= 0)
		return 1;

	nullpo_retr(1, data = itemdb_search(item_data->nameid));

	if(!itemdb_isequip2(data)) {
		// 装備品ではないので、既所有品なら個数のみ変化させる
		for(i=0; i<MAX_GUILD_STORAGE; i++) {
			if(stor->store_item[i].nameid  == item_data->nameid  &&
			   stor->store_item[i].card[0] == item_data->card[0] &&
			   stor->store_item[i].card[1] == item_data->card[1] &&
			   stor->store_item[i].card[2] == item_data->card[2] &&
			   stor->store_item[i].card[3] == item_data->card[3] &&
			   stor->store_item[i].limit   == item_data->limit)
			{
				if(stor->store_item[i].amount + amount > MAX_AMOUNT)
					return 1;
				stor->store_item[i].amount += amount;
				stor->dirty = 1;
				clif_guildstorageitemadded(sd,stor,i,amount);
				return 0;
			}
		}
	} else if(amount != 1) {
		return 1;
	}

	// 装備品か未所有品だったので空き欄へ追加
	for(i=0; i<MAX_GUILD_STORAGE; i++) {
		if(stor->store_item[i].nameid == 0) {
			memcpy(&stor->store_item[i],item_data,sizeof(stor->store_item[0]));
			stor->store_item[i].id     = ++stor->sortkey;
			stor->store_item[i].amount = amount;
			stor->storage_amount++;
			stor->dirty = 1;
			clif_guildstorageitemadded(sd,stor,i,amount);
			clif_updateguildstorageamount(sd,stor);
			return 0;
		}
	}

	return 1;
}
Exemplo n.º 17
0
/*==========================================
 * アイテムの名前テーブルを読み込む
 *------------------------------------------
 */
static int itemdb_read_itemnametable(void)
{
	char *buf,*p;
	int s;

	buf=(char *) grfio_reads("data\\idnum2itemdisplaynametable.txt",&s);

	if(buf==NULL)
		return -1;

	buf[s]=0;
	for(p=buf;p-buf<s;){
		int nameid;
		char buf2[64]; //Why 64? What's this for, other than holding an item's name? [Skotlex]

		if(	sscanf(p,"%d#%[^#]#",&nameid,buf2)==2 ){

#ifdef ITEMDB_OVERRIDE_NAME_VERBOSE
			if( itemdb_exists(nameid) &&
				strncmp(itemdb_search(nameid)->jname,buf2,ITEM_NAME_LENGTH)!=0 ){
				ShowNotice("[override] %d %s => %s\n",nameid
					,itemdb_search(nameid)->jname,buf2);
			}
#endif

			strncpy(itemdb_search(nameid)->jname,buf2,ITEM_NAME_LENGTH-1);
		}

		p=strchr(p,10);
		if(!p) break;
		p++;
	}
	aFree(buf);
	ShowStatus("Done reading '"CL_WHITE"%s"CL_RESET"'.\n","data\\idnum2itemdisplaynametable.txt");

	return 0;
}
Exemplo n.º 18
0
/*==========================================
 * Internal add-item function.
 *------------------------------------------
 */
static int storage_additem(struct map_session_data *sd,struct storage *stor,struct item *item_data,int amount)
{
	struct item_data *data;
	int i;

	if (sd->state.finalsave)
		return 1;

	if(item_data->nameid <= 0 || amount <= 0)
		return 1;
	
	data = itemdb_search(item_data->nameid);

	if (!itemdb_canstore(item_data, pc_isGM(sd)))
	{	//Check if item is storable. [Skotlex]
		clif_displaymessage (sd->fd, msg_txt(264));
		return 1;
	}
	
	if(itemdb_isstackable2(data)){ //Stackable
		for(i=0;i<MAX_STORAGE;i++){
			if( compare_item (&stor->storage_[i], item_data)) {
				if(amount > MAX_AMOUNT - stor->storage_[i].amount)
					return 1;
				stor->storage_[i].amount+=amount;
				clif_storageitemadded(sd,stor,i,amount);
				stor->dirty = 1;
				if(log_config.enable_logs&0x800)
					log_pick_pc(sd, "R", item_data->nameid, -amount, item_data);
				return 0;
			}
		}
	}
	//Add item
	for(i=0;i<MAX_STORAGE && stor->storage_[i].nameid;i++);
	
	if(i>=MAX_STORAGE)
		return 1;

	memcpy(&stor->storage_[i],item_data,sizeof(stor->storage_[0]));
	stor->storage_[i].amount=amount;
	stor->storage_amount++;
	clif_storageitemadded(sd,stor,i,amount);
	clif_updatestorageamount(sd,stor);
	stor->dirty = 1;
	if(log_config.enable_logs&0x800)
		log_pick_pc(sd, "R", item_data->nameid, -amount, item_data);
	return 0;
}
Exemplo n.º 19
0
/*==========================================
 * アイテムデータベースの読み込み
 *------------------------------------------
 */
static int itemdb_readdb(void)
{
	FILE *fp;
	char line[1024];
	int ln=0;
	int nameid,j;
	char *str[32],*p,*np;
	struct item_data *id;

	fp=fopen("db/item_db.txt","r");
	if(fp==NULL){
		printf("can't read db/item_db.txt\n");
		exit(1);
	}
	while(fgets(line,1020,fp)){
		if(line[0]=='/' && line[1]=='/')
			continue;
		memset(str,0,sizeof(str));
		for(j=0,np=p=line;j<17 && 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 || nameid>=20000)
			continue;
		ln++;

		//ID,Name,Jname,Type,Price,Sell,Weight,ATK,DEF,Range,Slot,Job,Gender,Loc,wLV,eLV,View
		id=itemdb_search(nameid);
		memcpy(id->name,str[1],24);
		memcpy(id->jname,str[2],24);
		id->type=atoi(str[3]);

	}
	fclose(fp);
	printf("read db/item_db.txt done (count=%d)\n",ln);
	return 0;
}
Exemplo n.º 20
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)))
				{
					/* +----+--------------+---------------+------+-----------+------------+--------+--------+---------+-------+-------+------------+---------------+-----------------+--------------+-------------+------+------------+--------------+
					   |  0 |            1 |             2 |    3 |         4 |          5 |      6 |      7 |       8 |     9 |    10 |         11 |          12 |            13 |              14 |           15 |   16        |         17 |   18 |     19 |
					   +----+--------------+---------------+------+-----------+------------+--------+--------+---------+-------+-------+------------+---------------+-----------------+--------------+-------------+------+------------+--------------+
					   | 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 |
					   +----+--------------+---------------+------+-----------+------------+--------+--------+---------+-------+-------+------------+---------------+-----------------+--------------+-------------+------+------------+--------------+ */

					nameid = atoi(sql_row[0]);

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

					ln++;

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

					id->type = atoi(sql_row[3]);
					if (id->type == 11)
					{	//Items that are consumed upon target confirmation
						//(yggdrasil leaf, spells & pet lures) [Skotlex]
						id->type = 2;
						id->flag.delay_consume=1;
					}

					// 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) ? atoi(sql_row[11]) : 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;
					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)
						aFree(id->script);
					if (sql_row[19] != NULL) {
						if (sql_row[19][0] == '{')
							id->script = parse_script((unsigned char *) sql_row[19], 0);
						else {
							sprintf(script, "{%s}", sql_row[19]);
							id->script = parse_script((unsigned char *) script, 0);
						}
					} else id->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.º 21
0
/*==================================
* SQL
*===================================
*/
static int itemdb_read_sqldb(void) {
	unsigned short nameid;
	unsigned long ln = 0;
	struct item_data *id;
	int buy_price, sell_price;
	char script[65535 + 2 + 1]; // Maximum length of MySQL TEXT type (65535) + 2 bytes for curly brackets + 1 byte for terminator

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

	sql_request("SELECT * FROM `%s`", item_db_db);

	while (sql_get_row()) {
		/* +----+--------------+---------------+------+-----------+------------+--------+--------+---------+-------+-------+------------+-------------+---------------+-----------------+--------------+-------------+------------+------+--------+--------------+----------------+
		   |  0 |            1 |             2 |    3 |         4 |          5 |      6 |      7 |       8 |     9 |    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 |
		   +----+--------------+---------------+------+-----------+------------+--------+--------+---------+-------+-------+------------+-------------+---------------+-----------------+--------------+-------------+------------+------+--------+--------------+----------------+ */

		nameid = sql_get_integer(0);

		// If the identifier is not within the valid range, process the next row
		if (nameid == 0 || nameid >= 20000)
			continue;
#ifdef __DEBUG
		if (battle_config.etc_log) {
			if (strlen(sql_get_string(1)) > 24)
				printf(CL_YELLOW "WARNING: Invalid item name" CL_RESET" (id: %d) - Name too long (> 24 char.) -> only 24 first characters are used.\n", nameid);
			if (strlen(sql_get_string(2)) > 24)
				printf(CL_YELLOW "WARNING: Invalid item jname" CL_RESET" (id: %d) - Name too long (> 24 char.) -> only 24 first characters are used.\n", nameid);
		}
#endif

		ln++;
		if (ln % 22 == 21) {
			printf("Reading item #%ld (id: %d)...\r", ln, nameid);
			fflush(stdout);
		}

		// Insert a new row into the item database

		// ----------
		id = itemdb_search(nameid);

		memset(id->name, 0, sizeof(id->name));
		strncpy(id->name, sql_get_string(1), ITEM_NAME_LENGTH);
		memset(id->jname, 0, sizeof(id->jname));
		strncpy(id->jname, sql_get_string(2), ITEM_NAME_LENGTH);

		id->type = sql_get_integer(3);
		if (id->type == 11) {
			id->type = 2;
			id->flag.delay_consume=1;
		}

		// fix NULL for buy/sell prices
		if (sql_get_string(4) == NULL)
			buy_price = 0;
		else
			buy_price = sql_get_integer(4);
		if (sql_get_string(5) == NULL)
			sell_price = 0;
		else
			sell_price = sql_get_integer(5);
		// If price_buy is not 0 and price_sell is not 0...
		if (buy_price > 0 && sell_price > 0) {
			id->value_buy = buy_price;
			id->value_sell = sell_price;
		// If price_buy is not 0 and price_sell is 0...
		} else if (buy_price > 0 && sell_price == 0) {
			id->value_buy = buy_price;
			id->value_sell = buy_price / 2;
		// If price_buy is 0 and price_sell is not 0...
		} else if (buy_price == 0 && sell_price > 0) {
			id->value_buy = sell_price * 2;
			id->value_sell = sell_price;
		// If price_buy is 0 and price_sell is 0...
		} else {
			id->value_buy = 0;
			id->value_sell = 0;
		}
		// check for bad prices that can possibly cause exploits
		if (((double)id->value_buy * (double)75) / 100 < ((double)id->value_sell * (double)124) / 100) {
			printf("Item %s [%d]: prices: buy %d / sell %d (" CL_YELLOW "WARNING" CL_RESET ").\n", id->name, id->nameid, id->value_buy, id->value_sell);
			printf("for merchant: buying: %d < selling:%d (" CL_YELLOW "possible exploit OC/DC" CL_RESET ").\n", id->value_buy * 75 / 100, id->value_sell * 124 / 100);
			id->value_buy = ((double)id->value_sell * (double)124) / (double)75 + 1;
			printf("->set to: buy %d, sell %d (change in database please).\n", id->value_buy, id->value_sell);
		}

		id->weight	= sql_get_integer( 6);

		id->atk   = (sql_get_string( 7) != NULL) ? sql_get_integer( 7) : 0;
		id->def   = (sql_get_string( 8) != NULL) ? sql_get_integer( 8) : 0;
		id->range = (sql_get_string( 9) != NULL) ? sql_get_integer( 9) : 0;
		id->slot  = (sql_get_string(10) != NULL) ? sql_get_integer(10) : 0;
		itemdb_jobid2mapid(id->class_base, (sql_get_string(11) != NULL) ? (unsigned int)strtoul(sql_get_string(11), NULL, 0) : 0);
		id->class_upper = (sql_get_string(12) != NULL) ? sql_get_integer(12) : 0;
		id->sex   = (sql_get_string(13) != NULL) ? sql_get_integer(13) : 0;
		id->equip = (sql_get_string(14) != NULL) ? sql_get_integer(14) : 0;
		id->wlv   = (sql_get_string(15) != NULL) ? sql_get_integer(15) : 0;
		id->elv   = (sql_get_string(16) != NULL) ? sql_get_integer(16) : 0;
		id->flag.no_refine = (sql_get_integer(17) == 0 || sql_get_integer(17) == 1)?0:1;
		id->look  = (sql_get_string(18) != NULL) ? sql_get_integer(18) : 0;

		id->view_id = 0;

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

		if (sql_get_string(19) != NULL) {
			if (sql_get_string(19)[0] == '{')
				id->script = parse_script((unsigned char *)sql_get_string(19), 0);
			else {
				sprintf(script, "{%s}", sql_get_string(19));
				id->script = parse_script((unsigned char *)script, 0);
			}
		} else {
			id->script = NULL;
		}

		if (sql_get_string(20) != NULL) {
			if (sql_get_string(20)[0] == '{')
				id->equip_script = parse_script((unsigned char *)sql_get_string(20), 0);
			else {
				sprintf(script, "{%s}", sql_get_string(20));
				id->equip_script = parse_script((unsigned char *)script, 0);
			}
		} else {
			id->equip_script = NULL;
		}

		if (sql_get_string(21) != NULL) {
			if (sql_get_string(21)[0] == '{')
				id->unequip_script = parse_script((unsigned char *)sql_get_string(21), 0);
			else {
				sprintf(script, "{%s}", sql_get_string(21));
				id->unequip_script = parse_script((unsigned char *)script, 0);
			}
		} else {
			id->equip_script = NULL;
		}

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

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

	printf("DB '" CL_WHITE "%s" CL_RESET "' readed ('" CL_WHITE "%ld" CL_RESET "' entrie%s).\n", item_db_db, ln, (ln > 1) ? "s" : "");

	return 0;
}
Exemplo n.º 22
0
/*==========================================
 * アイテムデータベースの読み込み
 *------------------------------------------
 */
static int itemdb_readdb(void)
{
	FILE *fp;
	char line[1024];
	int ln, lines = 0;
	int nameid, j;
	char *str[32], *p, *np;
	struct item_data *id;
	int i = 0;
	int buy_price, sell_price;
	char *filename[] = { "db/item_db.txt", "db/item_db2.txt" };
	#define ITEM_DB_SQL_NAME "item_db_map.sql"

#ifdef USE_SQL
	FILE *item_db_fp = NULL; // need to be initialized to avoid 'false' warning
	// code to create SQL item db
	if (create_item_db_script) {
		// if file exists (doesn't exist, was renamed!... unnormal that continue to exist)
		if (access(ITEM_DB_SQL_NAME, 0) == 0) // 0: file exist or not, 0 = success
			remove(ITEM_DB_SQL_NAME); // delete the file. return value = 0 (success), return value = -1 (denied access or not found file)
		if ((item_db_fp = fopen(ITEM_DB_SQL_NAME, "a")) != NULL) {
			printf("Generating the '" CL_WHITE ITEM_DB_SQL_NAME CL_RESET "' file.\n");
			fprintf(item_db_fp, "# You can regenerate this file with an option in inter_athena.conf" RETCODE);
			fprintf(item_db_fp, RETCODE);
			fprintf(item_db_fp, "DROP TABLE IF EXISTS `%s`;" RETCODE, item_db_db);
			fprintf(item_db_fp, "CREATE TABLE `%s` (" RETCODE, item_db_db);
			fprintf(item_db_fp, "  `id` smallint(5) unsigned NOT NULL default '0'," RETCODE);
			fprintf(item_db_fp, "  `name_english` varchar(50) NOT NULL default ''," RETCODE);
			fprintf(item_db_fp, "  `name_japanese` varchar(50) NOT NULL default ''," RETCODE);
			fprintf(item_db_fp, "  `type` tinyint(2) unsigned NOT NULL default '0'," RETCODE);
			fprintf(item_db_fp, "  `price_buy` meduimint(10) unsigned default NULL," RETCODE);
			fprintf(item_db_fp, "  `price_sell` mediumint(10) unsigned default NULL," RETCODE);
			fprintf(item_db_fp, "  `weight` smallint(5) unsigned NOT NULL default '0'," RETCODE);
			fprintf(item_db_fp, "  `attack` tinyint(4) unsigned default NULL," RETCODE);
			fprintf(item_db_fp, "  `defence` tinyint(4) unsigned default NULL," RETCODE);
			fprintf(item_db_fp, "  `range` tinyint(2) unsigned default NULL," RETCODE);
			fprintf(item_db_fp, "  `slots` tinyint(2) unsigned default NULL," RETCODE); // max 5, but set to tinyint(2) to avoid possible BOOL replacement
			fprintf(item_db_fp, "  `equip_jobs` int(12) unsigned default NULL," RETCODE);
			fprintf(item_db_fp, "  `equip_upper` tinyint(8) unsigned default NULL," RETCODE);
			fprintf(item_db_fp, "  `equip_genders` tinyint(2) unsigned default NULL," RETCODE); // max 3 (1+2), but set to tinyint(2) to avoid possible BOOL replacement
			fprintf(item_db_fp, "  `equip_locations` smallint(4) unsigned default NULL," RETCODE);
			fprintf(item_db_fp, "  `weapon_level` tinyint(2) unsigned default NULL," RETCODE); // max 4, but set to tinyint(2) to avoid possible BOOL replacement
			fprintf(item_db_fp, "  `equip_level` tinyint(3) unsigned default NULL," RETCODE);
			fprintf(item_db_fp, "  `refineable` tinyint(1) unsigned default NULL," RETCODE);
			fprintf(item_db_fp, "  `view` tinyint(3) unsigned default NULL," RETCODE);
			fprintf(item_db_fp, "  `script` text," RETCODE);
			fprintf(item_db_fp, "  `equip_script` text," RETCODE);
			fprintf(item_db_fp, "  `unequip_script` text," RETCODE);
			fprintf(item_db_fp, "  PRIMARY KEY (`id`)" RETCODE);
			fprintf(item_db_fp, ") TYPE=MyISAM;" RETCODE);
			fprintf(item_db_fp, RETCODE);
		} else {
			printf(CL_RED "Can not generate the '" ITEM_DB_SQL_NAME "' file." CL_RESET" \n");
			create_item_db_script = 0; // not continue to try to create file after
		}
	}
#endif /* USE_SQL */

	for(i = 0; i < 2; i++) {

		ln = 0;
		fp = fopen(filename[i], "r");
		if (fp == NULL) {
			if (i > 0)
				continue;
			printf("can't read %s\n", filename[i]);
#ifdef USE_SQL
			if (create_item_db_script && item_db_fp != NULL) {
				fclose(item_db_fp);
			}
#endif /* USE_SQL */
			exit(1);
		}

		lines = 0;
		while(fgets(line, sizeof(line), fp)) { // fgets reads until maximum one less than size and add '\0' -> so, it's not necessary to add -1
			lines++;
			if ((line[0] == '/' && line[1] == '/') || line[0] == '\0' || line[0] == '\n' || line[0] == '\r') {
#ifdef USE_SQL
				// code to create SQL item db
				if (create_item_db_script && item_db_fp != NULL) {
					/* remove carriage return if exist */
					while(line[0] != '\0' && (line[(j = strlen(line) - 1)] == '\n' || line[j] == '\r'))
						line[j] = '\0';
					// add comments in the sql script
					if ((line[0] == '/' && line[1] == '/' && strlen(line) > 2)) {
						fprintf(item_db_fp, "#%s" RETCODE, line + 2);
					} else {
						fprintf(item_db_fp, RETCODE);
					}
				}
#endif /* USE_SQL */
				continue;
			}

			/* remove carriage return if exist */
			while(line[0] != '\0' && (line[(j = strlen(line) - 1)] == '\n' || line[j] == '\r'))
				line[j] = '\0';

			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 || nameid >= 20000)
				continue;
#ifdef __DEBUG
			if (battle_config.etc_log) {
				if (strlen(str[1]) > ITEM_NAME_LENGTH)
					printf(CL_YELLOW "WARNING: Invalid item name" CL_RESET" (id: %d) - Name too long (> ITEM_NAME_LENGTH char.) -> only ITEM_NAME_LENGTH first characters are used.\n", nameid);
				if (strlen(str[2]) > ITEM_NAME_LENGTH)
					printf(CL_YELLOW "WARNING: Invalid item jname" CL_RESET" (id: %d) - Name too long (> ITEM_NAME_LENGTH char.) -> only ITEM_NAME_LENGTH first characters are used.\n", nameid);
			}
#endif

			ln++;
			if (ln % 20 == 19) {
				printf("Reading item #%d (id: %d)...\r", ln, nameid);
				fflush(stdout);
			}

			id = itemdb_search(nameid);
			memset(id->name, 0, sizeof(id->name));
			strncpy(id->name, str[1], ITEM_NAME_LENGTH);
			memset(id->jname, 0, sizeof(id->jname));
			strncpy(id->jname, str[2], ITEM_NAME_LENGTH);
			id->type = atoi(str[3]);
			if (id->type == 11) {
				id->type = 2;
				id->flag.delay_consume = 1;
			}

			buy_price = atoi(str[4]);
			sell_price = atoi(str[5]);
			// If price_buy is not 0 and price_sell is not 0...
			if (buy_price > 0 && sell_price > 0) {
				id->value_buy = buy_price;
				id->value_sell = sell_price;
			// If price_buy is not 0 and price_sell is 0...
			} else if (buy_price > 0 && sell_price == 0) {
				id->value_buy = buy_price;
				id->value_sell = buy_price / 2;
			// If price_buy is 0 and price_sell is not 0...
			} else if (buy_price == 0 && sell_price > 0) {
				id->value_buy = sell_price * 2;
				id->value_sell = sell_price;
			// If price_buy is 0 and price_sell is 0...
			} else {
				id->value_buy = 0;
				id->value_sell = 0;
			}
			// check for bad prices that can possibly cause exploits
			if (((double)id->value_buy * (double)75) / 100 < ((double)id->value_sell * (double)124) / 100) {
				printf("Item %s [%d]: prices: buy %d / sell %d (" CL_YELLOW "WARNING" CL_RESET ").\n", id->name, id->nameid, id->value_buy, id->value_sell);
				printf("for merchant: buying: %d < selling:%d (" CL_YELLOW "possible exploit OC/DC" CL_RESET ").\n", id->value_buy * 75 / 100, id->value_sell * 124 / 100);
				id->value_buy = ((double)id->value_sell * (double)124) / (double)75 + 1;
				printf("->set to: buy %d, sell %d (change in database please).\n", id->value_buy, id->value_sell);
			}

			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]);
			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]);
			}
			id->wlv = atoi(str[15]);
			id->elv = atoi(str[16]);
			id->flag.no_refine = atoi(str[17]) ? 0 : 1;
			id->look = atoi(str[18]);
			id->flag.available = 1;
			id->flag.value_notdc = 0;
			id->flag.value_notoc = 0;
			id->view_id = 0;

			id->script = NULL;
			id->equip_script = NULL;
			id->unequip_script = NULL;

			if ((p = strchr(np, '{')) != NULL) {
				id->script = parse_script((unsigned char *)p, lines);
				if ((p = strchr(p + 1, '{')) != NULL)
					id->equip_script = parse_script((unsigned char *)p, lines);
				if ((p = strchr(p + 1, '{')) != NULL)
					id->unequip_script = parse_script((unsigned char *)p, lines);
			}

#ifdef USE_SQL
/*			// code to create SQL item db
			if (create_item_db_script && item_db_fp != NULL) {
				char item_name[50]; // 24 * 2 + 1 + NULL
				char item_jname[50]; // 24 * 2 + 1 + NULL
				char script1[1024], script2[1024], script3[1024], temp_script[1024], comment_script[1024];
				char *p1, *p2, *p3;
				struct item_data *actual_item;

				actual_item = id;
				// escape item names
				memset(item_name, 0, sizeof(item_name));
				db_sql_escape_string(item_name, actual_item->name, strlen(actual_item->name));
				memset(item_jname, 0, sizeof(item_jname));
				db_sql_escape_string(item_jname, actual_item->jname, strlen(actual_item->jname));
				// extract script 1, 2 and 3
				memset(script1, 0, sizeof(script1));
				memset(script2, 0, sizeof(script2));
				memset(script3, 0, sizeof(script3));
				if ((p1 = strchr(np, '{')) != NULL && (p2 = strchr(p1, '}')) != NULL && (p3 = strchr(p3, '}')) != NULL)) {
					while(*p1 == ' ' || *p1 == '{')
						p1++;
					while((*p2 == ' ' || *p2 == '}') && p2 > p1)
						p2--;
					while((*p3 == ' ' || *p3 == '}') && p3 > p2)
						p3--;
					if (p2 > p1) {
						memset(temp_script, 0, sizeof(temp_script));
						strncpy(temp_script, p1, p2 - p1 + 1);
						memset(script1, 0, sizeof(script1));
						script1[0] = '\'';
						db_sql_escape_string(script1 + 1, temp_script, strlen(temp_script));
						strcat(script1, "'");
					}
					// search second script
					if ((p1 = strchr(p2, '{')) != NULL && (p2 = strchr(p1, '}')) != NULL) {
						while(*p1 == ' ' || *p1 == '{')
							p1++;
						while((*p2 == ' ' || *p2 == '}') && p2 > p1)
							p2--;
						if (p2 > p1) {
							memset(temp_script, 0, sizeof(temp_script));
							strncpy(temp_script, p1, p2 - p1 + 1);
							memset(script2, 0, sizeof(script2));
							script2[0] = '\'';
							db_sql_escape_string(script2 + 1, temp_script, strlen(temp_script));
							strcat(script2, "'");
						}
					}
					if ((p1 = strchr(p2, '{')) != NULL && (p2 = strchr(p1, '}')) != NULL) {
						while(*p1 == ' ' || *p1 == '{')
							p1++;
						while((*p2 == ' ' || *p2 == '}') && p2 > p1)
							p2--;
						if (p2 > p1) {
							memset(temp_script, 0, sizeof(temp_script));
							strncpy(temp_script, p1, p2 - p1 + 1);
							memset(script3, 0, sizeof(script3));
							script3[0] = '\'';
							db_sql_escape_string(script3 + 1, temp_script, strlen(temp_script));
							strcat(script3, "'");
						}
					}
				}

				memset(comment_script, 0 , sizeof(comment_script));
				if ((p1 = strchr(np, '/')) != NULL && p1[1] == '/') {
					comment_script[0] = ' ';
					comment_script[1] = '#';
					strcpy(comment_script + 2, p1 + 2);
				}
				// create request
				fprintf(item_db_fp, "INSERT INTO `%s` VALUES (%d, '%s', '%s', %d,"
				                                             " %d, %d,"
				                                             " %d, %d, %d, %d,"
				                                             " %d, '%s', %d, %d, %d,"
				                                             " %d, %d, %d, %d,"
				                                             " '%s', '%s', '%s');%s" RETCODE,
				                    item_db_db, nameid, item_name, item_jname, actual_item->type,
				                    atoi(str[4]), atoi(str[5]), // id->value_buy, id->value_sell: not modified
				                    actual_item->weight, actual_item->atk, actual_item->def, actual_item->range,
				                    actual_item->slot, str[11], actual_item->class_upper, actual_item->sex, actual_item->equip,
				                    actual_item->wlv, actual_item->elv, actual_item->flag.no_refine, actual_item->look,
				                    (script1[0] == 0) ? "NULL" : script1, (script2[0] == 0) ? "NULL" : script2, (script3[0] == 0) ? "NULL" : script3, comment_script);

			}
*/
#endif /* USE_SQL */
		}
		fclose(fp);
		printf("DB '" CL_WHITE "%s" CL_RESET "' readed ('" CL_WHITE "%d" CL_RESET "' %s).\n", filename[i], ln, (ln > 1) ? "entries" : "entry");
	}

#ifdef USE_SQL
		// code to create SQL item db
		if (create_item_db_script && item_db_fp != NULL) {
			fclose(item_db_fp);
		}
#endif /* USE_SQL */

	return 0;
}
Exemplo n.º 23
0
/*==========================================
 * Check here if we can add items in inventories (against full inventory)
 *------------------------------------------
 */
static int trade_check(struct map_session_data *sd, struct map_session_data *target_sd)
{
	struct item inventory[MAX_INVENTORY];
	struct item inventory2[MAX_INVENTORY];
	struct item_data *data;
	int trade_i, i, amount, idx;

	nullpo_retr(0, sd);
	nullpo_retr(0, target_sd);

	// get inventory of players
	memcpy(&inventory, &sd->status.inventory, sizeof(struct item) * MAX_INVENTORY);
	memcpy(&inventory2, &target_sd->status.inventory, sizeof(struct item) * MAX_INVENTORY);

	// check free slots in both inventories
	for(trade_i = 0; trade_i < MAX_DEAL_ITEMS; trade_i++) {
		amount = sd->trade.item_amount[trade_i];
		if (amount > 0) {
			idx = sd->trade.item_index[trade_i] - 2;
			if (itemdb_isdropable(inventory[idx].nameid)) {
				// check quantity
				if (amount > inventory[idx].amount) // player changes its inventory before to commit
					return 0;
				if (amount > 0) {
					// search if it's possible to add item (for full inventory)
					data = itemdb_search(inventory[idx].nameid);
					i = MAX_INVENTORY;
					// check for non-equipement items
					if (!itemdb_isequip2(data)) {
						for(i = 0; i < MAX_INVENTORY; i++)
							if (inventory2[i].nameid == inventory[idx].nameid &&
								inventory2[i].card[0] == inventory[idx].card[0] && inventory2[i].card[1] == inventory[idx].card[1] &&
								inventory2[i].card[2] == inventory[idx].card[2] && inventory2[i].card[3] == inventory[idx].card[3]) {
								if (inventory2[i].amount + amount > MAX_AMOUNT)
									return 0;
								inventory2[i].amount += amount;
								inventory[idx].amount -= amount;
								if (inventory[idx].amount <= 0)
									memset(&inventory[idx], 0, sizeof(struct item));
								break;
							}
					}
					// check for equipement
					if (i == MAX_INVENTORY) {
						for(i = 0; i < MAX_INVENTORY; i++) {
							if (inventory2[i].nameid == 0) {
								memcpy(&inventory2[i], &inventory[idx], sizeof(struct item));
								inventory2[i].amount = amount;
								inventory[idx].amount -= amount;
								if (inventory[idx].amount <= 0)
									memset(&inventory[idx], 0, sizeof(struct item));
								break;
							}
						}
						if (i == MAX_INVENTORY)
							return 0;
					}
				}
			}
		}
		amount = target_sd->trade.item_amount[trade_i];
		if (amount > 0) {
			idx = target_sd->trade.item_index[trade_i] - 2;
			if (itemdb_isdropable(inventory2[idx].nameid)) {
				// check quantity
				if (amount > inventory2[idx].amount) // player changes its inventory before to commit
					return 0;
				if (amount > 0) {
					// search if it's possible to add item (for full inventory)
					data = itemdb_search(inventory2[idx].nameid);
					i = MAX_INVENTORY;
					// check for non-equipement items
					if (!itemdb_isequip2(data)) {
						for(i = 0; i < MAX_INVENTORY; i++)
							if (inventory[i].nameid == inventory2[idx].nameid &&
								inventory[i].card[0] == inventory2[idx].card[0] && inventory[i].card[1] == inventory2[idx].card[1] &&
								inventory[i].card[2] == inventory2[idx].card[2] && inventory[i].card[3] == inventory2[idx].card[3]) {
								if (inventory[i].amount + amount > MAX_AMOUNT)
									return 0;
								inventory[i].amount += amount;
								inventory2[idx].amount -= amount;
								if (inventory2[idx].amount <= 0)
									memset(&inventory2[idx], 0, sizeof(struct item));
								break;
							}
					}
					// check for equipement
					if (i == MAX_INVENTORY) {
						for(i = 0; i < MAX_INVENTORY; i++) {
							if (inventory[i].nameid == 0) {
								memcpy(&inventory[i], &inventory2[idx], sizeof(struct item));
								inventory[i].amount = amount;
								inventory2[idx].amount -= amount;
								if (inventory2[idx].amount <= 0)
									memset(&inventory2[idx], 0, sizeof(struct item));
								break;
							}
						}
						if (i == MAX_INVENTORY)
							return 0;
					}
				}
			}
		}
	}

	return 1;
}
Exemplo n.º 24
0
bool itemdb_readdb(ZString filename)
{
    bool rv = true;

    int ln = 0, lines = 0;

    {
        io::ReadFile in(filename);

        if (!in.is_open())
        {
            PRINTF("can't read %s\n", filename);
            return false;
        }

        lines = 0;

        FString line;
        while (in.getline(line))
        {
            lines++;
            if (is_comment(line))
                continue;
            // a line is 17 normal fields followed by 2 {} fields
            // the fields are separated by ", *", but there may be ,
            // in the {}.

            auto it = std::find(line.begin(), line.end(), '{');
            XString main_part = line.xislice_h(it).rstrip();
            // According to the code, tail_part may be empty. See later.
            ZString tail_part = line.xislice_t(it);

            item_data idv {};
            if (!extract(
                        main_part, record<','>(
                            &idv.nameid,
                            lstripping(&idv.name),
                            lstripping(&idv.jname),
                            lstripping(&idv.type),
                            lstripping(&idv.value_buy),
                            lstripping(&idv.value_sell),
                            lstripping(&idv.weight),
                            lstripping(&idv.atk),
                            lstripping(&idv.def),
                            lstripping(&idv.range),
                            lstripping(&idv.magic_bonus),
                            lstripping(&idv.slot),
                            lstripping(&idv.sex),
                            lstripping(&idv.equip),
                            lstripping(&idv.wlv),
                            lstripping(&idv.elv),
                            lstripping(&idv.look)
                        )
                    )
            )
            {
                PRINTF("%s:%d: error: bad item line: %s\n",
                        filename, lines, line);
                rv = false;
                continue;
            }

            ln++;

            struct item_data *id = itemdb_search(idv.nameid);
            *id = std::move(idv);
            if (id->value_buy == 0 && id->value_sell == 0)
            {
            }
            else if (id->value_buy == 0)
            {
                id->value_buy = id->value_sell * 2;
            }
            else if (id->value_sell == 0)
            {
                id->value_sell = id->value_buy / 2;
            }

            id->use_script = NULL;
            id->equip_script = NULL;

            if (!tail_part)
                continue;
            id->use_script = parse_script(tail_part, lines);

            tail_part = tail_part.xislice_t(std::find(tail_part.begin() + 1, tail_part.end(), '{'));
            if (!tail_part)
                continue;
            id->equip_script = parse_script(tail_part, lines);
        }
        PRINTF("read %s done (count=%d)\n", filename, ln);
    }

    return rv;
}
Exemplo n.º 25
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;
}
Exemplo n.º 26
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 || nameid>=20000)
				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_search(nameid);
			memcpy(id->name, str[1], ITEM_NAME_LENGTH-1);
			memcpy(id->jname, str[2], ITEM_NAME_LENGTH-1);
			id->type=atoi(str[3]);
			if (id->type == 11)
			{	//Items that are consumed upon target confirmation
				//(yggdrasil leaf, spells & pet lures) [Skotlex]
				id->type = 2;
				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, atoi(str[11]));
			id->class_upper = atoi(str[12]);
			id->sex	= atoi(str[13]);
			if(id->equip != atoi(str[14])){
				id->equip=atoi(str[14]);
			}
			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) {
				aFree(id->script);
				id->script=NULL;
			}
			if((p=strchr(np,'{'))==NULL)
				continue;
			id->script = parse_script((unsigned char *) p,lines);
		}
		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.º 27
0
/**
 * Player setup a new shop
 * @param sd : player opening the shop
 * @param message : shop title
 * @param data : itemlist data \n
 *	data := {<index>.w <amount>.w <value>.l}[count]
 * @param count : number of different items
 * @return 0 If success, 1 - Cannot open (die, not state.prevend, trading), 2 - No cart, 3 - Count issue, 4 - Cart data isn't saved yet, 5 - No valid item found
 */
char vending_openvending(struct map_session_data* sd, const char* message, const uint8* data, int count) {
	int i, j;
	int vending_skill_lvl;
	char message_sql[MESSAGE_SIZE*2];
	
	nullpo_retr(false,sd);

	if ( pc_isdead(sd) || !sd->state.prevend || pc_istrading(sd)) {
		return 1; // can't open vendings lying dead || didn't use via the skill (wpe/hack) || can't have 2 shops at once
	}

	vending_skill_lvl = pc_checkskill(sd, MC_VENDING);
	
	// skill level and cart check
	if( !vending_skill_lvl || !pc_iscarton(sd) ) {
		clif_skill_fail(sd, MC_VENDING, USESKILL_FAIL_LEVEL, 0);
		return 2;
	}

	// check number of items in shop
	if( count < 1 || count > MAX_VENDING || count > 2 + vending_skill_lvl )
	{	// invalid item count
		clif_skill_fail(sd, MC_VENDING, USESKILL_FAIL_LEVEL, 0);
		return 3;
	}

	if (save_settings&2) // Avoid invalid data from saving
		chrif_save(sd, 0);

	// filter out invalid items
	i = 0;
	for( j = 0; j < count; j++ ) {
		short index        = *(uint16*)(data + 8*j + 0);
		short amount       = *(uint16*)(data + 8*j + 2);
		unsigned int value = *(uint32*)(data + 8*j + 4);

		index -= 2; // offset adjustment (client says that the first cart position is 2)

		if( index < 0 || index >= MAX_CART // invalid position
		||  pc_cartitem_amount(sd, index, amount) < 0 // invalid item or insufficient quantity
		//NOTE: official server does not do any of the following checks!
		||  !sd->status.cart[index].identify // unidentified item
		||  sd->status.cart[index].attribute == 1 // broken item
		||  sd->status.cart[index].expire_time // It should not be in the cart but just in case
		||  (sd->status.cart[index].bound && !pc_can_give_bounded_items(sd)) // can't trade account bound items and has no permission
		||  !itemdb_cantrade(&sd->status.cart[index], pc_get_group_level(sd), pc_get_group_level(sd)) ) // untradeable item
			continue;

		sd->vending[i].index = index;
		sd->vending[i].amount = amount;
		sd->vending[i].value = min(value, (unsigned int)battle_config.vending_max_value);

		// Player just moved item to cart and we don't have the correct cart ID yet.
		if (sd->status.cart[sd->vending[i].index].id == 0) {
			struct item_data *idb = itemdb_search(sd->status.cart[index].nameid);
			char msg[256];

			sprintf(msg, msg_txt(sd, 733), idb->jname);
			clif_displaymessage(sd->fd, msg);
			clif_skill_fail(sd, MC_VENDING, USESKILL_FAIL_LEVEL, 0);
			return 4;
		}

		i++; // item successfully added
	}

	if( i != j )
		clif_displaymessage (sd->fd, msg_txt(sd,266)); //"Some of your items cannot be vended and were removed from the shop."

	if( i == 0 ) { // no valid item found
		clif_skill_fail(sd, MC_VENDING, USESKILL_FAIL_LEVEL, 0); // custom reply packet
		return 5;
	}
	sd->state.prevend = 0;
	sd->state.vending = true;
	sd->vender_id = vending_getuid();
	sd->vend_num = i;
	safestrncpy(sd->message, message, MESSAGE_SIZE);
	
	Sql_EscapeString( mmysql_handle, message_sql, sd->message );

	if( Sql_Query( mmysql_handle, "INSERT INTO `%s`(`id`,`account_id`,`char_id`,`sex`,`map`,`x`,`y`,`title`,`autotrade`, `body_direction`, `head_direction`, `sit`) "
		"VALUES( %d, %d, %d, '%c', '%s', %d, %d, '%s', %d, '%d', '%d', '%d' );",
		vendings_db, sd->vender_id, sd->status.account_id, sd->status.char_id, sd->status.sex == 0 ? 'F' : 'M', map[sd->bl.m].name, sd->bl.x, sd->bl.y, message_sql, sd->state.autotrade, sd->ud.dir, sd->head_dir, pc_issit(sd) ) != SQL_SUCCESS ){
		Sql_ShowDebug(mmysql_handle);
	}

	for( i = 0; i < count; i++ ) {
		if( Sql_Query( mmysql_handle, "INSERT INTO `%s`(`vending_id`,`index`,`cartinventory_id`,`amount`,`price`) VALUES( %d, %d, %d, %d, %d );", vending_items_db, sd->vender_id, i, sd->status.cart[sd->vending[i].index].id, sd->vending[i].amount, sd->vending[i].value ) != SQL_SUCCESS ){
			Sql_ShowDebug(mmysql_handle);
		}
	}

	clif_openvending(sd,sd->bl.id,sd->vending);
	clif_showvendingboard(&sd->bl,message,0);

	idb_put(vending_db, sd->status.char_id, sd);

	return 0;
}
Exemplo n.º 28
0
/**
 * Player setup a new shop
 * @param sd : player opening the shop
 * @param message : shop title
 * @param data : itemlist data
 *	data := {<index>.w <amount>.w <value>.l}[count]
 * @param count : number of different items
 * @param at Autotrader info, or NULL if requetsed not from autotrade persistance
 * @return 0 If success, 1 - Cannot open (die, not state.prevend, trading), 2 - No cart, 3 - Count issue, 4 - Cart data isn't saved yet, 5 - No valid item found
 */
int8 vending_openvending(struct map_session_data* sd, const char* message, const uint8* data, int count, struct s_autotrader *at)
{
	int i, j, k, n;
	int vending_skill_lvl;
	char message_sql[MESSAGE_SIZE*2];
	int item_bad_price[MAX_VENDING];
	StringBuf buf;
	struct item_data *item;
	
	nullpo_retr(false,sd);

	if ( pc_isdead(sd) || !sd->state.prevend || pc_istrading(sd)) {
		return 1; // can't open vendings lying dead || didn't use via the skill (wpe/hack) || can't have 2 shops at once
	}

	vending_skill_lvl = pc_checkskill(sd, MC_VENDING);
	
	// skill level and cart check
	if( !vending_skill_lvl || !pc_iscarton(sd) ) {
		clif_skill_fail(sd, MC_VENDING, USESKILL_FAIL_LEVEL, 0);
		return 2;
	}

	// check number of items in shop
	if( count < 1 || count > MAX_VENDING || count > 2 + vending_skill_lvl ) { // invalid item count
		clif_skill_fail(sd, MC_VENDING, USESKILL_FAIL_LEVEL, 0);
		return 3;
	}

	if (save_settings&CHARSAVE_VENDING) // Avoid invalid data from saving
		chrif_save(sd, 0);

	// filter out invalid items
	i = k = 0;
	for( j = 0; j < count; j++ ) {
		short index        = *(uint16*)(data + 8*j + 0);
		short amount       = *(uint16*)(data + 8*j + 2);
		unsigned int value = *(uint32*)(data + 8*j + 4);

		index -= 2; // offset adjustment (client says that the first cart position is 2)

		if( index < 0 || index >= MAX_CART // invalid position
		||  pc_cartitem_amount(sd, index, amount) < 0 // invalid item or insufficient quantity
		//NOTE: official server does not do any of the following checks!
		||  !sd->status.cart[index].identify // unidentified item
		||  sd->status.cart[index].attribute == 1 // broken item
		||  sd->status.cart[index].expire_time // It should not be in the cart but just in case
		||  (sd->status.cart[index].bound && !pc_can_give_bounded_items(sd)) // can't trade account bound items and has no permission
		||  !itemdb_cantrade(&sd->status.cart[index], pc_get_group_level(sd), pc_get_group_level(sd)) ) // untradeable item
			continue;

		item = itemdb_search(sd->status.cart[index].nameid);

		if (item->value_buy_min > 0 && value > item->value_buy_min)
		{
			if (battle_config.vending_price_min_overflow  > 0 )
			{
				if (value > item->value_buy_min + (item->value_buy_min * (battle_config.vending_price_min_overflow / 10000.)))
				{
					item_bad_price[k++] = sd->status.cart[index].nameid;
					continue;
				}
			}
			else
			{
				item_bad_price[k++] = sd->status.cart[index].nameid;
				continue;
			}
		}

		sd->vending[i].index = index;
		sd->vending[i].amount = amount;
		sd->vending[i].value = min(value, (unsigned int)battle_config.vending_max_value);

		// Player just moved item to cart and we don't have the correct cart ID yet.
		if (sd->status.cart[sd->vending[i].index].id == 0) {
			char msg[256];

			snprintf(msg, 256, "äÍà·çÁ %s ÂѧäÁèä´éºÑ¹·Ö¡. ¡ÃسÒÍÍ¡à¢éÒãËÁè à¾×èÍãËéäÍà·çÁ·Ó¡ÒÃ૿ŧÃéÒ¹¤éÒ", item->jname);
			clif_displaymessage(sd->fd, msg);
			clif_skill_fail(sd, MC_VENDING, USESKILL_FAIL_LEVEL, 0);
			return 4;
		}

		i++; // item successfully added
	}

	//if( i != j )
		//clif_displaymessage (sd->fd, msg_txt(sd,266)); //"Some of your items cannot be vended and were removed from the shop."

	for (n = 0; n < k; n++)
	{
		char msg[512];

		item = itemdb_search(item_bad_price[n]);
		
		if (battle_config.vending_price_min_overflow > 0)
			sprintf(msg, "%s µÑé§ÃÒ¤Ò¢ÒÂÊÙ§¡ÇèÒ·Õè NPC ÁÕ¢ÒÂÍÂÙèà¡Ô¹ %d%% ¨Ð¶Ù¡µÑ´ÍÍ¡¨Ò¡ÃÒ¡ÒÃà¾×èÍ»éͧ¡Ñ¹¡ÒÃâ¡è§ÃÒ¤Ò", item->jname, battle_config.vending_price_min_overflow/100);
		else
			sprintf(msg, "%s µÑé§ÃÒ¤Ò¢ÒÂÊÙ§¡ÇèÒ·Õè NPC ÁÕ¢ÒÂÍÂÙè ¨Ð¶Ù¡µÑ´ÍÍ¡¨Ò¡ÃÒ¡ÒÃà¾×èÍ»éͧ¡Ñ¹¡ÒÃâ¡è§ÃÒ¤Ò", item->jname);
		clif_displaymessage(sd->fd, msg);
	}

	if( i == 0 ) { // no valid item found
		clif_skill_fail(sd, MC_VENDING, USESKILL_FAIL_LEVEL, 0); // custom reply packet
		return 5;
	}

	sd->state.prevend = 0;
	sd->state.vending = true;
	sd->vender_id = vending_getuid();
	sd->vend_num = i;
	safestrncpy(sd->message, message, MESSAGE_SIZE);
	
	Sql_EscapeString( mmysql_handle, message_sql, sd->message );

	if( Sql_Query( mmysql_handle, "INSERT INTO `%s`(`id`, `account_id`, `char_id`, `sex`, `map`, `x`, `y`, `title`, `autotrade`, `body_direction`, `head_direction`, `sit`) "
		"VALUES( %d, %d, %d, '%c', '%s', %d, %d, '%s', %d, '%d', '%d', '%d' );",
		vendings_db, sd->vender_id, sd->status.account_id, sd->status.char_id, sd->status.sex == 0 ? 'F' : 'M', map[sd->bl.m].name, sd->bl.x, sd->bl.y, message_sql, sd->state.autotrade, at ? at->dir : sd->ud.dir, at ? at->head_dir : sd->head_dir, at ? at->sit : pc_issit(sd) ) != SQL_SUCCESS ) {
		Sql_ShowDebug(mmysql_handle);
	}

	StringBuf_Init(&buf);
	StringBuf_Printf(&buf, "INSERT INTO `%s`(`vending_id`,`index`,`cartinventory_id`,`amount`,`price`) VALUES", vending_items_db);
	for (i = 0; i < count; i++) {
		StringBuf_Printf(&buf, "(%d,%d,%d,%d,%d)", sd->vender_id, i, sd->status.cart[sd->vending[i].index].id, sd->vending[i].amount, sd->vending[i].value);
		if (i < count-1)
			StringBuf_AppendStr(&buf, ",");
	}
	if (SQL_ERROR == Sql_QueryStr(mmysql_handle, StringBuf_Value(&buf)))
		Sql_ShowDebug(mmysql_handle);
	StringBuf_Destroy(&buf);

	clif_openvending(sd,sd->bl.id,sd->vending);
	clif_showvendingboard(&sd->bl,message,0);

	idb_put(vending_db, sd->status.char_id, sd);

	return 0;
}
Exemplo n.º 29
0
/*==========================================
 * Checks if trade is possible (against zeny limits, inventory limits, etc)
 *------------------------------------------*/
int trade_check (struct map_session_data *sd, struct map_session_data *tsd)
{
	struct item inventory[MAX_INVENTORY];
	struct item inventory2[MAX_INVENTORY];
	struct item_data *data;
	int trade_i, i, n;
	short amount;

	// check zenys value against hackers (Zeny was already checked on time of adding, but you never know when you lost some zeny since then.
	if (sd->deal.zeny > sd->status.zeny || (tsd->status.zeny > MAX_ZENY - sd->deal.zeny))
		return 0;

	if (tsd->deal.zeny > tsd->status.zeny || (sd->status.zeny > MAX_ZENY - tsd->deal.zeny))
		return 0;

	// get inventory of player
	memcpy (&inventory, &sd->status.inventory, sizeof (struct item) * MAX_INVENTORY);
	memcpy (&inventory2, &tsd->status.inventory, sizeof (struct item) * MAX_INVENTORY);

	// check free slot in both inventory
	for (trade_i = 0; trade_i < 10; trade_i++) {
		amount = sd->deal.item[trade_i].amount;

		if (amount) {
			n = sd->deal.item[trade_i].index;

			if (amount > inventory[n].amount)
				return 0; //qty Exploit?

			data = itemdb_search (inventory[n].nameid);
			i = MAX_INVENTORY;

			if (itemdb_isstackable2 (data)) { //Stackable item.
				for (i = 0; i < MAX_INVENTORY; i++)
					if (inventory2[i].nameid == inventory[n].nameid &&
							inventory2[i].card[0] == inventory[n].card[0] && inventory2[i].card[1] == inventory[n].card[1] &&
							inventory2[i].card[2] == inventory[n].card[2] && inventory2[i].card[3] == inventory[n].card[3]) {
						if (inventory2[i].amount + amount > MAX_AMOUNT)
							return 0;

						inventory2[i].amount += amount;
						inventory[n].amount -= amount;
						break;
					}
			}

			if (i == MAX_INVENTORY) {// look for an empty slot.
				for (i = 0; i < MAX_INVENTORY && inventory2[i].nameid; i++);

				if (i == MAX_INVENTORY)
					return 0;

				memcpy (&inventory2[i], &inventory[n], sizeof (struct item));
				inventory2[i].amount = amount;
				inventory[n].amount -= amount;
			}
		}

		amount = tsd->deal.item[trade_i].amount;

		if (!amount)
			continue;

		n = tsd->deal.item[trade_i].index;

		if (amount > inventory2[n].amount)
			return 0;

		// search if it's possible to add item (for full inventory)
		data = itemdb_search (inventory2[n].nameid);
		i = MAX_INVENTORY;

		if (itemdb_isstackable2 (data)) {
			for (i = 0; i < MAX_INVENTORY; i++)
				if (inventory[i].nameid == inventory2[n].nameid &&
						inventory[i].card[0] == inventory2[n].card[0] && inventory[i].card[1] == inventory2[n].card[1] &&
						inventory[i].card[2] == inventory2[n].card[2] && inventory[i].card[3] == inventory2[n].card[3]) {
					if (inventory[i].amount + amount > MAX_AMOUNT)
						return 0;

					inventory[i].amount += amount;
					inventory2[n].amount -= amount;
					break;
				}
		}

		if (i == MAX_INVENTORY) {
			for (i = 0; i < MAX_INVENTORY && inventory[i].nameid; i++);

			if (i == MAX_INVENTORY)
				return 0;

			memcpy (&inventory[i], &inventory2[n], sizeof (struct item));
			inventory[i].amount = amount;
			inventory2[n].amount -= amount;
		}
	}

	return 1;
}
Exemplo n.º 30
0
/*==========================================
 * Check here if we can add item in inventory (against full inventory)
 *------------------------------------------
 */
int trade_check(struct map_session_data *sd) {
	struct item inventory[MAX_INVENTORY];
	struct item inventory2[MAX_INVENTORY];
	struct item_data *data;
	struct map_session_data *target_sd;
	int trade_i, i, amount;

	target_sd = map_id2sd(sd->trade_partner);

	// get inventory of player
	memcpy(&inventory, &sd->status.inventory, sizeof(struct item) * MAX_INVENTORY);
	memcpy(&inventory2, &target_sd->status.inventory, sizeof(struct item) * MAX_INVENTORY);

	// check free slot in both inventory
	for(trade_i = 0; trade_i < 10; trade_i++) {
		amount = sd->deal.item[trade_i].amount;
		if (amount > 0) {
			int n = sd->deal.item[trade_i].index;
			// check quantity
			if (amount > inventory[n].amount)
				amount = inventory[n].amount;
			if (amount > 0) {
				data = itemdb_search(inventory[n].nameid);
				i = MAX_INVENTORY;
				// check for non-equipement item
				if (!itemdb_isequip2(data)) {
					for(i = 0; i < MAX_INVENTORY; i++)
						if (inventory2[i].nameid == inventory[n].nameid &&
							inventory2[i].card[0] == inventory[n].card[0] && inventory2[i].card[1] == inventory[n].card[1] &&
							inventory2[i].card[2] == inventory[n].card[2] && inventory2[i].card[3] == inventory[n].card[3]) {
							if (inventory2[i].amount + amount > MAX_AMOUNT)
								return 0;
							inventory2[i].amount += amount;
							inventory[n].amount -= amount;
							if (inventory[n].amount <= 0)
								memset(&inventory[n], 0, sizeof(struct item));
							break;
						}
				}
				// check for equipement
				if (i == MAX_INVENTORY) {
					for(i = 0; i < MAX_INVENTORY; i++) {
						if (inventory2[i].nameid == 0) {
							memcpy(&inventory2[i], &inventory[n], sizeof(struct item));
							inventory2[i].amount = amount;
							inventory[n].amount -= amount;
							if (inventory[n].amount <= 0)
								memset(&inventory[n], 0, sizeof(struct item));
							break;
						}
					}
					if (i == MAX_INVENTORY)
						return 0;
				}
			}
		}
		amount = target_sd->deal.item[trade_i].amount;
		if (amount > 0) {
			int n = target_sd->deal.item[trade_i].index;
			// check quantity
			if (amount > inventory2[n].amount)
				amount = inventory2[n].amount;
			if (amount > 0) {
				// search if it's possible to add item (for full inventory)
				data = itemdb_search(inventory2[n].nameid);
				i = MAX_INVENTORY;
				if (!itemdb_isequip2(data)) {
					for(i = 0; i < MAX_INVENTORY; i++)
						if (inventory[i].nameid == inventory2[n].nameid &&
							inventory[i].card[0] == inventory2[n].card[0] && inventory[i].card[1] == inventory2[n].card[1] &&
							inventory[i].card[2] == inventory2[n].card[2] && inventory[i].card[3] == inventory2[n].card[3]) {
							if (inventory[i].amount + amount > MAX_AMOUNT)
								return 0;
							inventory[i].amount += amount;
							inventory2[n].amount -= amount;
							if (inventory2[n].amount <= 0)
								memset(&inventory2[n], 0, sizeof(struct item));
							break;
						}
				}
				if (i == MAX_INVENTORY) {
					for(i = 0; i < MAX_INVENTORY; i++) {
						if (inventory[i].nameid == 0) {
							memcpy(&inventory[i], &inventory2[n], sizeof(struct item));
							inventory[i].amount = amount;
							inventory2[n].amount -= amount;
							if (inventory2[n].amount <= 0)
								memset(&inventory2[n], 0, sizeof(struct item));
							break;
						}
					}
					if (i == MAX_INVENTORY)
						return 0;
				}
			}
		}
	}

	return 1;
}