diff options
author | mekolat <mekolat@users.noreply.github.com> | 2016-04-13 10:05:15 -0400 |
---|---|---|
committer | mekolat <mekolat@users.noreply.github.com> | 2016-04-13 10:05:15 -0400 |
commit | f54f335c541ecb61f9e9888848eb21b8d43877b7 (patch) | |
tree | 5dcd2680a4ba6791afe4d952e10b1b43ec761580 /src | |
parent | 3cda94665c73447b09338d6f219ef22b58f066bd (diff) | |
parent | 607d40ebcac47555cc01da8ee61c2fae5cec3186 (diff) | |
download | tmwa-f54f335c541ecb61f9e9888848eb21b8d43877b7.tar.gz tmwa-f54f335c541ecb61f9e9888848eb21b8d43877b7.tar.bz2 tmwa-f54f335c541ecb61f9e9888848eb21b8d43877b7.tar.xz tmwa-f54f335c541ecb61f9e9888848eb21b8d43877b7.zip |
Merge pull request #205 from mekolat/version
consolidate client version handling
Diffstat (limited to 'src')
-rw-r--r-- | src/char/char.cpp | 25 | ||||
-rw-r--r-- | src/char/char.hpp | 2 | ||||
-rw-r--r-- | src/ints/wrap.hpp | 15 | ||||
-rw-r--r-- | src/login/login.cpp | 15 | ||||
-rw-r--r-- | src/login/login.hpp | 1 | ||||
-rw-r--r-- | src/map/chrif.cpp | 2 | ||||
-rw-r--r-- | src/map/clif.cpp | 183 | ||||
-rw-r--r-- | src/map/map.hpp | 2 | ||||
-rw-r--r-- | src/map/pc.cpp | 4 | ||||
-rw-r--r-- | src/map/pc.hpp | 2 | ||||
-rw-r--r-- | src/map/script-fun.cpp | 2 | ||||
-rw-r--r-- | src/mmo/fwd.hpp | 1 | ||||
-rw-r--r-- | src/mmo/ids.hpp | 1 | ||||
-rw-r--r-- | src/mmo/ids.py | 1 | ||||
-rw-r--r-- | src/mmo/version.hpp | 8 |
15 files changed, 144 insertions, 120 deletions
diff --git a/src/char/char.cpp b/src/char/char.cpp index 1dc0e90..3767c54 100644 --- a/src/char/char.cpp +++ b/src/char/char.cpp @@ -99,7 +99,7 @@ struct char_session_data : SessionData AccountId account_id; int login_id1, login_id2; SEX sex; - unsigned short packet_client_version; + ClientVersion client_version; AccountEmail email; }; } // namespace char_ @@ -1193,10 +1193,9 @@ void parse_tologin(Session *ls) case 0x2713: { Packet_Fixed<0x2713> fixed; - rv = recv_fpacket<0x2713, 51>(ls, fixed); + rv = recv_fpacket<0x2713, 55>(ls, fixed); if (rv != RecvResult::Complete) break; - for (io::FD i : iter_fds()) { AccountId acc = fixed.account_id; @@ -1218,6 +1217,7 @@ void parse_tologin(Session *ls) sd->email = stringish<AccountEmail>(fixed.email); if (!e_mail_check(sd->email)) sd->email = DEFAULT_EMAIL; + sd->client_version = fixed.client_protocol_version; // send characters to player mmo_char_send006b(s2, sd); } @@ -1689,10 +1689,10 @@ void parse_frommap(Session *ms) Packet_Payload<0x2afd> payload_fd; // not file descriptor payload_fd.account_id = account_id; payload_fd.login_id2 = afi.login_id2; - payload_fd.packet_client_version = afi.packet_client_version; + payload_fd.client_protocol_version = afi.client_version; FPRINTF(stderr, "From queue index %zd: recalling packet version %d\n"_fmt, - (&afi - &auth_fifo.front()), afi.packet_client_version); + (&afi - &auth_fifo.front()), afi.client_version); payload_fd.char_key = *ck; payload_fd.char_data = *cd; send_ppacket<0x2afd>(ms, payload_fd); @@ -2178,7 +2178,7 @@ void handle_x0066(Session *s, struct char_session_data *sd, uint8_t rfifob_2, IP auth_fifo_iter->delflag = 0; auth_fifo_iter->sex = sd->sex; auth_fifo_iter->ip = s->client_ip; - auth_fifo_iter->packet_client_version = sd->packet_client_version; + auth_fifo_iter->client_version = sd->client_version; auth_fifo_iter++; } } @@ -2249,7 +2249,6 @@ void parse_char(Session *s) sd->account_id = account_id; sd->login_id1 = fixed.login_id1; sd->login_id2 = fixed.login_id2; - sd->packet_client_version = fixed.packet_client_version; sd->sex = fixed.sex; // formerly: send back account_id @@ -2257,14 +2256,6 @@ void parse_char(Session *s) special.magic_packet_length = 4; send_ppacket<0x8000>(s, special); - if(sd->packet_client_version < MIN_CLIENT_VERSION) - { - Packet_Fixed<0x006a> fixed_6a; - fixed_6a.error_code = 5; - send_fpacket<0x006a, 23>(s, fixed_6a); - goto x65_out; - } - // search authentification for (AuthFifoEntry& afi : auth_fifo) { @@ -2285,9 +2276,7 @@ void parse_char(Session *s) fixed_16.account_id = sd->account_id; send_fpacket<0x2716, 6>(login_session, fixed_16); } - // Record client version - afi.packet_client_version = - sd->packet_client_version; + // send characters to player mmo_char_send006b(s, sd); } diff --git a/src/char/char.hpp b/src/char/char.hpp index 049875b..a771730 100644 --- a/src/char/char.hpp +++ b/src/char/char.hpp @@ -50,7 +50,7 @@ struct AuthFifoEntry IP4Address ip; int delflag; SEX sex; - unsigned short packet_client_version; + ClientVersion client_version; }; struct mmo_map_server diff --git a/src/ints/wrap.hpp b/src/ints/wrap.hpp index 25b03c1..2c8cd20 100644 --- a/src/ints/wrap.hpp +++ b/src/ints/wrap.hpp @@ -62,6 +62,21 @@ namespace ints { return l._value < r._value; } + template<class W, typename=typename W::wrapped_type> + bool operator > (W l, W r) + { + return l._value > r._value; + } + template<class W, typename=typename W::wrapped_type> + bool operator <= (W l, W r) + { + return l._value <= r._value; + } + template<class W, typename=typename W::wrapped_type> + bool operator >= (W l, W r) + { + return l._value >= r._value; + } template<class T> struct Sub : T diff --git a/src/login/login.cpp b/src/login/login.cpp index c071429..7ae95c7 100644 --- a/src/login/login.cpp +++ b/src/login/login.cpp @@ -114,6 +114,8 @@ bool extract(XString str, login::ACO *aco) } namespace login { +#define VERSION_2_UPDATEHOST (1<<0) + struct mmo_account { AccountName userid; @@ -908,8 +910,9 @@ void parse_fromchar(Session *s) fixed_13.account_id = acc; fixed_13.invalid = 0; fixed_13.email = ad.email; + fixed_13.client_protocol_version = auth_fifo[i].client_version; - send_fpacket<0x2713, 51>(s, fixed_13); + send_fpacket<0x2713, 55>(s, fixed_13); break; } } @@ -928,7 +931,7 @@ void parse_fromchar(Session *s) // fixed_13.email // fixed_13.connect_until - send_fpacket<0x2713, 51>(s, fixed_13); + send_fpacket<0x2713, 55>(s, fixed_13); } } break; @@ -2441,7 +2444,7 @@ void parse_login(Session *s) result = mmo_auth(&account, s); if (result == -1) { - if (fixed.version < MIN_CLIENT_VERSION) + if (fixed.client_protocol_version < wrap<ClientVersion>(MIN_CLIENT_VERSION)) result = 5; // client too old } if (result == -1) @@ -2478,7 +2481,7 @@ void parse_login(Session *s) * * All supported clients now send both, so the check is removed. */ - // if (version_2 & VERSION_2_UPDATEHOST) + if (fixed.flags & VERSION_2_UPDATEHOST) { if (login_conf.update_host) { @@ -2488,7 +2491,7 @@ void parse_login(Session *s) // Load list of char servers into outbound packet std::vector<Packet_Repeat<0x0069>> repeat_69; - // if (version_2 & VERSION_2_SERVERORDER) + //if (fixed.flags & VERSION_2_SERVERORDER) for (int i = 0; i < MAX_SERVERS; i++) { if (server_session[i]) @@ -2531,6 +2534,8 @@ void parse_login(Session *s) auth_fifo[auth_fifo_pos].delflag = 0; auth_fifo[auth_fifo_pos].ip = s->client_ip; + auth_fifo[auth_fifo_pos].client_version = + fixed.client_protocol_version; auth_fifo_pos++; // if no char-server, don't send void list of servers, just disconnect the player with proper message } diff --git a/src/login/login.hpp b/src/login/login.hpp index ba42bae..ed44e68 100644 --- a/src/login/login.hpp +++ b/src/login/login.hpp @@ -79,6 +79,7 @@ struct AuthFifo IP4Address ip; SEX sex; int delflag; + ClientVersion client_version; }; } // namespace login } // namespace tmwa diff --git a/src/map/chrif.cpp b/src/map/chrif.cpp index 7421344..708cbe1 100644 --- a/src/map/chrif.cpp +++ b/src/map/chrif.cpp @@ -864,7 +864,7 @@ void chrif_parse(Session *s) AccountId id = payload.account_id; int login_id2 = payload.login_id2; - short client_version = payload.packet_client_version; + ClientVersion client_version = payload.client_protocol_version; CharKey st_key = payload.char_key; CharData st_data = payload.char_data; pc_authok(id, login_id2, diff --git a/src/map/clif.cpp b/src/map/clif.cpp index 2a34870..386ac63 100644 --- a/src/map/clif.cpp +++ b/src/map/clif.cpp @@ -217,7 +217,8 @@ AString clif_validate_chat(dumb_ptr<map_session_data> sd, ChatType type, XString */ static void clif_send_sub(dumb_ptr<block_list> bl, const Buffer& buf, - dumb_ptr<block_list> src_bl, SendWho type, short min_version) + dumb_ptr<block_list> src_bl, SendWho type, ClientVersion min_version, + const Buffer& elseBuf) { nullpo_retv(bl); dumb_ptr<map_session_data> sd = bl->is_player(); @@ -245,12 +246,10 @@ void clif_send_sub(dumb_ptr<block_list> bl, const Buffer& buf, if (sd->sess != nullptr) { - { - if (sd->client_version >= min_version) - { - send_buffer(sd->sess, buf); - } - } + if (sd->client_version >= min_version) + send_buffer(sd->sess, buf); + else if (!elseBuf.bytes.empty()) + send_buffer(sd->sess, elseBuf); } } @@ -259,7 +258,7 @@ void clif_send_sub(dumb_ptr<block_list> bl, const Buffer& buf, *------------------------------------------ */ static -int clif_send(const Buffer& buf, dumb_ptr<block_list> bl, SendWho type, short min_version) +int clif_send(const Buffer& buf, dumb_ptr<block_list> bl, SendWho type, ClientVersion min_version, const Buffer& elseBuf) { int x0 = 0, x1 = 0, y0 = 0, y1 = 0; @@ -327,7 +326,7 @@ int clif_send(const Buffer& buf, dumb_ptr<block_list> bl, SendWho type, short mi { if (bl->bl_m != borrow(undefined_gat)) { - map_foreachinarea(std::bind(clif_send_sub, ph::_1, buf, bl, type, min_version), + map_foreachinarea(std::bind(clif_send_sub, ph::_1, buf, bl, type, min_version, elseBuf), bl->bl_m, bl->bl_x - AREA_SIZE, bl->bl_y - AREA_SIZE, bl->bl_x + AREA_SIZE, bl->bl_y + AREA_SIZE, @@ -339,7 +338,7 @@ int clif_send(const Buffer& buf, dumb_ptr<block_list> bl, SendWho type, short mi { if (bl->bl_m != borrow(undefined_gat)) { - map_foreachinarea(std::bind(clif_send_sub, ph::_1, buf, bl, SendWho::AREA_CHAT_WOC, min_version), + map_foreachinarea(std::bind(clif_send_sub, ph::_1, buf, bl, SendWho::AREA_CHAT_WOC, min_version, elseBuf), bl->bl_m, bl->bl_x - (AREA_SIZE), bl->bl_y - (AREA_SIZE), bl->bl_x + (AREA_SIZE), bl->bl_y + (AREA_SIZE), @@ -392,9 +391,9 @@ int clif_send(const Buffer& buf, dumb_ptr<block_list> bl, SendWho type, short mi sd->bl_x > x1 || sd->bl_y > y1)) continue; if (sd->client_version >= min_version) - { send_buffer(sd->sess, buf); - } + else if (!elseBuf.bytes.empty()) + send_buffer(sd->sess, elseBuf); } } for (io::FD i : iter_fds()) @@ -408,9 +407,9 @@ int clif_send(const Buffer& buf, dumb_ptr<block_list> bl, SendWho type, short mi if (sd->partyspy == p.party_id) { if (sd->client_version >= min_version) - { send_buffer(sd->sess, buf); - } + else if (!elseBuf.bytes.empty()) + send_buffer(sd->sess, elseBuf); } } } @@ -425,6 +424,8 @@ int clif_send(const Buffer& buf, dumb_ptr<block_list> bl, SendWho type, short mi { if (sd->client_version >= min_version) send_buffer(sd->sess, buf); + else if (!elseBuf.bytes.empty()) + send_buffer(sd->sess, elseBuf); } } break; @@ -438,6 +439,19 @@ int clif_send(const Buffer& buf, dumb_ptr<block_list> bl, SendWho type, short mi return 0; } +static +int clif_send(const Buffer& buf, dumb_ptr<block_list> bl, SendWho type, ClientVersion min_version) +{ + Buffer emptyBuf; + return clif_send(buf, bl, type, min_version, emptyBuf); +} + +static +int clif_send(const Buffer& buf, dumb_ptr<block_list> bl, SendWho type) +{ + return clif_send(buf, bl, type, wrap<ClientVersion>(MIN_CLIENT_VERSION)); +} + // // パケット作って送信 // @@ -542,7 +556,7 @@ int clif_dropflooritem(dumb_ptr<flooritem_data> fitem) Buffer buf; clif_set009e(fitem, buf); - clif_send(buf, fitem, SendWho::AREA, MIN_CLIENT_VERSION); + clif_send(buf, fitem, SendWho::AREA); return 0; } @@ -561,7 +575,7 @@ int clif_clearflooritem(dumb_ptr<flooritem_data> fitem, Session *s) if (!s) { Buffer buf = create_fpacket<0x00a1, 6>(fixed_a1); - clif_send(buf, fitem, SendWho::AREA, MIN_CLIENT_VERSION); + clif_send(buf, fitem, SendWho::AREA); } else { @@ -586,14 +600,14 @@ int clif_clearchar(dumb_ptr<block_list> bl, BeingRemoveWhy type) { fixed_80.type = BeingRemoveWhy::GONE; Buffer buf = create_fpacket<0x0080, 7>(fixed_80); - clif_send(buf, bl, SendWho::AREA, MIN_CLIENT_VERSION); + clif_send(buf, bl, SendWho::AREA); } else { fixed_80.type = type; Buffer buf = create_fpacket<0x0080, 7>(fixed_80); clif_send(buf, bl, - type == BeingRemoveWhy::DEAD ? SendWho::AREA : SendWho::AREA_WOS, MIN_CLIENT_VERSION); + type == BeingRemoveWhy::DEAD ? SendWho::AREA : SendWho::AREA_WOS); } return 0; @@ -814,8 +828,6 @@ void clif_npc_action(dumb_ptr<map_session_data> sd, BlockId npcid, short command, int id, short x, short y) { nullpo_retv(sd); - if(sd->client_version < 2) - return; Packet_Fixed<0x0212> fixed_212; fixed_212.npc_id = npcid; @@ -825,7 +837,7 @@ void clif_npc_action(dumb_ptr<map_session_data> sd, BlockId npcid, fixed_212.y = y; Buffer buf = create_fpacket<0x0212, 16>(fixed_212); - send_buffer(sd->sess, buf); + clif_send(buf, sd, SendWho::SELF, wrap<ClientVersion>(2)); } /*========================================== @@ -938,7 +950,7 @@ int clif_spawnpc(dumb_ptr<map_session_data> sd) Buffer buf; clif_set0078_alt_1d9(sd, buf); - clif_send(buf, sd, SendWho::AREA_WOS, MIN_CLIENT_VERSION); + clif_send(buf, sd, SendWho::AREA_WOS); clif_pvpstatus(sd); @@ -977,17 +989,17 @@ int clif_spawnnpc(dumb_ptr<npc_data> nd) fixed_7c.pos.y = nd->bl_y; Buffer buf = create_fpacket<0x007c, 41>(fixed_7c); - clif_send(buf, nd, SendWho::AREA, MIN_CLIENT_VERSION); + clif_send(buf, nd, SendWho::AREA); */ Buffer buf; clif_npc0078(nd, buf); - clif_send(buf, nd, SendWho::AREA, MIN_CLIENT_VERSION); + clif_send(buf, nd, SendWho::AREA); if(nd->sit == DamageType::SIT) { Buffer buff; clif_sitnpc_sub(buff, nd, nd->sit); - clif_send(buff, nd, SendWho::AREA, MIN_CLIENT_VERSION); + clif_send(buff, nd, SendWho::AREA); } return 0; @@ -1046,12 +1058,12 @@ int clif_spawnmob(dumb_ptr<mob_data> md) fixed_7c.pos.x = md->bl_x; fixed_7c.pos.y = md->bl_y; Buffer buf = create_fpacket<0x007c, 41>(fixed_7c); - clif_send(buf, md, SendWho::AREA, MIN_CLIENT_VERSION); + clif_send(buf, md, SendWho::AREA); } Buffer buf; clif_mob0078(md, buf); - clif_send(buf, md, SendWho::AREA, MIN_CLIENT_VERSION); + clif_send(buf, md, SendWho::AREA); return 0; } @@ -1105,7 +1117,7 @@ int clif_movechar(dumb_ptr<map_session_data> sd) Buffer buf; clif_set007b(sd, buf); - clif_send(buf, sd, SendWho::AREA_WOS, MIN_CLIENT_VERSION); + clif_send(buf, sd, SendWho::AREA_WOS); if (battle_config.save_clothcolor == 1 && sd->status.clothes_color > 0) clif_changelook(sd, LOOK::CLOTHES_COLOR, @@ -1200,7 +1212,7 @@ void clif_fixpos(dumb_ptr<block_list> bl) fixed_88.y = bl->bl_y; Buffer buf = create_fpacket<0x0088, 10>(fixed_88); - clif_send(buf, bl, SendWho::AREA, MIN_CLIENT_VERSION); + clif_send(buf, bl, SendWho::AREA); } /*========================================== @@ -1878,9 +1890,9 @@ int clif_changelook_towards(dumb_ptr<block_list> bl, LOOK type, int val, Buffer buf = create_fpacket<0x01d7, 11>(fixed_1d7); if (dstsd) - clif_send(buf, dstsd, SendWho::SELF, MIN_CLIENT_VERSION); + clif_send(buf, dstsd, SendWho::SELF); else - clif_send(buf, bl, SendWho::AREA, MIN_CLIENT_VERSION); + clif_send(buf, bl, SendWho::AREA); } else { @@ -1892,9 +1904,9 @@ int clif_changelook_towards(dumb_ptr<block_list> bl, LOOK type, int val, Buffer buf = create_fpacket<0x01d7, 11>(fixed_1d7); if (dstsd) - clif_send(buf, dstsd, SendWho::SELF, MIN_CLIENT_VERSION); + clif_send(buf, dstsd, SendWho::SELF); else - clif_send(buf, bl, SendWho::AREA, MIN_CLIENT_VERSION); + clif_send(buf, bl, SendWho::AREA); } return 0; } @@ -2058,7 +2070,7 @@ int clif_misceffect(dumb_ptr<block_list> bl, int type) fixed_19b.type = type; Buffer buf = create_fpacket<0x019b, 10>(fixed_19b); - clif_send(buf, bl, SendWho::AREA, MIN_CLIENT_VERSION); + clif_send(buf, bl, SendWho::AREA); return 0; } @@ -2071,7 +2083,7 @@ void clif_map_pvp(dumb_ptr<map_session_data> sd) fixed_199.status = sd->bl_m->flag.get(MapFlag::PVP)? 1: 0; Buffer buf = create_fpacket<0x0199, 4>(fixed_199); - clif_send(buf, sd, SendWho::SELF, 2); + clif_send(buf, sd, SendWho::SELF, wrap<ClientVersion>(2)); } static @@ -2091,7 +2103,7 @@ void clif_pvpstatus(dumb_ptr<map_session_data> sd) nullpo_retv(sd); Buffer buf; clif_pvpstatus_towards(buf, sd); - clif_send(buf, sd, SendWho::AREA, 2); + clif_send(buf, sd, SendWho::AREA, wrap<ClientVersion>(2)); } /*========================================== @@ -2115,7 +2127,7 @@ int clif_changeoption(dumb_ptr<block_list> bl) fixed_119.zero = 0; Buffer buf = create_fpacket<0x0119, 13>(fixed_119); - clif_send(buf, bl, SendWho::AREA, MIN_CLIENT_VERSION); + clif_send(buf, bl, SendWho::AREA); return 0; } @@ -2147,7 +2159,7 @@ int clif_useitemack(dumb_ptr<map_session_data> sd, IOff0 index, int amount, fixed_1c8.amount = amount; fixed_1c8.ok = ok; Buffer buf = create_fpacket<0x01c8, 13>(fixed_1c8); - clif_send(buf, sd, SendWho::SELF, MIN_CLIENT_VERSION); + clif_send(buf, sd, SendWho::SELF); } return 0; @@ -2404,7 +2416,7 @@ void clif_getareachar_pc(dumb_ptr<map_session_data> sd, Buffer buff; clif_pvpstatus_towards(buff, dstsd); - clif_send(buff, sd, SendWho::SELF, 2); + clif_send(buff, sd, SendWho::SELF, wrap<ClientVersion>(2)); if (battle_config.save_clothcolor == 1 && dstsd->status.clothes_color > 0) clif_changelook(dstsd, LOOK::CLOTHES_COLOR, @@ -2452,18 +2464,19 @@ void clif_movemob_sub(dumb_ptr<block_list> sd_bl, dumb_ptr<mob_data> md) dumb_ptr<map_session_data> sd = sd_bl->is_player(); Buffer buf; - if (sd->client_version < 3 || sd->client_version >= 4) + if (sd->client_version < wrap<ClientVersion>(3) || + sd->client_version >= wrap<ClientVersion>(4)) clif_mob007b(md, buf); // backward compatibility for old clients else { Buffer buf2; clif_mob0078(md, buf2); - clif_send(buf2, sd, SendWho::SELF, MIN_CLIENT_VERSION); + clif_send(buf2, sd, SendWho::SELF); clif_0225_being_move3(md, buf); } - clif_send(buf, sd, SendWho::SELF, MIN_CLIENT_VERSION); + clif_send(buf, sd, SendWho::SELF); } int clif_movemob(dumb_ptr<mob_data> md) @@ -2495,7 +2508,7 @@ int clif_fixmobpos(dumb_ptr<mob_data> md) { Buffer buf; clif_mob0078(md, buf); - clif_send(buf, md, SendWho::AREA, MIN_CLIENT_VERSION); + clif_send(buf, md, SendWho::AREA); } return 0; @@ -2513,13 +2526,13 @@ int clif_fixpcpos(dumb_ptr<map_session_data> sd) { Buffer buf; clif_set007b(sd, buf); - clif_send(buf, sd, SendWho::AREA, MIN_CLIENT_VERSION); + clif_send(buf, sd, SendWho::AREA); } else { Buffer buf; clif_set0078_main_1d8(sd, buf); - clif_send(buf, sd, SendWho::AREA, MIN_CLIENT_VERSION); + clif_send(buf, sd, SendWho::AREA); } clif_changelook_accessories(sd, nullptr); @@ -2552,7 +2565,7 @@ int clif_damage(dumb_ptr<block_list> src, dumb_ptr<block_list> dst, fixed_8a.damage_type = type; fixed_8a.damage2 = 0; Buffer buf = create_fpacket<0x008a, 29>(fixed_8a); - clif_send(buf, src, SendWho::AREA, MIN_CLIENT_VERSION); + clif_send(buf, src, SendWho::AREA); return 0; } @@ -2872,7 +2885,7 @@ int clif_skill_damage(dumb_ptr<block_list> src, dumb_ptr<block_list> dst, fixed_1de.div = div; fixed_1de.type_or_hit = (type > 0) ? type : skill_get_hit(skill_id); Buffer buf = create_fpacket<0x01de, 33>(fixed_1de); - clif_send(buf, src, SendWho::AREA, MIN_CLIENT_VERSION); + clif_send(buf, src, SendWho::AREA); return 0; } @@ -2890,7 +2903,7 @@ int clif_status_change(dumb_ptr<block_list> bl, StatusChange type, int flag) fixed_196.block_id = bl->bl_id; fixed_196.flag = flag; Buffer buf = create_fpacket<0x0196, 9>(fixed_196); - clif_send(buf, bl, SendWho::AREA, MIN_CLIENT_VERSION); + clif_send(buf, bl, SendWho::AREA); return 0; } @@ -2920,7 +2933,7 @@ void clif_GMmessage(dumb_ptr<block_list> bl, XString mes, int flag) (flag == 1) ? SendWho::ALL_SAMEMAP : (flag == 2) ? SendWho::AREA : (flag == 3) ? SendWho::SELF : - SendWho::ALL_CLIENT, MIN_CLIENT_VERSION); + SendWho::ALL_CLIENT); } /*========================================== @@ -2937,7 +2950,7 @@ void clif_resurrection(dumb_ptr<block_list> bl, int type) Buffer buf = create_fpacket<0x0148, 8>(fixed_148); clif_send(buf, bl, - type == 1 ? SendWho::AREA : SendWho::AREA_WOS, MIN_CLIENT_VERSION); + type == 1 ? SendWho::AREA : SendWho::AREA_WOS); } /*========================================== @@ -3024,7 +3037,7 @@ int clif_party_info(PartyPair p, Session *s) if (sd != nullptr) { Buffer buf = create_vpacket<0x00fb, 28, 46>(head_fb, repeat_fb); - clif_send(buf, sd, SendWho::PARTY, MIN_CLIENT_VERSION); + clif_send(buf, sd, SendWho::PARTY); } return 0; } @@ -3101,7 +3114,7 @@ void clif_party_option(PartyPair p, dumb_ptr<map_session_data> sd, int flag) if (flag == 0) { Buffer buf = create_fpacket<0x0101, 6>(fixed_101); - clif_send(buf, sd, SendWho::PARTY, MIN_CLIENT_VERSION); + clif_send(buf, sd, SendWho::PARTY); } else { @@ -3135,7 +3148,7 @@ void clif_party_leaved(PartyPair p, dumb_ptr<map_session_data> sd, if (sd != nullptr) { Buffer buf = create_fpacket<0x0105, 31>(fixed_105); - clif_send(buf, sd, SendWho::PARTY, MIN_CLIENT_VERSION); + clif_send(buf, sd, SendWho::PARTY); } } else if (sd != nullptr) @@ -3165,7 +3178,7 @@ void clif_party_message(PartyPair p, AccountId account_id, XString mes) Packet_Head<0x0109> head_109; head_109.account_id = account_id; Buffer buf = create_vpacket<0x0109, 8, 1>(head_109, mes); - clif_send(buf, sd, SendWho::PARTY, MIN_CLIENT_VERSION); + clif_send(buf, sd, SendWho::PARTY); } } @@ -3182,7 +3195,7 @@ int clif_party_xy(PartyPair , dumb_ptr<map_session_data> sd) fixed_107.x = sd->bl_x; fixed_107.y = sd->bl_y; Buffer buf = create_fpacket<0x0107, 10>(fixed_107); - clif_send(buf, sd, SendWho::PARTY_SAMEMAP_WOS, MIN_CLIENT_VERSION); + clif_send(buf, sd, SendWho::PARTY_SAMEMAP_WOS); return 0; } @@ -3200,7 +3213,7 @@ int clif_party_hp(PartyPair , dumb_ptr<map_session_data> sd) fixed_106.max_hp = (sd->status.max_hp > 0x7fff) ? 0x7fff : sd->status.max_hp; Buffer buf = create_fpacket<0x0106, 10>(fixed_106); - clif_send(buf, sd, SendWho::PARTY_AREA_WOS, MIN_CLIENT_VERSION); + clif_send(buf, sd, SendWho::PARTY_AREA_WOS); return 0; } @@ -3237,7 +3250,7 @@ void clif_emotion(dumb_ptr<block_list> bl, int type) fixed_c0.block_id = bl->bl_id; fixed_c0.type = type; Buffer buf = create_fpacket<0x00c0, 7>(fixed_c0); - clif_send(buf, bl, SendWho::AREA, MIN_CLIENT_VERSION); + clif_send(buf, bl, SendWho::AREA); } void clif_emotion_towards(dumb_ptr<block_list> bl, @@ -3270,7 +3283,7 @@ void clif_sitting(Session *, dumb_ptr<map_session_data> sd) fixed_8a.src_id = sd->bl_id; fixed_8a.damage_type = DamageType::SIT; Buffer buf = create_fpacket<0x008a, 29>(fixed_8a); - clif_send(buf, sd, SendWho::AREA, MIN_CLIENT_VERSION); + clif_send(buf, sd, SendWho::AREA); } static @@ -3294,7 +3307,7 @@ void clif_sitnpc_towards(dumb_ptr<map_session_data> sd, dumb_ptr<npc_data> nd, D Buffer buf; clif_sitnpc_sub(buf, nd, dmg); - clif_send(buf, sd, SendWho::SELF, MIN_CLIENT_VERSION); + clif_send(buf, sd, SendWho::SELF); } void clif_sitnpc(dumb_ptr<npc_data> nd, DamageType dmg) @@ -3303,7 +3316,7 @@ void clif_sitnpc(dumb_ptr<npc_data> nd, DamageType dmg) Buffer buf; clif_sitnpc_sub(buf, nd, dmg); - clif_send(buf, nd, SendWho::AREA, MIN_CLIENT_VERSION); + clif_send(buf, nd, SendWho::AREA); } static @@ -3340,7 +3353,7 @@ void clif_setnpcdirection_towards(dumb_ptr<map_session_data> sd, dumb_ptr<npc_da Buffer buf; clif_setnpcdirection_sub(buf, nd, direction); - clif_send(buf, sd, SendWho::SELF, MIN_CLIENT_VERSION); + clif_send(buf, sd, SendWho::SELF); } void clif_setnpcdirection(dumb_ptr<npc_data> nd, DIR direction) @@ -3349,7 +3362,7 @@ void clif_setnpcdirection(dumb_ptr<npc_data> nd, DIR direction) Buffer buf; clif_setnpcdirection_sub(buf, nd, direction); - clif_send(buf, nd, SendWho::AREA, MIN_CLIENT_VERSION); + clif_send(buf, nd, SendWho::AREA); } /*========================================== @@ -3408,9 +3421,9 @@ int clif_specialeffect(dumb_ptr<block_list> bl, int type, int flag) } } else if (flag == 1) - clif_send(buf, bl, SendWho::SELF, MIN_CLIENT_VERSION); + clif_send(buf, bl, SendWho::SELF); else if (!flag) - clif_send(buf, bl, SendWho::AREA, MIN_CLIENT_VERSION); + clif_send(buf, bl, SendWho::AREA); return 0; @@ -3839,10 +3852,18 @@ RecvResult clif_parse_GlobalMessage(Session *s, dumb_ptr<map_session_data> sd) } /* It's not a spell/magic message, so send the message to others. */ + Buffer sendbuf; clif_message_sub(sendbuf, sd, mbuf); - clif_send(sendbuf, sd, SendWho::AREA_CHAT_WOC, MIN_CLIENT_VERSION); + Buffer filteredBuf; // ManaPlus remote execution exploit prevention + XString filtered = mbuf; + if (mbuf.contains_seq("@@="_s) && mbuf.contains('|')) + filtered = "##B##3[##1Impossible to see this message. Please update your client.##3]"_s; + clif_message_sub(filteredBuf, sd, filtered); + + clif_send(sendbuf, sd, SendWho::AREA_CHAT_WOC, + wrap<ClientVersion>(6), filteredBuf); } /* Send the message back to the speaker. */ @@ -3868,8 +3889,6 @@ void clif_npc_send_title(Session *s, BlockId npcid, XString msg) void clif_change_music(dumb_ptr<map_session_data> sd, XString music) { nullpo_retv(sd); - if(sd->client_version < 2) - return; size_t msg_len = music.size(); if (msg_len > 128) @@ -3878,7 +3897,7 @@ void clif_change_music(dumb_ptr<map_session_data> sd, XString music) Packet_Head<0x0227> head_227; Buffer buf = create_vpacket<0x0227, 4, 1>(head_227, music); - send_buffer(sd->sess, buf); + clif_send(buf, sd, SendWho::SELF, wrap<ClientVersion>(2)); } void clif_message_towards(dumb_ptr<map_session_data> sd, dumb_ptr<block_list> bl, XString msg) @@ -3891,7 +3910,7 @@ void clif_message_towards(dumb_ptr<map_session_data> sd, dumb_ptr<block_list> bl Buffer buf; clif_message_sub(buf, bl, msg); - clif_send(buf, sd, SendWho::SELF, MIN_CLIENT_VERSION); + clif_send(buf, sd, SendWho::SELF); } void clif_message(dumb_ptr<block_list> bl, XString msg) @@ -3900,20 +3919,18 @@ void clif_message(dumb_ptr<block_list> bl, XString msg) Buffer buf; clif_message_sub(buf, bl, msg); - clif_send(buf, bl, SendWho::AREA, MIN_CLIENT_VERSION); + clif_send(buf, bl, SendWho::AREA); } void clif_send_mask(dumb_ptr<map_session_data> sd, int map_mask) { nullpo_retv(sd); - if(sd->client_version < 2) - return; Packet_Fixed<0x0226> fixed_226; fixed_226.mask = map_mask; Buffer buf = create_fpacket<0x0226, 10>(fixed_226); - send_buffer(sd->sess, buf); + clif_send(buf, sd, SendWho::SELF, wrap<ClientVersion>(2)); } /*========================================== @@ -3957,7 +3974,7 @@ RecvResult clif_parse_ChangeDir(Session *s, dumb_ptr<map_session_data> sd) fixed_9c.client_dir = client_dir; Buffer buf = create_fpacket<0x009c, 9>(fixed_9c); - clif_send(buf, sd, SendWho::AREA_WOS, MIN_CLIENT_VERSION); + clif_send(buf, sd, SendWho::AREA_WOS); return rv; } @@ -3982,7 +3999,7 @@ RecvResult clif_parse_Emotion(Session *s, dumb_ptr<map_session_data> sd) fixed_c0.block_id = sd->bl_id; fixed_c0.type = emote; Buffer buf = create_fpacket<0x00c0, 7>(fixed_c0); - clif_send(buf, sd, SendWho::AREA, MIN_CLIENT_VERSION); + clif_send(buf, sd, SendWho::AREA); } else clif_skill_fail(sd, SkillID::ONE, 0, 1); @@ -4053,7 +4070,7 @@ RecvResult clif_parse_ActionRequest(Session *s, dumb_ptr<map_session_data> sd) fixed_8a.src_id = sd->bl_id; fixed_8a.damage_type = DamageType::STAND; Buffer buf = create_fpacket<0x008a, 29>(fixed_8a); - clif_send(buf, sd, SendWho::AREA, MIN_CLIENT_VERSION); + clif_send(buf, sd, SendWho::AREA); break; } @@ -4951,7 +4968,7 @@ void clif_sendallquest(dumb_ptr<map_session_data> sd) if (!sd->sess) return; - if(sd->client_version < 2) // require 1.5.5.9 or above + if(sd->client_version < wrap<ClientVersion>(2)) // require 1.5.5.9 or above return; Session *s = sd->sess; @@ -4988,7 +5005,7 @@ void clif_sendquest(dumb_ptr<map_session_data> sd, QuestId questid, int value) if (!sd->sess) return; - if(sd->client_version < 2) // require 1.5.5.9 or above + if(sd->client_version < wrap<ClientVersion>(2)) // require 1.5.5.9 or above return; Session *s = sd->sess; @@ -5684,16 +5701,8 @@ AString clif_validate_chat(dumb_ptr<map_session_data> sd, ChatType type, XString return AString(); } - // ManaPlus remote command vulnerability fix - if (buf.contains_seq("@@="_s) && buf.contains('|')) - { - clif_setwaitclose(sd->sess); - WARN_MALFORMED_MSG(sd, "remote command exploit attempt"_s); - return AString(); - } - // Step beyond the separator. for older clients - if (type == ChatType::Global && sd->client_version < 6) + if (type == ChatType::Global && sd->client_version < wrap<ClientVersion>(6)) return buf.xslice_t(sd->status_key.name.to__actual().size() + 3); // newer clients will not send the name diff --git a/src/map/map.hpp b/src/map/map.hpp index a247bb6..47eef57 100644 --- a/src/map/map.hpp +++ b/src/map/map.hpp @@ -154,7 +154,7 @@ struct map_session_data : block_list, SessionData CharId char_id_; int login_id1, login_id2; SEX sex; - int client_version; // tmw client version + ClientVersion client_version; // tmw client version CharKey status_key; CharData status; GenericArray<Option<Borrowed<struct item_data>>, InventoryIndexing<IOff0, MAX_INVENTORY>> inventory_data = diff --git a/src/map/pc.cpp b/src/map/pc.cpp index cb115c3..c47925f 100644 --- a/src/map/pc.cpp +++ b/src/map/pc.cpp @@ -640,8 +640,8 @@ int pc_isequip(dumb_ptr<map_session_data> sd, IOff0 n) * char鯖から送られてきたステータスを設定 *------------------------------------------ */ -int pc_authok(AccountId id, int login_id2, - short client_version, const CharKey *st_key, const CharData *st_data) +int pc_authok(AccountId id, int login_id2, ClientVersion client_version, + const CharKey *st_key, const CharData *st_data) { dumb_ptr<map_session_data> sd = nullptr; diff --git a/src/map/pc.hpp b/src/map/pc.hpp index fc0bdb0..db1d5be 100644 --- a/src/map/pc.hpp +++ b/src/map/pc.hpp @@ -80,7 +80,7 @@ int pc_counttargeted(dumb_ptr<map_session_data> sd, dumb_ptr<block_list> src, int pc_setrestartvalue(dumb_ptr<map_session_data> sd, int type); void pc_makesavestatus(dumb_ptr<map_session_data>); int pc_setnewpc(dumb_ptr<map_session_data>, AccountId, CharId, int, uint32_t /*tick_t*/, SEX); -int pc_authok(AccountId, int, short client_version, const CharKey *, const CharData *); +int pc_authok(AccountId, int, ClientVersion, const CharKey *, const CharData *); int pc_authfail(AccountId accid); EPOS pc_equippoint(dumb_ptr<map_session_data> sd, IOff0 n); diff --git a/src/map/script-fun.cpp b/src/map/script-fun.cpp index 9014d2b..fe5a961 100644 --- a/src/map/script-fun.cpp +++ b/src/map/script-fun.cpp @@ -1161,7 +1161,7 @@ static void builtin_getversion(ScriptState *st) { dumb_ptr<map_session_data> sd = script_rid2sd(st);; - push_int<ScriptDataInt>(st->stack, sd->client_version); + push_int<ScriptDataInt>(st->stack, unwrap<ClientVersion>(sd->client_version)); } /*========================================== diff --git a/src/mmo/fwd.hpp b/src/mmo/fwd.hpp index 434885e..d98bd33 100644 --- a/src/mmo/fwd.hpp +++ b/src/mmo/fwd.hpp @@ -44,6 +44,7 @@ class PartyId; class ItemNameId; class BlockId; class GmLevel; +class ClientVersion; class AccountName; class AccountPass; diff --git a/src/mmo/ids.hpp b/src/mmo/ids.hpp index 28b146a..22f5eae 100644 --- a/src/mmo/ids.hpp +++ b/src/mmo/ids.hpp @@ -41,6 +41,7 @@ class ItemNameId : public Wrapped<uint16_t> { public: constexpr ItemNameId() : W class BlockId : public Wrapped<uint32_t> { public: constexpr BlockId() : Wrapped<uint32_t>() {} protected: constexpr explicit BlockId(uint32_t a) : Wrapped<uint32_t>(a) {} }; class QuestId : public Wrapped<uint16_t> { public: constexpr QuestId() : Wrapped<uint16_t>() {} protected: constexpr explicit QuestId(uint16_t a) : Wrapped<uint16_t>(a) {} }; +class ClientVersion : public Wrapped<uint32_t>{ public: constexpr ClientVersion() : Wrapped<uint32_t>() {} protected: constexpr explicit ClientVersion(uint32_t a) : Wrapped<uint32_t>(a) {} }; bool impl_extract(XString str, GmLevel *lvl); class GmLevel diff --git a/src/mmo/ids.py b/src/mmo/ids.py index a98920f..0d39aae 100644 --- a/src/mmo/ids.py +++ b/src/mmo/ids.py @@ -6,6 +6,7 @@ for s in [ 'ItemNameId', 'BlockId', 'QuestId', + 'ClientVersion', ]: class OtherId(object): __slots__ = ('_value') diff --git a/src/mmo/version.hpp b/src/mmo/version.hpp index 459b500..79d67fe 100644 --- a/src/mmo/version.hpp +++ b/src/mmo/version.hpp @@ -37,9 +37,11 @@ namespace tmwa // increase the min version when the protocol is incompatible with old m+ versions // 1 = latest mana, old manaplus, bots -// 2 = manaplus 1.5.5.9 and above -// 3 = manaplus 1.5.5.23 and above -// 4 = manaplus 1.5.8.15 and above +// 2 = manaplus 1.5.5.9 to manaplus 1.5.5.23 +// 3 = manaplus 1.5.5.23 to manaplus 1.5.8.15 +// 4 = manaplus 1.5.8.15 to manaplus 1.6.3.15 +// 5 = manaplus 1.6.3.15 to 1.6.4.23 (adds SMSG_SCRIPT_MESSAGE) +// 6 = manaplus 1.6.4.23 and above #define MIN_CLIENT_VERSION 1 // TODO now that I generate the protocol, split 'flags' out of the struct |