2025-03-16 14:07:56 -04:00
|
|
|
use crate::{
|
2025-06-18 20:53:07 -04:00
|
|
|
common::timestamp_secs,
|
2025-05-12 22:32:03 -04:00
|
|
|
inventory::Storage,
|
2025-05-02 00:47:11 -04:00
|
|
|
ipc::zone::{
|
2025-06-18 20:53:07 -04:00
|
|
|
ActorControlCategory, ActorControlSelf, ChatMessage, NpcSpawn, ServerZoneIpcData,
|
|
|
|
ServerZoneIpcSegment,
|
2025-05-02 00:47:11 -04:00
|
|
|
},
|
2025-03-26 18:28:51 -04:00
|
|
|
opcodes::ServerZoneIpcType,
|
2025-05-02 00:03:36 -04:00
|
|
|
packet::{PacketSegment, SegmentData, SegmentType},
|
2025-06-18 20:53:07 -04:00
|
|
|
world::ToServer,
|
2025-03-16 14:07:56 -04:00
|
|
|
};
|
|
|
|
|
2025-06-18 20:53:07 -04:00
|
|
|
use super::ZoneConnection;
|
2025-03-15 20:36:39 -04:00
|
|
|
|
|
|
|
pub struct ChatHandler {}
|
|
|
|
|
|
|
|
impl ChatHandler {
|
2025-06-18 20:53:07 -04:00
|
|
|
pub async fn handle_chat_message(connection: &mut ZoneConnection, chat_message: &ChatMessage) {
|
2025-03-15 20:36:39 -04:00
|
|
|
tracing::info!("Client sent chat message: {}!", chat_message.message);
|
|
|
|
|
|
|
|
let parts: Vec<&str> = chat_message.message.split(' ').collect();
|
|
|
|
match parts[0] {
|
2025-03-18 22:13:28 -04:00
|
|
|
"!spawnnpc" => {
|
2025-04-01 19:15:08 -04:00
|
|
|
connection
|
2025-06-18 20:38:55 -04:00
|
|
|
.handle
|
|
|
|
.send(ToServer::DebugNewNpc(
|
|
|
|
connection.id,
|
|
|
|
connection.player_data.actor_id,
|
|
|
|
))
|
2025-04-01 19:15:08 -04:00
|
|
|
.await;
|
2025-03-23 10:33:49 -04:00
|
|
|
}
|
|
|
|
"!spawnmonster" => {
|
2025-05-09 20:09:22 -04:00
|
|
|
connection
|
|
|
|
.handle
|
2025-06-18 20:38:55 -04:00
|
|
|
.send(ToServer::DebugNewEnemy(
|
2025-06-18 20:28:03 -04:00
|
|
|
connection.id,
|
|
|
|
connection.player_data.actor_id,
|
|
|
|
))
|
2025-05-09 20:09:22 -04:00
|
|
|
.await;
|
2025-03-16 14:07:56 -04:00
|
|
|
}
|
2025-04-01 19:15:08 -04:00
|
|
|
"!spawnclone" => {
|
|
|
|
// spawn another one of us
|
2025-04-01 21:37:41 -04:00
|
|
|
let player = &connection.player_data;
|
2025-04-01 19:15:08 -04:00
|
|
|
|
|
|
|
let mut common = connection
|
|
|
|
.get_player_common_spawn(Some(player.position), Some(player.rotation));
|
|
|
|
common.spawn_index = connection.get_free_spawn_index();
|
|
|
|
|
|
|
|
let ipc = ServerZoneIpcSegment {
|
|
|
|
op_code: ServerZoneIpcType::NpcSpawn,
|
|
|
|
timestamp: timestamp_secs(),
|
|
|
|
data: ServerZoneIpcData::NpcSpawn(NpcSpawn {
|
|
|
|
common,
|
|
|
|
..Default::default()
|
|
|
|
}),
|
2025-05-02 23:38:44 -04:00
|
|
|
..Default::default()
|
2025-04-01 19:15:08 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
connection
|
|
|
|
.send_segment(PacketSegment {
|
|
|
|
source_actor: 0x106ad804,
|
|
|
|
target_actor: connection.player_data.actor_id,
|
2025-05-02 00:03:36 -04:00
|
|
|
segment_type: SegmentType::Ipc,
|
|
|
|
data: SegmentData::Ipc { data: ipc },
|
2025-04-01 19:15:08 -04:00
|
|
|
})
|
|
|
|
.await;
|
|
|
|
}
|
2025-05-11 09:27:29 -04:00
|
|
|
"!unlockaction" => {
|
|
|
|
let parts: Vec<&str> = chat_message.message.split(' ').collect();
|
|
|
|
let id = parts[1].parse::<u32>().unwrap();
|
|
|
|
|
|
|
|
connection
|
|
|
|
.actor_control_self(ActorControlSelf {
|
|
|
|
category: ActorControlCategory::ToggleActionUnlock { id, unlocked: true },
|
|
|
|
})
|
|
|
|
.await;
|
|
|
|
}
|
2025-05-12 22:32:03 -04:00
|
|
|
"!equip" => {
|
|
|
|
let (_, name) = chat_message.message.split_once(' ').unwrap();
|
|
|
|
|
|
|
|
{
|
|
|
|
let mut gamedata = connection.gamedata.lock().unwrap();
|
|
|
|
|
|
|
|
if let Some((equip_category, id)) = gamedata.get_item_by_name(name) {
|
|
|
|
let slot = gamedata.get_equipslot_category(equip_category).unwrap();
|
|
|
|
|
|
|
|
connection
|
|
|
|
.player_data
|
|
|
|
.inventory
|
|
|
|
.equipped
|
|
|
|
.get_slot_mut(slot as u16)
|
|
|
|
.id = id;
|
|
|
|
connection
|
|
|
|
.player_data
|
|
|
|
.inventory
|
|
|
|
.equipped
|
|
|
|
.get_slot_mut(slot as u16)
|
|
|
|
.quantity = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
connection.send_inventory(true).await;
|
|
|
|
}
|
2025-05-06 22:03:31 -04:00
|
|
|
_ => {}
|
2025-03-15 20:36:39 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|