Exemple #1
0
void channel_close(struct channel_data *cd)
{
	int j;
	char output[128];
	struct map_session_data *pl_sd;
	DBIterator* iter;

	if( cd == NULL || cd->type != CHN_USER )
		return;
	
	sprintf(output, msg_txt(804), cd->name);
	clif_channel_message(cd, output, -1);

	iter = db_iterator(cd->users_db);
	for( pl_sd = (struct map_session_data *)dbi_first(iter); dbi_exists(iter); pl_sd = (struct map_session_data *)dbi_next(iter) )
	{
		idb_remove(cd->users_db, pl_sd->bl.id);
		ARR_FIND(0, MAX_USER_CHANNELS, j, pl_sd->cd[j] == cd);
		if( j == MAX_USER_CHANNELS )
			continue;
		
		pl_sd->cd[j] = NULL;
	}
	dbi_destroy(iter);
	
	db_destroy(cd->users_db);
	strdb_remove(channel_db, cd->name);
}
Exemple #2
0
bool channel_create(struct map_session_data *sd, const char* name, const char* pass, short type, short color, int op)
{
	struct channel_data *cd;
	int i = 0;

	if( !name || strlen(name) < 2 || strlen(name) >= NAME_LENGTH || name[0] != '#' )
	{
		if( sd ) clif_displaymessage(sd->fd, msg_txt(801));
		return false;
	}
	if( type == CHN_USER && !sd )
		return false; // Operator required for user channels
	if( sd && type == CHN_USER && (i = channel_slot_free(sd)) < 0 )
	{
		clif_displaymessage(sd->fd, msg_txt(800));
		return false;
	}
	if( (cd = (struct channel_data *)strdb_get(channel_db, name)) != NULL )
	{
		if( sd ) clif_displaymessage(sd->fd, msg_txt(802));
		return false; // Already exists
	}

	CREATE(cd, struct channel_data, 1);
	cd->channel_id = ++channel_counter;
	safestrncpy(cd->name, name, sizeof(cd->name));
	safestrncpy(cd->pass, pass, sizeof(cd->pass));
	cd->type = type;
	cd->color = channel_color[cap_value(color,0,38)];
	cd->users = 0;
	cd->op = 0;
	cd->users_db = idb_alloc(DB_OPT_BASE);

	if( type == CHN_USER )
	{
		char output[128];
		sprintf(output, msg_txt(803), cd->name, sd->status.name);
		
		sd->cd[i] = cd;
		cd->op = sd->bl.id;
		idb_put(cd->users_db, sd->bl.id, sd);
		cd->users++;
		clif_channel_message(cd, output, -1);
	}
	else if( type < CHN_USER )
	{
		server_channel[type] = cd; // Quick access to main channels
		ShowInfo("Channel System : New channel %s created.\n", cd->name);
	}
	else
		cd->op = op; // Server Channel

	strdb_put(channel_db, cd->name, cd);
	return true;
}
Exemple #3
0
int channel_invite_timer(int tid, unsigned int tick, int id, intptr_t data)
{
	struct channel_data *cd;
	struct map_session_data* sd = map_id2sd(id);
	char output[CHAT_SIZE_MAX];
	char *name = (char *)data;

	if( sd && (cd = (struct channel_data *)strdb_get(channel_db, name)) != NULL )
	{
		sprintf(output, msg_txt(701), cd->name, sd->status.name);
		clif_channel_message(cd, output, -1);
	}

	if( sd )
	{
		clif_disp_onlyself(sd, msg_txt(702), strlen(msg_txt(702)));
		sd->channel_invite_timer = INVALID_TIMER;
	}

	if( name ) aFree(name);
	return 1;
}
/*==========================================
 * Open shop
 * data := {<index>.w <amount>.w <value>.l}[count]
 *------------------------------------------*/
