
NoName_mods PlayerAPI
客户端Fabric库,为模组提供简洁、高级API,用于玩家输入、物品栏、世界查询、视角控制、事件、调度以及类人自动化,使模组无需接触Minecraft内部代码。这是Ceres、Poseidon和ESP的共享基础。
PlayerAPI
一个客户端 Fabric 库,提供了清晰、高级的 API,用于玩家交互、世界查询和类人自动化。设计为一个共享基础,以便其他模组无需重新实现相同的低级 Mixin。
GitHub: https://github.com/noname-mods/PlayerAPI
对于玩家
PlayerAPI 本身不执行任何操作。如果你下载了它,说明你使用的另一个模组将其作为依赖项。只需将 .jar 文件与该模组一起放入 mods 文件夹即可。
Minecraft 版本支持
此库一次只针对一个 Minecraft 版本。 当它更新到新的 Minecraft 版本时,之前的版本将不会得到任何进一步的支持 —— 不会向后移植,不会修复错误,并且永远不会发布同时支持多个 Minecraft 版本的版本。请使用与你游戏版本和依赖它的模组相匹配的 PlayerAPI 构建版本。
对于开发者
PlayerAPI — 设计与 API 参考
版本: 1.12.0
Minecraft: 26.1.2 (Fabric)
Maven 坐标: com.playerapi:playerapi:1.12.0
目录
1. 概述与理念
PlayerAPI 是一个客户端 Fabric 库,为客户端自动化或实用模组所需的所有与本地玩家交互的操作,提供了一个清晰、稳定的抽象层。它的存在使得消费模组无需直接导入 Minecraft 内部代码——所有游戏交互都通过 PlayerAPI 的公有 API 类进行。
核心设计原则:
- 关注点分离。 每个 API 类都有明确的职责:Info 类只读取状态,Action 类只执行动作。职责不混淆。
- 处处都有安全默认值。 如果玩家不在世界中,每个读取玩家状态的方法都会返回一个安全默认值(
0、false、""、空列表、EMPTY快照)。消费模组永远不需要进行空值检查。 - 仅主线程。 所有的动作调用和事件回调都在游戏主线程上运行。无需管理并发。
- 强制 vs. 人类。 有两个并行的动作系统。强制动作是即时且计算机精确的(适合精确定位)。人类动作会添加反应延迟、弹簧物理视角插值和鼠标噪声(适合看起来自然)。消费模组可以选择适合其用例的系统。
- 无内部状态泄露。 快照类型(
ItemSnapshot、EntitySnapshot、BlockSnapshot、EffectSnapshot)是不可变的 Java 记录。它们可以被自由存储和比较,而不会受到底层游戏对象过时的影响。
2. 架构
┌─────────────────────────────────────────────────────────┐
│ Consumer Mod │
│ (depends on PlayerAPI, never imports MC internals) │
└───────────────────┬─────────────────────────────────────┘
│ uses
┌───────────────────▼─────────────────────────────────────┐
│ PlayerAPI Public Surface │
│ │
│ Events Scheduler Actions (Forced) │
│ PlayerAPIEvents Scheduler MovementActions │
│ LookActions │
│ Info (read) InventoryActions │
│ PlayerInfo InteractionActions │
│ InventoryInfo ChatActions │
│ WorldInfo SoundActions │
│ TabListInfo DisplayActions │
│ │
│ Actions (Human) Data Types │
│ HumanActions ItemSnapshot │
│ HumanProfile EntitySnapshot │
│ BlockSnapshot │
│ EffectSnapshot │
└───────────────────┬─────────────────────────────────────┘
│ wraps
┌───────────────────▼─────────────────────────────────────┐
│ PlayerAPI Internals (not public) │
│ │
│ PlayerAPIMod — wires Fabric events, drives ticks │
│ KeyStateTracker — held-key set, mixin read target │
│ SchedulerState — tick-based task queue │
│ HumanLookState — spring-damper look interpolation │
│ MovementInputMixin — @Mixin(KeyboardInput) override │
│ PlayerInventoryAccessor — @Mixin accessor for slots │
└─────────────────────────────────────────────────────────┘
滴答流程(每个游戏滴答)
ClientTickEvents.END_CLIENT_TICK
│
├─ 1. SchedulerState.tick() — fires due scheduled tasks
├─ 2. HumanLookState.tick() — advances spring interpolation
├─ 3. diff-based event checks — health, position changes
└─ 4. PlayerAPIEvents.TICK.invoke() — consumer mod tick callbacks
按键覆盖机制
MovementInputMixin 是一个用于 KeyboardInput 的 @Mixin,在其 tick() 方法中有一个 TAIL 注入。在每个原版输入滴答结束时,如果 KeyStateTracker.isActive() 为 true,mixin 会将 input.pressingForward、input.pressingBack、input.pressingLeft、input.pressingRight、input.jumping 和 input.sneaking 覆盖为 KeyStateTracker 中存储的值。这意味着覆盖对于游戏的其他部分是完全透明的——移动、疾跑物理和服务器数据包的行为都正常。
3. 添加 PlayerAPI 作为依赖项
build.gradle
repositories {
mavenLocal()
}
dependencies {
modImplementation "com.playerapi:playerapi:1.12.0"
}
gradle.properties
playerapi_version=1.12.0
fabric.mod.json
"depends": {
"playerapi": ">=1.12.0"
}
首先构建 PlayerAPI:
cd PlayerAPI
./gradlew publishToMavenLocal
然后正常构建你的模组。
4. 线程模型
所有 PlayerAPI 的调用必须从主游戏线程进行。 这是运行 ClientTickEvents、渲染帧和处理网络数据包的线程。实际上这意味着:
- 在
PlayerAPIEvents.TICK处理器内部 — ✅ 始终安全 - 在注册到主线程的任何 Fabric 事件处理器内部 — ✅ 安全
- 从后台线程或
CompletableFuture— ❌ 从不安全;请使用MinecraftClient.getInstance().execute(() -> ...)编组回主线程
Scheduler 总是在主线程上触发回调。
5. 事件 — PlayerAPIEvents
所有事件都位于 com.playerapi.PlayerAPIEvents 上。在你的模组的 onInitializeClient() 中注册监听器。
PlayerAPIEvents.TICK.register(() -> {
// runs every tick
});
所有事件都使用 Fabric 的 EventFactory.createArrayBacked 模式——多个模组可以独立注册,并且所有监听器都会触发。
TICK
Event<PlayerAPIEvents.Tick> TICK
每个游戏滴答触发一次,在 END_CLIENT_TICK 之后,在调度器处理完到期的任务之后。
接口:
@FunctionalInterface
interface Tick {
void onTick();
}
备注:
- 这是任何每滴答自动化逻辑的主要入口点。
- 如果你的逻辑需要已加载的世界,请在顶部调用
PlayerInfo.isInWorld()。 - 调度器在这个事件触发之前运行,因此从上一个滴答计划的任务在你的
TICK处理器运行时已经完成。
CHAT_RECEIVED
Event<PlayerAPIEvents.ChatReceived> CHAT_RECEIVED
当任何聊天消息到达时触发——玩家聊天、系统消息或游戏消息。涵盖已签名的玩家消息和未签名的服务器消息。
接口:
@FunctionalInterface
interface ChatReceived {
void onChatReceived(String sender, String message);
}
| 参数 | 描述 |
|---|---|
sender |
发送者的显示名称,已去除颜色代码。对于系统/游戏消息为空字符串。 |
message |
完整消息文本,已去除颜色代码。 |
备注:
- 动作栏消息(
overlay=true)不会被转发。 ClientReceiveMessageEvents.CHAT(玩家消息)和ClientReceiveMessageEvents.GAME(系统/游戏消息)都会汇集到这个单一事件中。
HEALTH_CHANGED
Event<PlayerAPIEvents.HealthChanged> HEALTH_CHANGED
每当本地玩家的生命值以任意量变化时触发。
接口:
@FunctionalInterface
interface HealthChanged {
void onHealthChanged(float oldHealth, float newHealth);
}
备注:
- 如果生命值降至 0,
PLAYER_DEATH首先触发,然后HEALTH_CHANGED紧随其后触发。 - 在加入世界时不会触发(初始生命值读取)。仅在第一个滴答之后的变化时触发。
INVENTORY_CHANGED
Event<PlayerAPIEvents.InventoryChanged> INVENTORY_CHANGED
当玩家的主背包发生变化时触发。
接口:
@FunctionalInterface
interface InventoryChanged {
void onInventoryChanged(int slot, String newItemId);
}
| 参数 | 描述 |
|---|---|
slot |
发生变化的背包格子。-1 表示批量/未知变化。 |
newItemId |
该格子中新物品的命名空间 ID,例如 "minecraft:diamond_sword"。空-格-子为 "minecraft:air"。 |
POSITION_CHANGED
Event<PlayerAPIEvents.PositionChanged> POSITION_CHANGED
当玩家自上次触发以来移动超过 0.1 格时触发。这是一个基于阈值的事件——它不会每个滴答都触发,只在有意义的移动时触发。
接口:
@FunctionalInterface
interface PositionChanged {
void onPositionChanged(double x, double y, double z);
}
备注:
- 坐标是玩家的脚部位置。
- 0.1 格大约是正常渲染比例下可见的最小移动。
- 不适合毫米级精度追踪——对于那种精度,请在
TICK中使用PlayerInfo.getX/Y/Z()。
WORLD_JOIN
Event<PlayerAPIEvents.WorldJoin> WORLD_JOIN
在客户端连接到服务器或加载世界并且玩家实体可用后触发一次。
接口:
@FunctionalInterface
interface WorldJoin {
void onWorldJoin();
}
备注:
- 生命值/位置差异状态在加入世界时重置,因此
HEALTH_CHANGED和POSITION_CHANGED不会在第一个滴答时错误触发。 - 在此事件触发时,
PlayerInfo.isInWorld()返回 true。
WORLD_LEAVE
Event<PlayerAPIEvents.WorldLeave> WORLD_LEAVE
当客户端断开连接或离开世界时触发。所有按住的按键会被释放,任何激活的人类视角插值会在此事件触发前自动取消。
接口:
@FunctionalInterface
interface WorldLeave {
void onWorldLeave();
}
PLAYER_DEATH
Event<PlayerAPIEvents.PlayerDeath> PLAYER_DEATH
当玩家的生命值达到 0 时触发。
接口:
@FunctionalInterface
interface PlayerDeath {
void onPlayerDeath();
}
备注:
HEALTH_CHANGED也会紧随其后触发,newHealth = 0。- 在此事件触发时,玩家实体仍然存在(死亡画面稍后出现)。
TAB_LIST_UPDATED
Event<PlayerAPIEvents.TabListUpdated> TAB_LIST_UPDATED
当服务器更新 Tab 列表玩家列表时触发。限速为每秒最多一次(根据游戏帧率,即每 Tick 一次)。
接口:
@FunctionalInterface
interface TabListUpdated {
void onTabListUpdated();
}
BLOCK_BROKEN
Event<PlayerAPIEvents.BlockBroken> BLOCK_BROKEN
当本地玩家成功破坏一个方块时触发。由 Fabric 的 ClientPlayerBlockBreakEvents.AFTER 支持。
接口:
@FunctionalInterface
interface BlockBroken {
void onBlockBroken();
}
备注:
- 瞬间破坏的方块(作物、高草丛、花)会立即在客户端触发,无需等待服务器确认。这是农耕自动化最重要的场景。
- 生存模式下的方块(石头、木头等)会在服务器确认破坏后触发。
- 不传递位置或方块类型信息。如果你需要这些,请从之前的
TICK事件中读取WorldInfo.getBlockAtCrosshair()。
6. 调度器
com.playerapi.Scheduler — 基于游戏刻的任务调度(在主游戏线程上执行)。
1 刻 ≈ 50 毫秒(在 20 TPS 下)。
所有回调都是 Runnable,并在它们到期的刻结束时在主游戏线程上触发。
schedule(int delayTicks, Runnable task) → int
调度一个在 delayTicks 刻后运行的任务。返回一个取消令牌。
Scheduler.schedule(20, () -> doSomethingAfterOneSecond());
// token = return value, save it if you need to cancel
delayTicks = 0会在下一立即执行。- 如果游戏低于 20 TPS,任务不保证精确的定时,但它们永远不会提前执行。
scheduleMs(long delayMs, Runnable task) → int
便捷重载。将毫秒转换为刻(除以 50,向上取整,最小为 1)。
Scheduler.scheduleMs(500, () -> doSomethingAfterHalfSecond());
scheduleRepeating(int periodTicks, int times, Runnable task) → int
调度一个重复任务。
| 参数 | 描述 |
|---|---|
periodTicks |
每次调用之间的间隔刻数。 |
times |
触发次数。传入 0 表示无限次(运行直到被取消)。 |
task |
要运行的回调。 |
// Fire 5 times, once per second:
Scheduler.scheduleRepeating(20, 5, () -> BotLogger.info(“tick!”));
// Fire forever (infinite loop — cancel manually):
int token = Scheduler.scheduleRepeating(20, 0, () -> doPeriodicCheck());
// later:
Scheduler.cancel(token);
重要: 无限重复任务每次触发后会重新调度自己。取消初始令牌只能阻止当前待处理的调用触发——如果任务已经触发过一次,请使用 cancelAll() 或自己跟踪重新调度的令牌以实现硬取消。
cancel(int token)
通过令牌取消一个待处理的任务。使用无效/已触发的令牌调用是安全的。
cancelAll()
取消使用此调度器的所有模组的每个待处理任务。在 stopBot() 中有用,以确保在停止后没有残留的延迟动作触发。
getCurrentTick() → long
返回由 PlayerAPI 跟踪的当前全局刻数。在模组加载时从 0 开始,并在每次 END_CLIENT_TICK 时递增。对于时间戳和速率限制很有用。
long start = Scheduler.getCurrentTick();
// ...later...
long elapsed = Scheduler.getCurrentTick() - start; // in ticks
double seconds = elapsed / 20.0;
7. 强制动作
强制动作是即时且计算机精确的。它们会在下一个游戏刻立即生效,没有延迟、噪声或弹簧物理。在精度比外观更重要时使用这些。
7.1 MovementActions
控制玩家按住了哪些移动键。只有当调用了 setActive(true) 时,覆盖才生效。
有效的按键名称: “forward”、“back”、“left”、“right”、“sprint”、“sneak”、“jump”、“attack”、“use”
setActive(boolean active)
启用或禁用移动按键覆盖。禁用时,所有按键释放,玩家恢复完全的手动控制。在按下任何按键之前调用 setActive(true)。
MovementActions.setActive(true);
MovementActions.pressKey(“forward”);
MovementActions.pressKey(“sprint”);
// player now walks forward
isActive() → boolean
返回移动覆盖当前是否已启用。
pressKey(String key)
无限期按住一个键。该键在随后的每个刻中保持按住状态,直到调用 releaseKey 或 releaseAll。
MovementActions.pressKey(“jump”); // holds space bar
releaseKey(String key)
释放一个之前按住的键。
MovementActions.releaseKey(“sprint”);
releaseAll()
释放所有当前按住的键(forward, back, left, right, sprint, sneak, jump, attack, use)。不会禁用覆盖——setActive 状态保持不变。
tapKey(String key, long durationMs)
按下某个键 durationMs 毫秒,然后自动释放。内部转换为刻。
MovementActions.tapKey(“jump”, 100); // tap space for 100 ms (2 ticks)
pressKeys(Iterable<String> keys)
同时按下多个键。等同于为每个键调用 pressKey。
releaseDirectionKeys()
仅释放四个方向键(forward、back、left、right)。疾跑、潜行和跳跃状态不变。在保持疾跑模式的同时停止移动时很有用。
getHeldKeys() → Set<String>
返回当前所有按住的键名的不可修改快照。
isPressed(String key) → boolean
如果指定的键当前被覆盖系统按住,则返回 true。
randomDelay() → long
返回一个介于 50 毫秒和 260 毫秒之间的随机延迟。在编程按键之间作为定时抖动有用,用于反模式检测。
7.2 LookActions
立即设置玩家的视角方向。所有更改立竿见影——没有动画。
Minecraft 偏转角约定:
0°= 南 (+Z)90°= 西 (−X)180°= 北 (−Z)270°= 东 (+X)
俯仰角: −90° = 正上方,0° = 水平,90° = 正下方。
setYaw(float yaw)
将玩家的水平旋转精确设置为 yaw 度。
setPitch(float pitch)
将玩家的垂直旋转精确设置为 pitch 度。自动限制在 [−90, 90] 范围内。
lookAt(double x, double y, double z)
立即旋转视角以查看一个精确的世界坐标。从玩家当前的眼睛位置自动计算所需的偏转角和俯仰角。
LookActions.lookAt(100.0, 64.0, -200.0);
// For level aim: pass player.getY() + 1.62 as the y argument
lookAtBlock(int x, int y, int z)
立即查看方块的中心(x+0.5,y+0.5,z+0.5)。
lookAtBlock(BlockPos pos)
同上,接受一个 BlockPos。
lookAtBlock(int x, int y, int z, Direction face)
查看方块特定面的中心。face 是 Minecraft 的 Direction 枚举值(UP、DOWN、NORTH、SOUTH、EAST、WEST)。
LookActions.lookAtBlock(10, 64, -5, Direction.UP); // aim at top face
lookAtBlock(int x, int y, int z, double xOffset, double yOffset, double zOffset)
查看方块内部的自定义点。偏移量是 [0,1] 范围内的分数,其中 0.5,0.5,0.5 是方块中心。
LookActions.lookAtBlock(10, 64, -5, 0.5, 1.0, 0.5); // top-face centre
snapToNearestCardinal()
将玩家的偏转角对齐到最接近的 90° 倍数。在朝向基本方向移动之前进行对齐时有用。
getSnappedYaw() → int
返回当前偏转角舍入到最近的基本方向(0、90、180 或 270)。
7.3 InventoryActions
直接的背包操作。所有操作在下一个刻立即生效。
switchToSlot(int slot)
将选定的快捷栏格子切换到 slot(0–8)。如果 slot 超出范围则无效果。
switchToItem(String displayName) → boolean
切换到第一个显示名称完全匹配的快捷栏物品(不区分大小写)。如果找到并切换则返回 true,如果不在快捷栏中则返回 false。
InventoryActions.switchToItem(“Wheat Hoe”);
switchToItemStartingWith(String prefix) → boolean
切换到第一个物品显示名称以指定前缀开头的快捷栏格子(不区分大小写)。对于分级物品很有用,例如 “Pest Repellent I” / “Pest Repellent MAX”,你只知道前缀。
InventoryActions.switchToItemStartingWith(“Pest Repellent”);
switchToItemId(String idSubstring) → boolean
切换到第一个物品的命名空间 ID 包含 idSubstring(不区分大小写)的快捷栏格子。当物品名称被本地化或可能更改时,比显示名称匹配更稳定。
InventoryActions.switchToItemId(“diamond_hoe”);
dropItem()
从当前手持的物品堆中丢弃一个物品(相当于 Q 键)。
dropStack()
丢弃当前手持的整个物品堆(相当于 Ctrl+Q)。
dropAllInHotbar(String displayName)
切换到每个匹配 displayName 的快捷栏格子,并丢弃整个物品堆。之后恢复原始选中的格子。
7.4 InteractionActions
玩家与物品、方块和实体的交互。
useItem()
使用(右键点击)主手中的物品。向服务器发送相应的使用物品数据包。适用于消耗品、投掷物、放置方块、打开方块等。
useOffhandItem()
与 useItem() 相同,但适用于副手格子。
useItemHeld(long durationMs)
持续每刻发送 useItem(),持续 durationMs 毫秒。适用于需要按住右键的物品(钓鱼竿、弓、蓄力弩)。
InteractionActions.useItemHeld(1500); // hold right-click for 1.5 seconds
attackTargeted()
攻击当前位于玩家准星下的实体(client.targetedEntity)。如果没有目标实体则无效果。
attackBlockAtCrosshair()
为当前位于准星下的方块发送一个左键点击方块事件。每刻调用以模拟按住左键挖掘方块。如果准星没有对准方块则无效果。
interactTargeted()
与当前位于准星下的实体进行右键交互(client.targetedEntity)。用于与 NPC 交谈、骑乘实体等。
closeScreen()
关闭任何当前打开的界面(背包、容器、告示牌等)。相当于按 Escape 键。
respawn()
向服务器发送重生请求。当玩家处于死亡画面时调用此方法来重生。
7.5 ChatActions
sendChat(String message)
代表玩家发送一条普通的聊天消息。不要在开头包含 /。
ChatActions.sendChat(“Hello, world!”);
sendCommand(String command)
发送一条命令,不包含前导斜杠。PlayerAPI 会在内部添加斜杠。
ChatActions.sendCommand(“tp 0 64 0”); // sends /tp 0 64 0
ChatActions.sendCommand(“warp garden”); // sends /warp garden
7.6 SoundActions
播放来自内置 Minecraft 音效库或你自己的模组 .ogg 文件的音效。
浏览所有 Minecraft 音效 ID: https://misode.github.io/sounds/
registerSound(String namespace, String name) → SoundEvent
注册一个新的音效事件。在 onInitializeClient() 期间调用一次。.ogg 文件必须位于你模组资源 jar 中的 assets/<namespace>/sounds/<name>.ogg 路径下。
SoundActions.registerSound(“mymod”, “my_alert”); // assets/mymod/sounds/my_alert.ogg
play(Identifier soundId, float volume, float pitch)
通过 Identifier 播放音效。适用于已注册的模组音效和所有内置的 Minecraft 音效。
| 参数 | 范围 | 描述 |
|---|---|---|
volume |
0.0 – 2.0 | 1.0 = 正常音量 |
pitch |
0.5 – 2.0 | 1.0 = 正常音调/速度 |
play(String namespace, String name, float volume, float pitch)
便捷重载,接受命名空间和名称作为单独字符串。
SoundActions.play(“minecraft”, “entity.player.levelup”, 1.0f, 1.0f);
playById(String fullSoundId, float volume, float pitch)
通过完整字符串 ID 播放,例如 “minecraft:entity.player.levelup”。如果名称中没有命名空间的冒号,则默认为 “minecraft”。
SoundActions.playById(“entity.experience_orb.pickup”, 1.0f, 1.5f);
playRepeated(Identifier soundId, float volume, float pitch, int times, int intervalTicks)
播放音效 times 次,每次间隔 intervalTicks 刻。内部使用调度器。
// Play level-up sound 3 times, 1 second apart:
Identifier id = Identifier.of(“minecraft”, “entity.player.levelup”);
SoundActions.playRepeated(id, 1.0f, 1.0f, 3, 20);
playRepeated(Identifier soundId, float volume, float pitch, int times)
同上,但固定为 20 刻(1 秒)的间隔。
playByIdRepeated(String fullSoundId, float volume, float pitch, int times, int intervalTicks)
playRepeated 的字符串 ID 便捷版本。
SoundActions.playByIdRepeated(“minecraft:entity.player.levelup”, 1.0f, 1.0f, 5, 20);
stopAll()
停止所有当前正在播放的音效。
7.7 DisplayActions
显示游戏内 HUD 文本,而无需直接依赖 Minecraft 内部代码。
showTitle(String title, String subtitle)
显示标题和可选的副标题,使用默认时序(10 刻淡入 / 70 刻停留 / 20 刻淡出)。
支持 § 颜色代码。为任一参数传入 “” 以使其留空。
DisplayActions.showTitle(“§aBot Started”, “§7Primary path loaded”);
showTitle(String title, String subtitle, int fadeInTicks, int stayTicks, int fadeOutTicks)
同上,但使用自定义时序。
showActionBar(String message)
在动作栏上显示一条简短消息——即出现在快捷栏上方的行。大约 2 秒后消失。支持 § 颜色代码。
DisplayActions.showActionBar(“§ePaused — waiting for repellent”);
7.8 EntityHighlightActions
绘制一个半透明的、经过深度测试的彩色框,与实体的碰撞箱匹配。基于 Minecraft 的 Gizmos 调试绘制 API,因此它独立于原版的实体轮廓(发光)渲染通道——它不会像发光轮廓那样被视线遮挡削弱,也不受渲染器模组(Sodium 等)实现轮廓通道的方式影响。
高亮通过一个 owner 字符串进行命名空间隔离,以便多个消费模组可以同时高亮实体而不会相互覆盖。PlayerAPI 每刻重绘所有所有者的高亮;消费者只需发布他们当前的集合。
在 1.10.0 中添加。
setHighlights(String owner, Map<Integer, Integer> idToColor, float alpha)
在一次调用中替换 owner 的所有高亮。键是实体 ID,值是打包的 RGB int(0xRRGGBB)。alpha 是框的不透明度,0.0–1.0。
Map<Integer, Integer> highlights = Map.of(
entity.getId(), 0xFF5555);
EntityHighlightActions.setHighlights(“esp”, highlights, 0.35f);
setHighlight(String owner, int entityId, int color, float alpha)
在 owner 下添加或更新单个实体的高亮,不触及该所有者的其他高亮。
clearHighlight(String owner, int entityId)
从 owner 的高亮集合中移除一个实体。
`clearOwner(String owner)**
移除在 owner 下注册的每一个高亮。当你的功能被禁用或玩家离开世界时调用。
7.9 BlockHighlightActions
在世界方块坐标周围绘制彩色框——一种“方块 ESP” / X光式高亮。每个框都是始终在最上层绘制的,因此穿过墙壁也可见(这是对 EntityHighlightActions 的补充,后者的实体叠加是经过深度测试/仅限视线遮挡的)。基于相同的 Gizmos API,并通过 owner 字符串进行命名空间隔离。
在 1.11.0 中添加。
setHighlights(String owner, Collection<BlockPos> positions, int color, float alpha)
将所有 owner 的方块高亮替换为给定的坐标,全部使用一种颜色(0xRRGGBB)。alpha 是填充不透明度(0.0–1.0);轮廓绘制得稍强一些,以便框保持可读性。
BlockHighlightActions.setHighlights(“esp-blocks”, positions, 0x55FFFF, 0.35f);
clearOwner(String owner)
移除在 owner 下注册的每一个方块高亮。当你的功能被禁用或世界发生变化时调用。
8. 人类动作
人类 API 镜像了强制 API,但添加了类人的不完美性:反应延迟、带过冲的弹簧物理摄像头移动、移动结束时的随机噪声以及滚轮槽切换。所有时序参数都可以通过 HumanProfile 进行调整。
8.1 HumanActions
视角方法(平滑,弹簧物理)
所有视角方法都开始一个朝向目标的弹簧阻尼插值。在移动开始前有一个可配置的反应延迟,摄像头加速朝向目标,自然过冲,并以小的随机噪声偏移稳定下来。如果弹簧太慢,一个 3 秒的看门狗会强制完成。
| 方法 | 描述 |
|---|---|
lookAt(float yaw, float pitch) |
平滑查看给定的偏转角/俯仰角对。 |
lookAt(double x, double y, double z) |
平滑查看一个精确的世界坐标。 |
lookAt(int x, int y, int z) |
平滑查看方块的中心(整数坐标)。 |
lookAt(BlockPos pos) |
平滑查看一个方块坐标。 |
lookAt(int x, int y, int z, Direction face) |
平滑查看方块的特定面。 |
lookAt(BlockPos pos, Direction face) |
同上,使用 BlockPos。 |
lookAt(int x, int y, int z, double xOffset, double yOffset, double zOffset) |
平滑查看方块内的自定义点。 |
lookYaw(float yaw) |
仅改变偏转角,保持当前俯仰角。 |
lookPitch(float pitch) |
仅改变俯仰角,保持当前偏转角。 |
cancelLook() |
中止任何进行中的视角插值。视图保持当前位置。 |
isLooking() → boolean |
当视角(包括反应延迟)激活时返回 true。 |
按键方法(带反应延迟
正在加载版本记录…
正在加载评论…
评论在新手盒子客户端中发表,这里同步展示。