Beispiel #1
0
/**
 * Make a player leave a type of channel
 * @param sd: Player data
 * @param type: Quit type (1 - Quit guild channel, 2 - Quit ally channel, 4 - Quit map channel, 8 - Quit all users in channel)
 * @return
 *  0: Success
 * -1: Invalid player
 */
int channel_pcquit(struct map_session_data *sd, int type){
	int i;

	//On closing state we could have clean all chan by sd but pcquit is more used to free unit when
	//he quit a map_server, not call in map_quit cause we need to cleanup when we switch map-server as well
	if(!sd) return -1;

	// Leave all chat channels.
	if(type&(1|2) && channel_config.ally_tmpl.name != NULL && sd->guild){ //quit guild and ally chan
		struct guild *g = sd->guild;
		if(type&1 && channel_haspc(g->channel,sd)==1){
			channel_clean(g->channel,sd,0); //leave guild chan
		}
		if(type&2){
			for (i = 0; i < MAX_GUILDALLIANCE; i++) { //leave all alliance chan
				struct guild *ag; //allied guild
				if( g->alliance[i].guild_id && (ag = guild_search(g->alliance[i].guild_id) ) ) {
					if(channel_haspc(ag->channel,sd) == 1)
						channel_clean(ag->channel,sd,0);
					break;
				}
			}
		}
	}
	if(type&4 && channel_config.map_tmpl.name != NULL && channel_haspc(map[sd->bl.m].channel,sd)==1){ //quit map chan
		channel_clean(map[sd->bl.m].channel,sd,0);
	}
	if(type&8 && sd->channel_count ) { //quit all chan
		uint8 count = sd->channel_count;
		for( i = count-1; i >= 0; i--) { //going backward to avoid shifting
			channel_clean(sd->channels[i],sd,0);
		}
	}
	return 0;
}
Beispiel #2
0
/**
 * A player is attemting to kick a player
 * @param sd: Player data
 * @param chname: Channel name
 * @param pname: Player name to kick
 * @return 0 on success or -1 on failure
 */
int channel_pckick(struct map_session_data *sd, char *chname, char *pname) {
	struct Channel *channel;
	char output[CHAT_SIZE_MAX];
	struct map_session_data *tsd = map_nick2sd(pname,false);

	if( channel_chk(chname,NULL,1) ) {
		clif_displaymessage(sd->fd, msg_txt(sd,1405));// Channel name must start with '#'.
		return -1;
	}

	channel = channel_name2channel(chname,sd,0);
	if( !channel ) {
		sprintf(output, msg_txt(sd,1407), chname);// Channel '%s' is not available.
		clif_displaymessage(sd->fd, output);
		return -1;
	}

	if (!tsd) {
		clif_displaymessage(sd->fd, msg_txt(sd,3));
		return -1;
	}

	if( !pc_has_permission(sd, PC_PERM_CHANNEL_ADMIN) ) {
		if (channel->char_id != sd->status.char_id) {
			sprintf(output, msg_txt(sd,1412), chname);// You're not the owner of channel '%s'.
			clif_displaymessage(sd->fd, output);
		} else if (!channel_config.private_channel.kick) {
			sprintf(output, msg_txt(sd,766), chname); // You cannot kick a player from channel '%s'.
			clif_displaymessage(sd->fd, output);
		}
		return -1;
	}

	if (channel_pc_haschan(sd, channel) < 0) {
		sprintf(output, msg_txt(sd,1425), chname); // You're not part of the '%s' channel.
		clif_displaymessage(sd->fd, output);
		return -1;
	}

	if (channel->char_id == sd->status.char_id) {
		clif_displaymessage(sd->fd, msg_txt(sd, 767)); // You're not allowed to kick a player.
		return -1;
	}

	if( !channel_config.closing && (channel->opt & CHAN_OPT_ANNOUNCE_LEAVE) ) {
		safesnprintf(output, CHAT_SIZE_MAX, msg_txt(sd,768), channel->alias, tsd->status.name); // %s %s has been kicked.
		clif_channel_msg(channel,output,channel->color);
	}

	switch(channel->type){
		case CHAN_TYPE_ALLY: channel_pcquit(tsd,3); break;
		case CHAN_TYPE_MAP: channel_pcquit(tsd,4); break;
		default: //private and public atm
			channel_clean(channel,tsd,0);
	}

	return 1;
}
Beispiel #3
0
/**
 * A player is attempting to leave a channel
 * @param sd: Player data
 * @param chname: Channel name
 * @return 0 on success or -1 on failure
 */
