fix: bedrock block mappings
This commit is contained in:
parent
5d27ab34d3
commit
44fd621294
@ -5,6 +5,9 @@ This directory contains a number of different data files used to help support co
|
|||||||
- `block_states.nbt`
|
- `block_states.nbt`
|
||||||
- mined from BDS (file hosted at [pmmp/BedrockData](https://github.com/pmmp/BedrockData/blob/master/canonical_block_states.nbt), `canonical_block_states.nbt`)
|
- mined from BDS (file hosted at [pmmp/BedrockData](https://github.com/pmmp/BedrockData/blob/master/canonical_block_states.nbt), `canonical_block_states.nbt`)
|
||||||
- Provides a listing of all blocks and block states that exist in Bedrock. Used to build a mapping from Java block states to Bedrock ones by matching (string) identifiers and data components.
|
- Provides a listing of all blocks and block states that exist in Bedrock. Used to build a mapping from Java block states to Bedrock ones by matching (string) identifiers and data components.
|
||||||
|
- `blocks.nbt`
|
||||||
|
- downloaded from [GeyserMC/mappings](https://github.com/GeyserMC/mappings)
|
||||||
|
- Defines the exact Bedrock block identifier and property mappings for every Java Edition block state ID. Used in code generation to translate Java block states to Bedrock counterparts.
|
||||||
- `item_components.nbt`
|
- `item_components.nbt`
|
||||||
- mined from BDS (file hosted at [CloudburstMC/Data](https://github.com/CloudburstMC/Data))
|
- mined from BDS (file hosted at [CloudburstMC/Data](https://github.com/CloudburstMC/Data))
|
||||||
- `runtime_item_states.nbt`
|
- `runtime_item_states.nbt`
|
||||||
|
|||||||
BIN
assets/bedrock/blocks.nbt
Normal file
BIN
assets/bedrock/blocks.nbt
Normal file
Binary file not shown.
@ -843,6 +843,13 @@ pub fn build() -> TokenStream {
|
|||||||
let mut be_blocks_cursor = Cursor::new(be_blocks_data);
|
let mut be_blocks_cursor = Cursor::new(be_blocks_data);
|
||||||
let be_blocks = get_be_data_from_nbt(&mut be_blocks_cursor);
|
let be_blocks = get_be_data_from_nbt(&mut be_blocks_cursor);
|
||||||
|
|
||||||
|
let geyser_blocks_data = fs::read("../assets/bedrock/blocks.nbt").unwrap();
|
||||||
|
let geyser_nbt_compound =
|
||||||
|
pumpkin_nbt::nbt_compress::read_gzip_compound_tag(Cursor::new(geyser_blocks_data)).unwrap();
|
||||||
|
let bedrock_mappings_list = geyser_nbt_compound
|
||||||
|
.get_list("bedrock_mappings")
|
||||||
|
.expect("Missing bedrock_mappings list in Geyser blocks.nbt");
|
||||||
|
|
||||||
let blocks_assets: BlockAssets =
|
let blocks_assets: BlockAssets =
|
||||||
serde_json::from_str(&fs::read_to_string("../assets/blocks.json").unwrap())
|
serde_json::from_str(&fs::read_to_string("../assets/blocks.json").unwrap())
|
||||||
.expect("Failed to parse blocks.json");
|
.expect("Failed to parse blocks.json");
|
||||||
@ -956,22 +963,6 @@ pub fn build() -> TokenStream {
|
|||||||
#name_str => Block::#const_ident,
|
#name_str => Block::#const_ident,
|
||||||
});
|
});
|
||||||
|
|
||||||
let be_name = match block.name.as_str() {
|
|
||||||
"dead_bush" => "deadbush",
|
|
||||||
"tripwire" => "trip_wire",
|
|
||||||
"note_block" => "noteblock",
|
|
||||||
"powered_rail" => "golden_rail",
|
|
||||||
"cobweb" => "web",
|
|
||||||
"tall_seagrass" => "seagrass",
|
|
||||||
"wall_torch" => "torch",
|
|
||||||
"spawner" => "mob_spawner",
|
|
||||||
"snow" => "snow_layer",
|
|
||||||
"snow_block" => "snow",
|
|
||||||
name => name,
|
|
||||||
};
|
|
||||||
|
|
||||||
let be_state_list = be_blocks.get(be_name);
|
|
||||||
|
|
||||||
for (i, state) in block.states.iter().enumerate() {
|
for (i, state) in block.states.iter().enumerate() {
|
||||||
if state.has_random_ticks() {
|
if state.has_random_ticks() {
|
||||||
let state_id = LitInt::new(&state.id.0.to_string(), Span::call_site());
|
let state_id = LitInt::new(&state.id.0.to_string(), Span::call_site());
|
||||||
@ -988,49 +979,14 @@ pub fn build() -> TokenStream {
|
|||||||
|
|
||||||
let mut matched_be_id = 1;
|
let mut matched_be_id = 1;
|
||||||
|
|
||||||
if let Some(be_variants) = be_state_list {
|
if let Some(geyser_entry) = bedrock_mappings_list.get(state.id.0 as usize) {
|
||||||
let mut temp_index = i as u16;
|
let (bedrock_name, bedrock_props) = parse_geyser_entry(geyser_entry, &block.name);
|
||||||
let mut java_props_for_this_state = BTreeMap::new();
|
|
||||||
|
|
||||||
for mapping in property_mapping.iter().rev() {
|
|
||||||
match &mapping.property_type {
|
|
||||||
PropertyType::Bool => {
|
|
||||||
let val = temp_index % 2;
|
|
||||||
temp_index /= 2;
|
|
||||||
java_props_for_this_state.insert(
|
|
||||||
mapping.original_name.clone(),
|
|
||||||
if val == 0 { "true" } else { "false" }.to_string(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
PropertyType::Int { min, max } => {
|
|
||||||
let count = (*max - *min + 1) as u16;
|
|
||||||
let val = (temp_index % count) as u8;
|
|
||||||
temp_index /= count;
|
|
||||||
java_props_for_this_state
|
|
||||||
.insert(mapping.original_name.clone(), (val + *min).to_string());
|
|
||||||
}
|
|
||||||
PropertyType::Enum { name } => {
|
|
||||||
let enum_info = property_enums.get(name).unwrap();
|
|
||||||
let count = enum_info.values.len() as u16;
|
|
||||||
let val_idx = temp_index % count;
|
|
||||||
temp_index /= count;
|
|
||||||
|
|
||||||
let raw_val = &enum_info.values[val_idx as usize];
|
|
||||||
let val_str = if raw_val.starts_with('L') {
|
|
||||||
raw_val.strip_prefix('L').unwrap().to_string()
|
|
||||||
} else {
|
|
||||||
raw_val.clone()
|
|
||||||
};
|
|
||||||
java_props_for_this_state
|
|
||||||
.insert(mapping.original_name.clone(), val_str);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if let Some(be_variants) = be_blocks.get(&bedrock_name) {
|
||||||
matched_be_id = be_variants
|
matched_be_id = be_variants
|
||||||
.iter()
|
.iter()
|
||||||
.find(|(_, be_props)| {
|
.find(|(_, be_props)| {
|
||||||
java_props_for_this_state
|
bedrock_props
|
||||||
.iter()
|
.iter()
|
||||||
.all(|(k, v)| be_props.get(k).is_some_and(|be_v| be_v == v))
|
.all(|(k, v)| be_props.get(k).is_some_and(|be_v| be_v == v))
|
||||||
})
|
})
|
||||||
@ -1038,6 +994,11 @@ pub fn build() -> TokenStream {
|
|||||||
|| be_variants.first().map_or(1, |(id, _)| *id),
|
|| be_variants.first().map_or(1, |(id, _)| *id),
|
||||||
|(id, _)| *id,
|
|(id, _)| *id,
|
||||||
);
|
);
|
||||||
|
} else if let Some(be_variants) = be_blocks.get(&block.name) {
|
||||||
|
matched_be_id = be_variants.first().map_or(1, |(id, _)| *id);
|
||||||
|
}
|
||||||
|
} else if let Some(be_variants) = be_blocks.get(&block.name) {
|
||||||
|
matched_be_id = be_variants.first().map_or(1, |(id, _)| *id);
|
||||||
}
|
}
|
||||||
|
|
||||||
block_state_to_bedrock.push((state.id.0, matched_be_id));
|
block_state_to_bedrock.push((state.id.0, matched_be_id));
|
||||||
@ -1549,3 +1510,46 @@ fn get_be_data_from_nbt<R: Read + Seek>(
|
|||||||
|
|
||||||
block_data
|
block_data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_geyser_entry(
|
||||||
|
entry: &pumpkin_nbt::tag::NbtTag,
|
||||||
|
java_block_name: &str,
|
||||||
|
) -> (String, BTreeMap<String, String>) {
|
||||||
|
let compound = match entry {
|
||||||
|
pumpkin_nbt::tag::NbtTag::Compound(c) => c,
|
||||||
|
_ => panic!("Expected NbtCompound in Geyser bedrock_mappings list"),
|
||||||
|
};
|
||||||
|
|
||||||
|
let bedrock_identifier = compound
|
||||||
|
.get_string("bedrock_identifier")
|
||||||
|
.unwrap_or(java_block_name)
|
||||||
|
.strip_prefix("minecraft:")
|
||||||
|
.unwrap_or_else(|| {
|
||||||
|
compound.get_string("bedrock_identifier").unwrap_or(java_block_name)
|
||||||
|
})
|
||||||
|
.to_string();
|
||||||
|
|
||||||
|
let mut properties = BTreeMap::new();
|
||||||
|
if let Some(state_comp) = compound.get_compound("state") {
|
||||||
|
for (key, val) in state_comp.clone() {
|
||||||
|
let unpacked = match val {
|
||||||
|
pumpkin_nbt::tag::NbtTag::Byte(v) => {
|
||||||
|
if v == 1 {
|
||||||
|
"true".to_string()
|
||||||
|
} else {
|
||||||
|
"false".to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pumpkin_nbt::tag::NbtTag::Int(v) => v.to_string(),
|
||||||
|
pumpkin_nbt::tag::NbtTag::String(v) => v.to_string(),
|
||||||
|
_ => {
|
||||||
|
panic!("Unexpected NBT type in Geyser state tag for {}. Value: {:?}", key, val);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
properties.insert(key.to_string(), unpacked);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(bedrock_identifier, properties)
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user