Issue information

Issue ID
#8238
Status
New
Severity
None
Started
Garr
Jun 24, 2014 4:14
Last Post
Garr
Jun 27, 2014 4:29
Confirmation
Yes (2)
No (0)

Garr - Jun 24, 2014 4:14

I ran into an issue with old client, namely 2009-10-13 one. Whenever @spawn was used, client would freeze, and no further response given.

I've decided to find things out, and:

Got a WPE to sniff incoming packets (This is first time I work with packets, so please don't bash me)
[quote]
[color=#008000]//Packet on spawn from working server, spawned 2022, Nidd[/color]
F3 01 19 CA B5 06 58 01 00 00
7C 00 00 19 CA B5 06 96 00 00 00 00 00 00 00 00 00 00 00 00 00 E6 07 00 00 00 00 00 00 00 00 00 00 00 00 00 00 14 48 A0 00 00 00 00
17 01 F3 00 8A 84 1E 00 01 00 51 00 8A 00 28 54 5C 35
8E 00 1B 00 41 6C 6C 20 6D 6F 6E 73 74 65 72 73 20 73 75 6D 6D 6F 6E 65 64 21 00

[color=#008000]//Packets on spawn from Hercules[/color]
F3 01 6B A2 8E 06 58 01 00 00
7C 00 05 6B A2 8E 06 96 00 00 00 00 00 00 00 00 00 00 00 00 00 E6 07 00 00 00 00 00 00 00 00 00 00 00 00 00 00 21 0D 10 00 00
17 01 F3 00 80 84 1E 00 01 00 84 00 D1 00 DF 2E 7F 14
8E 00 1B 00 41 6C 6C 20 6D 6F 6E 73 74 65 72 73 20 73 75 6D 6D 6F 6E 65 64 21 00

F3 01 EE A1 8E 06 58 01 00 00
7C 00 05 EE A1 8E 06 96 00 00 00 00 00 00 00 00 00 00 00 00 00 E6 07 00 00 00 00 00 00 00 00 00 00 00 00 00 00 21 8C B0 00 00
17 01 F3 00 80 84 1E 00 01 00 86 00 CB 00 DC 7D 08 17
8E 00 1B 00 41 6C 6C 20 6D 6F 6E 73 74 65 72 73 20 73 75 6D 6D 6F 6E 65 64 21 00

F3 01 EF A1 8E 06 58 01 00 00
7C 00 05 EF A1 8E 06 96 00 00 00 00 00 00 00 00 00 00 00 00 00 E6 07 00 00 00 00 00 00 00 00 00 00 00 00 00 00 20 8C 60 00 00
17 01 F3 00 80 84 1E 00 01 00 82 00 C6 00 93 CF 17 17
8E 00 1B 00 41 6C 6C 20 6D 6F 6E 73 74 65 72 73 20 73 75 6D 6D 6F 6E 65 64 21 00[/quote]

I'm not sure if I divided them right into new lines (packet per line), but I think it should be so. As seen here, hercules packet 0x007c is 2 bytes shorter.

I think problem lies here in clif.c:[code=auto:1023] void clif_spawn_unit2(struct block_list* bl, enum send_target target) { #if PACKETVER < 20091103 struct map_session_data* sd; struct status_change* sc = status->get_sc(bl); struct view_data* vd = status->get_viewdata(bl); struct packet_spawn_unit2 p; int g_id = status->get_guild_id(bl); sd = BL_CAST(BL_PC, bl); p.PacketType = spawn_unit2Type; #if PACKETVER >= 20071106 p.objecttype = clif_bl_type(bl); #endif p.GID = bl->id; p.speed = status->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.head = vd->hair_style; p.weapon = vd->weapon; p.accessory = vd->head_bottom; p.job = vd->class_; 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 = status->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.isPKModeON = (sd && sd->status.karma) ? 1 : 0; p.sex = vd->sex; WBUFPOS(&p.PosDir[0],0,bl->x,bl->y,unit->getdir(bl)); p.xSize = p.ySize = (sd) ? 5 : 0; clif->send(&p,sizeof(p),bl,target); #else return; #endif [/code]
Tested it by replacing
clif->send(&p,sizeof(p),bl,target);
with
clif->send(&p,(sizeof(p)+2),bl,target);
. It works now, but I don't know what bytes of info I'm missing. Thanks for reading and sorry if report is a bit confusing.

This post has been edited by Garr on Jun 24, 2014 4:18

Garr - Jun 27, 2014 4:29

To add to the issue:

While using @disguise, mob spawn packet wasn't sent to the player disguised, so everyone but him would see him disguised, he'd remain invisible on his screen.

Same part of code as above, need to add:
[code=auto:0] if( disguised(bl) ) { nullpo_retv(sd); if( sd->status.class_ != sd->disguise ) clif->send(&p,(sizeof(p)+2),bl,target); p.GID = -bl->id; clif->send(&p,(sizeof(p)+2),bl,SELF); } else [/code]
(Was using analogy with clif_unit_spawn)

Resulting so far:
[code=auto:1023] void clif_spawn_unit2(struct block_list* bl, enum send_target target) { #if PACKETVER < 20091103 struct map_session_data* sd; struct status_change* sc = status->get_sc(bl); struct view_data* vd = status->get_viewdata(bl); struct packet_spawn_unit2 p; int g_id = status->get_guild_id(bl); sd = BL_CAST(BL_PC, bl); p.PacketType = spawn_unit2Type; #if PACKETVER >= 20071106 p.objecttype = clif_bl_type(bl); #endif p.GID = bl->id; p.speed = status->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.head = vd->hair_style; p.weapon = vd->weapon; p.accessory = vd->head_bottom; p.job = vd->class_; 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 = status->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.isPKModeON = (sd && sd->status.karma) ? 1 : 0; p.sex = vd->sex; WBUFPOS(&p.PosDir[0],0,bl->x,bl->y,unit->getdir(bl)); p.xSize = p.ySize = (sd) ? 5 : 0; if( disguised(bl) ) { nullpo_retv(sd); if( sd->status.class_ != sd->disguise ) clif->send(&p,(sizeof(p)+2),bl,target); p.GID = -bl->id; clif->send(&p,(sizeof(p)+2),bl,SELF); } else clif->send(&p,(sizeof(p)+2),bl,target); #else return; #endif } [/code]