int channel_pcleave(struct map_session_data *sd, char *chname){
	struct Channel *channel;
	char output[CHAT_SIZE_MAX];

	if(!sd || !chname)
		return 0;

	if( channel_chk(chname,NULL,1) ) {
		clif_displaymessage(sd->fd, msg_txt(sd,1405));// Channel name must start with '#'.
		return -1;
	}

	channel = channel_name2channel(chname,sd,0);
	if(channel_pc_haschan(sd,channel)<0){
		sprintf(output, msg_txt(sd,1425),chname);// You're not part of the '%s' channel.
		clif_displaymessage(sd->fd, output);
		return -2; //channel doesn't exist or player don't have it
	}

	if (!(channel->opt&CHAN_OPT_CAN_LEAVE)) {
		sprintf(output, msg_txt(sd,762), chname); // You cannot leave channel '%s'.
		clif_displaymessage(sd->fd, output);
		return -1;
	}

	if( !channel_config.closing && (channel->opt & CHAN_OPT_ANNOUNCE_LEAVE) ) {
		safesnprintf(output, CHAT_SIZE_MAX, msg_txt(sd,763), channel->alias, sd->status.name); // %s %s left.
		clif_channel_msg(channel,output,channel->color);
	}
	switch(channel->type){
	case CHAN_TYPE_ALLY: channel_pcquit(sd,3); break;
	case CHAN_TYPE_MAP: channel_pcquit(sd,4); break;
	default: //private and public atm
		channel_clean(channel,sd,0);
	}

	sprintf(output, msg_txt(sd,1426),chname); // You've left the '%s' channel.
	clif_displaymessage(sd->fd, output);
	return 0;
}
Beispiel #4
0
/**
 * Delete a channel
 * - Checks if there is any user in channel and make them quit
 * @param channel: Channel data
 * @param force: Forcefully remove channel
 * @return
 *   0: Success
 *  -1: Invalid channel
 *  -2: Can't delete now
 */
int channel_delete(struct Channel *channel, bool force) {
	if(!channel)
		return -1;
	if(!force && channel->type == CHAN_TYPE_PUBLIC && runflag == MAPSERVER_ST_RUNNING) //only delete those serv stop
		return -2;
	if( db_size(channel->users)) {
		struct map_session_data *sd;
		DBIterator *iter = db_iterator(channel->users);
		for( sd = (struct map_session_data *)dbi_first(iter); dbi_exists(iter); sd = (struct map_session_data *)dbi_next(iter) ) { //for all users
			channel_clean(channel,sd,1); //make all quit
		}
		dbi_destroy(iter);
	}
	if (battle_config.etc_log)
		ShowInfo("Deleting channel %s alias %s type %d\n",channel->name,channel->alias,channel->type);
	db_destroy(channel->users);
	db_destroy(channel->banned);
	if (channel->groups)
		aFree(channel->groups);
	channel->groups = NULL;
	channel->group_count = 0;
	switch(channel->type){
	case CHAN_TYPE_MAP:
		map_getmapdata(channel->m)->channel = NULL;
		aFree(channel);
		break;
	case CHAN_TYPE_ALLY: {
		struct guild *g = guild_search(channel->gid);
		if(g) g->channel = NULL;
		aFree(channel);
		break;
	}
	default:
		strdb_remove(channel_db, channel->name);
		break;
	}
	return 0;
}
Beispiel #5
0
/**
 * A player is attempting to modify the banlist
 * @param sd: Player data
 * @param chname: Channel name
 * @param pname: Player to ban or unban
 * @param flag: Ban options (0 - Ban, 1 - Unban, 2 - Unban all, 3 - Ban list)
 * @return 0 on success or -1 on failure
 */
