This PR is a part of global project refactoring.
First of all, I implemented WorldPacket
and LoginPacket
proc macroses to make packets description easier. Also was implemented with_opcode!
which is required for outcome packets because proc macros should know how to build header where opcode is used (macros generates Self::opcode()
method, so more verbose alternative is just implement this method on the struct). Proc macroses allow to declare dynamic fields, so this field can be built in another way described in method which name should be same as field.
#[derive(WorldPacket, Debug)]
#[options(no_opcode)]
#[allow(dead_code)]
struct Income {
message_type: u8,
language: u32,
sender_guid: u64,
skip: u32,
#[dynamic_field]
channel_name: String,
target_guid: u64,
message_length: u32,
#[dynamic_field]
message: String,
}
impl Income {
fn message<R: BufRead>(mut reader: R, initial: &mut Self) -> String {
let mut buffer = vec![0u8; initial.message_length as usize];
reader.read_exact(&mut buffer).unwrap();
String::from_utf8(buffer).unwrap()
}
fn channel_name<R: BufRead>(mut reader: R, initial: &mut Self) -> String {
if initial.message_type == MessageType::CHANNEL {
let mut buffer = Vec::new();
reader.read_until(0, &mut buffer).unwrap();
String::from_utf8(buffer).unwrap()
} else {
String::default()
}
}
}
dynamic field can be used in case when need to parse field conditionally or when field depends on another field.
Also it is possible to build packets with dynamic opcode, for this purpose need to use .unpack_with_opcode(opcode)
on Outcome packets instead of just .unpack()
.
fn build_movement_packet(
opcode: u32,
guid: u64,
new_position: Position,
movement_flags: MovementFlags
) -> (u32, Vec<u8>) {
let now = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap();
Outcome {
guid: PackedGuid(guid),
movement_flags: movement_flags.bits(),
movement_flags2: MovementFlagsExtra::NONE.bits(),
// TODO: need to investigate how better get u32 value from timestamp
time: now.as_millis() as u32,
x: new_position.x,
y: new_position.y,
z: new_position.z,
direction: new_position.orientation,
unknown: 0
}.unpack_with_opcode(opcode)
}
Also within this PR added pretty output for packet details, fixed UI history scrolling (when select specific output details panel show wrong text).
Added support for .env files to store sensitive data (currently host to connect).
Refactored .send_<>_message
methods of MessageIncome
, now this methods receive extra optional String param to allow output extra data in debug details panel.
UI updates
- Added extra info panel to show additional output (incoming/outcoming counter; in DEBUG mode shows selected/total items).
- Added scrolling for details panel (using CTRL + arrows UP/DOWN)
- Added support for PageUp/PageDown fast scroll; added support for Home/End fast scroll to select first/last item in output
- Fixed UI freeze when switch between modes