跳转至

levilamina::player · 玩家

玩家:用选择器指定,每次调用都重新解析。

只有 xuid 能当作键

PlayerSel::Name 在宿主那边对不上任何账号名时,会退回去匹配显示名,而显示名是别的模组可以改的。一名玩家把自己的显示名改成某个离线玩家的账号名,所有按名字的调用就都落到了他身上。权限、经济和归属的判断都要用 Player::by_xuid;见 crate::sel 的模块文档。

玩家也是实体

Player::as_entity 经 player_resolve 取得 ActorUniqueID,之后 crate::entity::Entity 的全部能力都可以用。两套接口互相补充:物品栏、能力位、标题、踢出这类玩家特有的在这里,生命值、传送、标签这类实体通用的在那里。

Player

Rust
1
2
3
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。

  • 参数:
    • name : impl Into<String>
  • 返回值类型:Player

Player::by_xuid

Rust
pub fn by_xuid(xuid: impl Into<String>) -> Player

按 xuid 指定:唯一,伪造不了,玩家自己也改不了。

  • 参数:
    • xuid : impl Into<String>
  • 返回值类型:Player

Player::by_uuid

Rust
pub fn by_uuid(uuid: impl Into<String>) -> Player
  • 参数:
    • uuid : impl Into<String>
  • 返回值类型:Player

Player::from_sel

Rust
pub fn from_sel(sel: PlayerSel) -> Player
  • 参数:
    • sel : PlayerSel
  • 返回值类型:Player

Player::sel

Rust
pub fn sel(&self) -> &PlayerSel
  • 返回值类型:&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_* 数值属性。

  • 参数:
    • prop : i32
  • 返回值类型:Result<f64>
  • 对应槽位:player_get_num

Player::set_num

Rust
pub fn set_num(&self, prop: i32, v: f64) -> Result<()>

写入一个 PIER_PPROP_* 数值属性。只有标着 (S) 的才能写。

  • 参数:
    • prop : i32
    • v : f64
  • 返回值类型:Result<()>
  • 对应槽位:player_set_num

Player::text

Rust
pub fn text(&self, prop: i32) -> Result<String>

读取一个 PIER_PSTR_* 字符串属性。

  • 参数:
    • prop : i32
  • 返回值类型:Result<String>
  • 对应槽位:player_get_str

Player::last_death_pos

Rust
pub fn last_death_pos(&self) -> Result<Option<(PositionF64, i32)>>

上一次死亡的位置。从来没死过时返回 Ok(None),因为宿主给的是空字符串。

  • 返回值类型:Result<Option<(PositionF64, i32)>>
  • 对应槽位:player_get_str

Player::game_type

Rust
pub fn game_type(&self) -> Result<GameMode>

Player::permission_level

Rust
pub fn permission_level(&self) -> Result<PlayerPermission>
  • 返回值类型:Result<PlayerPermission>
  • 对应槽位:player_get_num

Player::set_level

Rust
pub fn set_level(&self, level: i32) -> Result<()>
  • 参数:
    • level : i32
  • 返回值类型:Result<()>
  • 对应槽位:player_set_num

Player::set_experience

Rust
pub fn set_experience(&self, progress: f64) -> Result<()>

经验条的进度,从 0 到 1。

  • 参数:
    • progress : f64
  • 返回值类型:Result<()>
  • 对应槽位:player_set_num

Player::set_hunger

Rust
pub fn set_hunger(&self, v: f64) -> Result<()>
  • 参数:
    • v : f64
  • 返回值类型:Result<()>
  • 对应槽位:player_set_num

Player::set_saturation

Rust
pub fn set_saturation(&self, v: f64) -> Result<()>
  • 参数:
    • v : f64
  • 返回值类型:Result<()>
  • 对应槽位:player_set_num

Player::set_exhaustion

Rust
pub fn set_exhaustion(&self, v: f64) -> Result<()>
  • 参数:
    • v : f64
  • 返回值类型:Result<()>
  • 对应槽位:player_set_num

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<()>
  • 参数:
    • reason : &str
  • 返回值类型:Result<()>
  • 对应槽位:player_disconnect

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<()>

按下标设置能力位,用于宿主比这一层新、多出了能力位的情况。

  • 参数:
    • index : i32
    • value : f64
  • 返回值类型:Result<()>
  • 对应槽位:player_action

Player::can_use_ability

Rust
pub fn can_use_ability(&self, ability: Ability) -> Result<bool>
  • 参数:
    • ability : Ability
  • 返回值类型:Result<bool>
  • 对应槽位:player_action

Player::set_permission_level

Rust
pub fn set_permission_level(&self, level: PlayerPermission) -> Result<()>
  • 参数:
    • level : PlayerPermission
  • 返回值类型:Result<()>
  • 对应槽位:player_action

Player::set_selected_slot

Rust
pub fn set_selected_slot(&self, slot: i32) -> Result<()>
  • 参数:
    • slot : i32
  • 返回值类型:Result<()>
  • 对应槽位:player_action

Player::give_item

Rust
pub fn give_item(&self, item: &ItemStack) -> Result<()>
  • 参数:
    • item : &ItemStack
  • 返回值类型:Result<()>
  • 对应槽位:player_action

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<()>
  • 参数:
    • xp : i32
  • 返回值类型:Result<()>
  • 对应槽位:player_action

Player::add_levels

Rust
pub fn add_levels(&self, levels: i32) -> Result<()>
  • 参数:
    • levels : i32
  • 返回值类型:Result<()>
  • 对应槽位:player_action

Player::set_chunk_radius

Rust
pub fn set_chunk_radius(&self, radius: i32) -> Result<()>
  • 参数:
    • radius : i32
  • 返回值类型:Result<()>
  • 对应槽位:player_action