int channel_pcban(struct map_session_data *sd, char *chname, char *pname, int flag){
	struct Channel *channel;
	char output[CHAT_SIZE_MAX];
	struct map_session_data *tsd = map_nick2sd(pname,false);

	if( channel_chk(chname,NULL,1) ) {
		clif_displaymessage(sd->fd, msg_txt(sd,1405));// Channel name must start with '#'.
		return -1;
	}

	channel = channel_name2channel(chname,sd,0);
	if( !channel ) {
		sprintf(output, msg_txt(sd,1407), chname);// Channel '%s' is not available.
		clif_displaymessage(sd->fd, output);
		return -1;
	}

	if( !pc_has_permission(sd, PC_PERM_CHANNEL_ADMIN) ) {
		if (channel->char_id != sd->status.char_id) {
			sprintf(output, msg_txt(sd,1412), chname);// You're not the owner of channel '%s'.
			clif_displaymessage(sd->fd, output);
			return -1;
		} else if (!channel_config.private_channel.ban) {
			sprintf(output, msg_txt(sd,765), chname); // You're not allowed to ban a player.
			clif_displaymessage(sd->fd, output);
			return -1;
		}
	}

	if(flag != 2 && flag != 3){
		char banned;
		if(!tsd || pc_has_permission(tsd, PC_PERM_CHANNEL_ADMIN) ) {
			sprintf(output, msg_txt(sd,1464), pname);// Ban failed for player '%s'.
			clif_displaymessage(sd->fd, output);
			return -1;
		}

		banned = channel_haspcbanned(channel,tsd);
		if(!flag &&  banned==1) {
			sprintf(output, msg_txt(sd,1465), tsd->status.name);// Player '%s' is already banned from this channel.
			clif_displaymessage(sd->fd, output);
			return -1;
		}
		else if(flag==1 && banned==0) {
			sprintf(output, msg_txt(sd,1440), tsd->status.name);// Player '%s' is not banned from this channel.
			clif_displaymessage(sd->fd, output);
			return -1;
		}
	}
	else {
		if( !db_size(channel->banned) ) {
			sprintf(output, msg_txt(sd,1439), chname);// Channel '%s' contains no banned players.
			clif_displaymessage(sd->fd, output);
			return 0;
		}
	}

	//let properly alter the list now
	switch(flag){
	case 0: {
		struct chan_banentry *cbe;
		if (!tsd)
			return -1;
		CREATE(cbe, struct chan_banentry, 1);
		cbe->char_id = tsd->status.char_id;
		strcpy(cbe->char_name,tsd->status.name);
		idb_put(channel->banned, tsd->status.char_id, cbe);
		channel_clean(channel,tsd,0);
		sprintf(output, msg_txt(sd,1437),tsd->status.name,chname); // Player '%s' is banned from the '%s' channel.
		break;
		}
	case 1:
		if (!tsd)
			return -1;
		idb_remove(channel->banned, tsd->status.char_id);
		sprintf(output, msg_txt(sd,1441),tsd->status.name,chname); // Player '%s' is unbanned from the '%s' channel.
		break;
	case 2:
		db_clear(channel->banned);
		sprintf(output, msg_txt(sd,1442),chname); // Cleared all bans from the '%s' channel.
		break;
	case 3: {
		DBIterator *iter = db_iterator(channel->banned);
		struct chan_banentry *cbe;
		sprintf(output, msg_txt(sd,1443), channel->name);// ---- '#%s' Ban List:
		clif_displaymessage(sd->fd, output);
		for( cbe = (struct chan_banentry *)dbi_first(iter); dbi_exists(iter); cbe = (struct chan_banentry *)dbi_next(iter) ) { //for all users
			if (cbe->char_name[0])
				sprintf(output, "%d: %s",cbe->char_id,cbe->char_name);
			else
				sprintf(output, "%d: ****",cbe->char_id);
			clif_displaymessage(sd->fd, output);
		}
		dbi_destroy(iter);
		}
		return 0;
	}
	clif_displaymessage(sd->fd, output);

	return 0;
}