Esempio n. 1
0
/**
 * Joins a channel.
 *
 * Ban and password checks are performed before joining the channel.
 * If the channel is an HCS_TYPE_ALLY channel, alliance channels are automatically joined.
 *
 * @param chan     The channel to join
 * @param sd       The character
 * @param password The specified join password, if any
 * @param silent   If true, suppress the "You're now in the <x> channel" greeting message
 * @retval HCS_STATUS_OK      if the operation succeeded
 * @retval HCS_STATUS_ALREADY if the character is already in the channel
 * @retval HCS_STATUS_NOPERM  if the specified password doesn't match
 * @retval HCS_STATUS_BANNED  if the character is in the channel's ban list
 * @retval HCS_STATUS_FAIL    in case of generic error
 */
enum channel_operation_status channel_join(struct channel_data *chan, struct map_session_data *sd, const char *password, bool silent)
{
	bool stealth = false;

	nullpo_retr(HCS_STATUS_FAIL, chan);
	nullpo_retr(HCS_STATUS_FAIL, sd);
	nullpo_retr(HCS_STATUS_FAIL, password);

	if (idb_exists(chan->users, sd->status.char_id)) {
		return HCS_STATUS_ALREADY;
	}

	if (chan->password[0] != '\0' && strcmp(chan->password, password) != 0) {
		if (pc_has_permission(sd, PC_PERM_HCHSYS_ADMIN)) {
			stealth = true;
		} else {
			return HCS_STATUS_NOPERM;
		}
	}

	if (chan->banned && idb_exists(chan->banned, sd->status.account_id)) {
		return HCS_STATUS_BANNED;
	}

	if (!silent && !(chan->options&HCS_OPT_ANNOUNCE_JOIN)) {
		char output[CHAT_SIZE_MAX];
		if (chan->type == HCS_TYPE_MAP) {
			sprintf(output, msg_sd(sd,1435), chan->name, map->list[chan->m].name); // You're now in the '#%s' channel for '%s'
		} else {
			sprintf(output, msg_sd(sd,1403), chan->name); // You're now in the '%s' channel
		}
		clif->messagecolor_self(sd->fd, COLOR_DEFAULT, output);
	}

	if (chan->type == HCS_TYPE_ALLY) {
		struct guild *g = sd->guild;
		int i;
		for (i = 0; i < MAX_GUILDALLIANCE; i++) {
			struct guild *sg = NULL;
			if (g->alliance[i].opposition == 0 && g->alliance[i].guild_id && (sg = guild->search(g->alliance[i].guild_id)) != NULL) {
				if (!(sg->channel->banned && idb_exists(sg->channel->banned, sd->status.account_id))) {
					channel->join_sub(sg->channel, sd, stealth);
				}
			}
		}
	}

	channel->join_sub(chan, sd, stealth);

	return HCS_STATUS_OK;
}
Esempio n. 2
0
/**
 * Unbans a character from the given channel.
 *
 * @param chan The channel.
 * @param ssd  The source character, if any.
 * @param tsd  The target character. If no target character is specified, all characters are unbanned.
 * @retval HCS_STATUS_OK if the operation succeeded.
 * @retval HCS_STATUS_ALREADY if the target character is not banned.
 * @retval HCS_STATUS_NOPERM if the source character doesn't have enough permissions.
 * @retval HCS_STATUS_FAIL in case of generic failure.
 */
enum channel_operation_status channel_unban(struct channel_data *chan, const struct map_session_data *ssd, struct map_session_data *tsd)
{
	nullpo_retr(HCS_STATUS_FAIL, chan);

	if (ssd && chan->owner != ssd->status.char_id && !pc_has_permission(ssd, PC_PERM_HCHSYS_ADMIN))
		return HCS_STATUS_NOPERM;

	if (!chan->banned)
		return HCS_STATUS_ALREADY;

	if (!tsd) {
		// Unban all
		db_destroy(chan->banned);
		chan->banned = NULL;
		return HCS_STATUS_OK;
	}

	// Unban one
	if (!idb_exists(chan->banned, tsd->status.account_id))
		return HCS_STATUS_ALREADY;

	idb_remove(chan->banned, tsd->status.account_id);
	if (!db_size(chan->banned)) {
		db_destroy(chan->banned);
		chan->banned = NULL;
	}

	return HCS_STATUS_OK;
}
Esempio n. 3
0
/**
 * Bans a character from the given channel.
 *
 * @param chan The channel.
 * @param ssd  The source character, if any.
 * @param tsd  The target character.
 * @retval HCS_STATUS_OK if the operation succeeded.
 * @retval HCS_STATUS_ALREADY if the target character is already banned.
 * @retval HCS_STATUS_NOPERM if the source character doesn't have enough permissions.
 * @retval HCS_STATUS_FAIL in case of generic failure.
 */
enum channel_operation_status channel_ban(struct channel_data *chan, const struct map_session_data *ssd, struct map_session_data *tsd)
{
	struct channel_ban_entry *entry = NULL;

	nullpo_retr(HCS_STATUS_FAIL, chan);
	nullpo_retr(HCS_STATUS_FAIL, tsd);

	if (ssd && chan->owner != ssd->status.char_id && !pc_has_permission(ssd, PC_PERM_HCHSYS_ADMIN))
		return HCS_STATUS_NOPERM;

	if (pc_has_permission(tsd, PC_PERM_HCHSYS_ADMIN))
		return HCS_STATUS_FAIL;

