From 227c8c1eb23c2368eb43700f60ef2b04a56b4fd3 Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Sat, 29 Mar 2025 00:39:00 -0400 Subject: [PATCH] Add //gm wireframe command --- USAGE.md | 1 + src/bin/kawari-world.rs | 58 ++++++++++++++++++++++++---------- src/world/ipc/actor_control.rs | 2 ++ src/world/ipc/mod.rs | 1 + 4 files changed, 45 insertions(+), 17 deletions(-) diff --git a/USAGE.md b/USAGE.md index 184a7a3..161cfd4 100644 --- a/USAGE.md +++ b/USAGE.md @@ -93,3 +93,4 @@ These GM commands are implemented in the FFXIV protocol, but only some of them a * `//gm teri `: Changes to the specified territory * `//gm weather `: Changes the weather +* `//gm wireframe`: Toggle wireframe rendering for the environment diff --git a/src/bin/kawari-world.rs b/src/bin/kawari-world.rs index 2bf8de0..30b7caa 100644 --- a/src/bin/kawari-world.rs +++ b/src/bin/kawari-world.rs @@ -602,9 +602,7 @@ async fn main() { connection.change_zone(*arg as u16).await } GameMasterCommandType::ToggleInvisibility => { - // Control Data - { - let ipc = ServerZoneIpcSegment { + let ipc = ServerZoneIpcSegment { op_code: ServerZoneIpcType::ActorControlSelf, timestamp: timestamp_secs(), data: ServerZoneIpcData::ActorControlSelf( @@ -618,20 +616,46 @@ async fn main() { ..Default::default() }; - connection - .send_segment(PacketSegment { - source_actor: connection - .player_data - .actor_id, - target_actor: connection - .player_data - .actor_id, - segment_type: SegmentType::Ipc { - data: ipc, - }, - }) - .await; - } + connection + .send_segment(PacketSegment { + source_actor: connection + .player_data + .actor_id, + target_actor: connection + .player_data + .actor_id, + segment_type: SegmentType::Ipc { + data: ipc, + }, + }) + .await; + } + GameMasterCommandType::ToggleWireframe => { + let ipc = ServerZoneIpcSegment { + op_code: ServerZoneIpcType::ActorControlSelf, + timestamp: timestamp_secs(), + data: ServerZoneIpcData::ActorControlSelf( + ActorControlSelf { + category: + ActorControlCategory::ToggleWireframeRendering(), + }, + ), + ..Default::default() + }; + + connection + .send_segment(PacketSegment { + source_actor: connection + .player_data + .actor_id, + target_actor: connection + .player_data + .actor_id, + segment_type: SegmentType::Ipc { + data: ipc, + }, + }) + .await; } } } diff --git a/src/world/ipc/actor_control.rs b/src/world/ipc/actor_control.rs index bdc7f8f..6e97d11 100644 --- a/src/world/ipc/actor_control.rs +++ b/src/world/ipc/actor_control.rs @@ -28,6 +28,8 @@ pub enum ActorControlCategory { #[brw(pad_before = 2)] icon: OnlineStatus, }, + #[brw(magic = 0x261u16)] + ToggleWireframeRendering(), } #[binrw] diff --git a/src/world/ipc/mod.rs b/src/world/ipc/mod.rs index a817cd1..b4d344e 100644 --- a/src/world/ipc/mod.rs +++ b/src/world/ipc/mod.rs @@ -129,6 +129,7 @@ pub struct ActorSetPos { pub enum GameMasterCommandType { ChangeWeather = 0x6, ToggleInvisibility = 0xD, + ToggleWireframe = 0x26, ChangeTerritory = 0x58, }