Player::set_enchantment_seed

Rust
pub fn set_enchantment_seed(&self, seed: i32) -> Result<()>
  • 参数:
    • seed : i32
  • 返回值类型:Result<()>
  • 对应槽位:player_action

Player::play_emote

Rust
pub fn play_emote(&self, piece_id: &str) -> Result<()>
  • 参数:
    • piece_id : &str
  • 返回值类型:Result<()>
  • 对应槽位:player_action

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<()>
  • 参数:
    • vehicle : Entity
  • 返回值类型:Result<()>
  • 对应槽位:player_action

Player::stop_riding

Rust
pub fn stop_riding(&self) -> Result<()>

Player::attack

Rust
pub fn attack(&self, target: Entity) -> Result<()>
  • 参数:
    • target : Entity
  • 返回值类型:Result<()>
  • 对应槽位:player_action

Player::interact

Rust
pub fn interact(&self, target: Entity) -> Result<()>
  • 参数:
    • target : Entity
  • 返回值类型:Result<()>
  • 对应槽位:player_action

Player::drop_item

Rust
pub fn drop_item(&self, item: &ItemStack, random: bool) -> Result<()>
  • 参数:
    • item : &ItemStack
    • random : bool
  • 返回值类型:Result<()>
  • 对应槽位:player_action

Player::set_sidebar

Rust
pub fn set_sidebar(&self, objective: &str, title: &str, lines: &[String]) -> Result<()>

只对这名玩家显示的侧边栏。lines 从上到下排列。

  • 参数:
    • objective : &str
    • title : &str
    • lines : &[String]
  • 返回值类型:Result<()>
  • 对应槽位:player_action

Player::clear_sidebar

Rust
pub fn clear_sidebar(&self, objective: &str) -> Result<()>
  • 参数:
    • objective : &str
  • 返回值类型:Result<()>
  • 对应槽位:player_action

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<()>
  • 参数:
    • text : &str
  • 返回值类型:Result<()>
  • 对应槽位:player_send_title

Player::set_subtitle

Rust
pub fn set_subtitle(&self, text: &str) -> Result<()>
  • 参数:
    • text : &str
  • 返回值类型:Result<()>
  • 对应槽位:player_send_title

Player::set_actionbar

Rust
pub fn set_actionbar(&self, text: &str) -> Result<()>
  • 参数:
    • text : &str
  • 返回值类型:Result<()>
  • 对应槽位:player_send_title

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
  • 返回值类型:Container

Player::ender_chest

Rust
pub fn ender_chest(&self) -> Container
  • 返回值类型:Container

Player::armor

Rust
pub fn armor(&self) -> Container
  • 返回值类型:Container

Player::offhand_container

Rust
pub fn offhand_container(&self) -> Container
  • 返回值类型:Container

Player::offhand

Rust
pub fn offhand(&self) -> Result<ItemStack>

副手里的物品。空手给出的是空气物品,不算错误。

  • 返回值类型:Result<ItemStack>

Player::set_offhand

Rust
pub fn set_offhand(&self, item: &ItemStack) -> Result<()>

写入副手。之后记得调用 Container::refresh,否则客户端会一直显示旧的物品。

  • 参数:
    • item : &ItemStack
  • 返回值类型:Result<()>

Player::carried_item

Rust
pub fn carried_item(&self) -> Result<ItemStack>

手里拿着的物品。

Player::item

Rust
pub fn item(&self, slot: i32) -> Result<ItemStack>

物品栏的某一格。

  • 参数:
    • slot : i32
  • 返回值类型:Result<ItemStack>
  • 对应槽位:player_get_item

Player::set_item

Rust
pub fn set_item(&self, slot: i32, item: &ItemStack) -> Result<()>
  • 参数:
    • slot : i32
    • item : &ItemStack
  • 返回值类型:Result<()>
  • 对应槽位:player_set_item

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<()>
  • 参数:
    • item_name : &str
    • ticks : i32
  • 返回值类型:Result<()>
  • 对应槽位:player_start_cooldown

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。

Player::platform_online_id

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>

Player::platform

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
  • 参数:
    • v : impl Into<String>
  • 返回值类型:PlayerSel

PlayerSel::xuid

Rust
pub fn xuid(v: impl Into<String>) -> PlayerSel
  • 参数:
    • v : impl Into<String>
  • 返回值类型:PlayerSel

PlayerSel::uuid

Rust
pub fn uuid(v: impl Into<String>) -> PlayerSel
  • 参数:
    • v : impl Into<String>
  • 返回值类型:PlayerSel

PlayerSel::kind

Rust
pub fn kind(&self) -> i32

底层的 kind 值,0、1 或 2,和 abi.h 对齐。

  • 返回值类型:i32

PlayerSel::value

Rust
pub fn value(&self) -> &str
  • 返回值类型:&str

PlayerSel::is_stable

Rust
pub fn is_stable(&self) -> bool

这个选择器是不是可靠的身份,也就是 xuid 或 uuid。

权限、经济或归属的判断拿到 false 时要当心;见模块文档。

  • 返回值类型:bool

PlayerSel::is_empty

Rust
pub fn is_empty(&self) -> bool

检查是否为空:空的选择器解析不到任何人,早点发现,好过在调用处看到一个莫名其妙的 false。

  • 返回值类型:bool

PlayerInfo

Rust
1
2
3
4
5
6
7
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 为空,这时退回到名字,并且会表明这一点,调用方由此知道这个键靠不住。

  • 返回值类型:PlayerSel

NetworkStatus

Rust
1
2
3
4
5
6
7
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