	if (chan->banned && idb_exists(chan->banned, tsd->status.account_id))
		return HCS_STATUS_ALREADY;

	if (!chan->banned)
		chan->banned = idb_alloc(DB_OPT_BASE|DB_OPT_ALLOW_NULL_DATA|DB_OPT_RELEASE_DATA);

	CREATE(entry, struct channel_ban_entry, 1);
	safestrncpy(entry->name, tsd->status.name, NAME_LENGTH);
	idb_put(chan->banned, tsd->status.account_id, entry);

	channel->leave(chan, tsd);

	return HCS_STATUS_OK;
}
Esempio n. 4
0
 /**
 * Join an existing chat room.
 * @param sd : player requesting
 * @param chatid : ID of the chat room
 * @param pass : password of chat room
 * @return 0
 */
int chat_joinchat(struct map_session_data* sd, int chatid, const char* pass)
{
	struct chat_data* cd;

	nullpo_ret(sd);

	cd = (struct chat_data*)map_id2bl(chatid);

	if( cd == NULL || cd->bl.type != BL_CHAT || cd->bl.m != sd->bl.m || sd->state.vending || sd->state.buyingstore || sd->chatID || ((cd->owner->type == BL_NPC) ? cd->users+1 : cd->users) >= cd->limit ) {
		clif_joinchatfail(sd,0);
		return 0;
	}

	if( !cd->pub && strncmp(pass, cd->pass, sizeof(cd->pass)) != 0 && !pc_has_permission(sd, PC_PERM_JOIN_ALL_CHAT) ) {
		clif_joinchatfail(sd,1);
		return 0;
	}

	if( sd->status.base_level < cd->minLvl || sd->status.base_level > cd->maxLvl ) {
		if(sd->status.base_level < cd->minLvl)
			clif_joinchatfail(sd,5);
		else
			clif_joinchatfail(sd,6);

		return 0;
	}

	if( sd->status.zeny < cd->zeny ) {
		clif_joinchatfail(sd,4);
		return 0;
	}

	if( cd->owner->type != BL_NPC && idb_exists(cd->kick_list,sd->status.char_id) ) {
		clif_joinchatfail(sd,2);//You have been kicked out of the room.
		return 0;
	}

	pc_stop_walking(sd,1);
	cd->usersd[cd->users] = sd;
	cd->users++;

	pc_setchatid(sd,cd->bl.id);

	clif_joinchatok(sd, cd); //To the person who newly joined the list of all
	clif_addchat(cd, sd); //Reports To the person who already in the chat
	clif_dispchat(cd, 0); //Reported number of changes to the people around

	if (cd->owner->type == BL_PC)
		achievement_update_objective(map_id2sd(cd->owner->id), AG_CHAT_COUNT, 1, cd->users);

	chat_triggerevent(cd); //Event

	return 0;
}
Esempio n. 5
0
/*==========================================
 * join an existing chatroom
 *------------------------------------------*/
bool chat_joinchat(struct map_session_data* sd, int chatid, const char* pass) {
	struct chat_data* cd;

	nullpo_ret(sd);
	nullpo_ret(pass);
	cd = map->id2cd(chatid);

	if (cd == NULL || cd->bl.type != BL_CHAT || cd->bl.m != sd->bl.m
	 || sd->state.vending || sd->state.buyingstore || sd->chat_id != 0
	 || ((cd->owner->type == BL_NPC) ? cd->users+1 : cd->users) >= cd->limit
	) {
		clif->joinchatfail(sd,0); // room full
		return false;
	}

	if( !cd->pub && strncmp(pass, cd->pass, sizeof(cd->pass)) != 0 && !pc_has_permission(sd, PC_PERM_JOIN_ALL_CHAT) )
	{
		clif->joinchatfail(sd,1); // wrong password
		return false;
	}

	if( sd->status.base_level < cd->minLvl || sd->status.base_level > cd->maxLvl ) {
		if(sd->status.base_level < cd->minLvl)
			clif->joinchatfail(sd,5); // too low level
		else
			clif->joinchatfail(sd,6); // too high level

		return false;
	}

	if( sd->status.zeny < cd->zeny ) {
		clif->joinchatfail(sd,4); // not enough zeny
		return false;
	}

	if( cd->owner->type != BL_NPC && idb_exists(cd->kick_list,sd->status.char_id) ) {
		clif->joinchatfail(sd,2); // You have been kicked out of the room.
		return false;
	}

	pc_stop_walking(sd, STOPWALKING_FLAG_FIXPOS);
	cd->usersd[cd->users] = sd;
	cd->users++;

	pc_setchatid(sd,cd->bl.id);

	clif->joinchatok(sd, cd); //To the person who newly joined the list of all
	clif->addchat(cd, sd); //Reports To the person who already in the chat
	clif->dispchat(cd, 0); //Reported number of changes to the people around

	chat->trigger_event(cd); //Event

	return true;
}
Esempio n. 6
0
/**
 * Checks if player group with given ID exists.
 * @param group_id group id
 * @returns true if group exists, false otherwise
 */
bool pc_group_exists(int group_id)
{
	return idb_exists(pc_group_db, group_id);
}
Esempio n. 7
0
/**
 * Check if player is banned from channel
 * @return
 * -1: Invalid player or channel
 *  0: Player not found or not banned
 *  1: Player is banned
 */
int channel_haspcbanned(struct Channel *channel,struct map_session_data *sd){
	if(!channel || !sd) return -1;
	return (idb_exists(channel->banned, sd->status.char_id))?1:0;
}