2025-03-15 20:36:39 -04:00
|
|
|
use tokio::net::TcpStream;
|
|
|
|
|
|
|
|
use crate::{
|
|
|
|
common::timestamp_secs,
|
|
|
|
ipc::{ActorSetPos, IPCOpCode, IPCSegment, IPCStructData},
|
|
|
|
packet::{
|
|
|
|
CompressionType, ConnectionType, PacketSegment, SegmentType, State, parse_packet,
|
|
|
|
send_packet,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2025-03-15 20:49:07 -04:00
|
|
|
use super::{InitZone, Position, UpdateClassInfo, Zone};
|
2025-03-15 20:36:39 -04:00
|
|
|
|
|
|
|
pub struct ZoneConnection {
|
|
|
|
pub socket: TcpStream,
|
|
|
|
|
|
|
|
pub state: State,
|
|
|
|
pub player_id: u32,
|
2025-03-15 20:49:07 -04:00
|
|
|
|
|
|
|
pub zone: Zone,
|
2025-03-16 14:07:56 -04:00
|
|
|
pub spawn_index: u8,
|
2025-03-15 20:36:39 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
impl ZoneConnection {
|
|
|
|
pub async fn parse_packet(&mut self, data: &[u8]) -> (Vec<PacketSegment>, ConnectionType) {
|
|
|
|
parse_packet(data, &mut self.state).await
|
|
|
|
}
|
|
|
|
|
|
|
|
pub async fn send_segment(&mut self, segment: PacketSegment) {
|
|
|
|
send_packet(
|
|
|
|
&mut self.socket,
|
|
|
|
&[segment],
|
|
|
|
&mut self.state,
|
|
|
|
CompressionType::Oodle,
|
|
|
|
)
|
|
|
|
.await;
|
|
|
|
}
|
|
|
|
|
|
|
|
pub async fn set_player_position(&mut self, position: Position) {
|
|
|
|
// set pos
|
|
|
|
{
|
|
|
|
let ipc = IPCSegment {
|
|
|
|
op_code: IPCOpCode::ActorSetPos,
|
|
|
|
timestamp: timestamp_secs(),
|
|
|
|
data: IPCStructData::ActorSetPos(ActorSetPos {
|
|
|
|
unk: 0x020fa3b8,
|
|
|
|
position,
|
|
|
|
..Default::default()
|
|
|
|
}),
|
2025-03-16 14:07:56 -04:00
|
|
|
..Default::default()
|
2025-03-15 20:36:39 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
let response_packet = PacketSegment {
|
|
|
|
source_actor: self.player_id,
|
|
|
|
target_actor: self.player_id,
|
|
|
|
segment_type: SegmentType::Ipc { data: ipc },
|
|
|
|
};
|
|
|
|
send_packet(
|
|
|
|
&mut self.socket,
|
|
|
|
&[response_packet],
|
|
|
|
&mut self.state,
|
|
|
|
CompressionType::Oodle,
|
|
|
|
)
|
|
|
|
.await;
|
|
|
|
}
|
|
|
|
}
|
2025-03-15 20:49:07 -04:00
|
|
|
|
|
|
|
pub async fn change_zone(&mut self, new_zone_id: u16) {
|
|
|
|
self.zone = Zone::load(new_zone_id);
|
|
|
|
|
|
|
|
// Player Class Info
|
|
|
|
{
|
|
|
|
let ipc = IPCSegment {
|
|
|
|
op_code: IPCOpCode::UpdateClassInfo,
|
|
|
|
timestamp: timestamp_secs(),
|
|
|
|
data: IPCStructData::UpdateClassInfo(UpdateClassInfo {
|
|
|
|
class_id: 35,
|
|
|
|
unknown: 1,
|
|
|
|
synced_level: 90,
|
|
|
|
class_level: 90,
|
|
|
|
..Default::default()
|
|
|
|
}),
|
2025-03-16 14:07:56 -04:00
|
|
|
..Default::default()
|
2025-03-15 20:49:07 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
self.send_segment(PacketSegment {
|
|
|
|
source_actor: self.player_id,
|
|
|
|
target_actor: self.player_id,
|
|
|
|
segment_type: SegmentType::Ipc { data: ipc },
|
|
|
|
})
|
|
|
|
.await;
|
|
|
|
}
|
|
|
|
|
|
|
|
// link shell information
|
|
|
|
{
|
|
|
|
let ipc = IPCSegment {
|
|
|
|
op_code: IPCOpCode::LinkShellInformation,
|
|
|
|
timestamp: timestamp_secs(),
|
|
|
|
data: IPCStructData::LinkShellInformation { unk: [0; 456] },
|
2025-03-16 14:07:56 -04:00
|
|
|
..Default::default()
|
2025-03-15 20:49:07 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
self.send_segment(PacketSegment {
|
|
|
|
source_actor: self.player_id,
|
|
|
|
target_actor: self.player_id,
|
|
|
|
segment_type: SegmentType::Ipc { data: ipc },
|
|
|
|
})
|
|
|
|
.await;
|
|
|
|
}
|
|
|
|
|
2025-03-16 14:07:56 -04:00
|
|
|
// TODO: send unk16?
|
2025-03-15 20:49:07 -04:00
|
|
|
|
|
|
|
// Init Zone
|
|
|
|
{
|
|
|
|
let ipc = IPCSegment {
|
|
|
|
op_code: IPCOpCode::InitZone,
|
|
|
|
timestamp: timestamp_secs(),
|
|
|
|
data: IPCStructData::InitZone(InitZone {
|
2025-03-16 14:07:56 -04:00
|
|
|
server_id: 0,
|
2025-03-15 20:49:07 -04:00
|
|
|
zone_id: self.zone.id,
|
|
|
|
weather_id: 1,
|
|
|
|
..Default::default()
|
|
|
|
}),
|
2025-03-16 14:07:56 -04:00
|
|
|
..Default::default()
|
2025-03-15 20:49:07 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
self.send_segment(PacketSegment {
|
|
|
|
source_actor: self.player_id,
|
|
|
|
target_actor: self.player_id,
|
|
|
|
segment_type: SegmentType::Ipc { data: ipc },
|
|
|
|
})
|
|
|
|
.await;
|
|
|
|
}
|
|
|
|
}
|
2025-03-16 14:07:56 -04:00
|
|
|
|
|
|
|
pub fn get_free_spawn_index(&mut self) -> u8 {
|
|
|
|
self.spawn_index += 1;
|
2025-03-16 14:09:12 -04:00
|
|
|
self.spawn_index
|
2025-03-16 14:07:56 -04:00
|
|
|
}
|
2025-03-15 20:36:39 -04:00
|
|
|
}
|