Exemple #1
0
/*==========================================
 * timer関数
 * 今このmap鯖に繋がっているクライアント人数をchar鯖へ送る
 *------------------------------------------*/
int send_users_tochar(void)
{
	int users = 0, i = 0;
	struct map_session_data* sd;
	struct s_mapiterator* iter;

	chrif_check(-1);

	// get user count (TODO: improve this)
	iter = mapit_getallusers();
	for( mapit_first(iter); mapit_exists(iter); mapit_next(iter) )
		users++;
	mapit_free(iter);

	// build the packet
	WFIFOHEAD(char_fd, 6+8*users);
	WFIFOW(char_fd,0) = 0x2aff;
	iter = mapit_getallusers();
	for( sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC*)mapit_next(iter) )
	{
		WFIFOL(char_fd,6+8*i) = sd->status.account_id;
		WFIFOL(char_fd,6+8*i+4) = sd->status.char_id;
		i++;
	}
	mapit_free(iter);
	WFIFOW(char_fd,2) = 6 + 8*users;
	WFIFOW(char_fd,4) = users;
	WFIFOSET(char_fd, 6+8*users);

	return 0;
}
Exemple #2
0
// 所属キャラの確認
int guild_check_member(struct guild *g)
{
	int i;
	struct map_session_data *sd;
	struct s_mapiterator* iter;

	nullpo_ret(g);

	iter = mapit_getallusers();
	for( sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC*)mapit_next(iter) )
	{
		if( sd->status.guild_id != g->guild_id )
			continue;

		i = guild_getindex(g,sd->status.account_id,sd->status.char_id);
		if (i < 0) {
			sd->status.guild_id=0;
			sd->guild_emblem_id=0;
			ShowWarning("guild: check_member %d[%s] is not member\n",sd->status.account_id,sd->status.name);
		}
	}
	mapit_free(iter);

	return 0;
}
Exemple #3
0
/// Checks if each char having a party actually belongs to that party.
/// If check fails, the char gets marked as 'not in a party'.
int party_check_member(struct party *p)
{
	int i;
	struct map_session_data *sd;
	struct s_mapiterator* iter;

	nullpo_retr(0, p);

	iter = mapit_getallusers();
	for( sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC*)mapit_next(iter) )
	{
		if( sd->status.party_id != p->party_id )
			continue;

		ARR_FIND( 0, MAX_PARTY, i, p->member[i].account_id == sd->status.account_id && p->member[i].char_id == sd->status.char_id );
		if( i == MAX_PARTY )
		{
			ShowWarning("party_check_member: '%s' (acc:%d) is not member of party '%s' (id:%d)\n",sd->status.name,sd->status.account_id,p->name,p->party_id);
			sd->status.party_id = 0;
		}
	}
	mapit_free(iter);

	return 0;
}
void itemdb_reload(void)
{
	struct s_mapiterator* iter;
	struct map_session_data* sd;

	int i;

	itemdb_save_serials(); // Store lastest serials
	// 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();

	// 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);
}
Exemple #5
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);
}
Exemple #6
0
/**
 * Reload PC Groups
 * Used in @reloadatcommand
 * @public
 */
void pc_groups_reload(void) {
	struct map_session_data* sd = NULL;
	struct s_mapiterator* iter;

	do_final_pc_groups();
	do_init_pc_groups();
	
	/* refresh online users permissions */
	iter = mapit_getallusers();
	for (sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC*)mapit_next(iter))	{
		pc_group_pc_load(sd);
	}
	mapit_free(iter);
}
Exemple #7
0
// 情報所得失敗(そのIDのキャラを全部未所属にする)
int guild_recv_noinfo(int guild_id)
{
	struct map_session_data *sd;
	struct s_mapiterator* iter;

	iter = mapit_getallusers();
	for( sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC*)mapit_next(iter) )
	{
		if( sd->status.guild_id == guild_id )
			sd->status.guild_id = 0; // erase guild
	}
	mapit_free(iter);

	return 0;
}
Exemple #8
0
// unused
int send_usercount_tochar(int tid, unsigned int tick, int id, int data)
{
	int count = 0;
	struct s_mapiterator* iter;

	chrif_check(-1);

	iter = mapit_getallusers();
	for( mapit_first(iter); mapit_exists(iter); mapit_next(iter) )
		count++;
	mapit_free(iter);

	WFIFOHEAD(char_fd,4);
	WFIFOW(char_fd,0) = 0x2afe;
	WFIFOW(char_fd,2) = count;
	WFIFOSET(char_fd,4);
	return 0;
}
Exemple #9
0
int battleground_countlogin(struct map_session_data *sd, bool check_bat_room)
{
	int c = 0, m = map_mapname2mapid("bat_room");
	struct map_session_data* pl_sd;
	struct s_mapiterator* iter;
	nullpo_ret(sd);

	iter = mapit_getallusers();
	for( pl_sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC*)mapit_next(iter) )
	{
		if( !(pl_sd->qd || map[pl_sd->bl.m].flag.battleground || (check_bat_room && pl_sd->bl.m == m)) )
			continue;
		if( session[sd->fd]->client_addr == session[pl_sd->fd]->client_addr )
			c++;
	}
	mapit_free(iter);
	return c;
}
Exemple #10
0
/*==========================================
 * Reloads the instance in runtime (reloadscript)
 *------------------------------------------*/
