From 7b0361fb160a1126dc6f9873f87f8a02f704764e Mon Sep 17 00:00:00 2001 From: shennetsind Date: Sun, 4 Aug 2013 13:09:27 -0300 Subject: Fixed Bug #7605 http://hercules.ws/board/tracker/issue-7605-problem-with-old-client-versions/ Signed-off-by: shennetsind --- src/map/clif.c | 66 ++++++++++++++++++++++++++++++++++++++++++++---- src/map/clif.h | 1 + src/map/packets_struct.h | 39 +++++++++++++++++++++++++--- 3 files changed, 98 insertions(+), 8 deletions(-) diff --git a/src/map/clif.c b/src/map/clif.c index d3fe7df14..f9ea6e2c1 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -853,7 +853,53 @@ static int clif_setlevel(struct block_list* bl) { } return lv; } - +#if PACKETVER < 20091103 +/* for 'packetver < 20091103' 0x78 non-pc-looking unit handling */ +void clif_set_unit_idle2(struct block_list* bl, struct map_session_data *tsd, enum send_target target) { + struct map_session_data* sd; + struct status_change* sc = iStatus->get_sc(bl); + struct view_data* vd = iStatus->get_viewdata(bl); + struct packet_idle_unit2 p; + int g_id = iStatus->get_guild_id(bl); + + sd = BL_CAST(BL_PC, bl); + + p.PacketType = idle_unit2Type; + p.objecttype = clif_bl_type(bl); + p.GID = bl->id; + p.speed = iStatus->get_speed(bl); + p.bodyState = (sc) ? sc->opt1 : 0; + p.healthState = (sc) ? sc->opt2 : 0; + p.effectState = (sc) ? sc->option : bl->type == BL_NPC ? ((TBL_NPC*)bl)->option : 0; + p.job = vd->class_; + p.head = vd->hair_style; + p.weapon = vd->weapon; + p.accessory = vd->head_bottom; + p.shield = vd->shield; + p.accessory2 = vd->head_top; + p.accessory3 = vd->head_mid; + if( bl->type == BL_NPC && vd->class_ == FLAG_CLASS ) { //The hell, why flags work like this? + p.shield = iStatus->get_emblem_id(bl); + p.accessory2 = GetWord(g_id, 1); + p.accessory3 = GetWord(g_id, 0); + } + p.headpalette = vd->hair_color; + p.bodypalette = vd->cloth_color; + p.headDir = (sd)? sd->head_dir : 0; + p.GUID = g_id; + p.GEmblemVer = iStatus->get_emblem_id(bl); + p.honor = (sd) ? sd->status.manner : 0; + p.virtue = (sc) ? sc->opt3 : 0; + p.isPKModeON = (sd) ? sd->status.karma : 0; + p.sex = vd->sex; + WBUFPOS(&p.PosDir[0],0,bl->x,bl->y,unit_getdir(bl)); + p.xSize = p.ySize = (sd) ? 5 : 0; + p.state = vd->dead_sit; + p.clevel = clif_setlevel(bl); + + clif->send(&p,sizeof(p),tsd?&tsd->bl:bl,target); +} +#endif /*========================================== * Prepares 'unit standing' packet *------------------------------------------*/ @@ -864,6 +910,11 @@ void clif_set_unit_idle(struct block_list* bl, struct map_session_data *tsd, enu struct packet_idle_unit p; int g_id = iStatus->get_guild_id(bl); +#if PACKETVER < 20091103 + if( !pcdb_checkid(vd->class_) ) + return clif->set_unit_idle2(bl,tsd,target); +#endif + sd = BL_CAST(BL_PC, bl); p.PacketType = idle_unitType; @@ -886,7 +937,7 @@ void clif_set_unit_idle(struct block_list* bl, struct map_session_data *tsd, enu p.accessory2 = vd->head_top; p.accessory3 = vd->head_mid; if( bl->type == BL_NPC && vd->class_ == FLAG_CLASS ) { //The hell, why flags work like this? - p.accessory = g_id; + p.accessory = iStatus->get_emblem_id(bl); p.accessory2 = GetWord(g_id, 1); p.accessory3 = GetWord(g_id, 0); } @@ -960,7 +1011,7 @@ void clif_spawn_unit2(struct block_list* bl, enum send_target target) { p.accessory2 = vd->head_top; p.accessory3 = vd->head_mid; if( bl->type == BL_NPC && vd->class_ == FLAG_CLASS ) { //The hell, why flags work like this? - p.accessory = g_id; + p.shield = iStatus->get_emblem_id(bl); p.accessory2 = GetWord(g_id, 1); p.accessory3 = GetWord(g_id, 0); } @@ -972,6 +1023,8 @@ void clif_spawn_unit2(struct block_list* bl, enum send_target target) { WBUFPOS(&p.PosDir[0],0,bl->x,bl->y,unit_getdir(bl)); p.xSize = p.ySize = (sd) ? 5 : 0; p.clevel = clif_setlevel(bl); + + clif->send(&p,sizeof(p),bl,target); } #endif void clif_spawn_unit(struct block_list* bl, enum send_target target) { @@ -1008,7 +1061,7 @@ void clif_spawn_unit(struct block_list* bl, enum send_target target) { p.accessory2 = vd->head_top; p.accessory3 = vd->head_mid; if( bl->type == BL_NPC && vd->class_ == FLAG_CLASS ) { //The hell, why flags work like this? - p.accessory = g_id; + p.accessory = iStatus->get_emblem_id(bl); p.accessory2 = GetWord(g_id, 1); p.accessory3 = GetWord(g_id, 0); } @@ -1071,6 +1124,8 @@ void clif_set_unit_walking(struct block_list* bl, struct map_session_data *tsd, p.PacketType = unit_walkingType; #if PACKETVER >= 20091103 p.PacketLength = sizeof(p); +#endif +#if PACKETVER > 7 p.objecttype = clif_bl_type(bl); #endif p.GID = bl->id; @@ -17728,7 +17783,7 @@ void clif_bc_ready(void) { int do_init_clif(void) { const char* colors[COLOR_MAX] = { "0xFF0000", "0x00ff00", "0xffffff" }; int i; - + /** * Setup Color Table (saves unnecessary load of strtoul on every call) **/ @@ -17855,6 +17910,7 @@ void clif_defaults(void) { clif->spawn_unit = clif_spawn_unit; #if PACKETVER < 20091103 clif->spawn_unit2 = clif_spawn_unit2; + clif->set_unit_idle2 = clif_set_unit_idle2; #endif clif->set_unit_walking = clif_set_unit_walking; clif->calc_walkdelay = clif_calc_walkdelay; diff --git a/src/map/clif.h b/src/map/clif.h index 43b2fa1a6..f68eaafa3 100644 --- a/src/map/clif.h +++ b/src/map/clif.h @@ -527,6 +527,7 @@ struct clif_interface { void (*spawn_unit) (struct block_list* bl, enum send_target target); #if PACKETVER < 20091103 void (*spawn_unit2) (struct block_list* bl, enum send_target target); + void (*set_unit_idle2) (struct block_list* bl, struct map_session_data *tsd, enum send_target target); #endif void (*set_unit_walking) (struct block_list* bl, struct map_session_data *tsd,struct unit_data* ud, enum send_target target); int (*calc_walkdelay) (struct block_list *bl,int delay, int type, int damage, int div_); diff --git a/src/map/packets_struct.h b/src/map/packets_struct.h index b514ab8df..053cd96b8 100644 --- a/src/map/packets_struct.h +++ b/src/map/packets_struct.h @@ -55,6 +55,7 @@ enum packet_headers { status_change_endType = 0x196, #if PACKETVER < 20091103 spawn_unit2Type = 0x7c, + idle_unit2Type = 0x78, #endif #if PACKETVER < 4 spawn_unitType = 0x79, @@ -177,6 +178,36 @@ struct packet_dropflooritem { short count; } __attribute__((packed)); #if PACKETVER < 20091103 +struct packet_idle_unit2 { + short PacketType; + unsigned char objecttype; + unsigned int GID; + short speed; + short bodyState; + short healthState; + short effectState; + short job; + short head; + short weapon; + short accessory; + short shield; + short accessory2; + short accessory3; + short headpalette; + short bodypalette; + short headDir; + unsigned int GUID; + short GEmblemVer; + short honor; + short virtue; + bool isPKModeON; + unsigned char sex; + unsigned char PosDir[3]; + unsigned char xSize; + unsigned char ySize; + unsigned char state; + short clevel; +} __attribute__((packed)); struct packet_spawn_unit2 { short PacketType; unsigned char objecttype; @@ -240,7 +271,7 @@ struct packet_spawn_unit { unsigned int GUID; short GEmblemVer; short honor; -#if PACKETVER >= 20091103 +#if PACKETVER > 7 int virtue; #else short virtue; @@ -265,6 +296,8 @@ struct packet_unit_walking { short PacketType; #if PACKETVER >= 20091103 short PacketLength; +#endif +#if PACKETVER > 7 unsigned char objecttype; #endif unsigned int GID; @@ -299,7 +332,7 @@ struct packet_unit_walking { unsigned int GUID; short GEmblemVer; short honor; -#if PACKETVER >= 20091103 +#if PACKETVER > 7 int virtue; #else short virtue; @@ -357,7 +390,7 @@ struct packet_idle_unit { unsigned int GUID; short GEmblemVer; short honor; -#if PACKETVER >= 20091103 +#if PACKETVER > 7 int virtue; #else short virtue; -- cgit v1.2.3-60-g2f50