int clif_send(const uint8* buf, int len, struct block_list* bl, enum send_target type)
{
int i;
struct map_session_data *sd, *tsd;
struct party_data *p = NULL;
struct guild *g = NULL;
struct battleground_data *bg = NULL;
int x0 = 0, x1 = 0, y0 = 0, y1 = 0, fd;
struct s_mapiterator* iter;
if( type != ALL_CLIENT && type != BG_LISTEN )
nullpo_ret(bl);
sd = BL_CAST(BL_PC, bl);
switch(type) {
case ALL_CLIENT: //All player clients.
case BG_LISTEN:
iter = mapit_getallusers();
while( (tsd = (TBL_PC*)mapit_next(iter)) != NULL )
{
if( type == BG_LISTEN && !(tsd->state.bg_listen || tsd->qd) )
continue;
if( packet_db[tsd->packet_ver][RBUFW(buf,0)].len )
{ // packet must exist for the client version
WFIFOHEAD(tsd->fd, len);
memcpy(WFIFOP(tsd->fd,0), buf, len);
WFIFOSET(tsd->fd,len);
}
}
mapit_free(iter);
break;
case ALL_SAMEMAP: //All players on the same map
iter = mapit_getallusers();
while( (tsd = (TBL_PC*)mapit_next(iter)) != NULL )
{
if( bl->m == tsd->bl.m && packet_db[tsd->packet_ver][RBUFW(buf,0)].len )
{ // packet must exist for the client version
WFIFOHEAD(tsd->fd, len);
memcpy(WFIFOP(tsd->fd,0), buf, len);
WFIFOSET(tsd->fd,len);
}
}
mapit_free(iter);
break;
case AREA:
case AREA_WOSC:
if (sd && bl->prev == NULL) //Otherwise source misses the packet.[Skotlex]
clif_send (buf, len, bl, SELF);
case AREA_WOC:
case AREA_WOS:
map_foreachinarea(clif_send_sub, bl->m, bl->x-AREA_SIZE, bl->y-AREA_SIZE, bl->x+AREA_SIZE, bl->y+AREA_SIZE,
BL_PC, buf, len, bl, type);
break;
case AREA_CHAT_WOC:
map_foreachinarea(clif_send_sub, bl->m, bl->x-(AREA_SIZE-5), bl->y-(AREA_SIZE-5),
bl->x+(AREA_SIZE-5), bl->y+(AREA_SIZE-5), BL_PC, buf, len, bl, AREA_WOC);
break;
case CHAT:
case CHAT_WOS:
{
struct chat_data *cd;
if (sd) {
cd = (struct chat_data*)map_id2bl(sd->chatID);
} else if (bl->type == BL_CHAT) {
cd = (struct chat_data*)bl;
} else break;
if (cd == NULL)
break;
for(i = 0; i < cd->users; i++) {
if (type == CHAT_WOS && cd->usersd[i] == sd)
continue;
if (packet_db[cd->usersd[i]->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version
if ((fd=cd->usersd[i]->fd) >0 && session[fd]) // Added check to see if session exists [PoW]
{
WFIFOHEAD(fd,len);
memcpy(WFIFOP(fd,0), buf, len);
WFIFOSET(fd,len);
}
}
}
}
break;
case CHAT_MAINCHAT: //[LuzZza]
iter = mapit_getallusers();
while( (tsd = (TBL_PC*)mapit_next(iter)) != NULL )
{
if( tsd->state.mainchat && tsd->chatID == 0 && packet_db[tsd->packet_ver][RBUFW(buf,0)].len )
{ // packet must exist for the client version
WFIFOHEAD(tsd->fd, len);
memcpy(WFIFOP(tsd->fd,0), buf, len);
WFIFOSET(tsd->fd,len);
}
}
mapit_free(iter);
break;
case PARTY_AREA:
case PARTY_AREA_WOS:
x0 = bl->x - AREA_SIZE;
y0 = bl->y - AREA_SIZE;
x1 = bl->x + AREA_SIZE;
y1 = bl->y + AREA_SIZE;
case PARTY:
case PARTY_WOS:
case PARTY_SAMEMAP:
case PARTY_SAMEMAP_WOS:
if (sd && sd->status.party_id)
p = party_search(sd->status.party_id);
if (p) {
for(i=0;i<MAX_PARTY;i++){
if( (sd = p->data[i].sd) == NULL )
continue;
if( !(fd=sd->fd) )
continue;
if( sd->bl.id == bl->id && (type == PARTY_WOS || type == PARTY_SAMEMAP_WOS || type == PARTY_AREA_WOS) )
continue;
if( type != PARTY && type != PARTY_WOS && bl->m != sd->bl.m )
continue;
if( (type == PARTY_AREA || type == PARTY_AREA_WOS) && (sd->bl.x < x0 || sd->bl.y < y0 || sd->bl.x > x1 || sd->bl.y > y1) )
continue;
if( packet_db[sd->packet_ver][RBUFW(buf,0)].len )
{ // packet must exist for the client version
WFIFOHEAD(fd,len);
memcpy(WFIFOP(fd,0), buf, len);
WFIFOSET(fd,len);
}
}
if (!enable_spy) //Skip unnecessary parsing. [Skotlex]
break;
iter = mapit_getallusers();
while( (tsd = (TBL_PC*)mapit_next(iter)) != NULL )
{
if( tsd->partyspy == p->party.party_id && packet_db[tsd->packet_ver][RBUFW(buf,0)].len )
{ // packet must exist for the client version
WFIFOHEAD(tsd->fd, len);
memcpy(WFIFOP(tsd->fd,0), buf, len);
WFIFOSET(tsd->fd,len);
}
}
mapit_free(iter);
}
break;
case DUEL:
case DUEL_WOS:
if (!sd || !sd->duel_group) break; //Invalid usage.
iter = mapit_getallusers();
while( (tsd = (TBL_PC*)mapit_next(iter)) != NULL )
{
if( type == DUEL_WOS && bl->id == tsd->bl.id )
continue;
if( sd->duel_group == tsd->duel_group && packet_db[tsd->packet_ver][RBUFW(buf,0)].len )
{ // packet must exist for the client version
WFIFOHEAD(tsd->fd, len);
memcpy(WFIFOP(tsd->fd,0), buf, len);
WFIFOSET(tsd->fd,len);
}
}
mapit_free(iter);
break;
case SELF:
if (sd && (fd=sd->fd) && packet_db[sd->packet_ver][RBUFW(buf,0)].len) { // packet must exist for the client version
WFIFOHEAD(fd,len);
memcpy(WFIFOP(fd,0), buf, len);
WFIFOSET(fd,len);
}
break;
// New definitions for guilds [Valaris] - Cleaned up and reorganized by [Skotlex]
case GUILD_AREA:
case GUILD_AREA_WOS:
x0 = bl->x - AREA_SIZE;
y0 = bl->y - AREA_SIZE;
x1 = bl->x + AREA_SIZE;
y1 = bl->y + AREA_SIZE;
case GUILD_SAMEMAP:
case GUILD_SAMEMAP_WOS:
case GUILD:
case GUILD_WOS:
case GUILD_NOBG:
if (sd && sd->status.guild_id)
g = guild_search(sd->status.guild_id);
if (g) {
for(i = 0; i < g->max_member; i++) {
if( (sd = g->member[i].sd) != NULL )
{
if( !(fd=sd->fd) )
continue;
if( type == GUILD_NOBG && sd->bg_id )
continue;
if( sd->bl.id == bl->id && (type == GUILD_WOS || type == GUILD_SAMEMAP_WOS || type == GUILD_AREA_WOS) )
continue;
if( type != GUILD && type != GUILD_NOBG && type != GUILD_WOS && sd->bl.m != bl->m )
continue;
if( (type == GUILD_AREA || type == GUILD_AREA_WOS) && (sd->bl.x < x0 || sd->bl.y < y0 || sd->bl.x > x1 || sd->bl.y > y1) )
continue;
if( packet_db[sd->packet_ver][RBUFW(buf,0)].len )
{ // packet must exist for the client version
WFIFOHEAD(fd,len);
memcpy(WFIFOP(fd,0), buf, len);
WFIFOSET(fd,len);
}
}
}
if (!enable_spy) //Skip unnecessary parsing. [Skotlex]
break;
iter = mapit_getallusers();
while( (tsd = (TBL_PC*)mapit_next(iter)) != NULL )
{
if( tsd->guildspy == g->guild_id && packet_db[tsd->packet_ver][RBUFW(buf,0)].len )
{ // packet must exist for the client version
WFIFOHEAD(tsd->fd, len);
memcpy(WFIFOP(tsd->fd,0), buf, len);
WFIFOSET(tsd->fd,len);
}
}
mapit_free(iter);
}
break;
case BG_AREA:
case BG_AREA_WOS:
x0 = bl->x - AREA_SIZE;
y0 = bl->y - AREA_SIZE;
x1 = bl->x + AREA_SIZE;
y1 = bl->y + AREA_SIZE;
case BG_SAMEMAP:
case BG_SAMEMAP_WOS:
case BG:
case BG_WOS:
if( sd && sd->bg_id && (bg = bg_team_search(sd->bg_id)) != NULL )
{
for( i = 0; i < MAX_BG_MEMBERS; i++ )
{
if( (sd = bg->members[i].sd) == NULL || !(fd = sd->fd) )
continue;
if( sd->bl.id == bl->id && (type == BG_WOS || type == BG_SAMEMAP_WOS || type == BG_AREA_WOS) )
continue;
if( type != BG && type != BG_WOS && sd->bl.m != bl->m )
continue;
if( (type == BG_AREA || type == BG_AREA_WOS) && (sd->bl.x < x0 || sd->bl.y < y0 || sd->bl.x > x1 || sd->bl.y > y1) )
continue;
if( packet_db[sd->packet_ver][RBUFW(buf,0)].len )
{ // packet must exist for the client version
WFIFOHEAD(fd,len);
memcpy(WFIFOP(fd,0), buf, len);
WFIFOSET(fd,len);
}
}
}
break;
default:
ShowError("clif_send: Unrecognized type %d\n",type);
return -1;
}
return 0;
}