📄 clif.c
字号:
// $Id: clif.c,v 1.19 2003/07/04 15:26:33 lemit Exp $
#define DUMP_UNKNOWN_PACKET 1
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdarg.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "socket.h"
#include "timer.h"
#include "map.h"
#include "chrif.h"
#include "clif.h"
#include "pc.h"
#include "npc.h"
#include "itemdb.h"
#include "chat.h"
#include "trade.h"
#include "storage.h"
#include "script.h"
#include "skill.h"
#include "atcommand.h"
#include "intif.h"
#include "battle.h"
#include "mob.h"
#include "party.h"
#include "guild.h"
#include "vending.h"
#include "pet.h"
#include "version.h"
#ifdef MEMWATCH
#include "memwatch.h"
#endif
static const int packet_len_table[0x200]={
10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
//#0x0040
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 55, 17, 3, 37, 46, -1, 23, -1, 3,108, 3, 2,
#if PACKETVER < 2
3, 28, 19, 11, 3, -1, 9, 5, 52, 51, 56, 58, 41, 2, 6, 6,
#else // 78-7b 婽搰埲崀 lv99僄僼僃僋僩梡
3, 28, 19, 11, 3, -1, 9, 5, 54, 53, 58, 60, 41, 2, 6, 6,
#endif
//#0x0080
7, 3, 2, 2, 2, 5, 16, 12, 10, 7, 29, 23, -1, -1, -1, 0,
7, 22, 28, 2, 6, 30, -1, -1, 3, -1, -1, 5, 9, 17, 17, 6,
23, 6, 6, -1, -1, -1, -1, 8, 7, 6, 7, 4, 7, 0, -1, 6,
8, 8, 3, 3, -1, 6, 6, -1, 7, 6, 2, 5, 6, 44, 5, 3,
//#0x00C0
7, 2, 6, 8, 6, 7, -1, -1, -1, -1, 3, 3, 6, 6, 2, 27,
3, 4, 4, 2, -1, -1, 3, -1, 6, 14, 3, -1, 28, 29, -1, -1,
30, 30, 26, 2, 6, 26, 3, 3, 8, 19, 5, 2, 3, 2, 2, 2,
3, 2, 6, 8, 21, 8, 8, 2, 2, 26, 3, -1, 6, 27, 30, 10,
//#0x0100
2, 6, 6, 30, 79, 31, 10, 10, -1, -1, 4, 6, 6, 2, 11, -1,
10, 39, 4, 10, 31, 35, 10, 18, 2, 13, 15, 20, 68, 2, 3, 16,
6, 14, -1, -1, 21, 8, 8, 8, 8, 8, 2, 2, 3, 4, 2, -1,
6, 86, 6, -1, -1, 7, -1, 6, 3, 16, 4, 4, 4, 6, 24, 26,
//#0x0140
22, 14, 6, 10, 23, 19, 6, 39, 8, 9, 6, 27, -1, 2, 6, 6,
110, 6, -1, -1, -1, -1, -1, 6, -1, 54, 66, 54, 90, 42, 6, 42,
-1, -1, -1, -1, -1, 30, -1, 3, 14, 3, 30, 10, 43, 14,186,182,
14, 30, 10, 3, -1, 6,106, -1, 4, 5, 4, -1, 6, 7, -1, -1,
//#0x0180
6, 3,106, 10, 10, 34, 0, 6, 8, 4, 4, 4, 29, -1, 10, 6,
#if PACKETVER < 1
90, 86, 24, 6, 30,102, 8, 4, 8, 4, 14, 10, -1, 6, 2, 6,
#else // 196 comodo埲崀 忬懺昞帵傾僀僐儞梡
90, 86, 24, 6, 30,102, 9, 4, 8, 4, 14, 10, -1, 6, 2, 6,
#endif
3, 3, 35, 5, 11, 26, -1, 4, 4, 6, 10, 12, 6, -1, 4, 4,
11, 7, -1, 67, 12, 18,114, 6, 3, 6, 26, 26, 26, 26, 2, 3,
//#0x01C0, Set 0x1d5=-1
2, 14, 10, -1, 22, 22, 4, 2, 13, 97, 0, 9, 9, 30, 6, 28,
8, 14, 10, 35, 6, -1, 4, 11, 54, 53, 60, 2, -1, 47, 33, 6,
0, 8, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 0, -1, -1,
-1, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
// local define
enum {
ALL_CLIENT,
ALL_SAMEMAP,
AREA,
AREA_WOS,
AREA_WOC,
AREA_WOSC,
AREA_CHAT_WOC,
CHAT,
CHAT_WOS,
PARTY,
PARTY_WOS,
PARTY_SAMEMAP,
PARTY_SAMEMAP_WOS,
PARTY_AREA,
PARTY_AREA_WOS,
GUILD,
GUILD_WOS,
SELF };
#define WBUFPOS(p,pos,x,y) { unsigned char *__p = (p); __p+=(pos); __p[0] = (x)>>2; __p[1] = ((x)<<6) | (((y)>>4)&0x3f); __p[2] = (y)<<4; }
#define WBUFPOS2(p,pos,x0,y0,x1,y1) { unsigned char *__p = (p); __p+=(pos); __p[0] = (x0)>>2; __p[1] = ((x0)<<6) | (((y0)>>4)&0x3f); __p[2] = ((y0)<<4) | (((x1)>>6)&0x0f); __p[3]=((x1)<<2) | (((y1)>>8)&0x03); __p[4]=(y1); }
#define WFIFOPOS(fd,pos,x,y) { WBUFPOS (WFIFOP(fd,pos),0,x,y); }
#define WFIFOPOS2(fd,pos,x0,y0,x1,y1) { WBUFPOS2(WFIFOP(fd,pos),0,x0,y0,x1,y1); }
static char map_ip_str[16];
static in_addr_t map_ip;
static int map_port = 5121;
/*==========================================
* map嶪偺ip愝掕
*------------------------------------------
*/
void clif_setip(char *ip)
{
memcpy(map_ip_str,ip,16);
map_ip=inet_addr(map_ip_str);
}
/*==========================================
* map嶪偺port愝掕
*------------------------------------------
*/
void clif_setport(int port)
{
map_port=port;
}
/*==========================================
* map嶪偺ip撉傒弌偟
*------------------------------------------
*/
in_addr_t clif_getip(void)
{
return map_ip;
}
/*==========================================
* map嶪偺port撉傒弌偟
*------------------------------------------
*/
int clif_getport(void)
{
return map_port;
}
/*==========================================
*
*------------------------------------------
*/
int clif_countusers(void)
{
int users=0,i;
struct map_session_data *sd;
for(i=0;i<fd_max;i++){
if(session[i] && (sd=session[i]->session_data) && sd->state.auth)
users++;
}
return users;
}
/*==========================================
* 慡偰偺client偵懳偟偰func()幚峴
*------------------------------------------
*/
int clif_foreachclient(int (*func)(struct map_session_data*,va_list),...)
{
int i;
va_list ap;
struct map_session_data *sd;
va_start(ap,func);
for(i=0;i<fd_max;i++){
if(session[i] && (sd=session[i]->session_data) && sd->state.auth)
func(sd,ap);
}
va_end(ap);
return 0;
}
/*==========================================
* clif_send偱AREA*巜掕帪梡
*------------------------------------------
*/
int clif_send_sub(struct block_list *bl,va_list ap)
{
unsigned char *buf;
int len;
struct block_list *src_bl;
int type;
struct map_session_data *sd;
buf=va_arg(ap,unsigned char*);
len=va_arg(ap,int);
src_bl=va_arg(ap,struct block_list*);
type=va_arg(ap,int);
sd=(struct map_session_data *)bl;
switch(type){
case AREA_WOS:
if(bl==src_bl)
return 0;
break;
case AREA_WOC:
if(sd->chatID || bl==src_bl)
return 0;
break;
case AREA_WOSC:
if(sd->chatID && sd->chatID == ((struct map_session_data*)src_bl)->chatID)
return 0;
break;
}
memcpy(WFIFOP(sd->fd,0),buf,len);
WFIFOSET(sd->fd,len);
return 0;
}
/*==========================================
*
*------------------------------------------
*/
int clif_send(unsigned char *buf,int len,struct block_list *bl,int type)
{
int i;
struct map_session_data *sd;
struct chat_data *cd;
struct party *p=NULL;
struct guild *g=NULL;
int x0=0,x1=0,y0=0,y1=0;
switch(type){
case ALL_CLIENT: // 慡僋儔僀傾儞僩偵憲怣
for(i=0;i<fd_max;i++){
if(session[i] && (sd=session[i]->session_data) && sd->state.auth){
memcpy(WFIFOP(i,0),buf,len);
WFIFOSET(i,len);
}
}
break;
case ALL_SAMEMAP: // 摨偠儅僢僾偺慡僋儔僀傾儞僩偵憲怣
for(i=0;i<fd_max;i++){
if(session[i] && (sd=session[i]->session_data) && sd->state.auth &&
sd->bl.m == bl->m){
memcpy(WFIFOP(i,0),buf,len);
WFIFOSET(i,len);
}
}
break;
case AREA:
case AREA_WOS:
case AREA_WOC:
case AREA_WOSC:
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:
cd=(struct chat_data*)bl;
if(bl->type==BL_PC){
sd=(struct map_session_data*)bl;
cd=(struct chat_data*)map_id2bl(sd->chatID);
} else if(bl->type!=BL_CHAT)
break;
if(cd==NULL)
break;
for(i=0;i<cd->users;i++){
if(type==CHAT_WOS && cd->usersd[i]==(struct map_session_data*)bl)
continue;
memcpy(WFIFOP(cd->usersd[i]->fd,0),buf,len);
WFIFOSET(cd->usersd[i]->fd,len);
}
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(bl->type==BL_PC){
sd=(struct map_session_data *)bl;
if(sd->status.party_id>0)
p=party_search(sd->status.party_id);
}
if(p){
for(i=0;i<MAX_PARTY;i++){
if((sd=p->member[i].sd)!=NULL){
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;
memcpy(WFIFOP(sd->fd,0),buf,len);
WFIFOSET(sd->fd,len);
// if(battle_config.etc_log)
// printf("send party %d %d %d\n",p->party_id,i,flag);
}
}
}
break;
case SELF:
sd=(struct map_session_data *)bl;
memcpy(WFIFOP(sd->fd,0),buf,len);
WFIFOSET(sd->fd,len);
break;
case GUILD:
case GUILD_WOS:
if(bl->type==BL_PC){
sd=(struct map_session_data *)bl;
if(sd->status.guild_id>0)
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(type==GUILD_WOS && sd->bl.id==bl->id)
continue;
memcpy(WFIFOP(sd->fd,0),buf,len);
WFIFOSET(sd->fd,len);
}
}
}
break;
default:
if(battle_config.error_log)
printf("clif_send 傑偩嶌偭偰側偄傛乕\n");
return -1;
}
return 0;
}
//
// 僷働僢僩嶌偭偰憲怣
//
/*==========================================
*
*------------------------------------------
*/
int clif_authok(struct map_session_data *sd)
{
int fd=sd->fd;
WFIFOW(fd,0)=0x73;
WFIFOL(fd,2)=gettick();
WFIFOPOS(fd,6,sd->bl.x,sd->bl.y);
WFIFOB(fd,9)=5;
WFIFOB(fd,10)=5;
WFIFOSET(fd,packet_len_table[0x73]);
return 0;
}
/*==========================================
*
*------------------------------------------
*/
int clif_authfail_fd(int fd,int type)
{
WFIFOW(fd,0)=0x81;
WFIFOL(fd,2)=type;
WFIFOSET(fd,packet_len_table[0x81]);
clif_setwaitclose(fd);
return 0;
}
/*==========================================
*
*------------------------------------------
*/
int clif_charselectok(int id)
{
struct map_session_data *sd;
int fd;
if((sd=map_id2sd(id))==NULL)
return 1;
fd=sd->fd;
WFIFOW(fd,0)=0xb3;
WFIFOB(fd,2)=1;
WFIFOSET(fd,packet_len_table[0xb3]);
return 0;
}
/*==========================================
*
*------------------------------------------
*/
static int clif_set009e(struct flooritem_data *fitem,unsigned char *buf)
{
int view;
//009e <ID>.l <name ID>.w <identify flag>.B <X>.w <Y>.w <subX>.B <subY>.B <amount>.w
WBUFW(buf,0)=0x9e;
WBUFL(buf,2)=fitem->bl.id;
if((view = itemdb_viewid(fitem->item_data.nameid)) > 0)
WBUFW(buf,6)=view;
else
WBUFW(buf,6)=fitem->item_data.nameid;
WBUFB(buf,8)=fitem->item_data.identify;
WBUFW(buf,9)=fitem->bl.x;
WBUFW(buf,11)=fitem->bl.y;
WBUFB(buf,13)=fitem->subx;
WBUFB(buf,14)=fitem->suby;
WBUFW(buf,15)=fitem->item_data.amount;
return packet_len_table[0x9e];
}
/*==========================================
*
*------------------------------------------
*/
int clif_dropflooritem(struct flooritem_data *fitem)
{
char buf[64];
if(fitem->item_data.nameid <= 0)
return 0;
clif_set009e(fitem,buf);
clif_send(buf,packet_len_table[0x9e],&fitem->bl,AREA);
return 0;
}
/*==========================================
*
*------------------------------------------
*/
int clif_clearflooritem(struct flooritem_data *fitem,int fd)
{
unsigned char buf[16];
WBUFW(buf,0) = 0xa1;
WBUFL(buf,2) = fitem->bl.id;
if(fd==0){
clif_send(buf,packet_len_table[0xa1],&fitem->bl,AREA);
} else {
memcpy(WFIFOP(fd,0),buf,6);
WFIFOSET(fd,packet_len_table[0xa1]);
}
return 0;
}
/*==========================================
*
*------------------------------------------
*/
int clif_clearchar(struct block_list *bl,int type)
{
unsigned char buf[16];
WBUFW(buf,0) = 0x80;
WBUFL(buf,2) = bl->id;
WBUFB(buf,6) = type;
clif_send(buf,packet_len_table[0x80],bl,type==1 ? AREA : AREA_WOS);
return 0;
}
static int clif_clearchar_delay_sub(int tid,unsigned int tick,int id,int data)
{
struct block_list *bl = (struct block_list *)id;
clif_clearchar(bl,data);
map_freeblock(bl);
return 0;
}
int clif_clearchar_delay(unsigned int tick,struct block_list *bl,int type)
{
struct block_list *tmpbl=calloc(sizeof(struct block_list), 1);
if(tmpbl == NULL) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -