Add JoinGame variant and handling, dimension type (with min_y) is now nested within registry codecs

This commit is contained in:
ice_iix 2022-08-07 16:32:21 -07:00
parent c230070bb4
commit 915d45bbc3
4 changed files with 84 additions and 13 deletions

View File

@ -1344,6 +1344,48 @@ state_packets!(
}
/// JoinGame is sent after completing the login process. This
/// sets the initial state for the client.
packet JoinGame_WorldNames_IsHard_SimDist_HasDeath {
/// The entity id the client will be referenced by
field entity_id: i32 =,
/// Whether hardcore mode is enabled
field is_hardcore: bool =,
/// The starting gamemode of the client
field gamemode: u8 =,
/// The previous gamemode of the client
field previous_gamemode: u8 =,
/// Identifiers for all worlds on the server
field world_names: LenPrefixed<VarInt, String> =,
/// Represents a dimension registry
field registry_codec: Option<nbt::NamedTag> =,
/// Name of the dimension type being spawned into
field dimension_type: String =,
/// The world being spawned into
field world_name: String =,
/// Truncated SHA-256 hash of world's seed
field hashed_seed: i64 =,
/// The max number of players on the server
field max_players: VarInt =,
/// The render distance (2-32)
field view_distance: VarInt =,
/// The distance the client will process entities
field simulation_distance: VarInt =,
/// Whether the client should reduce the amount of debug
/// information it displays in F3 mode
field reduced_debug_info: bool =,
/// Whether to prompt or immediately respawn
field enable_respawn_screen: bool =,
/// Whether the world is in debug mode
field is_debug: bool =,
/// Whether the world is a superflat world
field is_flat: bool =,
/// If true, then the next two fields are present.
field has_death_location: bool =,
/// Name of the dimension the player died in
field death_dimension_name: String = when(|p: &JoinGame_WorldNames_IsHard_SimDist_HasDeath| p.has_death_location),
/// The location that the player died at
field death_location: Position = when(|p: &JoinGame_WorldNames_IsHard_SimDist_HasDeath| p.has_death_location),
}
packet JoinGame_WorldNames_IsHard_SimDist {
/// The entity id the client will be referenced by
field entity_id: i32 =,
@ -2527,8 +2569,7 @@ impl Serializable for LoginProperty {
let name: String = Serializable::read_from(buf)?;
let value: String = Serializable::read_from(buf)?;
let is_signed: bool = Serializable::read_from(buf)?;
let signature: Option<String> =
if is_signed {
let signature: Option<String> = if is_signed {
Some(Serializable::read_from(buf)?)
} else {
None

View File

@ -11,7 +11,7 @@ protocol_packet_ids!(
0x00 => TeleportConfirm
0x01 => QueryBlockNBT
0x02 => SetDifficulty
//TODO 0x03 => ChatCommand
//TODO 0x03 => ChatCommand
0x04 => ChatMessage
//TODO 0x05 => ChatPreview
//TODO 0x06 => ClientCommand
@ -95,7 +95,7 @@ protocol_packet_ids!(
0x20 => Effect
0x21 => Particle_f64
0x22 => UpdateLight_Arrays
0x23 => JoinGame_WorldNames_IsHard_SimDist
0x23 => JoinGame_WorldNames_IsHard_SimDist_HasDeath
0x24 => Maps
0x25 => TradeList_WithRestock
0x26 => EntityMove_i16

View File

@ -15,6 +15,7 @@
use crate::ecs;
use crate::entity;
use crate::format;
use crate::nbt;
use crate::protocol::{self, forge, mojang, packet};
use crate::render;
use crate::resources;
@ -201,7 +202,10 @@ impl Server {
}
protocol::packet::Packet::LoginSuccess_Sig(val) => {
warn!("Server is running in offline mode");
debug!("Login: {} {:?} {:?}", val.username, val.uuid, val.properties);
debug!(
"Login: {} {:?} {:?}",
val.username, val.uuid, val.properties
);
let mut read = conn.clone();
let mut write = conn;
read.state = protocol::State::Play;
@ -287,7 +291,10 @@ impl Server {
break;
}
protocol::packet::Packet::LoginSuccess_Sig(val) => {
debug!("Login: {} {:?} {:?}", val.username, val.uuid, val.properties);
debug!(
"Login: {} {:?} {:?}",
val.username, val.uuid, val.properties
);
uuid = val.uuid;
read.state = protocol::State::Play;
write.state = protocol::State::Play;
@ -625,6 +632,7 @@ impl Server {
self pck {
PluginMessageClientbound_i16 => on_plugin_message_clientbound_i16,
PluginMessageClientbound => on_plugin_message_clientbound_1,
JoinGame_WorldNames_IsHard_SimDist_HasDeath => on_game_join_worldnames_ishard_simdist_hasdeath,
JoinGame_WorldNames_IsHard_SimDist => on_game_join_worldnames_ishard_simdist,
JoinGame_WorldNames_IsHard => on_game_join_worldnames_ishard,
JoinGame_WorldNames => on_game_join_worldnames,
@ -1102,6 +1110,24 @@ impl Server {
.write_plugin_message(channel, data); // TODO handle errors
}
fn on_game_join_worldnames_ishard_simdist_hasdeath(
&mut self,
join: packet::play::clientbound::JoinGame_WorldNames_IsHard_SimDist_HasDeath,
) {
if let Some(nbt::NamedTag(_, nbt::Tag::Compound(registries))) = join.registry_codec {
if let Some(nbt::Tag::Compound(dimension_type)) =
registries.get("minecraft:dimension_type")
{
self.world.load_dimension_type_tags(dimension_type);
}
let _biome_registry = registries.get("minecraft:worldgen/biome");
let _chat_type_registry = registries.get("minecraft:chat_type");
}
self.on_game_join(join.gamemode, join.entity_id)
}
fn on_game_join_worldnames_ishard_simdist(
&mut self,
join: packet::play::clientbound::JoinGame_WorldNames_IsHard_SimDist,
@ -1984,7 +2010,7 @@ impl Server {
self.received_chat_at = Some(Instant::now());
}
fn load_block_entities(&mut self, block_entities: Vec<Option<crate::nbt::NamedTag>>) {
fn load_block_entities(&mut self, block_entities: Vec<Option<nbt::NamedTag>>) {
for block_entity in block_entities.into_iter().flatten() {
let x = block_entity.1.get("x").unwrap().as_int().unwrap();
let y = block_entity.1.get("y").unwrap().as_int().unwrap();

View File

@ -1009,15 +1009,19 @@ impl World {
pub fn load_dimension_type(&mut self, dimension_tags: Option<crate::nbt::NamedTag>) {
if let Some(crate::nbt::NamedTag(_, crate::nbt::Tag::Compound(tags))) = dimension_tags {
info!("Dimension type: {:?}", tags);
if let Some(crate::nbt::Tag::Int(min_y)) = tags.get("min_y") {
self.min_y = *min_y;
}
// TODO: More tags https://wiki.vg/Protocol#Login_.28play.29
self.load_dimension_type_tags(&tags);
}
}
pub fn load_dimension_type_tags(&mut self, tags: &HashMap<String, crate::nbt::Tag>) {
info!("Dimension type: {:?}", tags);
if let Some(crate::nbt::Tag::Int(min_y)) = tags.get("min_y") {
self.min_y = *min_y;
}
// TODO: More tags https://wiki.vg/Protocol#Login_.28play.29
}
#[allow(clippy::or_fun_call)]
fn load_chunk19_to_117(
&mut self,