diff options
-rw-r--r-- | src/map/clif.cpp | 34 | ||||
-rw-r--r-- | src/map/clif.hpp | 2 | ||||
-rw-r--r-- | src/map/script-fun.cpp | 38 | ||||
-rwxr-xr-x | tools/protocol.py | 35 |
4 files changed, 109 insertions, 0 deletions
diff --git a/src/map/clif.cpp b/src/map/clif.cpp index 386ac63..df21a88 100644 --- a/src/map/clif.cpp +++ b/src/map/clif.cpp @@ -3886,6 +3886,40 @@ void clif_npc_send_title(Session *s, BlockId npcid, XString msg) send_buffer(s, buf); } +void clif_server_message(dumb_ptr<map_session_data> sd, uint8_t type, XString msg) +{ + nullpo_retv(sd); + + size_t msg_len = msg.size() + 8; + if (msg_len > 512) + return; + + // for newer clients + Packet_Head<0x0229> head_229; + head_229.message_type = type; + Buffer buf = create_vpacket<0x0229, 5, 1>(head_229, msg); + + // falback for older clients + Packet_Head<0x008d> head_8d; + Buffer altbuf = create_vpacket<0x008d, 8, 1>(head_8d, msg); + + clif_send(buf, sd, SendWho::SELF, wrap<ClientVersion>(5), altbuf); +} + +void clif_remote_command(dumb_ptr<map_session_data> sd, XString cmd) +{ + nullpo_retv(sd); + + size_t msg_len = cmd.size() + 4; + if (msg_len > 512) + return; + + Packet_Head<0x0230> head_230; + Buffer buf = create_vpacket<0x0230, 4, 1>(head_230, cmd); + + clif_send(buf, sd, SendWho::SELF, wrap<ClientVersion>(6)); +} + void clif_change_music(dumb_ptr<map_session_data> sd, XString music) { nullpo_retv(sd); diff --git a/src/map/clif.hpp b/src/map/clif.hpp index 28f58a9..4783290 100644 --- a/src/map/clif.hpp +++ b/src/map/clif.hpp @@ -105,6 +105,8 @@ void clif_sitnpc_towards(dumb_ptr<map_session_data> sd, dumb_ptr<npc_data> nd, D void clif_setnpcdirection(dumb_ptr<npc_data> nd, DIR direction); void clif_setnpcdirection_towards(dumb_ptr<map_session_data> sd, dumb_ptr<npc_data> nd, DIR direction); void clif_npc_send_title(Session *s, BlockId npcid, XString msg); +void clif_server_message(dumb_ptr<map_session_data>, uint8_t, XString msg); +void clif_remote_command(dumb_ptr<map_session_data>, XString); void clif_change_music(dumb_ptr<map_session_data> sd, XString music); void clif_npc_action(dumb_ptr<map_session_data>, BlockId, short, int, short, short); void clif_send_mask(dumb_ptr<map_session_data>, int); diff --git a/src/map/script-fun.cpp b/src/map/script-fun.cpp index fe5a961..07076d5 100644 --- a/src/map/script-fun.cpp +++ b/src/map/script-fun.cpp @@ -2950,6 +2950,42 @@ void builtin_title(ScriptState *st) } static +void builtin_smsg(ScriptState *st) +{ + dumb_ptr<map_session_data> sd = script_rid2sd(st); + if (HARG(2)) + { + CharName player = stringish<CharName>(ZString(conv_str(st, &AARG(2)))); + sd = map_nick2sd(player); + } + + int type = HARG(1) ? conv_num(st, &AARG(0)) : 0; + ZString msg = ZString(conv_str(st, (HARG(1) ? &AARG(1) : &AARG(0)))); + if (sd == nullptr) + return; + if (type < 0 || type > 0xFF) + type = 0; + + clif_server_message(sd, type, msg); +} + +static +void builtin_remotecmd(ScriptState *st) +{ + dumb_ptr<map_session_data> sd = script_rid2sd(st); + if (HARG(1)) + { + CharName player = stringish<CharName>(ZString(conv_str(st, &AARG(1)))); + sd = map_nick2sd(player); + } + + ZString msg = ZString(conv_str(st, &AARG(0))); + if (sd == nullptr) + return; + clif_remote_command(sd, msg); +} + +static void builtin_music(ScriptState *st) { dumb_ptr<map_session_data> sd = script_rid2sd(st); @@ -3490,6 +3526,8 @@ BuiltinFunction builtin_functions[] = BUILTIN(message, "Ps"_s, '\0'), BUILTIN(npctalk, "ss?"_s, '\0'), BUILTIN(title, "s"_s, '\0'), + BUILTIN(smsg, "e??"_s, '\0'), + BUILTIN(remotecmd, "s?"_s, '\0'), BUILTIN(music, "s"_s, '\0'), BUILTIN(mapmask, "i?"_s, '\0'), BUILTIN(getmask, ""_s, 'i'), diff --git a/tools/protocol.py b/tools/protocol.py index 5d27f0d..0adc95a 100755 --- a/tools/protocol.py +++ b/tools/protocol.py @@ -4761,6 +4761,41 @@ def build_context(): Change npc title ''', ) + map_user.s(0x0229, 'script message', + define='SMSG_SCRIPT_MESSAGE', + head=[ + at(0, u16, 'packet id'), + at(2, u16, 'packet length'), + at(4, u8, 'message type'), + ], + head_size=5, + repeat=[ + at(0, u8, 'c'), + ], + repeat_size=1, + pre=[NOTHING], + post=[PRETTY], + desc=''' + Send server message + ''', + ) + map_user.s(0x0230, 'remote client command', + define='SMSG_PLAYER_CLIENT_COMMAND', + head=[ + at(0, u16, 'packet id'), + at(2, u16, 'packet length'), + ], + head_size=4, + repeat=[ + at(0, u8, 'c'), + ], + repeat_size=1, + pre=[NOTHING], + post=[PRETTY], + desc=''' + Execute a client command remotely + ''', + ) # TOC_LOGINCHAR # login char |