From 6fd7eab6ba5d836c47847aca618ee02a50967072 Mon Sep 17 00:00:00 2001 From: mekolat Date: Thu, 7 May 2015 19:35:44 -0400 Subject: allow to make npcs sit --- src/map/atcommand.cpp | 27 +++++++++++++++++++++++++++ src/map/clif.cpp | 43 +++++++++++++++++++++++++------------------ src/map/clif.hpp | 1 + src/map/map.hpp | 1 + src/map/npc-parse.cpp | 4 ++++ tools/protocol.py | 36 +++++++++++++++++++----------------- 6 files changed, 77 insertions(+), 35 deletions(-) diff --git a/src/map/atcommand.cpp b/src/map/atcommand.cpp index 63a1159..d587bde 100644 --- a/src/map/atcommand.cpp +++ b/src/map/atcommand.cpp @@ -4156,6 +4156,30 @@ ATCE atcommand_npcmove(Session *, dumb_ptr, return ATCE::OKAY; } +static +ATCE atcommand_npcsit(Session *, dumb_ptr sd, + ZString message) +{ + NpcName character; + dumb_ptr nd = nullptr; + + if (!asplit(message, &character)) + return ATCE::USAGE; + + nd = npc_name2id(character); + if (nd == nullptr) + return ATCE::EXIST; + + if(nd->sit == DamageType::SIT) + nd->sit = DamageType::STAND; + else + nd->sit = DamageType::SIT; + + clif_sitnpc(sd, nd, true); + + return ATCE::OKAY; +} + static ATCE atcommand_addwarp(Session *s, dumb_ptr sd, ZString message) @@ -5267,6 +5291,9 @@ Map atcommand_info = {"npcmove"_s, {" "_s, 80, atcommand_npcmove, "Force an NPC to move on the map"_s}}, + {"npcsit"_s, {""_s, + 80, atcommand_npcsit, + "Force an NPC to move on the map"_s}}, {"charpvp"_s, {" "_s, 40, atcommand_charpvp, "Set the pvp channel of another player"_s}}, diff --git a/src/map/clif.cpp b/src/map/clif.cpp index 897244e..e48b2fd 100644 --- a/src/map/clif.cpp +++ b/src/map/clif.cpp @@ -781,10 +781,6 @@ void clif_mob0078(dumb_ptr md, Buffer& buf) fixed_78.pos.x = md->bl_x; fixed_78.pos.y = md->bl_y; fixed_78.pos.dir = md->dir; - fixed_78.five1 = 5; - fixed_78.five2 = 5; - int level = battle_get_lv(md); - fixed_78.level = (level > battle_config.max_lv) ? battle_config.max_lv : level; buf = create_fpacket<0x0078, 54>(fixed_78); } @@ -884,11 +880,6 @@ void clif_npc0078(dumb_ptr nd, Buffer& buf) fixed_78.pos.x = nd->bl_x; fixed_78.pos.y = nd->bl_y; fixed_78.pos.dir = nd->dir; - fixed_78.five1 = 5; - fixed_78.five2 = 5; - fixed_78.zero = 0; - fixed_78.level = 0; - buf = create_fpacket<0x0078, 54>(fixed_78); } @@ -951,7 +942,7 @@ int clif_spawnnpc(dumb_ptr nd) if (nd->flag & 1 || nd->npc_class == INVISIBLE_CLASS) return 0; - + /* manaplus is skipping this packet Packet_Fixed<0x007c> fixed_7c; fixed_7c.block_id = nd->bl_id; fixed_7c.speed = nd->speed; @@ -961,10 +952,14 @@ int clif_spawnnpc(dumb_ptr nd) Buffer buf = create_fpacket<0x007c, 41>(fixed_7c); clif_send(buf, nd, SendWho::AREA); - + */ + Buffer buf; clif_npc0078(nd, buf); clif_send(buf, nd, SendWho::AREA); + if(nd->sit == DamageType::SIT) + clif_sitnpc(nullptr, nd, true); + return 0; } @@ -995,15 +990,8 @@ int clif_spawn_fake_npc_for_player(dumb_ptr sd, BlockId fake_n fixed_78.opt2 = Opt2::ZERO; fixed_78.option = Opt0::ZERO; fixed_78.species = FAKE_NPC_CLASS; - fixed_78.unused_head_bottom_or_species_again = unwrap(FAKE_NPC_CLASS); fixed_78.pos.x = sd->bl_x; fixed_78.pos.y = sd->bl_y; - fixed_78.unused_pos_again.x = sd->bl_x; - fixed_78.unused_pos_again.y = sd->bl_y; - fixed_78.five1 = 5; - fixed_78.five2 = 5; - fixed_78.zero = 0; - fixed_78.level = 0; send_fpacket<0x0078, 54>(s, fixed_78); return 0; @@ -2374,6 +2362,9 @@ void clif_getareachar_npc(dumb_ptr sd, dumb_ptr nd) Buffer buf; clif_npc0078(nd, buf); send_buffer(sd->sess, buf); + + if(nd->sit == DamageType::SIT) + clif_sitnpc(sd, nd, false); } /*========================================== @@ -3190,6 +3181,22 @@ void clif_sitting(Session *, dumb_ptr sd) clif_send(buf, sd, SendWho::AREA); } +void clif_sitnpc(dumb_ptr sd, dumb_ptr nd, bool area) +{ + nullpo_retv(nd); + nullpo_retv(sd); + + Packet_Fixed<0x008a> fixed_8a; + fixed_8a.src_id = nd->bl_id; + fixed_8a.damage_type = nd->sit; + Buffer buf = create_fpacket<0x008a, 29>(fixed_8a); + + if(area) + clif_send(buf, nd, SendWho::AREA); + else if(sd) + clif_send(buf, sd, SendWho::SELF); +} + /*========================================== * *------------------------------------------ diff --git a/src/map/clif.hpp b/src/map/clif.hpp index 5117ff3..862aed9 100644 --- a/src/map/clif.hpp +++ b/src/map/clif.hpp @@ -98,6 +98,7 @@ int clif_useitemack(dumb_ptr, IOff0, int, int); // self void clif_emotion(dumb_ptr bl, int type); void clif_emotion_towards(dumb_ptr bl, dumb_ptr target, int type); void clif_sitting(Session *, dumb_ptr sd); +void clif_sitnpc(dumb_ptr sd, dumb_ptr nd, bool area); // trade void clif_traderequest(dumb_ptr sd, CharName name); diff --git a/src/map/map.hpp b/src/map/map.hpp index ce434fa..b5f8566 100644 --- a/src/map/map.hpp +++ b/src/map/map.hpp @@ -324,6 +324,7 @@ struct npc_data : block_list short n; Species npc_class; DIR dir; + DamageType sit; interval_t speed; NpcName name; Opt1 opt1; diff --git a/src/map/npc-parse.cpp b/src/map/npc-parse.cpp index 4d9fcbd..0a0d682 100644 --- a/src/map/npc-parse.cpp +++ b/src/map/npc-parse.cpp @@ -152,6 +152,7 @@ bool npc_load_warp(ast::npc::Warp& warp) nd->bl_y = y; nd->dir = DIR::S; nd->flag = 0; + nd->sit = DamageType::STAND; nd->name = warp.name.data; nd->npc_class = WARP_CLASS; @@ -233,6 +234,7 @@ bool npc_load_shop(ast::npc::Shop& shop) nd->bl_id = npc_get_new_npc_id(); nd->dir = dir; nd->flag = 0; + nd->sit = DamageType::STAND; nd->name = shop.name.data; nd->npc_class = npc_class; nd->speed = 200_ms; @@ -446,6 +448,7 @@ bool npc_load_script_none(ast::script::ScriptBody& body, ast::npc::ScriptNone& s nd->bl_id = npc_get_new_npc_id(); nd->dir = DIR::S; nd->flag = 0; + nd->sit = DamageType::STAND; nd->npc_class = INVISIBLE_CLASS; nd->speed = 200_ms; nd->scr.script = std::move(script); @@ -567,6 +570,7 @@ bool npc_load_script_map(ast::script::ScriptBody& body, ast::npc::ScriptMap& scr nd->bl_id = npc_get_new_npc_id(); nd->dir = dir; nd->flag = 0; + nd->sit = DamageType::STAND; nd->npc_class = npc_class; nd->speed = 200_ms; nd->scr.script = std::move(script); diff --git a/tools/protocol.py b/tools/protocol.py index f13d627..e15d5f0 100755 --- a/tools/protocol.py +++ b/tools/protocol.py @@ -2249,27 +2249,29 @@ def build_context(): at(10, opt2, 'opt2'), at(12, option, 'option'), at(14, species, 'species'), - at(16, u16, 'unused hair style'), + at(16, u8, 'unused hair style'), + at(17, u8, 'unused look'), at(18, u16, 'unused weapon'), - at(20, u16, 'unused head bottom or species again'), - at(22, u16, 'unused shield or part of guild emblem'), - at(24, u16, 'unused head top or unused part of guild emblem'), - at(26, u16, 'unused head mid or part of guild id'), - at(28, u16, 'unused hair color or part of guild id'), + at(20, u16, 'unused head bottom'), + at(22, u16, 'unused shield'), + at(24, u16, 'unused head top'), + at(26, u16, 'unused head mid'), + at(28, u8, 'unused hair color'), + at(29, u8, 'unused'), at(30, u16, 'unused clothes color'), - at(32, u16, 'unused 1'), - at(34, u16, 'unused 2'), - at(36, pos1, 'unused pos again'), - at(39, u8, 'unused 4b'), - at(40, u16, 'unused 5'), - at(42, u16, 'unused zero 1'), - at(44, u8, 'unused zero 2'), + at(32, u16, 'unused gloves'), + at(34, u32, 'unused guild id'), + at(38, u16, 'unused guild emblem id'), + at(40, u16, 'unused manner'), + at(42, u16, 'unused opt3'), + at(44, u8, 'unused karma or atk range'), at(45, u8, 'unused sex'), at(46, pos1, 'pos'), - at(49, u8, 'five1'), - at(50, u8, 'five2'), - at(51, u8, 'zero'), - at(52, u16, 'level'), + at(49, u8, 'unused2'), + at(50, u8, 'unused3'), + at(51, u8, 'unused4'), + at(52, u8, 'unused5'), + at(53, u8, 'unused6'), ], fixed_size=54, pre=[BOOT, FINISH, GM, MAGIC, SCRIPT, TIMER, 0x007d, 0x0085, 0x0089, 0x008c, 0x009f, 0x00b8, 0x00b9, 0x00e6, 0x00f7, 0x0143, 0x0146, 0x01d5], -- cgit v1.2.3-60-g2f50 From 3474fe93eef3cde085b6a9ee8c7efd4a5e2cddea Mon Sep 17 00:00:00 2001 From: mekolat Date: Thu, 7 May 2015 20:42:47 -0400 Subject: add a builtin to change npc direction and make them sit --- src/map/atcommand.cpp | 27 --------------- src/map/clif.cpp | 94 ++++++++++++++++++++++++++++++++++++++++++++------ src/map/clif.hpp | 5 ++- src/map/script-fun.cpp | 38 ++++++++++++++++++++ 4 files changed, 126 insertions(+), 38 deletions(-) diff --git a/src/map/atcommand.cpp b/src/map/atcommand.cpp index d587bde..63a1159 100644 --- a/src/map/atcommand.cpp +++ b/src/map/atcommand.cpp @@ -4156,30 +4156,6 @@ ATCE atcommand_npcmove(Session *, dumb_ptr, return ATCE::OKAY; } -static -ATCE atcommand_npcsit(Session *, dumb_ptr sd, - ZString message) -{ - NpcName character; - dumb_ptr nd = nullptr; - - if (!asplit(message, &character)) - return ATCE::USAGE; - - nd = npc_name2id(character); - if (nd == nullptr) - return ATCE::EXIST; - - if(nd->sit == DamageType::SIT) - nd->sit = DamageType::STAND; - else - nd->sit = DamageType::SIT; - - clif_sitnpc(sd, nd, true); - - return ATCE::OKAY; -} - static ATCE atcommand_addwarp(Session *s, dumb_ptr sd, ZString message) @@ -5291,9 +5267,6 @@ Map atcommand_info = {"npcmove"_s, {" "_s, 80, atcommand_npcmove, "Force an NPC to move on the map"_s}}, - {"npcsit"_s, {""_s, - 80, atcommand_npcsit, - "Force an NPC to move on the map"_s}}, {"charpvp"_s, {" "_s, 40, atcommand_charpvp, "Set the pvp channel of another player"_s}}, diff --git a/src/map/clif.cpp b/src/map/clif.cpp index e48b2fd..5297084 100644 --- a/src/map/clif.cpp +++ b/src/map/clif.cpp @@ -130,6 +130,9 @@ int clif_changelook_towards(dumb_ptr bl, LOOK type, int val, static void clif_quitsave(Session *, dumb_ptr sd); +static +void clif_sitnpc_sub(Buffer& buf, dumb_ptr nd, DamageType dmg); + static void clif_delete(Session *s) { @@ -958,7 +961,11 @@ int clif_spawnnpc(dumb_ptr nd) clif_send(buf, nd, SendWho::AREA); if(nd->sit == DamageType::SIT) - clif_sitnpc(nullptr, nd, true); + { + Buffer buff; + clif_sitnpc_sub(buff, nd, nd->sit); + clif_send(buff, nd, SendWho::AREA); + } return 0; } @@ -2364,7 +2371,11 @@ void clif_getareachar_npc(dumb_ptr sd, dumb_ptr nd) send_buffer(sd->sess, buf); if(nd->sit == DamageType::SIT) - clif_sitnpc(sd, nd, false); + { + Buffer buff; + clif_sitnpc_sub(buff, nd, nd->sit); + send_buffer(sd->sess, buff); + } } /*========================================== @@ -3181,20 +3192,83 @@ void clif_sitting(Session *, dumb_ptr sd) clif_send(buf, sd, SendWho::AREA); } -void clif_sitnpc(dumb_ptr sd, dumb_ptr nd, bool area) +static +void clif_sitnpc_sub(Buffer& buf, dumb_ptr nd, DamageType dmg) { nullpo_retv(nd); - nullpo_retv(sd); Packet_Fixed<0x008a> fixed_8a; fixed_8a.src_id = nd->bl_id; - fixed_8a.damage_type = nd->sit; - Buffer buf = create_fpacket<0x008a, 29>(fixed_8a); + fixed_8a.damage_type = dmg; + buf = create_fpacket<0x008a, 29>(fixed_8a); +} - if(area) - clif_send(buf, nd, SendWho::AREA); - else if(sd) - clif_send(buf, sd, SendWho::SELF); +void clif_sitnpc_towards(dumb_ptr sd, dumb_ptr nd, DamageType dmg) +{ + nullpo_retv(nd); + nullpo_retv(sd); + + if(!sd) + return; + + Buffer buf; + clif_sitnpc_sub(buf, nd, dmg); + clif_send(buf, sd, SendWho::SELF); +} + +void clif_sitnpc(dumb_ptr nd, DamageType dmg) +{ + nullpo_retv(nd); + + Buffer buf; + clif_sitnpc_sub(buf, nd, dmg); + clif_send(buf, nd, SendWho::AREA); +} + +static +void clif_setnpcdirection_sub(Buffer& buf, dumb_ptr nd, DIR direction) +{ + nullpo_retv(nd); + short dir = 1 | 0; + + switch (direction) + { + case DIR::S: dir = 1 | 0; break; // down + case DIR::SW: dir = 1 | 2; break; + case DIR::W: dir = 0 | 2; break; // left + case DIR::NW: dir = 4 | 2; break; + case DIR::N: dir = 4 | 0; break; // up + case DIR::NE: dir = 4 | 8; break; + case DIR::E: dir = 0 | 8; break; // right + case DIR::SE: dir = 1 | 8; break; + } + + Packet_Fixed<0x009c> fixed_9c; + fixed_9c.block_id = nd->bl_id; + fixed_9c.client_dir = dir; + buf = create_fpacket<0x009c, 9>(fixed_9c); +} + +void clif_setnpcdirection_towards(dumb_ptr sd, dumb_ptr nd, DIR direction) +{ + nullpo_retv(nd); + nullpo_retv(sd); + + if(!sd) + return; + + Buffer buf; + clif_setnpcdirection_sub(buf, nd, direction); + clif_send(buf, sd, SendWho::SELF); +} + +void clif_setnpcdirection(dumb_ptr nd, DIR direction) +{ + nullpo_retv(nd); + + Buffer buf; + clif_setnpcdirection_sub(buf, nd, direction); + clif_send(buf, nd, SendWho::AREA); } /*========================================== diff --git a/src/map/clif.hpp b/src/map/clif.hpp index 862aed9..3cc308c 100644 --- a/src/map/clif.hpp +++ b/src/map/clif.hpp @@ -98,7 +98,10 @@ int clif_useitemack(dumb_ptr, IOff0, int, int); // self void clif_emotion(dumb_ptr bl, int type); void clif_emotion_towards(dumb_ptr bl, dumb_ptr target, int type); void clif_sitting(Session *, dumb_ptr sd); -void clif_sitnpc(dumb_ptr sd, dumb_ptr nd, bool area); +void clif_sitnpc(dumb_ptr nd, DamageType dmg); +void clif_sitnpc_towards(dumb_ptr sd, dumb_ptr nd, DamageType dmg); +void clif_setnpcdirection(dumb_ptr nd, DIR direction); +void clif_setnpcdirection_towards(dumb_ptr sd, dumb_ptr nd, DIR direction); // trade void clif_traderequest(dumb_ptr sd, CharName name); diff --git a/src/map/script-fun.cpp b/src/map/script-fun.cpp index 9020203..7617e0d 100644 --- a/src/map/script-fun.cpp +++ b/src/map/script-fun.cpp @@ -1631,6 +1631,43 @@ void builtin_setnpctimer(ScriptState *st) npc_settimerevent_tick(nd, tick); } +static +void builtin_setnpcdirection(ScriptState *st) +{ + dumb_ptr nd_; + DIR dir = static_cast(conv_num(st, &AARG(0))); + bool save = bool(conv_num(st, &AARG(2))); + DamageType action; + + if (HARG(3)) + nd_ = npc_name2id(stringish(ZString(conv_str(st, &AARG(3))))); + else + nd_ = map_id_is_npc(st->oid); + + if (bool(conv_num(st, &AARG(1)))) + action = DamageType::SIT; + else + action = DamageType::STAND; + + if (save) + { + nd_->dir = dir; + nd_->sit = action; + } + + if (st->rid) + { + dumb_ptr sd = script_rid2sd(st); + clif_sitnpc_towards(sd, nd_, action); + clif_setnpcdirection_towards(sd, nd_, dir); + } + else + { + clif_sitnpc(nd_, action); + clif_setnpcdirection(nd_, dir); + } +} + /*========================================== * 天の声アナウンス *------------------------------------------ @@ -3062,6 +3099,7 @@ BuiltinFunction builtin_functions[] = BUILTIN(stopnpctimer, "?"_s, '\0'), BUILTIN(getnpctimer, "i?"_s, 'i'), BUILTIN(setnpctimer, "i?"_s, '\0'), + BUILTIN(setnpcdirection, "iii?"_s, '\0'), BUILTIN(announce, "si"_s, '\0'), BUILTIN(mapannounce, "Msi"_s, '\0'), BUILTIN(getusers, "i"_s, 'i'), -- cgit v1.2.3-60-g2f50 From c6c3671dbe28c596ef06b4670979c5923c8821b6 Mon Sep 17 00:00:00 2001 From: mekolat Date: Tue, 19 May 2015 18:27:46 -0400 Subject: fix mob hp, add mob range, unfuck packets --- src/map/clif.cpp | 25 ++++++++++++----- src/map/map.hpp | 1 + tools/protocol.py | 80 ++++++++++++++++++++++++++++++------------------------- 3 files changed, 62 insertions(+), 44 deletions(-) diff --git a/src/map/clif.cpp b/src/map/clif.cpp index 5297084..bae0bf1 100644 --- a/src/map/clif.cpp +++ b/src/map/clif.cpp @@ -772,6 +772,8 @@ static void clif_mob0078(dumb_ptr md, Buffer& buf) { nullpo_retv(md); + int max_hp = md->stats[mob_stat::MAX_HP]; + int hp = md->hp; Packet_Fixed<0x0078> fixed_78; fixed_78.block_id = md->bl_id; @@ -785,6 +787,12 @@ void clif_mob0078(dumb_ptr md, Buffer& buf) fixed_78.pos.y = md->bl_y; fixed_78.pos.dir = md->dir; + fixed_78.gloves_or_part_of_hp = static_cast(hp >> 16); + fixed_78.part_of_guild_id_or_part_of_hp = static_cast(hp & 0xffff); + fixed_78.part_of_guild_id_or_part_of_max_hp = static_cast(max_hp >> 16); + fixed_78.guild_emblem_or_part_of_max_hp = static_cast(max_hp & 0xffff); + fixed_78.karma_or_attack_range = battle_get_range(md); + buf = create_fpacket<0x0078, 54>(fixed_78); } @@ -796,6 +804,8 @@ static void clif_mob007b(dumb_ptr md, Buffer& buf) { nullpo_retv(md); + int max_hp = md->stats[mob_stat::MAX_HP]; + int hp = md->hp; Packet_Fixed<0x007b> fixed_7b; fixed_7b.block_id = md->bl_id; @@ -805,18 +815,18 @@ void clif_mob007b(dumb_ptr md, Buffer& buf) fixed_7b.option = md->option; fixed_7b.mob_class = md->mob_class; // snip: stuff for monsters disguised as PCs - fixed_7b.tick_and_maybe_part_of_guild_emblem = gettick(); - fixed_7b.max_hp = md->stats[mob_stat::MAX_HP]; - fixed_7b.hp = md->hp; + fixed_7b.tick = gettick(); fixed_7b.pos2.x0 = md->bl_x; fixed_7b.pos2.y0 = md->bl_y; fixed_7b.pos2.x1 = md->to_x; fixed_7b.pos2.y1 = md->to_y; - fixed_7b.five1 = 5; - fixed_7b.five2 = 5; - int level = battle_get_lv(md); - fixed_7b.level = (level > battle_config.max_lv) ? battle_config.max_lv : level; + + fixed_7b.gloves_or_part_of_hp = static_cast(hp >> 16); + fixed_7b.part_of_guild_id_or_part_of_hp = static_cast(hp & 0xffff); + fixed_7b.part_of_guild_id_or_part_of_max_hp = static_cast(max_hp >> 16); + fixed_7b.guild_emblem_or_part_of_max_hp = static_cast(max_hp & 0xffff); + fixed_7b.karma_or_attack_range = battle_get_range(md); buf = create_fpacket<0x007b, 60>(fixed_7b); } @@ -883,6 +893,7 @@ void clif_npc0078(dumb_ptr nd, Buffer& buf) fixed_78.pos.x = nd->bl_x; fixed_78.pos.y = nd->bl_y; fixed_78.pos.dir = nd->dir; + fixed_78.sex = nd->sex; buf = create_fpacket<0x0078, 54>(fixed_78); } diff --git a/src/map/map.hpp b/src/map/map.hpp index b5f8566..aac646b 100644 --- a/src/map/map.hpp +++ b/src/map/map.hpp @@ -324,6 +324,7 @@ struct npc_data : block_list short n; Species npc_class; DIR dir; + SEX sex; DamageType sit; interval_t speed; NpcName name; diff --git a/tools/protocol.py b/tools/protocol.py index e15d5f0..003f511 100755 --- a/tools/protocol.py +++ b/tools/protocol.py @@ -2249,29 +2249,30 @@ def build_context(): at(10, opt2, 'opt2'), at(12, option, 'option'), at(14, species, 'species'), - at(16, u8, 'unused hair style'), - at(17, u8, 'unused look'), - at(18, u16, 'unused weapon'), - at(20, u16, 'unused head bottom'), - at(22, u16, 'unused shield'), - at(24, u16, 'unused head top'), - at(26, u16, 'unused head mid'), - at(28, u8, 'unused hair color'), - at(29, u8, 'unused'), - at(30, u16, 'unused clothes color'), - at(32, u16, 'unused gloves'), - at(34, u32, 'unused guild id'), - at(38, u16, 'unused guild emblem id'), - at(40, u16, 'unused manner'), - at(42, u16, 'unused opt3'), - at(44, u8, 'unused karma or atk range'), - at(45, u8, 'unused sex'), + at(16, u8, 'hair style'), + at(17, u8, 'look'), + at(18, u16, 'weapon'), + at(20, u16, 'head bottom'), + at(22, u16, 'shield'), + at(24, u16, 'head top'), + at(26, u16, 'head mid'), + at(28, u8, 'hair color'), + at(29, u8, 'unused 1'), + at(30, u16, 'shoes or clothes color'), + at(32, u16, 'gloves or part of hp'), + at(34, u16, 'part of guild id or part of hp'), + at(36, u16, 'part of guild id or part of max hp'), + at(38, u16, 'guild emblem or part of max hp'), + at(40, u16, 'manner'), + at(42, u16, 'opt3'), + at(44, u8, 'karma or attack range'), + at(45, sex, 'sex'), at(46, pos1, 'pos'), - at(49, u8, 'unused2'), - at(50, u8, 'unused3'), - at(51, u8, 'unused4'), - at(52, u8, 'unused5'), - at(53, u8, 'unused6'), + at(49, u8, 'unused 2'), + at(50, u8, 'unused 3'), + at(51, u8, 'unused 4'), + at(52, u8, 'unused 5'), + at(53, u8, 'unused 6'), ], fixed_size=54, pre=[BOOT, FINISH, GM, MAGIC, SCRIPT, TIMER, 0x007d, 0x0085, 0x0089, 0x008c, 0x009f, 0x00b8, 0x00b9, 0x00e6, 0x00f7, 0x0143, 0x0146, 0x01d5], @@ -2290,26 +2291,31 @@ def build_context(): at(10, opt2, 'opt2'), at(12, option, 'option'), at(14, species, 'mob class'), - at(16, u16, 'unused hair style'), + at(16, u8, 'hair style'), + at(17, u8, 'look'), at(18, u16, 'unused weapon'), at(20, u16, 'unused head bottom'), - at(22, tick32, 'tick and maybe part of guild emblem'), - at(26, u16, 'unused shield or maybe part of guild emblem'), - at(28, u16, 'unused head top or maybe part of guild id'), - at(30, u16, 'unused head mid or maybe part of guild id'), - at(32, u16, 'unused hair color'), + at(22, tick32, 'tick'), + at(26, u16, 'unused shield'), + at(28, u16, 'unused head top'), + at(30, u16, 'unused head mid'), + at(32, u8, 'unused hair color'), + at(33, u8, 'unused 1'), at(34, u16, 'unused clothes color'), - at(36, i32, 'max_hp'), - at(40, i32, 'hp'), - at(44, u16, 'unused 5'), - at(46, u16, 'unused zero 1'), - at(48, u8, 'unused zero 2'), + at(36, u16, 'gloves or part of hp'), + at(38, u16, 'part of guild id or part of hp'), + at(40, u16, 'part of guild id or part of max hp'), + at(42, u16, 'guild emblem or part of max hp'), + at(44, u16, 'manner'), + at(46, u16, 'opt3'), + at(48, u8, 'karma or attack range'), at(49, u8, 'unused sex'), at(50, pos2, 'pos2'), - at(55, u8, 'zero'), - at(56, u8, 'five1'), - at(57, u8, 'five2'), - at(58, u16, 'level'), + at(55, u8, 'unused 2'), + at(56, u8, 'unused 3'), + at(57, u8, 'unused 4'), + at(58, u8, 'unused 5'), + at(59, u8, 'unused 6'), ], fixed_size=60, pre=[FINISH, GM, MAGIC, SCRIPT, TIMER, 0x007d, 0x0085, 0x0089, 0x008c, 0x009f], -- cgit v1.2.3-60-g2f50 From f8fb37a14476e0d8fd7cc2c87fe9813ae9dc30b5 Mon Sep 17 00:00:00 2001 From: mekolat Date: Tue, 19 May 2015 21:09:48 -0400 Subject: handle old client in login server too --- src/char/char.hpp | 3 --- src/login/login.cpp | 4 +--- src/login/login.hpp | 2 -- src/mmo/login.t.hpp | 44 -------------------------------------------- src/mmo/version.hpp | 3 +++ tools/protocol.py | 7 +------ 6 files changed, 5 insertions(+), 58 deletions(-) delete mode 100644 src/mmo/login.t.hpp diff --git a/src/char/char.hpp b/src/char/char.hpp index 8adac4d..049875b 100644 --- a/src/char/char.hpp +++ b/src/char/char.hpp @@ -42,9 +42,6 @@ std::chrono::seconds DEFAULT_AUTOSAVE_INTERVAL = 5_min; constexpr GmLevel default_gm_level = GmLevel::from(0_u32); -// increase the min version when the protocol is incompatible with old m+ versions -#define MIN_CLIENT_VERSION 1 - struct AuthFifoEntry { AccountId account_id; diff --git a/src/login/login.cpp b/src/login/login.cpp index 886c510..9310ad3 100644 --- a/src/login/login.cpp +++ b/src/login/login.cpp @@ -2494,9 +2494,7 @@ void parse_login(Session *s) result = mmo_auth(&account, s); if (result == -1) { - VERSION_2 version_2 = fixed.version_2_flags; - if (!bool(version_2 & VERSION_2::UPDATEHOST) - || !bool(version_2 & VERSION_2::SERVERORDER)) + if (fixed.version < MIN_CLIENT_VERSION) result = 5; // client too old } if (result == -1) diff --git a/src/login/login.hpp b/src/login/login.hpp index ae99558..ba42bae 100644 --- a/src/login/login.hpp +++ b/src/login/login.hpp @@ -18,8 +18,6 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -#include "login.t.hpp" - #include "fwd.hpp" #include "../strings/vstring.hpp" diff --git a/src/mmo/login.t.hpp b/src/mmo/login.t.hpp deleted file mode 100644 index f2c775a..0000000 --- a/src/mmo/login.t.hpp +++ /dev/null @@ -1,44 +0,0 @@ -#pragma once -// login.t.hpp - externally useful types from login -// -// Copyright © ????-2004 Athena Dev Teams -// Copyright © 2004-2011 The Mana World Development Team -// Copyright © 2011-2014 Ben Longbons -// -// This file is part of The Mana World (Athena server) -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include "fwd.hpp" - -#include - -#include "../generic/enum.hpp" - - -namespace tmwa -{ -namespace e -{ -enum class VERSION_2 : uint8_t -{ - /// client supports updatehost - UPDATEHOST = 0x01, - /// send servers in forward order - SERVERORDER = 0x02, -}; -ENUM_BITWISE_OPERATORS(VERSION_2) -} -using e::VERSION_2; -} // namespace tmwa diff --git a/src/mmo/version.hpp b/src/mmo/version.hpp index a09953f..6de3a9c 100644 --- a/src/mmo/version.hpp +++ b/src/mmo/version.hpp @@ -35,6 +35,9 @@ namespace tmwa #define TMWA_SERVER_INTER 0x04 #define TMWA_SERVER_MAP 0x08 +// increase the min version when the protocol is incompatible with old m+ versions +#define MIN_CLIENT_VERSION 1 + // TODO now that I generate the protocol, split 'flags' out of the struct struct Version { diff --git a/tools/protocol.py b/tools/protocol.py index 003f511..86b625f 100755 --- a/tools/protocol.py +++ b/tools/protocol.py @@ -1456,9 +1456,6 @@ def build_context(): #md5_native = md5_h.native('md5_native') #SaltString = md5_h.native('SaltString') - VERSION_2 = login_th.native('VERSION_2') - - Position1 = clif_th.native('Position1') NetPosition1 = clif_th.network('NetPosition1') Position2 = clif_th.native('Position2') @@ -1588,8 +1585,6 @@ def build_context(): ] ) - version_2 = ctx.enum(VERSION_2, u8) - stats6 = ctx.struct( 'Stats6', [ @@ -1966,7 +1961,7 @@ def build_context(): at(2, u32, 'unknown'), at(6, account_name, 'account name'), at(30, account_pass, 'account pass'), - at(54, version_2, 'version 2 flags'), + at(54, u8, 'version'), ], fixed_size=55, pre=[HUMAN, 0x7531], -- cgit v1.2.3-60-g2f50 From 4166a53fa3ced75afa25bd5bfb20ca87eca0e25f Mon Sep 17 00:00:00 2001 From: mekolat Date: Tue, 19 May 2015 22:33:16 -0400 Subject: update changelog --- CHANGELOG | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 8790848..a4b24c8 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,12 @@ +v15.5.19 + - check client version in login server + - make npcs sit-able + - send mob attack range + - send mob hp properly + - send npc sex + - add builtin setnpcdirection + - make packet SMSG_BEING_VISIBLE follow manaplus spec + - make packet SMSG_BEING_MOVE follow manaplus spec v15.5.18 - reject old incompatible clients - check client version before sending quest data -- cgit v1.2.3-60-g2f50