void do_reload_instance(void)
{
	struct instance_data *im;
	struct instance_db *db;
	struct s_mapiterator* iter;
	struct map_session_data *sd;
	int i;

	for( i = 1; i < MAX_INSTANCE_DATA; i++ ) {
		im = &instance_data[i];
		if(!im->cnt_map)
			continue;
		else {
			// First we load the NPCs again
			instance_addnpc(im);

			// Create new keep timer
			if((db = instance_searchtype_db(im->type)) != NULL)
				im->keep_limit = (unsigned int)time(NULL) + db->limit;
		}
	}

	// Reset player to instance beginning
	iter = mapit_getallusers();
	for( sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC*)mapit_next(iter) )
		if(sd && map[sd->bl.m].instance_id) {
			struct party_data *p;
			if(!(p = party_search(sd->status.party_id)) || p->instance_id != map[sd->bl.m].instance_id) // Someone not in party is on instance map
				continue;
			im = &instance_data[p->instance_id];
			if((db = instance_searchtype_db(im->type)) != NULL && !instance_enter(sd,db->name)) { // All good
				clif_displaymessage(sd->fd, msg_txt(sd,515)); // Instance has been reloaded
				instance_reqinfo(sd,p->instance_id);
			} else // Something went wrong
				ShowError("do_reload_instance: Error setting character at instance start: character_id=%d instance=%s.\n",sd->status.char_id,db->name);
		}
	mapit_free(iter);
}
Exemple #11
0
// ギルドエンブレム変更通知
int guild_emblem_changed(int len,int guild_id,int emblem_id,const char *data)
{
	int i;
	struct map_session_data *sd;
	struct guild *g=guild_search(guild_id);
	if(g==NULL)
		return 0;

	memcpy(g->emblem_data,data,len);
	g->emblem_len=len;
	g->emblem_id=emblem_id;

	for(i=0;i<g->max_member;i++){
		if((sd=g->member[i].sd)!=NULL){
			sd->guild_emblem_id=emblem_id;
			clif_guild_belonginfo(sd,g);
			clif_guild_emblem(sd,g);
			clif_guild_emblem_area(&sd->bl);
		}
	}
	{// update guardians (mobs)
		DBIterator* iter = db_iterator(castle_db);
		struct guild_castle* gc;
		for( gc = (struct guild_castle*)dbi_first(iter) ; dbi_exists(iter); gc = (struct guild_castle*)dbi_next(iter) )
		{
			if( gc->guild_id != guild_id )
				continue;
			// update permanent guardians
			for( i = 0; i < ARRAYLENGTH(gc->guardian); ++i )
			{
				TBL_MOB* md = (gc->guardian[i].id ? map_id2md(gc->guardian[i].id) : NULL);
				if( md == NULL || md->guardian_data == NULL )
					continue;
				md->guardian_data->emblem_id = emblem_id;
				clif_guild_emblem_area(&md->bl);
			}
			// update temporary guardians
			for( i = 0; i < gc->temp_guardians_max; ++i )
			{
				TBL_MOB* md = (gc->temp_guardians[i] ? map_id2md(gc->temp_guardians[i]) : NULL);
				if( md == NULL || md->guardian_data == NULL )
					continue;
				md->guardian_data->emblem_id = emblem_id;
				clif_guild_emblem_area(&md->bl);
			}
		}
		dbi_destroy(iter);
	}
	{// update npcs (flags or other npcs that used flagemblem to attach to this guild)
		// TODO this is not efficient [FlavioJS]
		struct s_mapiterator* iter = mapit_geteachnpc();
		TBL_NPC* nd;
		for( nd = (TBL_NPC*)mapit_first(iter) ; mapit_exists(iter); nd = (TBL_NPC*)mapit_next(iter) )
		{
			if( nd->subtype != SCRIPT || nd->u.scr.guild_id != guild_id )
				continue;
			clif_guild_emblem_area(&nd->bl);
		}
		mapit_free(iter);
	}
	return 0;
}
Exemple #12
0
void channel_message(struct map_session_data *sd, const char* channel, const char* message)
{
	struct channel_data *cd;
	char output[CHAT_SIZE_MAX];
	struct map_session_data *p_sd;

	if( !sd || !message || !*message || strlen(message) < 1 )
		return;

	if( (cd = (struct channel_data *)strdb_get(channel_db, channel)) == NULL )
	{
		clif_displaymessage(sd->fd, msg_txt(805));
		clif_displaymessage(sd->fd, msg_txt(815));
		return;
	}

	if( channel_slot_get(sd,cd) < 0 )
	{
		clif_displaymessage(sd->fd, msg_txt(816));
		return;
	}

	if( message[0] == '|' && strlen(message) >= 4 && message[3] == '.' )
		message += 3;

	if( message[0] == '.' )
	{ // Channel commands
		size_t len = strlen(message);
		char* option_text;

		if( !strncasecmp(message, ".item ", 6) && len > 0 && cd->type == CHN_VENDING && server_channel[CHN_VENDING] && vendingbot_timer < gettick() )
		{
			struct map_session_data *pl_sd, *b_sd[MAX_SEARCH];
			struct s_mapiterator* iter;
			struct item_data *item_array[MAX_SEARCH];
			int total[MAX_SEARCH], amount[MAX_SEARCH];
			unsigned int MinPrice[MAX_SEARCH], MaxPrice[MAX_SEARCH];
			int i, j, count = 1;

			option_text = (char *)message + 6;

			if( (item_array[0] = itemdb_exists(atoi(option_text))) == NULL )
				count = itemdb_searchname_array(item_array, MAX_SEARCH, option_text);

			if( count < 1 )
			{
				clif_displaymessage(sd->fd, msg_txt(19));
				return;
			}

			if( count > MAX_SEARCH ) count = MAX_SEARCH;
			for( i = 0; i < MAX_SEARCH; i++ )
			{
				total[i] = amount[i] = MaxPrice[i] = 0;
				MinPrice[i] = battle_config.vending_max_value + 1;
				b_sd[i] = NULL;
			}

			iter = mapit_getallusers();
			for( pl_sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC*)mapit_next(iter) )
			{
				if( !pl_sd->vender_id )
					continue;

				for( i = 0; i < pl_sd->vend_num; i++ )
				{ // Searching in the Vending List
					for( j = 0; j < count; j++ )
					{ // Compares with each search result
						if( pl_sd->status.cart[pl_sd->vending[i].index].nameid != item_array[j]->nameid )
							continue;

						amount[j] += pl_sd->vending[i].amount;
						total[j]++;

						if( pl_sd->vending[i].value < MinPrice[j] )
						{ // Best Price
							MinPrice[j] = pl_sd->vending[i].value;
							b_sd[j] = pl_sd;
						}
						if( pl_sd->vending[i].value > MaxPrice[j] )
							MaxPrice[j] = pl_sd->vending[i].value;
					}
				}
			}
			mapit_free(iter);

			for( i = 0; i < count; i++ )
			{
				if( total[i] > 0 && b_sd[i] != NULL )
				{
					sprintf(output, msg_txt(829), server_channel[CHN_VENDING]->name, item_array[i]->jname, MinPrice[i], b_sd[i]->status.name, map[b_sd[i]->bl.m].name, b_sd[i]->bl.x, b_sd[i]->bl.y, MaxPrice[i], total[i], amount[i]);
					clif_channel_message(cd, output, -1);
				}
			}
			vendingbot_timer = gettick() + 5000; // 5 Seconds Protection from flood
		}
		else if( !strncasecmp(message, ".exit", 5) )
			channel_leave(sd, cd->name, true);
		else if( cd->op != sd->bl.id && pc_has_permission(sd,PC_PERM_CHANNEL_OPERATOR) )
			return;
		else if( !strncasecmp(message, ".invite ", 8) && len > 11 )
		{ // Invite a User to the Channel
			option_text = (char *)message + 8;
			if( (p_sd = map_nick2sd(option_text)) == NULL )
				clif_displaymessage(sd->fd, msg_txt(893));
			else if( p_sd == sd )
				clif_displaymessage(sd->fd, msg_txt(894));
			else if( p_sd->state.noask )
				clif_displaymessage(sd->fd, msg_txt(700));
			else if( channel_slot_get(p_sd, cd) >= 0 )
				clif_displaymessage(sd->fd, msg_txt(895));
			else if( p_sd->channel_invite_timer != INVALID_TIMER )
				clif_displaymessage(sd->fd, msg_txt(897));
			else
			{
				sprintf(output, msg_txt(896), cd->name, sd->status.name, p_sd->status.name);
				clif_channel_message(cd, output, -1); // Notify about the invitation to the Channel

				sprintf(output, msg_txt(898), sd->status.name, cd->name);
				clif_disp_onlyself(p_sd, output, strlen(output)); // Notify Player

				p_sd->channel_invite_timer = add_timer(gettick() + 30000, channel_invite_timer, p_sd->bl.id, (intptr_t)aStrdup(cd->name));
			}
		}
		else if( !strncasecmp(message, ".kick ", 6) && len > 9 )
		{ // Kick Users
			option_text = (char *)message + 6;
			if( (p_sd = map_nick2sd(option_text)) == NULL || channel_slot_get(p_sd, cd) < 0 )
				clif_displaymessage(sd->fd, msg_txt(817));
			else if( p_sd == sd )
				clif_displaymessage(sd->fd, msg_txt(818));
			else
			{
				channel_leave(p_sd, cd->name, false);
				sprintf(output, msg_txt(819), cd->name, p_sd->status.name);
				clif_channel_message(cd, output, -1);
				p_sd->canjoinchn_tick = gettick() + 10000;
			}
		}
		else if( !strncasecmp(message, ".color ", 7) && len > 7 )
		{ // Set Chat Room Color
			short color = atoi(message + 7);
			if( color < 1 || color > 39 )
				clif_displaymessage(sd->fd, msg_txt(830));
			else
			{
				cd->color = channel_color[color - 1];
				sprintf(output, msg_txt(831), cd->name);
				clif_channel_message(cd, output, -1);
			}
		}
		else if( !strncasecmp(message, ".op ", 4) && len > 7 )
		{
			option_text = (char *)message + 4;
			if( cd->type != CHN_USER )
				clif_displaymessage(sd->fd, msg_txt(875));
			else if( (p_sd = map_nick2sd(option_text)) == NULL || channel_slot_get(p_sd, cd) < 0 )
				clif_displaymessage(sd->fd, msg_txt(817));
			else if( p_sd == sd )
				clif_displaymessage(sd->fd, msg_txt(832));
			else
			{
				cd->op = p_sd->bl.id;
				sprintf(output, msg_txt(833), cd->name, p_sd->status.name);
				clif_channel_message(cd, output, -1);
			}
		}
		else if( !strncasecmp(message, ".pass ", 6) && len > 6 )
		{
			option_text = trim((char *)message + 6);
			if( cd->type != CHN_USER )
				clif_displaymessage(sd->fd, msg_txt(875));
			else if( !strcmpi(option_text, "off") )
			{
				memset(cd->pass, '\0', sizeof(cd->pass));
				sprintf(output, msg_txt(834), cd->name);
				clif_channel_message(cd, output, -1);
			}
			else if( strlen(option_text) > 1 && strlen(option_text) < NAME_LENGTH )
			{
				safestrncpy(cd->pass, option_text, sizeof(cd->pass));
				sprintf(output, msg_txt(835), cd->name);
				clif_channel_message(cd, output, -1);
			}
			else
				clif_displaymessage(sd->fd, msg_txt(836));
		}
		else if( !strncasecmp(message, ".close", 6) )
		{
			if( cd->type != CHN_USER )
				clif_displaymessage(sd->fd, msg_txt(875));
			else
				channel_close(cd);
		}
		else if( !strncasecmp(message, ".list", 6) )
		{
			DBIterator* iter = db_iterator(cd->users_db);
			clif_displaymessage(sd->fd, msg_txt(837));
			for( p_sd = (struct map_session_data *)dbi_first(iter); dbi_exists(iter); p_sd = (struct map_session_data *)dbi_next(iter) )
				clif_displaymessage(sd->fd, p_sd->status.name);
			dbi_destroy(iter);
			clif_displaymessage(sd->fd, msg_txt(838));
		}
		else if( !strncasecmp(message, ".help", 5) )
		{ // Command List
			clif_displaymessage(sd->fd, msg_txt(839));
			clif_displaymessage(sd->fd, msg_txt(840));
			clif_displaymessage(sd->fd, msg_txt(841));
			clif_displaymessage(sd->fd, msg_txt(842));
			clif_displaymessage(sd->fd, msg_txt(843));
			clif_displaymessage(sd->fd, msg_txt(844));
			clif_displaymessage(sd->fd, msg_txt(845));
			clif_displaymessage(sd->fd, msg_txt(846));
		}
		else
			clif_displaymessage(sd->fd, msg_txt(847));

		return;
	}

	snprintf(output, sizeof(output), "%s : [%s] %s", cd->name, sd->status.name, message);
	clif_channel_message(cd, output, -1);
}
Exemple #13
0
void searchstore_query(struct map_session_data* sd, unsigned char type, unsigned int min_price, unsigned int max_price, const unsigned short* itemlist, unsigned int item_count, const unsigned short* cardlist, unsigned int card_count)
{
	unsigned int i;
	struct map_session_data* pl_sd;
	struct s_mapiterator* iter;
	struct s_search_store_search s;
	searchstore_searchall_t store_searchall;
	time_t querytime;

	if( !battle_config.feature_search_stores )
	{
		return;
	}

	if( !sd->searchstore.open )
	{
		return;
	}

	if( ( store_searchall = searchstore_getsearchallfunc(type) ) == NULL )
	{
		ShowError("searchstore_query: Unknown search type %u (account_id=%d).\n", (unsigned int)type, sd->bl.id);
		return;
	}

	time(&querytime);

	if( sd->searchstore.nextquerytime > querytime )
	{
		clif_search_store_info_failed(sd, SSI_FAILED_LIMIT_SEARCH_TIME);
		return;
	}

	if( !sd->searchstore.uses )
	{
		clif_search_store_info_failed(sd, SSI_FAILED_SEARCH_CNT);
		return;
	}

	// validate lists
	for( i = 0; i < item_count; i++ )
	{
		if( !itemdb_exists(itemlist[i]) )
		{
			ShowWarning("searchstore_query: Client resolved item %hu is not known.\n", itemlist[i]);
			clif_search_store_info_failed(sd, SSI_FAILED_NOTHING_SEARCH_ITEM);
			return;
		}
	}
	for( i = 0; i < card_count; i++ )
	{
		if( !itemdb_exists(cardlist[i]) )
		{
			ShowWarning("searchstore_query: Client resolved card %hu is not known.\n", cardlist[i]);
			clif_search_store_info_failed(sd, SSI_FAILED_NOTHING_SEARCH_ITEM);
			return;
		}
	}

	if( max_price < min_price )
	{
		swap(min_price, max_price);
	}

	sd->searchstore.uses--;
	sd->searchstore.type = type;
	sd->searchstore.nextquerytime = querytime+battle_config.searchstore_querydelay;

	// drop previous results
	searchstore_clear(sd);

	// allocate max. amount of results
	sd->searchstore.items = (struct s_search_store_info_item*)aMalloc(sizeof(struct s_search_store_info_item)*battle_config.searchstore_maxresults);

	// search
	s.search_sd  = sd;
	s.itemlist   = itemlist;
	s.cardlist   = cardlist;
	s.item_count = item_count;
	s.card_count = card_count;
	s.min_price  = min_price;
	s.max_price  = max_price;
	iter         = mapit_geteachpc();

	for( pl_sd = (struct map_session_data*)mapit_first(iter); mapit_exists(iter);  pl_sd = (struct map_session_data*)mapit_next(iter) )
	{
		if( sd == pl_sd )
		{// skip own shop, if any
			continue;
		}

		if( !store_searchall(pl_sd, &s) )
		{// exceeded result size
			clif_search_store_info_failed(sd, SSI_FAILED_OVER_MAXCOUNT);
			break;
		}
	}

	mapit_free(iter);

	if( sd->searchstore.count )
	{
		// reclaim unused memory
		sd->searchstore.items = (struct s_search_store_info_item*)aRealloc(sd->searchstore.items, sizeof(struct s_search_store_info_item)*sd->searchstore.count);

		// present results
		clif_search_store_info_ack(sd);

		// one page displayed
		sd->searchstore.pages++;
	}
	else
	{
		// cleanup
		searchstore_clear(sd);

		// update uses
		clif_search_store_info_ack(sd);

		// notify of failure
		clif_search_store_info_failed(sd, SSI_FAILED_NOTHING_SEARCH_ITEM);
	}
}