mirror of https://github.com/zyllian/classics.git synced 2025-05-10 07:06:39 -07:00

implement SetSpawnPoint packet, resolves #49

This commit is contained in:
zyl 2025-01-18 13:26:49 -08:00
parent b0abc32ca9
commit eb69d03e46
Signed by: zyl
SSH key fingerprint: SHA256:uxxbSXbdroP/OnKBGnEDk5q7EKB2razvstC/KmzdXXs
2 changed files with 65 additions and 10 deletions

View file

@ -84,7 +84,7 @@ pub enum Command<'m> {
/// sets the current player's password /// sets the current player's password
SetPass { password: &'m str }, SetPass { password: &'m str },
/// sets the level spawn to the player's location /// sets the level spawn to the player's location
SetLevelSpawn, SetLevelSpawn { overwrite_others: bool },
/// changes the levels weather /// changes the levels weather
Weather { weather_type: &'m str }, Weather { weather_type: &'m str },
/// saves the current level /// saves the current level
@ -155,7 +155,9 @@ impl<'m> Command<'m> {
CMD_SETPASS => Self::SetPass { CMD_SETPASS => Self::SetPass {
password: arguments.trim(), password: arguments.trim(),
}, },
CMD_SETLEVELSPAWN => Self::SetLevelSpawn, CMD_SETLEVELSPAWN => Self::SetLevelSpawn {
overwrite_others: Self::next_bool(&mut arguments)?.unwrap_or_default(),
},
CMD_WEATHER => Self::Weather { CMD_WEATHER => Self::Weather {
weather_type: arguments, weather_type: arguments,
}, },
@ -196,7 +198,7 @@ impl<'m> Command<'m> {
Self::Ban { .. } => CMD_BAN, Self::Ban { .. } => CMD_BAN,
Self::AllowEntry { .. } => CMD_ALLOWENTRY, Self::AllowEntry { .. } => CMD_ALLOWENTRY,
Self::SetPass { .. } => CMD_SETPASS, Self::SetPass { .. } => CMD_SETPASS,
Self::SetLevelSpawn => CMD_SETLEVELSPAWN, Self::SetLevelSpawn { .. } => CMD_SETLEVELSPAWN,
Self::Weather { .. } => CMD_WEATHER, Self::Weather { .. } => CMD_WEATHER,
Self::Save => CMD_SAVE, Self::Save => CMD_SAVE,
Self::Teleport { .. } => CMD_TELEPORT, Self::Teleport { .. } => CMD_TELEPORT,
@ -259,7 +261,7 @@ impl<'m> Command<'m> {
], ],
CMD_SETPASS => vec![c("<new password>"), "&fUpdates your password.".to_string()], CMD_SETPASS => vec![c("<new password>"), "&fUpdates your password.".to_string()],
CMD_SETLEVELSPAWN => vec![ CMD_SETLEVELSPAWN => vec![
c(""), c("[overwrite_others]"),
"&fSets the level's spawn to your location.".to_string(), "&fSets the level's spawn to your location.".to_string(),
], ],
CMD_WEATHER => vec![ CMD_WEATHER => vec![
@ -321,6 +323,21 @@ impl<'m> Command<'m> {
Ok(n) Ok(n)
} }
/// gets the next bool from the command
fn next_bool(args: &mut &'m str) -> Result<Option<bool>, String> {
if args.is_empty() {
return Ok(None);
}
let s = Self::next_string(args)?.to_lowercase();
if s == "true" {
Ok(Some(true))
} else if s == "false" {
Ok(Some(false))
} else {
Err(format!("Expected bool, got {s}"))
}
}
/// processes the command >:3 /// processes the command >:3
pub fn process(self, data: &mut ServerData, own_id: i8) -> Vec<String> { pub fn process(self, data: &mut ServerData, own_id: i8) -> Vec<String> {
let mut messages = Vec::new(); let mut messages = Vec::new();
@ -546,14 +563,31 @@ impl<'m> Command<'m> {
} }
} }
Command::SetLevelSpawn => { Command::SetLevelSpawn { overwrite_others } => {
let x = player.x;
let y = player.y;
let z = player.z;
let yaw = player.yaw;
let pitch = player.pitch;
data.config.spawn = Some(ConfigCoordinatesWithOrientation { data.config.spawn = Some(ConfigCoordinatesWithOrientation {
x: player.x.to_f32(), x: x.to_f32(),
y: player.y.to_f32(), y: y.to_f32(),
z: player.z.to_f32(), z: z.to_f32(),
yaw: player.yaw, yaw,
pitch: player.pitch, pitch,
}); });
if overwrite_others {
let packet = ServerPacket::SetSpawnPoint {
spawn_x: x,
spawn_y: y,
spawn_z: z,
spawn_yaw: yaw,
spawn_pitch: pitch,
};
for player in &mut data.players {
player.packets_to_send.push(packet.clone());
}
}
data.config_needs_saving = true; data.config_needs_saving = true;
messages.push("Level spawn updated!".to_string()); messages.push("Level spawn updated!".to_string());
} }

View file

@ -111,6 +111,14 @@ pub enum ServerPacket {
EnvWeatherType { weather_type: WeatherType }, EnvWeatherType { weather_type: WeatherType },
/// packet to set a block's position in the client's inventory /// packet to set a block's position in the client's inventory
SetInventoryOrder { order: u8, block: u8 }, SetInventoryOrder { order: u8, block: u8 },
/// sets a player's spawn point without moving them
SetSpawnPoint {
spawn_x: f16,
spawn_y: f16,
spawn_z: f16,
spawn_yaw: u8,
spawn_pitch: u8,
},
ExtEntityTeleport { ExtEntityTeleport {
entity_id: i8, entity_id: i8,
teleport_behavior: TeleportBehavior, teleport_behavior: TeleportBehavior,
@ -148,6 +156,7 @@ impl ServerPacket {
Self::HoldThis { .. } => 0x14, Self::HoldThis { .. } => 0x14,
Self::EnvWeatherType { .. } => 0x1f, Self::EnvWeatherType { .. } => 0x1f,
Self::SetInventoryOrder { .. } => 0x2c, Self::SetInventoryOrder { .. } => 0x2c,
Self::SetSpawnPoint { .. } => 0x2e,
Self::ExtEntityTeleport { .. } => 0x36, Self::ExtEntityTeleport { .. } => 0x36,
} }
} }
@ -272,6 +281,18 @@ impl ServerPacket {
} => writer.write_u8(*block).write_bool(*prevent_change), } => writer.write_u8(*block).write_bool(*prevent_change),
Self::EnvWeatherType { weather_type } => writer.write_u8(weather_type.into()), Self::EnvWeatherType { weather_type } => writer.write_u8(weather_type.into()),
Self::SetInventoryOrder { order, block } => writer.write_u8(*order).write_u8(*block), Self::SetInventoryOrder { order, block } => writer.write_u8(*order).write_u8(*block),
Self::SetSpawnPoint {
spawn_x,
spawn_y,
spawn_z,
spawn_yaw,
spawn_pitch,
} => writer
.write_f16(*spawn_x)
.write_f16(*spawn_y)
.write_f16(*spawn_z)
.write_u8(*spawn_yaw)
.write_u8(*spawn_pitch),
Self::ExtEntityTeleport { Self::ExtEntityTeleport {
entity_id, entity_id,
teleport_behavior, teleport_behavior,