levilamina::player · 玩家
玩家:用选择器指定,每次调用都重新解析。
只有 xuid 能当作键
PlayerSel::Name 在宿主那边对不上任何账号名时,会退回去匹配显示名,而显示名是别的模组可以改的。一名玩家把自己的显示名改成某个离线玩家的账号名,所有按名字的调用就都落到了他身上。权限、经济和归属的判断都要用 Player::by_xuid;见 crate::sel 的模块文档。
玩家也是实体
Player::as_entity 经 player_resolve 取得 ActorUniqueID,之后 crate::entity::Entity 的全部能力都可以用。两套接口互相补充:物品栏、能力位、标题、踢出这类玩家特有的在这里,生命值、传送、标签这类实体通用的在那里。
Player
| Rust |
|---|
| pub struct Player {
// private fields
}
|
一名玩家。它只存着选择器,不存指针。
- 实现的 trait:
Debug、Clone、PartialEq、Eq、Hash、Display、From
Player::by_name
| Rust |
|---|
| pub fn by_name(name: impl Into<String>) -> Player
|
按名字指定。这会经过显示名的回退,所以认人要用 Player::by_xuid。
Player::by_xuid
| Rust |
|---|
| pub fn by_xuid(xuid: impl Into<String>) -> Player
|
按 xuid 指定:唯一,伪造不了,玩家自己也改不了。
Player::by_uuid
| Rust |
|---|
| pub fn by_uuid(uuid: impl Into<String>) -> Player
|
Player::from_sel
| Rust |
|---|
| pub fn from_sel(sel: PlayerSel) -> Player
|
Player::sel
| Rust |
|---|
| pub fn sel(&self) -> &PlayerSel
|
Player::list
| Rust |
|---|
| pub fn list() -> Vec<PlayerInfo>
|
在线玩家的列表。
宿主每个玩家输出一段 SNBT。解析不了的条目会被跳过并记一条警告,不会让整张表变空:一条坏数据不应该让「服务器上有谁」变得答不上来。每个 ABI v2 宿主都提供 list_players,服务器和客户端都一样,所以列表为空就表示没有人在线。
Player::broadcast
| Rust |
|---|
| pub fn broadcast(msg: &str) -> Result<()>
|
给每个在线玩家发送一条消息。
Player::is_online
| Rust |
|---|
| pub fn is_online(&self) -> bool
|
这个选择器当前能不能解析到某个人。每个 ABI v2 宿主都提供 player_resolve,服务器和客户端都一样,所以这里的 false 表示没有人对得上,不会是宿主分辨不出来。
Player::as_entity
| Rust |
|---|
| pub fn as_entity(&self) -> Result<Entity>
|
把玩家当作实体使用,获得 Entity 的全部能力。
Player::num
| Rust |
|---|
| pub fn num(&self, prop: i32) -> Result<f64>
|
读取一个 PIER_PPROP_* 数值属性。
Player::set_num
| Rust |
|---|
| pub fn set_num(&self, prop: i32, v: f64) -> Result<()>
|
写入一个 PIER_PPROP_* 数值属性。只有标着 (S) 的才能写。
Player::text
| Rust |
|---|
| pub fn text(&self, prop: i32) -> Result<String>
|
读取一个 PIER_PSTR_* 字符串属性。
Player::last_death_pos
| Rust |
|---|
| pub fn last_death_pos(&self) -> Result<Option<(PositionF64, i32)>>
|
上一次死亡的位置。从来没死过时返回 Ok(None),因为宿主给的是空字符串。
Player::game_type
| Rust |
|---|
| pub fn game_type(&self) -> Result<GameMode>
|
Player::permission_level
| Rust |
|---|
| pub fn permission_level(&self) -> Result<PlayerPermission>
|
Player::set_level
| Rust |
|---|
| pub fn set_level(&self, level: i32) -> Result<()>
|
Player::set_experience
| Rust |
|---|
| pub fn set_experience(&self, progress: f64) -> Result<()>
|
经验条的进度,从 0 到 1。
Player::set_hunger
| Rust |
|---|
| pub fn set_hunger(&self, v: f64) -> Result<()>
|
Player::set_saturation
| Rust |
|---|
| pub fn set_saturation(&self, v: f64) -> Result<()>
|
Player::set_exhaustion
| Rust |
|---|
| pub fn set_exhaustion(&self, v: f64) -> Result<()>
|
Player::position
| Rust |
|---|
| pub fn position(&self) -> Result<(PositionF64, i32)>
|
位置。它走的是专用的槽位,没有用属性编号:一次调用就拿到三个坐标和维度,分三次读属性的话,玩家可能在两次调用之间移动了。
Player::network_status
| Rust |
|---|
| pub fn network_status(&self) -> Result<NetworkStatus>
|
详细的网络状态。
Player::conn_id
| Rust |
|---|
| pub fn conn_id(&self) -> Result<u64>
|
这名玩家的连接 id,和数据包拦截器看到的是同一个数。
0 表示不在线,或者拿不到网络标识。在 ABI 上 0 不是有效的连接 id,所以这里如实地把它报告成 Err,不交出一个 0。
Player::disconnect
| Rust |
|---|
| pub fn disconnect(&self, reason: &str) -> Result<()>
|
Player::set_gamemode
| Rust |
|---|
| pub fn set_gamemode(&self, mode: GameMode) -> Result<()>
|
Player::teleport
| Rust |
|---|
| pub fn teleport(&self, dim: i32, x: f64, y: f64, z: f64) -> Result<()>
|
传送。id 为 3 及以上的自定义维度也走这里;维度桥接构造不出对得上的实例时,宿主会让调用失败,不会把人丢进一个对不上的维度。
- 参数:
- dim :
i32
- x :
f64
- y :
f64
- z :
f64
- 返回值类型:
Result<()>
- 对应槽位:
player_teleport
Player::act
| Rust |
|---|
| pub fn act(&self, action: i32, sarg: &str, a: f64, b: f64, c: f64) -> Result<String>
|
执行一个 PIER_PACT_* 动作,返回它的输出。
- 参数:
- action :
i32
- sarg :
&str
- a :
f64
- b :
f64
- c :
f64
- 返回值类型:
Result<String>
- 对应槽位:
player_action
Player::set_ability
| Rust |
|---|
| pub fn set_ability<V: AbilityValue>(&self, ability: Ability, value: V) -> Result<()>
|
设置一个能力位。
在浮点类的能力上传布尔值不会报错,只会按另一种解释写进去,所以 Ability::is_float 会先把它拦下来。
- 参数:
- ability :
Ability
- value :
V
- 返回值类型:
Result<()>
- 对应槽位:
player_action
Player::set_ability_raw
| Rust |
|---|
| pub fn set_ability_raw(&self, index: i32, value: f64) -> Result<()>
|
按下标设置能力位,用于宿主比这一层新、多出了能力位的情况。
Player::can_use_ability
| Rust |
|---|
| pub fn can_use_ability(&self, ability: Ability) -> Result<bool>
|
Player::set_permission_level
| Rust |
|---|
| pub fn set_permission_level(&self, level: PlayerPermission) -> Result<()>
|
Player::set_selected_slot
| Rust |
|---|
| pub fn set_selected_slot(&self, slot: i32) -> Result<()>
|
Player::give_item
| Rust |
|---|
| pub fn give_item(&self, item: &ItemStack) -> Result<()>
|
Player::set_spawn_point
| Rust |
|---|
| pub fn set_spawn_point(&self, dim: i32, x: i32, y: i32, z: i32) -> Result<()>
|
- 参数:
- dim :
i32
- x :
i32
- y :
i32
- z :
i32
- 返回值类型:
Result<()>
- 对应槽位:
player_action
Player::add_experience
| Rust |
|---|
| pub fn add_experience(&self, xp: i32) -> Result<()>
|
Player::add_levels
| Rust |
|---|
| pub fn add_levels(&self, levels: i32) -> Result<()>
|
Player::set_chunk_radius
| Rust |
|---|
| pub fn set_chunk_radius(&self, radius: i32) -> Result<()>
|
Player::set_enchantment_seed
| Rust |
|---|
| pub fn set_enchantment_seed(&self, seed: i32) -> Result<()>
|
Player::play_emote
| Rust |
|---|
| pub fn play_emote(&self, piece_id: &str) -> Result<()>
|
Player::resend_all_chunks
| Rust |
|---|
| pub fn resend_all_chunks(&self) -> Result<()>
|
Player::open_inventory
| Rust |
|---|
| pub fn open_inventory(&self) -> Result<()>
|
Player::start_riding
| Rust |
|---|
| pub fn start_riding(&self, vehicle: Entity) -> Result<()>
|
Player::stop_riding
| Rust |
|---|
| pub fn stop_riding(&self) -> Result<()>
|
Player::attack
| Rust |
|---|
| pub fn attack(&self, target: Entity) -> Result<()>
|
Player::interact
| Rust |
|---|
| pub fn interact(&self, target: Entity) -> Result<()>
|
Player::drop_item
| Rust |
|---|
| pub fn drop_item(&self, item: &ItemStack, random: bool) -> Result<()>
|
- 参数:
- item :
&ItemStack
- random :
bool
- 返回值类型:
Result<()>
- 对应槽位:
player_action
| Rust |
|---|
| pub fn set_sidebar(&self, objective: &str, title: &str, lines: &[String]) -> Result<()>
|
只对这名玩家显示的侧边栏。lines 从上到下排列。
- 参数:
- objective :
&str
- title :
&str
- lines :
&[String]
- 返回值类型:
Result<()>
- 对应槽位:
player_action
| Rust |
|---|
| pub fn clear_sidebar(&self, objective: &str) -> Result<()>
|
Player::send_message
| Rust |
|---|
| pub fn send_message(&self, msg: &str) -> Result<()>
|
Player::tell
| Rust |
|---|
| pub fn tell(&self, msg: &str, kind: MessageType) -> Result<()>
|
按指定的 TextPacketType 发送一条消息。
Player::send_title
| Rust |
|---|
| pub fn send_title(&self, kind: TitleKind, text: &str, times: Option<TitleTimes>) -> Result<()>
|
发送一个标题。
它通过真正的 SetTitlePacket 发送,没有拼 /title 命令:拼命令会把文本原样塞进命令行,名字里带引号或者 @e 的地皮就成了一次命令注入。
给了 times 时会先发一个 Times 包,计时是确定的;省略它则沿用客户端上一次存下的时长。三个时长不能只给一部分,那样的组合宿主会直接拒绝。
- 参数:
- kind :
TitleKind
- text :
&str
- times :
Option<TitleTimes>
- 返回值类型:
Result<()>
- 对应槽位:
player_send_title
Player::set_title
| Rust |
|---|
| pub fn set_title(&self, text: &str) -> Result<()>
|
Player::set_subtitle
| Rust |
|---|
| pub fn set_subtitle(&self, text: &str) -> Result<()>
|
Player::set_actionbar
| Rust |
|---|
| pub fn set_actionbar(&self, text: &str) -> Result<()>
|
Player::clear_title
| Rust |
|---|
| pub fn clear_title(&self) -> Result<()>
|
Player::spawn_particle
| Rust |
|---|
| pub fn spawn_particle(&self, dim: i32, effect: &str, x: f64, y: f64, z: f64) -> Result<()>
|
只为这一名玩家生成粒子。
World::spawn_particle 会向整个维度广播,这个则只有这名玩家看得到。选区高亮这类东西必须用这个,否则全服务器都看得到。
- 参数:
- dim :
i32
- effect :
&str
- x :
f64
- y :
f64
- z :
f64
- 返回值类型:
Result<()>
- 对应槽位:
spawn_particle_for
Player::send_packet
| Rust |
|---|
| pub fn send_packet(&self, packet_id: i32, body: &[u8]) -> Result<()>
|
把一个原始数据包推到这名玩家的连接上。
这是一个逃生口:body 是当前游戏版本的线上格式,每次版本变化都要跟着改,这由调用方负责。有命名的接口时,请优先用那些。
- 参数:
- packet_id :
i32
- body :
&[u8]
- 返回值类型:
Result<()>
- 对应槽位:
send_packet
Player::inventory
| Rust |
|---|
| pub fn inventory(&self) -> Container
|
Player::ender_chest
| Rust |
|---|
| pub fn ender_chest(&self) -> Container
|
Player::armor
| Rust |
|---|
| pub fn armor(&self) -> Container
|
Player::offhand_container
| Rust |
|---|
| pub fn offhand_container(&self) -> Container
|
Player::offhand
| Rust |
|---|
| pub fn offhand(&self) -> Result<ItemStack>
|
副手里的物品。空手给出的是空气物品,不算错误。
Player::set_offhand
| Rust |
|---|
| pub fn set_offhand(&self, item: &ItemStack) -> Result<()>
|
写入副手。之后记得调用 Container::refresh,否则客户端会一直显示旧的物品。
Player::carried_item
| Rust |
|---|
| pub fn carried_item(&self) -> Result<ItemStack>
|
手里拿着的物品。
Player::item
| Rust |
|---|
| pub fn item(&self, slot: i32) -> Result<ItemStack>
|
物品栏的某一格。
Player::set_item
| Rust |
|---|
| pub fn set_item(&self, slot: i32, item: &ItemStack) -> Result<()>
|
Player::equipment
| Rust |
|---|
| pub fn equipment(&self) -> Result<Vec<(i32, ItemStack)>>
|
全部装备。slot 的编号见 crate::types::EquipSlot。
Player::cooldown
| Rust |
|---|
| pub fn cooldown(&self, item_name: &str) -> Result<i32>
|
某个物品的冷却还剩多少刻。
在 ABI 上,-1 同时表示不在冷却中和玩家不在线。这里原样交出,并把这一点写明,不替调用方去猜(契约 §5.2)。要区分这两种情况,先调用 Player::is_online。
Player::start_cooldown
| Rust |
|---|
| pub fn start_cooldown(&self, item_name: &str, ticks: i32) -> Result<()>
|
Player::real_name
| Rust |
|---|
| pub fn real_name(&self) -> Result<String>
|
账号名。
Player::uuid
| Rust |
|---|
| pub fn uuid(&self) -> Result<String>
|
Player::xuid
| Rust |
|---|
| pub fn xuid(&self) -> Result<String>
|
Player::ip_and_port
| Rust |
|---|
| pub fn ip_and_port(&self) -> Result<String>
|
地址:端口。IPv6 也是这个形状,所以不能按最后一个冒号去切分。
Player::locale_code
| Rust |
|---|
| pub fn locale_code(&self) -> Result<String>
|
Player::respawn_pos
| Rust |
|---|
| pub fn respawn_pos(&self) -> Result<String>
|
以 SNBT {x,y,z,dim} 给出这名玩家会在哪里重生。不会为空:没有床的玩家报告的是世界出生点,这两种情况区分不开。
Player::name_tag
| Rust |
|---|
| pub fn name_tag(&self) -> Result<String>
|
显示在头顶上的名字,可以被修改。认人要用 Player::xuid。
| Rust |
|---|
| pub fn platform_online_id(&self) -> Result<String>
|
Player::dimension
| Rust |
|---|
| pub fn dimension(&self) -> Result<i32>
|
Player::level
| Rust |
|---|
| pub fn level(&self) -> Result<i32>
|
经验等级。
Player::experience
| Rust |
|---|
| pub fn experience(&self) -> Result<f64>
|
经验条的进度,从 0 到 1。它表示的并非累计的经验值。
Player::hunger
| Rust |
|---|
| pub fn hunger(&self) -> Result<f64>
|
Player::saturation
| Rust |
|---|
| pub fn saturation(&self) -> Result<f64>
|
饱和度;它耗尽以后饥饿值才开始下降。
Player::exhaustion
| Rust |
|---|
| pub fn exhaustion(&self) -> Result<f64>
|
消耗度;每攒满一个单位,扣掉一点饱和度。
Player::xp_needed_for_next_level
| Rust |
|---|
| pub fn xp_needed_for_next_level(&self) -> Result<i32>
|
距离下一级还差多少经验。
Player::luck
| Rust |
|---|
| pub fn luck(&self) -> Result<f64>
|
Player::selected_slot
| Rust |
|---|
| pub fn selected_slot(&self) -> Result<i32>
|
Player::score
| Rust |
|---|
| pub fn score(&self) -> Result<i32>
|
计分板上的 score 伪计分项,和任何自定义的计分项无关。
Player::chunk_radius
| Rust |
|---|
| pub fn chunk_radius(&self) -> Result<i32>
|
客户端请求的视距,单位是区块。
Player::enchantment_seed
| Rust |
|---|
| pub fn enchantment_seed(&self) -> Result<i32>
|
| Rust |
|---|
| pub fn platform(&self) -> Result<i32>
|
BuildPlatform 的值,并非操作系统的名字。
Player::direction
| Rust |
|---|
| pub fn direction(&self) -> Result<i32>
|
朝向:0 南,1 西,2 北,3 东。
Player::ping
| Rust |
|---|
| pub fn ping(&self) -> Result<i32>
|
往返延迟,单位毫秒。详细情况见 Player::network_status。
Player::client_sub_id
| Rust |
|---|
| pub fn client_sub_id(&self) -> Result<i32>
|
Player::fall_distance
| Rust |
|---|
| pub fn fall_distance(&self) -> Result<f64>
|
Player::is_operator
| Rust |
|---|
| pub fn is_operator(&self) -> Result<bool>
|
在 permissions.json 里被列为管理员。它和 Player::permission_level 是两回事,后者在运行时可能改变。
Player::can_use_operator_blocks
| Rust |
|---|
| pub fn can_use_operator_blocks(&self) -> Result<bool>
|
Player::is_flying
| Rust |
|---|
| pub fn is_flying(&self) -> Result<bool>
|
Player::can_jump
| Rust |
|---|
| pub fn can_jump(&self) -> Result<bool>
|
Player::is_emoting
| Rust |
|---|
| pub fn is_emoting(&self) -> Result<bool>
|
Player::is_in_raid
| Rust |
|---|
| pub fn is_in_raid(&self) -> Result<bool>
|
Player::is_hurt
| Rust |
|---|
| pub fn is_hurt(&self) -> Result<bool>
|
正处在受伤后的无敌帧里。
Player::is_scoping
| Rust |
|---|
| pub fn is_scoping(&self) -> Result<bool>
|
Player::can_sleep
| Rust |
|---|
| pub fn can_sleep(&self) -> Result<bool>
|
Player::has_respawn_position
| Rust |
|---|
| pub fn has_respawn_position(&self) -> Result<bool>
|
Player::is_using_item
| Rust |
|---|
| pub fn is_using_item(&self) -> Result<bool>
|
Player::is_blocking
| Rust |
|---|
| pub fn is_blocking(&self) -> Result<bool>
|
Player::is_gliding
| Rust |
|---|
| pub fn is_gliding(&self) -> Result<bool>
|
Player::is_swimming
| Rust |
|---|
| pub fn is_swimming(&self) -> Result<bool>
|
Player::is_dead
| Rust |
|---|
| pub fn is_dead(&self) -> Result<bool>
|
Player::has_died_before
| Rust |
|---|
| pub fn has_died_before(&self) -> Result<bool>
|
在这个存档里至少死过一次。
PlayerSel
| Rust |
|---|
| pub enum PlayerSel {
/// By name. The account name is matched first and the host falls back to the display
/// name on a miss; see the module documentation and do not use it as an identity.
Name(String),
/// By xuid: unique, unforgeable and unchangeable by the player. This is the one to use
/// as a key.
/// It may be an empty string on an offline-mode server, where only `Name` remains.
Xuid(String),
/// By uuid in its canonical string form. Equally stable and suited to a save key.
Uuid(String),
}
|
怎样指定一名玩家。
- 实现的 trait:
Debug、Clone、PartialEq、Eq、Hash、From、Display
PlayerSel::name
| Rust |
|---|
| pub fn name(v: impl Into<String>) -> PlayerSel
|
PlayerSel::xuid
| Rust |
|---|
| pub fn xuid(v: impl Into<String>) -> PlayerSel
|
PlayerSel::uuid
| Rust |
|---|
| pub fn uuid(v: impl Into<String>) -> PlayerSel
|
PlayerSel::kind
| Rust |
|---|
| pub fn kind(&self) -> i32
|
底层的 kind 值,0、1 或 2,和 abi.h 对齐。
PlayerSel::value
| Rust |
|---|
| pub fn value(&self) -> &str
|
PlayerSel::is_stable
| Rust |
|---|
| pub fn is_stable(&self) -> bool
|
这个选择器是不是可靠的身份,也就是 xuid 或 uuid。
权限、经济或归属的判断拿到 false 时要当心;见模块文档。
PlayerSel::is_empty
| Rust |
|---|
| pub fn is_empty(&self) -> bool
|
检查是否为空:空的选择器解析不到任何人,早点发现,好过在调用处看到一个莫名其妙的 false。
PlayerInfo
| Rust |
|---|
| pub struct PlayerInfo {
pub name: String,
pub xuid: String,
pub uuid: String,
pub dimension: Option<i32>,
pub pos: Option<PositionF64>,
}
|
list_players 报告的一项。
dimension 和 pos 是 Option,没有用裸值。世界还没就绪,或者这名玩家正在换维度时,宿主会省略这两个键,而填 0 就等于说他在主世界的原点。契约 §5.1 记录的领地保护绕过就是这个形状:自定义维度里的一个事件读不到 dim,使用方写了 unwrap_or(0),结果一切都被当成主世界放行了。
想要默认值的调用方自己写 .unwrap_or(0),这个默认值的后果也由它自己负责。
- 实现的 trait:
Debug、Clone、Default、PartialEq
PlayerInfo::selector
| Rust |
|---|
| pub fn selector(&self) -> PlayerSel
|
用 xuid 构造一个稳定的选择器。离线模式的服务器上 xuid 为空,这时退回到名字,并且会表明这一点,调用方由此知道这个键靠不住。
NetworkStatus
| Rust |
|---|
| pub struct NetworkStatus {
pub ping: i32,
pub avg_ping: i32,
pub max_ping: i32,
/// Per mille, exactly as the host gives it.
pub packet_loss: i32,
}
|
一名玩家的网络状态,取自 PIER_PSTR_NETWORK_STATUS。
- 实现的 trait:
Debug、Clone、Copy、Default、PartialEq、Eq