void vending_openvending(struct map_session_data* sd, const char* message, bool flag, const uint8* data, int count)
{
	int i, j, char_id;
	int vending_skill_lvl;
	nullpo_retv(sd);

	if( !flag ) // cancelled
		return; // nothing to do

	if (pc_istrading(sd))
		return; // 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, 0, 0);
		return;
	}

	// 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, 0, 0);
		return;
	}

	if((sd->bl.m == map_mapname2mapid("mercadores") 
 	 && (
	((sd->bl.x != 65) && (sd->bl.x != 74) && (sd->bl.x != 85) && (sd->bl.x != 94)
	&& (sd->bl.x != 34) && (sd->bl.x != 25) && (sd->bl.x != 14) && (sd->bl.x != 5)
	&& (sd->bl.x != 44) && (sd->bl.x != 55))
 	))) {
	clif_displaymessage(sd->fd,"Você não pode abrir lojas no meio da Sala."); 
	return; 
	}

	// 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 // Can't Trade Account bound items
		||  ( sd->status.cart[index].card[0] == CARD0_CREATE && (char_id = MakeDWord(sd->status.cart[index].card[2],sd->status.cart[index].card[3])) > 0 && ((battle_config.bg_reserved_char_id && char_id == battle_config.bg_reserved_char_id) || (battle_config.ancient_reserved_char_id && char_id == battle_config.ancient_reserved_char_id)) )
		||  !itemdb_cantrade(&sd->status.cart[index], pc_isGM(sd), pc_isGM(sd)) ) // untradeable item
			continue;

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

		i++; // item successfully added
	}

	if( i != j )
		clif_displaymessage (sd->fd, msg_txt(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, 0, 0); // custom reply packet
		return;
	}

	sd->state.vending = true;
	sd->vender_id = vending_getuid();
	sd->vend_num = i;
	safestrncpy(sd->message, message, MESSAGE_SIZE);

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

	if( battle_config.channel_announces&0x10 )
	{
		char chat_message[256];
		sprintf(chat_message, msg_txt(820), vending_chat_nick, sd->status.name, sd->message, map[sd->bl.m].name, sd->bl.x, sd->bl.y);
		clif_channel_message(server_channel[CHN_VENDING], chat_message, 27);
	}

	if( map[sd->bl.m].flag.vending_cell )
		map_setcell(sd->bl.m, sd->bl.x, sd->bl.y, CELL_NOBOARDS, false);
}
Exemple #5
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 #6
0
void channel_leave(struct map_session_data *sd, const char* name, bool msg)
{
	struct channel_data *cd;
	char output[128];
	int i;

	if( (cd = (struct channel_data *)strdb_get(channel_db, name)) == NULL )
		return;
	if( (i = channel_slot_get(sd, cd)) != -1 )
	{
		sd->cd[i] = NULL;
		clif_displaymessage(sd->fd, msg_txt(809));
		if( cd->type != CHN_USER && msg )
		{
			switch( cd->type )
			{
				case CHN_MAIN: sd->channels &= ~1; break;
				case CHN_VENDING: sd->channels &= ~2; break;
				case CHN_BATTLEGROUND: sd->channels &= ~4; break;
				case CHN_GAMEMASTER: sd->channels &= ~8; break;
			}
			pc_setaccountreg(sd, "#CHANNEL_CONF", sd->channels);
		}
	}

	if( idb_get(cd->users_db, sd->bl.id) != NULL )
	{
		idb_remove(cd->users_db, sd->bl.id);
		cd->users--;
		if( msg )
		{
			sprintf(output, msg_txt(810), cd->name, sd->status.name);
			clif_channel_message(cd, output, -1);
		}
	}

	if( cd->type != CHN_USER )
		return;

	if( cd->users < 1 )
	{ // No more users in the channel
		channel_close(cd);
		return;
	}

	if( sd->bl.id == cd->op )
	{ // Select another Operator
		struct map_session_data *pl_sd;
		DBIterator* iter = db_iterator(cd->users_db);

		cd->op = 0;
		if( (pl_sd = (struct map_session_data *)dbi_first(iter)) != NULL && dbi_exists(iter) )
		{
			cd->op = pl_sd->bl.id;
			sprintf(output, msg_txt(811), cd->name, pl_sd->status.name);
			clif_channel_message(cd, output, -1);
		}
		dbi_destroy(iter);
	}

	if( cd->users <= 0 )
	{
		ShowWarning("Channel '%s' with no users reporting %d users. Destroying it!!.\n", cd->name, cd->users);
		channel_close(cd);
	}
}
Exemple #7
0
void channel_join(struct map_session_data *sd, const char* name, const char* pass, bool invite)
{
	char output[256];
	struct channel_data *cd;
	int i = 0;
	
	if( !name || strlen(name) < 2 || strlen(name) >= NAME_LENGTH || name[0] != '#' )
	{
		clif_displaymessage(sd->fd, msg_txt(801));
		return;
	}

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

	if( channel_slot_get(sd, cd) != -1 )
	{
		clif_displaymessage(sd->fd, msg_txt(806));
		return;
	}

	if( (i = channel_slot_free(sd)) < 0 )
	{
		clif_displaymessage(sd->fd, msg_txt(800));
		return;
	}

	if( !invite )
	{
		if( cd->pass[0] && strcmp(cd->pass, pass) != 0 )
		{ // Check password only if not invited
			clif_displaymessage(sd->fd, msg_txt(808));
			return;
		}
		if( cd->type == CHN_GAMEMASTER && pc_has_permission(sd,PC_PERM_CHANNEL_OPERATOR) )
		{
			clif_displaymessage(sd->fd, msg_txt(703));
			return;
		}
	}

	if( battle_config.channel_announce_join )
	{
		sprintf(output, msg_txt(803), cd->name, sd->status.name);
		clif_channel_message(cd, output, -1);
	}

	sprintf(output, msg_txt(710), sd->status.name, cd->name);
	clif_wis_message(sd->fd, cd->name, output, strlen(output) + 1);

	// Joining Channel
	sd->cd[i] = cd;
	sd->canjoinchn_tick = gettick() + 10000;
	idb_put(cd->users_db, sd->bl.id, sd);
	cd->users++;

	if( sd->channel_invite_timer != INVALID_TIMER )
	{
		const struct TimerData * td = get_timer(sd->channel_invite_timer);
		char *name = td ? (char *)td->data : NULL;

		if( strcmp(name, cd->name) == 0 )
			channel_invite_clear(sd); // Invitation removed as the user joined the channel
	}

	if( cd->type != CHN_USER )
	{
		switch( cd->type )
		{
			case CHN_MAIN: sd->channels |= 1; break;
			case CHN_VENDING: sd->channels |= 2; break;
			case CHN_BATTLEGROUND: sd->channels |= 4; break;
			case CHN_GAMEMASTER: sd->channels |= 8; break;
		}
		pc_setaccountreg(sd, "#CHANNEL_CONF", sd->channels);
	}
}