diff options
-rw-r--r-- | src/elogin/send.c | 2 | ||||
-rw-r--r-- | src/emap/clif.c | 66 | ||||
-rw-r--r-- | src/emap/clif.h | 1 | ||||
-rw-r--r-- | src/emap/init.c | 1 |
4 files changed, 69 insertions, 1 deletions
diff --git a/src/elogin/send.c b/src/elogin/send.c index 01c2906..1365f91 100644 --- a/src/elogin/send.c +++ b/src/elogin/send.c @@ -24,7 +24,7 @@ void send_server_version(int fd) WFIFOW(fd, 0) = 0x7531; WFIFOW(fd, 2) = 16; WFIFOL(fd, 4) = 0; // unused - WFIFOL(fd, 8) = 14; // plugin version + WFIFOL(fd, 8) = 15; // plugin version WFIFOL(fd, 12) = serverPacketVersion; // server packet version WFIFOSET(fd, WFIFOW(fd,2)); diff --git a/src/emap/clif.c b/src/emap/clif.c index e36127b..686cb08 100644 --- a/src/emap/clif.c +++ b/src/emap/clif.c @@ -1484,3 +1484,69 @@ void eclif_useskill(struct block_list* bl, clif->send(buf, len, bl, AREA); } } + +void eclif_skillinfoblock_pre(struct map_session_data **sdPtr) +{ + struct map_session_data *sd = *sdPtr; + nullpo_retv(sd); + struct SessionExt *data = session_get_bysd(sd); + if (!data) + return; + if (data->clientVersion < 18) + return; + + int fd = sd->fd; + if (!fd) + return; + + WFIFOHEAD(fd, MAX_SKILL * 41 + 4); + WFIFOW(fd, 0) = 0x10f; + int len = 4; + int i; + for (i = 0; i < MAX_SKILL; i++) + { + int id = sd->status.skill[i].id; + if (id != 0) + { + const int skillSize = 41; + if (len + skillSize > 16384) + break; + + WFIFOW(fd, len) = id; + WFIFOL(fd, len + 2) = skill->get_inf(id); + WFIFOL(fd, len + 6) = skill->get_inf2(id); + const int level = sd->status.skill[i].lv; + WFIFOW(fd, len + 10) = level; + if (level) + { + WFIFOW(fd, len + 12) = skill->get_sp(id, level); + WFIFOW(fd, len + 14) = skill->get_range2(&sd->bl, id, level); + } + else + { + WFIFOW(fd, len + 12) = 0; + WFIFOW(fd, len + 14) = 0; + } + safestrncpy(WFIFOP(fd, len + 16), skill->get_name(id), NAME_LENGTH); + if (sd->status.skill[i].flag == SKILL_FLAG_PERMANENT) + WFIFOB(fd, len + 40) = (sd->status.skill[i].lv < skill->tree_get_max(id, sd->status.class_)) ? 1 : 0; + else + WFIFOB(fd, len + 40) = 0; + len += skillSize; + } + } + WFIFOW(fd, 2) = len; + WFIFOSET(fd, len); + + // workaround for bugreport:5348; send the remaining skills one by one to bypass packet size limit + for ( ; i < MAX_SKILL; i++) + { + int id = sd->status.skill[i].id; + if (id != 0) + { + clif->addskill(sd, id); + clif->skillinfo(sd, id, 0); + } + } + hookStop(); +} diff --git a/src/emap/clif.h b/src/emap/clif.h index 9d4b774..d1ce26f 100644 --- a/src/emap/clif.h +++ b/src/emap/clif.h @@ -93,5 +93,6 @@ void eclif_useskill(struct block_list* bl, uint16 skill_id, uint16 skill_lv, int casttime); +void eclif_skillinfoblock_pre(struct map_session_data **sdPtr); #endif // EVOL_MAP_CLIF diff --git a/src/emap/init.c b/src/emap/init.c index 3c57019..ddb4c8e 100644 --- a/src/emap/init.c +++ b/src/emap/init.c @@ -228,6 +228,7 @@ HPExport void plugin_init (void) addHookPre(clif, send_actual, eclif_send_actual_pre); addHookPre(clif, pLoadEndAck, eclif_parse_LoadEndAck_pre); addHookPre(clif, spawn_unit, eclif_spawn_unit_pre); + addHookPre(clif, skillinfoblock, eclif_skillinfoblock_pre); addHookPre(itemdb, is_item_usable, eitemdb_is_item_usable_pre); addHookPre(itemdb, readdb_additional_fields, eitemdb_readdb_additional_fields_pre); addHookPre(itemdb, destroy_item_data, edestroy_item_data_pre); |