2025-03-21 19:56:16 -04:00
|
|
|
use binrw::binrw;
|
|
|
|
|
|
|
|
use crate::{
|
|
|
|
CHAR_NAME_MAX_LENGTH,
|
|
|
|
common::read_string,
|
2025-03-21 21:26:32 -04:00
|
|
|
lobby::ipc::CharacterDetails,
|
2025-03-21 19:56:16 -04:00
|
|
|
packet::{IpcSegment, ReadWriteIpcSegment},
|
|
|
|
};
|
|
|
|
|
|
|
|
use super::write_string;
|
|
|
|
|
|
|
|
pub type CustomIpcSegment = IpcSegment<CustomIpcType, CustomIpcData>;
|
|
|
|
|
|
|
|
impl ReadWriteIpcSegment for CustomIpcSegment {
|
|
|
|
fn calc_size(&self) -> u32 {
|
|
|
|
// 16 is the size of the IPC header
|
|
|
|
16 + match self.op_code {
|
|
|
|
CustomIpcType::RequestCreateCharacter => 1024 + CHAR_NAME_MAX_LENGTH as u32,
|
|
|
|
CustomIpcType::CharacterCreated => 12,
|
|
|
|
CustomIpcType::GetActorId => 8,
|
|
|
|
CustomIpcType::ActorIdFound => 4,
|
|
|
|
CustomIpcType::CheckNameIsAvailable => CHAR_NAME_MAX_LENGTH as u32,
|
|
|
|
CustomIpcType::NameIsAvailableResponse => 1,
|
2025-03-21 21:26:32 -04:00
|
|
|
CustomIpcType::RequestCharacterList => 4,
|
|
|
|
CustomIpcType::RequestCharacterListRepsonse => 1184 * 8,
|
2025-03-22 17:32:00 -04:00
|
|
|
CustomIpcType::DeleteCharacter => 4,
|
|
|
|
CustomIpcType::CharacterDeleted => 1,
|
2025-03-21 19:56:16 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[binrw]
|
|
|
|
#[brw(repr = u16)]
|
|
|
|
#[derive(Default, Clone, PartialEq, Debug)]
|
|
|
|
pub enum CustomIpcType {
|
|
|
|
#[default]
|
|
|
|
/// Request the world server to create a character
|
|
|
|
RequestCreateCharacter = 0x1,
|
|
|
|
/// Response from the world server when the character is created
|
|
|
|
CharacterCreated = 0x2,
|
|
|
|
/// Request the actor id from the content id of a character
|
|
|
|
GetActorId = 0x3,
|
|
|
|
/// Response from the world server when the actor id is found
|
|
|
|
ActorIdFound = 0x4,
|
|
|
|
/// Check if a name is available on the world server
|
|
|
|
CheckNameIsAvailable = 0x5,
|
|
|
|
/// Response to CheckNameIsAvailable
|
|
|
|
NameIsAvailableResponse = 0x6,
|
2025-03-21 21:26:32 -04:00
|
|
|
/// Request the character list from the world server
|
|
|
|
RequestCharacterList = 0x7,
|
|
|
|
/// Response to RequestCharacterList
|
|
|
|
RequestCharacterListRepsonse = 0x8,
|
2025-03-22 17:32:00 -04:00
|
|
|
/// Request that a character be deleted from the world server
|
|
|
|
DeleteCharacter = 0x9,
|
|
|
|
/// Response to DeleteCharacter
|
|
|
|
CharacterDeleted = 0x10,
|
2025-03-21 19:56:16 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
#[binrw]
|
|
|
|
#[br(import(magic: &CustomIpcType))]
|
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
pub enum CustomIpcData {
|
|
|
|
#[br(pre_assert(*magic == CustomIpcType::RequestCreateCharacter))]
|
|
|
|
RequestCreateCharacter {
|
|
|
|
#[bw(pad_size_to = CHAR_NAME_MAX_LENGTH)]
|
|
|
|
#[br(count = CHAR_NAME_MAX_LENGTH)]
|
|
|
|
#[br(map = read_string)]
|
|
|
|
#[bw(map = write_string)]
|
|
|
|
name: String,
|
|
|
|
#[bw(pad_size_to = 1024)]
|
|
|
|
#[br(count = 1024)]
|
|
|
|
#[br(map = read_string)]
|
|
|
|
#[bw(map = write_string)]
|
|
|
|
chara_make_json: String,
|
|
|
|
},
|
|
|
|
#[br(pre_assert(*magic == CustomIpcType::CharacterCreated))]
|
|
|
|
CharacterCreated { actor_id: u32, content_id: u64 },
|
|
|
|
#[br(pre_assert(*magic == CustomIpcType::GetActorId))]
|
|
|
|
GetActorId { content_id: u64 },
|
|
|
|
#[br(pre_assert(*magic == CustomIpcType::ActorIdFound))]
|
|
|
|
ActorIdFound { actor_id: u32 },
|
|
|
|
#[br(pre_assert(*magic == CustomIpcType::CheckNameIsAvailable))]
|
|
|
|
CheckNameIsAvailable {
|
|
|
|
#[bw(pad_size_to = CHAR_NAME_MAX_LENGTH)]
|
|
|
|
#[br(count = CHAR_NAME_MAX_LENGTH)]
|
|
|
|
#[br(map = read_string)]
|
|
|
|
#[bw(map = write_string)]
|
|
|
|
name: String,
|
|
|
|
},
|
|
|
|
#[br(pre_assert(*magic == CustomIpcType::NameIsAvailableResponse))]
|
|
|
|
NameIsAvailableResponse { free: u8 },
|
2025-03-21 21:26:32 -04:00
|
|
|
#[br(pre_assert(*magic == CustomIpcType::RequestCharacterList))]
|
|
|
|
RequestCharacterList { service_account_id: u32 },
|
|
|
|
#[br(pre_assert(*magic == CustomIpcType::RequestCharacterListRepsonse))]
|
|
|
|
RequestCharacterListRepsonse {
|
|
|
|
#[bw(calc = characters.len() as u8)]
|
|
|
|
num_characters: u8,
|
|
|
|
#[br(count = num_characters)]
|
|
|
|
characters: Vec<CharacterDetails>, // TODO: maybe chunk this into 4 parts ala the lobby server?
|
|
|
|
},
|
2025-03-22 17:32:00 -04:00
|
|
|
#[br(pre_assert(*magic == CustomIpcType::DeleteCharacter))]
|
|
|
|
DeleteCharacter { content_id: u64 },
|
|
|
|
#[br(pre_assert(*magic == CustomIpcType::CharacterDeleted))]
|
|
|
|
CharacterDeleted { deleted: u8 },
|
2025-03-21 19:56:16 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Default for CustomIpcData {
|
|
|
|
fn default() -> CustomIpcData {
|
|
|
|
CustomIpcData::RequestCreateCharacter {
|
|
|
|
chara_make_json: String::new(),
|
|
|
|
name: String::new(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|