Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions core/src/ipc/zone/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,20 @@ pub enum ClientZoneIpcData {
#[brw(pad_after = 6)] // Seems to just be padding/garbage
name: String,
},
Dive {
rotation: f32,
target_position: Position,
#[brw(pad_after = 4)]
original_position: Position,
},
WorldInteraction {
action: u32,
param1: u32,
param2: u32,
param3: u32,
param4: u32,
position: Position,
},
}

#[cfg(test)]
Expand Down
2 changes: 2 additions & 0 deletions core/src/ipc/zone/server/actor_set_pos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ pub enum WarpType {
/// Seen during Mt Gulg, assuming it applies to all instanced content.
#[brw(magic = 25u8)]
InstanceContent,
#[brw(magic = 26u8)]
Dive,
#[brw(magic = 30u8)]
Unk4,
Unknown(u8),
Expand Down
1 change: 1 addition & 0 deletions core/src/ipc/zone/server/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ pub enum ServerZoneIpcData {
log_message: u32,
target_zone: u16,
animation: u16,
/// This, in conjunction with unk1, seem to influence visual effects displayed during the zoning transition. For example, when diving, param4 is 218, and unk1 is 6 (with hide_character set to 1). When surfacing, param4 is 227, unk1 6, and hide_character 1. When going through an underwater portal, param4 is 15, unk1 is 4, and hide_character is 2.
param4: u8,
hide_character: u8,
/// Must match what is used in ActorSetPos (if applicable) otherwise weird stuff like EnterTerritoryEvent is sent by the client again.
Expand Down
8 changes: 8 additions & 0 deletions resources/data/opcodes.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1068,6 +1068,14 @@ ClientZoneIpcType:
comment: The client requests that any attachments in this letter be given to them.
opcode: 590
size: 64
- name: Dive
comment: The client dives underwater.
opcode: 631
size: 32
- name: WorldInteraction
comment: The client interacts with the world in some way.
opcode: 296
size: 32
ServerLobbyIpcType:
- name: NackReply
comment: Sent by the server to indicate an lobby error occured.
Expand Down
13 changes: 10 additions & 3 deletions servers/world/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use kawari::{
ClientTrigger, Conditions, Config, CrossworldLinkshellInvite, InviteReply, InviteType,
OnlineStatus, PartyMemberEntry, PartyMemberPositions, PartyUpdateStatus,
ReadyCheckReply, ServerZoneIpcSegment, SpawnNpc, SpawnObject, SpawnPlayer,
SpawnTreasure, StrategyBoard, StrategyBoardUpdate, WaymarkPlacementMode,
SpawnTreasure, StrategyBoard, StrategyBoardUpdate, WarpType, WaymarkPlacementMode,
WaymarkPosition, WaymarkPreset,
},
},
Expand Down Expand Up @@ -278,8 +278,15 @@ pub enum ToServer {
// TODO: the connection should not be in charge and telling the global server what zone they just loaded in! but this will work for now
ZoneLoaded(ClientId, ObjectId, SpawnPlayer),
/// The connection wants to enter a new zone.
// TODO: temporary as this is only used for commands and those aren't run on global server state yet
ChangeZone(ClientId, ObjectId, u16, Option<Position>, Option<f32>),
// TODO: temporary as this is only used for commands (and diving/surfacing due to this being the least intrusive way to do this currently) and those aren't run on global server state yet
ChangeZone(
ClientId,
ObjectId,
u16,
Option<Position>,
Option<f32>,
Option<(WarpType, u8, u8, u8)>,
),
/// The player walks through a zone change line.
EnterZoneJump(ClientId, ObjectId, u32),
/// The connection disconnected.
Expand Down
47 changes: 46 additions & 1 deletion servers/world/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use kawari::ipc::zone::{
ActorControlCategory, CWLSLeaveReason, Conditions, ContentFinderUserAction, CrossRealmListing,
CrossRealmListings, EventType, LinkshellInviteResponse, MapEffects, MarketBoardItem,
OnlineStatus, OnlineStatusMask, PlayerSetup, SceneFlags, SearchInfo, SocialListRequestType,
TrustContent, TrustInformation,
TrustContent, TrustInformation, WarpType,
};

use kawari::ipc::zone::{
Expand Down Expand Up @@ -2942,6 +2942,51 @@ async fn process_packet(
.remove_from_friend_list(*content_id, name.clone())
.await;
}
ClientZoneIpcData::Dive {
target_position,
rotation,
..
} => {
connection
.change_zone(
connection.player_data.volatile.zone_id as u16,
Some(*target_position),
Some(*rotation),
Some((WarpType::Dive, 218, 1, 6)),
)
.await;
}
ClientZoneIpcData::WorldInteraction {
action,
param1,
param2,
param3,
param4,
position,
} => {
match action {
0xD1 => { // Underwater portal
// TODO: This uses param1 somehow. It doesn't appear to be a poprange or exit box. If it's an index into a sheet, I have no idea which.
// TODO: The ActorSetPos for underwater portals uses warp_type: WarpType::InstanceContent, param4 = 15, hide_character = 2, unk1 = 4.
}
0x25F => {
// Surfacing from diving
connection
.change_zone(
connection.player_data.volatile.zone_id as u16,
Some(*position),
Some(connection.player_data.volatile.rotation as f32),
Some((WarpType::Dive, 227, 1, 6)),
)
.await;
}
_ => {
tracing::info!(
"Client executed uninplemented world interaction {action} with params {param1} {param2} {param3} {param4}"
);
}
}
}
ClientZoneIpcData::Unknown { unk } => {
tracing::warn!(
"Unknown Zone packet {:?} recieved ({} bytes), this should be handled!",
Expand Down
38 changes: 32 additions & 6 deletions servers/world/src/server/zone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -776,6 +776,9 @@ fn begin_change_zone<'a>(
destination_zone_id: u16,
actor_id: ObjectId,
warp_type: WarpType,
param4: u8,
hide_character: u8,
unk1: u8,
) -> Option<(&'a mut Instance, bool)> {
let mut needs_init_zone = false;

Expand All @@ -785,10 +788,10 @@ fn begin_change_zone<'a>(
fade_out_time: 1,
log_message: 0,
animation: 0,
param4: 0,
hide_character: 0,
param4,
hide_character,
param_7: 0,
unk1: 0,
unk1,
unk2: 0,
});

Expand Down Expand Up @@ -837,6 +840,9 @@ pub fn change_zone_warp_to_pop_range(
destination_zone_id,
actor_id,
warp_type,
0,
0,
0,
)
.unwrap();

Expand Down Expand Up @@ -928,6 +934,9 @@ pub fn change_zone_to_player(
destination_zone_id,
from_actor_id,
WarpType::Normal,
0,
0,
0,
)
.unwrap();

Expand Down Expand Up @@ -1031,20 +1040,37 @@ pub fn handle_zone_messages(

true
}
ToServer::ChangeZone(from_id, actor_id, zone_id, new_position, new_rotation) => {
ToServer::ChangeZone(
from_id,
actor_id,
zone_id,
new_position,
new_rotation,
warp_type_info,
) => {
tracing::info!("{from_id:?} is requesting to go to zone {zone_id}");

let mut data = data.lock();
let mut network = network.lock();
let mut game_data = game_data.lock();

let (warp_type, param4, hide_character, unk1) =
if let Some((w_type, param, hide, unk)) = warp_type_info {
(*w_type, *param, *hide, *unk)
} else {
(WarpType::Normal, 0, 0, 0)
};

let (target_instance, needs_init_zone) = begin_change_zone(
&mut data,
&mut network,
&mut game_data,
*zone_id,
*actor_id,
WarpType::Normal,
warp_type,
param4,
hide_character,
unk1,
)
.unwrap();
do_change_zone(
Expand All @@ -1054,7 +1080,7 @@ pub fn handle_zone_messages(
*new_position,
*new_rotation,
*from_id,
WarpType::Normal,
warp_type,
);

true
Expand Down
2 changes: 1 addition & 1 deletion servers/world/src/zone_connection/lua.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ impl ZoneConnection {
exit_position,
exit_rotation,
} => {
self.change_zone(*zone_id, *exit_position, *exit_rotation)
self.change_zone(*zone_id, *exit_position, *exit_rotation, None)
.await
}
LuaTask::SetRemakeMode(remake_mode) => {
Expand Down
4 changes: 3 additions & 1 deletion servers/world/src/zone_connection/zone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use kawari::{
constants::OBFUSCATION_ENABLED_MODE,
ipc::zone::{
ActorControlCategory, Condition, ContentRegistrationFlags, House, HouseList, InitZone,
InitZoneFlags, ServerZoneIpcData, ServerZoneIpcSegment, WeatherChange,
InitZoneFlags, ServerZoneIpcData, ServerZoneIpcSegment, WarpType, WeatherChange,
},
packet::{ConnectionState, PacketSegment, ScramblerKeyGenerator, SegmentData, SegmentType},
};
Expand All @@ -24,6 +24,7 @@ impl ZoneConnection {
new_zone_id: u16,
new_position: Option<Position>,
new_rotation: Option<f32>,
warp_type_info: Option<(WarpType, u8, u8, u8)>,
) {
self.teleport_reason = TeleportReason::NotSpecified;
self.handle
Expand All @@ -33,6 +34,7 @@ impl ZoneConnection {
new_zone_id,
new_position,
new_rotation,
warp_type_info,
))
.await;
}
Expand Down
Loading