1
Fork 0
mirror of https://github.com/redstrate/Kawari.git synced 2025-07-17 10:47:44 +00:00

Add support for the LevequestCompleteList IPC opcode

We also tell the client it completed every levequest in the game,
to showcase this works.
This commit is contained in:
Joshua Goins 2025-07-13 11:59:56 -04:00
parent 2cc562de38
commit c3291b1e47
4 changed files with 49 additions and 1 deletions

View file

@ -289,6 +289,11 @@
"name": "QuestActiveList",
"opcode": 398,
"size": 480
},
{
"name": "LevequestCompleteList",
"opcode": 371,
"size": 232
}
],
"ClientZoneIpcType": [

View file

@ -94,6 +94,7 @@ pub use object_spawn::ObjectSpawn;
mod quest_active_list;
pub use quest_active_list::QuestActiveList;
use crate::COMPLETED_LEVEQUEST_BITMASK_SIZE;
use crate::COMPLETED_QUEST_BITMASK_SIZE;
use crate::TITLE_UNLOCK_BITMASK_SIZE;
use crate::common::ObjectTypeId;
@ -472,6 +473,16 @@ pub enum ServerZoneIpcData {
},
#[br(pre_assert(*magic == ServerZoneIpcType::QuestActiveList))]
QuestActiveList(QuestActiveList),
#[br(pre_assert(*magic == ServerZoneIpcType::LevequestCompleteList))]
LevequestCompleteList {
#[br(count = COMPLETED_LEVEQUEST_BITMASK_SIZE)]
#[bw(pad_size_to = COMPLETED_LEVEQUEST_BITMASK_SIZE)]
completed_levequests: Vec<u8>,
// TODO: what is in ehre?
#[br(count = 6)]
#[bw(pad_size_to = 6)]
unk2: Vec<u8>,
},
Unknown {
#[br(count = size - 32)]
unk: Vec<u8>,
@ -952,6 +963,13 @@ mod tests {
ServerZoneIpcType::QuestActiveList,
ServerZoneIpcData::QuestActiveList(QuestActiveList::default()),
),
(
ServerZoneIpcType::LevequestCompleteList,
ServerZoneIpcData::LevequestCompleteList {
completed_levequests: Vec::default(),
unk2: Vec::default(),
},
),
];
for (opcode, data) in &ipc_types {

View file

@ -79,6 +79,9 @@ pub const COMPLETED_QUEST_BITMASK_SIZE: usize = 691;
/// The size of the unlocked title bitmask.
pub const TITLE_UNLOCK_BITMASK_SIZE: usize = 112;
/// The size of the completed levequest bitmask.
pub const COMPLETED_LEVEQUEST_BITMASK_SIZE: usize = 226;
/// The size of various classjob arrays.
pub const CLASSJOB_ARRAY_SIZE: usize = 32;

View file

@ -9,7 +9,7 @@ use mlua::Function;
use tokio::net::TcpStream;
use crate::{
CLASSJOB_ARRAY_SIZE, COMPLETED_QUEST_BITMASK_SIZE,
CLASSJOB_ARRAY_SIZE, COMPLETED_LEVEQUEST_BITMASK_SIZE, COMPLETED_QUEST_BITMASK_SIZE,
common::{
GameData, ObjectId, ObjectTypeId, Position, timestamp_secs, value_to_flag_byte_index_value,
},
@ -1333,5 +1333,27 @@ impl ZoneConnection {
})
.await;
}
// levequest complete list
// NOTE: all levequests are unlocked by default
{
let ipc = ServerZoneIpcSegment {
op_code: ServerZoneIpcType::LevequestCompleteList,
timestamp: timestamp_secs(),
data: ServerZoneIpcData::LevequestCompleteList {
completed_levequests: vec![0xFF; COMPLETED_LEVEQUEST_BITMASK_SIZE],
unk2: Vec::default(),
},
..Default::default()
};
self.send_segment(PacketSegment {
source_actor: self.player_data.actor_id,
target_actor: self.player_data.actor_id,
segment_type: SegmentType::Ipc,
data: SegmentData::Ipc { data: ipc },
})
.await;
}
}
}