levilamina::nbt · NBT
NBT 值:跨越边界的所有结构化数据的载体。
Pier 的 ABI 上不传递任何结构体。事件载荷、表单、物品、方块状态、实体快照、命令参数、服务的请求和回答,全都是 SNBT 字符串,所以从一段 SNBT 里读出某个字段,是模组代码里最常做的事。
有两族访问函数,含义不同:
opt_* 返回 Option:有就给我,剩下的我自己处理。
get_* 返回 Result,缺少键和类型不符是两种不同的错误,消息里带着键名和实际的类型。保护判断(权限、地皮、经济)用这一族,遇到 Err 就拒绝。把两者合成一种回答会有什么后果,见 crate::event。
函数
nbt::binary::to_binary
| Rust |
|---|
| pub fn to_binary(snbt: &str, fmt: NbtFormat) -> Result<Vec<u8>>
|
把 SNBT 文本转成二进制。
nbt::binary::from_binary
| Rust |
|---|
| pub fn from_binary(data: &[u8], fmt: NbtFormat) -> Result<String>
|
把二进制转成 SNBT 文本。
NbtValue
| Rust |
|---|
| pub enum NbtValue {
Byte(i8),
Short(i16),
Int(i32),
Long(i64),
Float(f32),
Double(f64),
String(String),
List(Vec<NbtValue>),
Compound(BTreeMap<String, NbtValue>),
ByteArray(Vec<i8>),
IntArray(Vec<i32>),
LongArray(Vec<i64>),
}
|
一个 NBT 值。各个变体和基岩版的标签类型一一对应。
变体的集合和早先的一代相同,所以现有的代码不用改就能编译。
- 实现的 trait:
Debug、Clone、PartialEq、From、> From、Display
NbtValue::compound
| Rust |
|---|
| pub fn compound() -> NbtValue
|
一个空的复合标签。
NbtValue::obj
| Rust |
|---|
| pub fn obj<K, I>(entries: I) -> NbtValue
where
K: Into<String>,
I: IntoIterator<Item = (K, NbtValue)>,
|
直接用键值对构造一个复合标签。
| Rust |
|---|
| let v = NbtValue::obj([
("x", 10.into()),
("name", "stone".into()),
]);
|
NbtValue::list
| Rust |
|---|
| pub fn list<I: IntoIterator<Item = NbtValue>>(items: I) -> NbtValue
|
用一串值构造一个列表。
NbtValue::vec3
| Rust |
|---|
| pub fn vec3(x: f64, y: f64, z: f64) -> NbtValue
|
形如 [x, y, z] 的 double 列表,载荷里的坐标就是这个形状。
NbtValue::parse
| Rust |
|---|
| pub fn parse(text: &str) -> std::result::Result<NbtValue, ParseError>
|
解析一段 SNBT。
- 参数:
- 返回值类型:
std::result::Result<NbtValue, ParseError>
NbtValue::to_snbt
| Rust |
|---|
| pub fn to_snbt(&self) -> String
|
序列化成 SNBT。浮点数总是带 d 或 f 后缀,byte 带 b,long 带 L。没有后缀的话,另一边会把 100.0 读成 Int,写进去一个 double、读回来却失败,根源就在这里。
NbtValue::type_name
| Rust |
|---|
| pub fn type_name(&self) -> &'static str
|
这个值的类型名,只用在错误消息里。
NbtValue::as_i64
| Rust |
|---|
| pub fn as_i64(&self) -> Option<i64>
|
把任意整数类型转成 i64。浮点数不转换,因为 3.7 悄悄变成 3 会带来 bug。
NbtValue::as_i32
| Rust |
|---|
| pub fn as_i32(&self) -> Option<i32>
|
同上,收窄成 i32。超出范围时返回 None,不截断。
NbtValue::as_f64
| Rust |
|---|
| pub fn as_f64(&self) -> Option<f64>
|
把任意数值类型转成 f64,包括整数。
NbtValue::as_bool
| Rust |
|---|
| pub fn as_bool(&self) -> Option<bool>
|
布尔值。SNBT 里的布尔值是 1b 或 0b,所以接受任意整数类型,非零即为真。
NbtValue::as_str
| Rust |
|---|
| pub fn as_str(&self) -> Option<&str>
|
NbtValue::as_list
| Rust |
|---|
| pub fn as_list(&self) -> Option<&[NbtValue]>
|
- 返回值类型:
Option<&[NbtValue]>
NbtValue::as_compound
| Rust |
|---|
| pub fn as_compound(&self) -> Option<&BTreeMap<String, NbtValue>>
|
- 返回值类型:
Option<&BTreeMap<String, NbtValue>>
NbtValue::as_compound_mut
| Rust |
|---|
| pub fn as_compound_mut(&mut self) -> Option<&mut BTreeMap<String, NbtValue>>
|
- 返回值类型:
Option<&mut BTreeMap<String, NbtValue>>
NbtValue::as_vec3
| Rust |
|---|
| pub fn as_vec3(&self) -> Option<(f64, f64, f64)>
|
把 [x, y, z] 列表转成三元组。宿主表示坐标就用这个形状,比如 edit_trace_ray 的 pos 和 block,actor_get_aabb 的 min 和 max。
- 返回值类型:
Option<(f64, f64, f64)>
NbtValue::as_block_pos
| Rust |
|---|
| pub fn as_block_pos(&self) -> Option<(i32, i32, i32)>
|
同上,但用整数,用于方块坐标。
- 返回值类型:
Option<(i32, i32, i32)>
NbtValue::is_compound
| Rust |
|---|
| pub fn is_compound(&self) -> bool
|
NbtValue::is_list
| Rust |
|---|
| pub fn is_list(&self) -> bool
|
NbtValue::get
| Rust |
|---|
| pub fn get(&self, key: &str) -> Option<&NbtValue>
|
读取一个直接的子键。
- 参数:
- 返回值类型:
Option<&NbtValue>
NbtValue::get_mut
| Rust |
|---|
| pub fn get_mut(&mut self, key: &str) -> Option<&mut NbtValue>
|
- 参数:
- 返回值类型:
Option<&mut NbtValue>
NbtValue::index
| Rust |
|---|
| pub fn index(&self, i: usize) -> Option<&NbtValue>
|
读取列表的第 i 项。
- 参数:
- 返回值类型:
Option<&NbtValue>
NbtValue::insert
| Rust |
|---|
| pub fn insert(&mut self, key: impl Into<String>, value: NbtValue) -> bool
|
写入一个键。这个值不是复合标签时返回 false,永远不会悄悄把它变成复合标签。
- 参数:
- key :
impl Into<String>
- value :
NbtValue
- 返回值类型:
bool
NbtValue::remove
| Rust |
|---|
| pub fn remove(&mut self, key: &str) -> Option<NbtValue>
|
- 参数:
- 返回值类型:
Option<NbtValue>
NbtValue::contains
| Rust |
|---|
| pub fn contains(&self, key: &str) -> bool
|
NbtValue::path
| Rust |
|---|
| pub fn path(&self, dotted: &str) -> Option<&NbtValue>
|
用点分隔、带数组下标的路径,例如 "a.b[2].c"。
早先的一代只支持纯粹的点,读一个碰撞箱 min 的 y 要写三行。
- 参数:
- 返回值类型:
Option<&NbtValue>
NbtValue::require
| Rust |
|---|
| pub fn require(&self, path: &str) -> NbtResult<&NbtValue>
|
按路径读取。缺少值时得到 Missing,里面带着完整的路径名。
- 参数:
- 返回值类型:
NbtResult<&NbtValue>
NbtValue::get_i64
| Rust |
|---|
| pub fn get_i64(&self, path: &str) -> NbtResult<i64>
|
读取一个整数。缺少键得到 Missing,类型不符得到 WrongType。它从不拿 0 来充数。
NbtValue::get_i32
| Rust |
|---|
| pub fn get_i32(&self, path: &str) -> NbtResult<i32>
|
NbtValue::get_f64
| Rust |
|---|
| pub fn get_f64(&self, path: &str) -> NbtResult<f64>
|
NbtValue::get_bool
| Rust |
|---|
| pub fn get_bool(&self, path: &str) -> NbtResult<bool>
|
- 参数:
- 返回值类型:
NbtResult<bool>
NbtValue::get_str
| Rust |
|---|
| pub fn get_str(&self, path: &str) -> NbtResult<&str>
|
- 参数:
- 返回值类型:
NbtResult<&str>
NbtValue::get_list
| Rust |
|---|
| pub fn get_list(&self, path: &str) -> NbtResult<&[NbtValue]>
|
- 参数:
- 返回值类型:
NbtResult<&[NbtValue]>
NbtValue::get_vec3
| Rust |
|---|
| pub fn get_vec3(&self, path: &str) -> NbtResult<(f64, f64, f64)>
|
- 参数:
- 返回值类型:
NbtResult<(f64, f64, f64)>
NbtValue::get_block_pos
| Rust |
|---|
| pub fn get_block_pos(&self, path: &str) -> NbtResult<(i32, i32, i32)>
|
- 参数:
- 返回值类型:
NbtResult<(i32, i32, i32)>
NbtValue::opt_i64
| Rust |
|---|
| pub fn opt_i64(&self, path: &str) -> Option<i64>
|
NbtValue::opt_i32
| Rust |
|---|
| pub fn opt_i32(&self, path: &str) -> Option<i32>
|
NbtValue::opt_f64
| Rust |
|---|
| pub fn opt_f64(&self, path: &str) -> Option<f64>
|
NbtValue::opt_bool
| Rust |
|---|
| pub fn opt_bool(&self, path: &str) -> Option<bool>
|
NbtValue::opt_str
| Rust |
|---|
| pub fn opt_str(&self, path: &str) -> Option<&str>
|
NbtValue::first_str
| Rust |
|---|
| pub fn first_str(&self, paths: &[&str]) -> Option<&str>
|
按顺序尝试几条路径,返回第一个存在的字符串。
有这个方法的原因很具体:同一个概念在不同事件里的键名不一样,player、_player.name 或 name,业务代码已经在写这个循环了。
NbtValue::to_json
| Rust |
|---|
| pub fn to_json(&self) -> serde_json::Value
|
转成 serde_json::Value。类型后缀的信息会丢失,因为 JSON 不区分 byte 和 long,所以这条路适合保存、记日志和发给网页,不适合再转回来交给宿主。
NbtValue::from_json
| Rust |
|---|
| pub fn from_json(v: &serde_json::Value) -> NbtValue
|
从 serde_json::Value 转换。整数变成 Long,浮点数变成 Double,这是不丢信息的选择。更窄的类型要手工构造。
NbtValue::to_binary
| Rust |
|---|
| pub fn to_binary(&self, fmt: NbtFormat) -> Result<Vec<u8>>
|
把这棵树编码成二进制 NBT。
NbtValue::from_binary
| Rust |
|---|
| pub fn from_binary(data: &[u8], fmt: NbtFormat) -> Result<NbtValue>
|
从二进制 NBT 解码出一棵树。
| Rust |
|---|
| pub enum NbtFormat {
/// The little-endian form used in a save.
LittleEndian = 0,
/// The variable-length encoding used on the network.
Network = 1,
}
|
二进制 NBT 的两种编码。
- 实现的 trait:
Debug、Clone、Copy、PartialEq、Eq
| Rust |
|---|
| pub fn as_i32(self) -> i32
|
NbtError
| Rust |
|---|
| pub enum NbtError {
/// The key is simply not there.
Missing { path: String },
/// The key is there with a type other than the one requested.
WrongType {
path: String,
want: &'static str,
got: &'static str,
},
/// Reading a key on something that is not a compound tag, or an index on something that is
/// not a list.
NotIndexable { path: String, got: &'static str },
}
|
读取失败的原因。缺少键和类型不符是两回事,不能都合成 None。
- 实现的 trait:
Debug、Clone、PartialEq、Eq、Display、Error
NbtResult
| Rust |
|---|
| pub type NbtResult<T> = std::result::Result<T, NbtError>;
|
一次读取的结果。
ParseError
| Rust |
|---|
| pub struct ParseError {
pub at: usize,
pub what: String,
}
|
解析失败。at 是出错处的字节偏移。
- 实现的 trait:
Debug、Clone、PartialEq、Eq、Display、Error