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
4 changes: 2 additions & 2 deletions core/src/ipc/chat/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use binrw::binrw;

#[binrw]
#[brw(repr = u16)]
#[derive(Clone, Copy, Debug, Default)]
#[derive(Clone, Copy, Debug, Default, PartialEq)]
pub enum ChatChannelType {
#[default]
None = 0,
Expand All @@ -20,7 +20,7 @@ pub enum ChatChannelType {
}

#[binrw]
#[derive(Clone, Copy, Debug, Default)]
#[derive(Clone, Copy, Debug, Default, PartialEq)]
pub struct ChatChannel {
pub channel_number: u32,
pub channel_type: ChatChannelType,
Expand Down
24 changes: 17 additions & 7 deletions core/src/ipc/zone/server/linkshell.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
use binrw::binrw;
use strum_macros::FromRepr;

use crate::common::{read_bool_from, write_bool_as};
use crate::ipc::zone::server::{CHAR_NAME_MAX_LENGTH, ChatChannel, read_string, write_string};

/// Represents one entry in the Linkshells opcode.
#[binrw]
#[derive(Clone, Debug, Default)]
pub struct LinkshellEntry {
pub linkshell_id: u64,
pub chatchannel_id: ChatChannel,
pub common_ids: CWLSCommonIdentifiers,
pub unk1: u32,
#[brw(pad_size_to = CHAR_NAME_MAX_LENGTH)]
#[br(count = CHAR_NAME_MAX_LENGTH)]
Expand All @@ -26,14 +27,23 @@ impl LinkshellEntry {
#[binrw]
#[derive(Debug, Default, Clone)]
pub struct CWLSMemberListEntry {
content_id: u64,
unk1: [u8; 14],
pub content_id: u64,
pub unk_timestamp: u32, // Possibly when this member joined, or last had their rank changed?
pub home_world_id: u16,
pub current_world_id: u16,
pub zone_id: u16,
pub rank: CWLSPermissionRank,
pub unk1: u8,
#[br(map = read_bool_from::<u8>)]
#[bw(map = write_bool_as::<u8>)]
pub is_online: bool,
pub unk2: u8, // TODO: What is this? It seems to always be 1, but changing it makes no apparent difference.
#[brw(pad_after = 2)] // Seems to be empty/zeroes
#[brw(pad_size_to = CHAR_NAME_MAX_LENGTH)]
#[br(count = CHAR_NAME_MAX_LENGTH)]
#[br(map = read_string)]
#[bw(map = write_string)]
name: String,
pub name: String,
}

impl CWLSMemberListEntry {
Expand All @@ -45,7 +55,7 @@ impl CWLSMemberListEntry {
#[binrw]
#[brw(repr = u8)]
#[repr(u8)]
#[derive(Debug, Default, Clone)]
#[derive(Clone, Copy, Debug, Default, FromRepr, PartialEq)]
pub enum CWLSPermissionRank {
#[default]
/// The player has been invited but has yet to answer the invitation.
Expand All @@ -66,7 +76,7 @@ pub struct CWLSCommonIdentifiers {
pub linkshell_chat_id: ChatChannel,
}

/// Represents the CWLS's name permission rank info. This was added to help reduce copy paste in CrossworldLinkshell & CrossworldLinkshellEx.
/// Represents the CWLS's name & permission rank info. This was added to help reduce copy paste in CrossworldLinkshell & CrossworldLinkshellEx.
#[binrw]
#[derive(Debug, Default, Clone)]
pub struct CWLSCommon {
Expand Down
9 changes: 6 additions & 3 deletions core/src/ipc/zone/server/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,8 @@ pub use marketboard::MarketBoardItem;

mod linkshell;
pub use linkshell::{
CWLSMemberListEntry, CrossworldLinkshell, CrossworldLinkshellEx, LinkshellEntry,
CWLSMemberListEntry, CWLSPermissionRank, CrossworldLinkshell, CrossworldLinkshellEx,
LinkshellEntry,
};

mod spawn_treasure;
Expand Down Expand Up @@ -1013,11 +1014,13 @@ pub enum ServerZoneIpcData {
},
CrossworldLinkshellMemberList {
linkshell_id: u64,
#[brw(pad_after = 6)] // Seems to be empty/zeroes
#[brw(pad_after = 2)] // Seems to be empty/zeroes
sequence: u16,
next_index: u16,
current_index: u16,
#[br(count = CWLSMemberListEntry::COUNT)]
#[brw(pad_size_to = CWLSMemberListEntry::COUNT * CWLSMemberListEntry::SIZE)]
linkshells: Vec<CWLSMemberListEntry>,
members: Vec<CWLSMemberListEntry>,
},
SpawnTreasure(SpawnTreasure),
OpenedTreasure {
Expand Down
119 changes: 67 additions & 52 deletions servers/world/migrations/current_world/up.sql

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

70 changes: 67 additions & 3 deletions servers/world/src/chat_connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@ use super::common::ClientId;
use crate::{MessageInfo, ServerHandle};
use kawari::common::{ObjectId, timestamp_secs};
use kawari::config::WorldConfig;
use kawari::ipc::chat::{
ChatChannel, ChatChannelType, ClientChatIpcSegment, PartyMessage, ServerChatIpcData,
ServerChatIpcSegment, TellMessage, TellNotFoundError,
use kawari::ipc::{
chat::{
CWLinkshellMessage, ChatChannel, ChatChannelType, ClientChatIpcSegment, PartyMessage,
ServerChatIpcData, ServerChatIpcSegment, TellMessage, TellNotFoundError,
},
zone::CrossworldLinkshellEx,
};

use kawari::opcodes::ServerChatIpcType;
use kawari::packet::IpcSegmentHeader;
use kawari::packet::{
Expand All @@ -25,6 +29,8 @@ pub struct ChatConnection {
pub last_keep_alive: Instant,
pub handle: ServerHandle,
pub party_chatchannel: ChatChannel,
pub cwls_chatchannels: [ChatChannel; CrossworldLinkshellEx::COUNT],
pub local_ls_chatchannels: [ChatChannel; CrossworldLinkshellEx::COUNT],
}

impl ChatConnection {
Expand Down Expand Up @@ -140,8 +146,19 @@ impl ChatConnection {
.await;
}

// Do some initial setup to prepare all of our chatchannels. Our chat connection mainly acts as a filter between the client's chat connection and our global server state. The global state will eventually fill in our channel numbers as needed.
self.party_chatchannel.world_id = self.config.world_id;
self.party_chatchannel.channel_type = ChatChannelType::Party;

for linkshell in self.cwls_chatchannels.iter_mut() {
linkshell.world_id = 10008; // This seems to always be used for CWLSes.
linkshell.channel_type = ChatChannelType::CWLinkshell;
}

for linkshell in self.local_ls_chatchannels.iter_mut() {
linkshell.world_id = self.config.world_id;
linkshell.channel_type = ChatChannelType::Linkshell
}
}

pub async fn tell_message_received(&mut self, message_info: MessageInfo) {
Expand All @@ -163,12 +180,59 @@ impl ChatConnection {
}

pub async fn party_message_received(&mut self, message_info: PartyMessage) {
if message_info.party_chatchannel != self.party_chatchannel {
tracing::error!(
"party_message_received: We received a message not destined for our party! What happened? Discarding message. The destination chatchannel was {:#?}",
message_info.party_chatchannel
);
return;
}

let sender_actor_id = message_info.sender_actor_id;
let ipc = ServerChatIpcSegment::new(ServerChatIpcData::PartyMessage(message_info));

self.send_ipc(ipc, sender_actor_id).await;
}

pub async fn cwls_message_received(&mut self, message_info: CWLinkshellMessage) {
if !self
.cwls_chatchannels
.contains(&message_info.cwls_chatchannel)
{
tracing::error!(
"cwls_message_received: We received a message not destined for one of our linkshells, what happened? Discarding message. The destination linkshell was {:#?}",
message_info.cwls_chatchannel
);
return;
}

let sender_actor_id = message_info.sender_actor_id;
let ipc = ServerChatIpcSegment::new(ServerChatIpcData::CWLinkshellMessage(message_info));

self.send_ipc(ipc, sender_actor_id).await;
}

pub async fn set_linkshell_chatchannels(&mut self, cwlses: Vec<u32>, locals: Vec<u32>) {
if (cwlses.len() > self.cwls_chatchannels.len())
|| (locals.len() > self.local_ls_chatchannels.len())
{
tracing::error!(
"set_linkshell_chatchannels: cwlses ({}) or locals ({})vecs had too many entries! What happened?",
cwlses.len(),
locals.len()
);
return;
}

for (index, ls) in cwlses.iter().enumerate() {
self.cwls_chatchannels[index].channel_number = *ls;
}

for (index, ls) in locals.iter().enumerate() {
self.local_ls_chatchannels[index].channel_number = *ls;
}
}

pub async fn set_party_chatchannel(&mut self, party_channel_number: u32) {
self.party_chatchannel.channel_number = party_channel_number;
}
Expand Down
Loading
Loading