Skip to main content

EntityRef

Struct EntityRef 

Source
pub struct EntityRef { /* private fields */ }
Expand description

A reference to an entity in a world.

This is different from [Entity], since you can perform actions with just an EntityRef instead of it only being an identifier.

Most functions on EntityRef that return a value will result in a panic if the client has despawned, so if your code involves waiting, you should check Self::is_alive or Self::exists before calling those functions.

Also, since EntityRef stores the Client alongside the entity, this means that it supports interactions such as Self::attack.

Not to be confused with Bevy’s EntityRef.

Implementations§

Source§

impl EntityRef

Source

pub fn position(&self) -> Vec3

Get the entity’s position in the world, which is the same as its feet position.

To get the client’s eye position, use Self::eye_position.

Also see Client::position.

Examples found in repository?
azalea/examples/testbot/commands/movement.rs (line 25)
14pub fn register(commands: &mut CommandDispatcher<Mutex<CommandSource>>) {
15    commands.register(
16        literal("goto")
17            .executes(|ctx: &Ctx| {
18                let source = ctx.source.lock();
19                println!("got goto");
20                // look for the sender
21                let Some(entity) = source.entity() else {
22                    source.reply("I can't see you!");
23                    return 0;
24                };
25                let position = entity.position();
26                source.reply("ok");
27                source
28                    .bot
29                    .start_goto(BlockPosGoal(BlockPos::from(position.up(0.5))));
30                1
31            })
32            .then(literal("xz").then(argument("x", integer()).then(
33                argument("z", integer()).executes(|ctx: &Ctx| {
34                    let source = ctx.source.lock();
35                    let x = get_integer(ctx, "x").unwrap();
36                    let z = get_integer(ctx, "z").unwrap();
37                    println!("goto xz {x} {z}");
38                    source.reply("ok");
39                    source.bot.start_goto(XZGoal { x, z });
40                    1
41                }),
42            )))
43            .then(literal("radius").then(argument("radius", float()).then(
44                argument("x", integer()).then(argument("y", integer()).then(
45                    argument("z", integer()).executes(|ctx: &Ctx| {
46                        let source = ctx.source.lock();
47                        let radius = get_float(ctx, "radius").unwrap();
48                        let x = get_integer(ctx, "x").unwrap();
49                        let y = get_integer(ctx, "y").unwrap();
50                        let z = get_integer(ctx, "z").unwrap();
51                        println!("goto radius {radius}, position: {x} {y} {z}");
52                        source.reply("ok");
53                        source.bot.start_goto(RadiusGoal {
54                            pos: BlockPos::new(x, y, z).center(),
55                            radius,
56                        });
57                        1
58                    }),
59                )),
60            )))
61            .then(argument("x", integer()).then(argument("y", integer()).then(
62                argument("z", integer()).executes(|ctx: &Ctx| {
63                    let source = ctx.source.lock();
64                    let x = get_integer(ctx, "x").unwrap();
65                    let y = get_integer(ctx, "y").unwrap();
66                    let z = get_integer(ctx, "z").unwrap();
67                    println!("goto xyz {x} {y} {z}");
68                    source.reply("ok");
69                    source.bot.start_goto(BlockPosGoal(BlockPos::new(x, y, z)));
70                    1
71                }),
72            ))),
73    );
74
75    commands.register(literal("down").executes(|ctx: &Ctx| {
76        let source = ctx.source.clone();
77        tokio::spawn(async move {
78            let bot = source.lock().bot.clone();
79            let position = BlockPos::from(bot.position());
80            source.lock().reply("mining...");
81            bot.mine(position.down(1)).await;
82            source.lock().reply("done");
83        });
84        1
85    }));
86
87    commands.register(
88        literal("look")
89            .executes(|ctx: &Ctx| {
90                // look for the sender
91                let source = ctx.source.lock();
92                let Some(entity) = source.entity() else {
93                    source.reply("I can't see you!");
94                    return 0;
95                };
96                let eye_position = entity.eye_position();
97                source.bot.look_at(eye_position);
98                1
99            })
100            .then(argument("x", integer()).then(argument("y", integer()).then(
101                argument("z", integer()).executes(|ctx: &Ctx| {
102                    let pos = BlockPos::new(
103                        get_integer(ctx, "x").unwrap(),
104                        get_integer(ctx, "y").unwrap(),
105                        get_integer(ctx, "z").unwrap(),
106                    );
107                    println!("{pos:?}");
108                    let source = ctx.source.lock();
109                    source.bot.look_at(pos.center());
110                    1
111                }),
112            ))),
113    );
114
115    commands.register(
116        literal("walk").then(argument("seconds", float()).executes(|ctx: &Ctx| {
117            let mut seconds = get_float(ctx, "seconds").unwrap();
118            let source = ctx.source.lock();
119            let bot = source.bot.clone();
120
121            if seconds < 0. {
122                bot.walk(WalkDirection::Backward);
123                seconds = -seconds;
124            } else {
125                bot.walk(WalkDirection::Forward);
126            }
127
128            tokio::spawn(async move {
129                tokio::time::sleep(Duration::from_secs_f32(seconds)).await;
130                bot.walk(WalkDirection::None);
131            });
132            source.reply(format!("ok, walking for {seconds} seconds"));
133            1
134        })),
135    );
136    commands.register(
137        literal("sprint").then(argument("seconds", float()).executes(|ctx: &Ctx| {
138            let seconds = get_float(ctx, "seconds").unwrap();
139            let source = ctx.source.lock();
140            let bot = source.bot.clone();
141            bot.sprint(SprintDirection::Forward);
142            tokio::spawn(async move {
143                tokio::time::sleep(Duration::from_secs_f32(seconds)).await;
144                bot.walk(WalkDirection::None);
145            });
146            source.reply(format!("ok, sprinting for {seconds} seconds"));
147            1
148        })),
149    );
150
151    commands.register(literal("north").executes(|ctx: &Ctx| {
152        let source = ctx.source.lock();
153        source.bot.set_direction(180., 0.);
154        source.reply("ok");
155        1
156    }));
157    commands.register(literal("south").executes(|ctx: &Ctx| {
158        let source = ctx.source.lock();
159        source.bot.set_direction(0., 0.);
160        source.reply("ok");
161        1
162    }));
163    commands.register(literal("east").executes(|ctx: &Ctx| {
164        let source = ctx.source.lock();
165        source.bot.set_direction(-90., 0.);
166        source.reply("ok");
167        1
168    }));
169    commands.register(literal("west").executes(|ctx: &Ctx| {
170        let source = ctx.source.lock();
171        source.bot.set_direction(90., 0.);
172        source.reply("ok");
173        1
174    }));
175    commands.register(
176        literal("jump")
177            .executes(|ctx: &Ctx| {
178                let source = ctx.source.lock();
179                source.bot.jump();
180                source.reply("ok");
181                1
182            })
183            .then(argument("enabled", bool()).executes(|ctx: &Ctx| {
184                let jumping = get_bool(ctx, "enabled").unwrap();
185                let source = ctx.source.lock();
186                source.bot.set_jumping(jumping);
187                1
188            })),
189    );
190
191    let sneak = |ctx: &Ctx| {
192        let source = ctx.source.lock();
193        source.bot.set_crouching(!source.bot.crouching());
194        source.reply("ok");
195        1
196    };
197    let sneak_enabled = argument("enabled", bool()).executes(|ctx: &Ctx| {
198        let sneaking = get_bool(ctx, "enabled").unwrap();
199        let source = ctx.source.lock();
200        source.bot.set_crouching(sneaking);
201        1
202    });
203    commands.register(literal("sneak").executes(sneak).then(sneak_enabled.clone()));
204    commands.register(literal("crouch").executes(sneak).then(sneak_enabled));
205
206    commands.register(literal("stop").executes(|ctx: &Ctx| {
207        let source = ctx.source.lock();
208        source.bot.stop_pathfinding();
209        source.reply("ok");
210        *source.state.task.lock() = BotTask::None;
211        1
212    }));
213    commands.register(literal("forcestop").executes(|ctx: &Ctx| {
214        let source = ctx.source.lock();
215        source.bot.force_stop_pathfinding();
216        source.reply("ok");
217        *source.state.task.lock() = BotTask::None;
218        1
219    }));
220}
More examples
Hide additional examples
azalea/examples/testbot/commands/debug.rs (line 53)
26pub fn register(commands: &mut CommandDispatcher<Mutex<CommandSource>>) {
27    commands.register(literal("ping").executes(|ctx: &Ctx| {
28        let source = ctx.source.lock();
29        source.reply("pong!");
30        1
31    }));
32    commands.register(
33        literal("say").then(argument("message", greedy_string()).executes(|ctx: &Ctx| {
34            let source = ctx.source.lock();
35            let message = get_string(ctx, "message").unwrap();
36            source.bot.chat(message);
37            1
38        })),
39    );
40
41    commands.register(literal("disconnect").executes(|ctx: &Ctx| {
42        let source = ctx.source.lock();
43        source.bot.disconnect();
44        1
45    }));
46
47    commands.register(literal("whereami").executes(|ctx: &Ctx| {
48        let source = ctx.source.lock();
49        let Some(entity) = source.entity() else {
50            source.reply("You aren't in render distance!");
51            return 0;
52        };
53        let position = entity.position();
54        source.reply(format!(
55            "You are at {}, {}, {}",
56            position.x, position.y, position.z
57        ));
58        1
59    }));
60
61    commands.register(literal("entityid").executes(|ctx: &Ctx| {
62        let source = ctx.source.lock();
63        let Some(entity) = source.entity() else {
64            source.reply("You aren't in render distance!");
65            return 0;
66        };
67        let entity_id = entity.minecraft_id();
68        source.reply(format!(
69            "Your Minecraft ID is {} and your ECS ID is {entity:?}",
70            *entity_id
71        ));
72        1
73    }));
74
75    let whereareyou = |ctx: &Ctx| {
76        let source = ctx.source.lock();
77        let position = source.bot.position();
78        source.reply(format!(
79            "I'm at {}, {}, {}",
80            position.x, position.y, position.z
81        ));
82        1
83    };
84    commands.register(literal("whereareyou").executes(whereareyou));
85    commands.register(literal("pos").executes(whereareyou));
86
87    commands.register(literal("whoareyou").executes(|ctx: &Ctx| {
88        let source = ctx.source.lock();
89        source.reply(format!(
90            "I am {} ({}, {})",
91            source.bot.username(),
92            source.bot.uuid(),
93            source.bot.entity
94        ));
95        1
96    }));
97
98    commands.register(literal("getdirection").executes(|ctx: &Ctx| {
99        let source = ctx.source.lock();
100        let direction = source.bot.direction();
101        source.reply(format!(
102            "I'm looking at {}, {}",
103            direction.y_rot(),
104            direction.x_rot()
105        ));
106        1
107    }));
108
109    commands.register(literal("health").executes(|ctx: &Ctx| {
110        let source = ctx.source.lock();
111
112        let health = source.bot.health();
113        source.reply(format!("I have {health} health"));
114        1
115    }));
116
117    commands.register(literal("lookingat").executes(|ctx: &Ctx| {
118        let source = ctx.source.lock();
119
120        let hit_result = source.bot.hit_result();
121
122        match &hit_result {
123            HitResult::Block(r) => {
124                if r.miss {
125                    source.reply("I'm not looking at anything");
126                    return 0;
127                }
128                let block_pos = r.block_pos;
129                let block = source.bot.world().read().get_block_state(block_pos);
130                source.reply(format!("I'm looking at {block:?} at {block_pos:?}"));
131            }
132            HitResult::Entity(r) => {
133                let entity_kind = **source.bot.entity_component::<EntityKindComponent>(r.entity);
134                source.reply(format!(
135                    "I'm looking at {entity_kind} ({:?}) at {}",
136                    r.entity, r.location
137                ));
138            }
139        }
140
141        1
142    }));
143
144    commands.register(literal("getblock").then(argument("x", integer()).then(
145        argument("y", integer()).then(argument("z", integer()).executes(|ctx: &Ctx| {
146            let source = ctx.source.lock();
147            let x = get_integer(ctx, "x").unwrap();
148            let y = get_integer(ctx, "y").unwrap();
149            let z = get_integer(ctx, "z").unwrap();
150            println!("getblock xyz {x} {y} {z}");
151            let block_pos = BlockPos::new(x, y, z);
152            let block = source.bot.world().read().get_block_state(block_pos);
153            source.reply(format!("BlockKind at {block_pos} is {block:?}"));
154            1
155        })),
156    )));
157    commands.register(literal("getfluid").then(argument("x", integer()).then(
158        argument("y", integer()).then(argument("z", integer()).executes(|ctx: &Ctx| {
159            let source = ctx.source.lock();
160            let x = get_integer(ctx, "x").unwrap();
161            let y = get_integer(ctx, "y").unwrap();
162            let z = get_integer(ctx, "z").unwrap();
163            println!("getfluid xyz {x} {y} {z}");
164            let block_pos = BlockPos::new(x, y, z);
165            let block = source.bot.world().read().get_fluid_state(block_pos);
166            source.reply(format!("Fluid at {block_pos} is {block:?}"));
167            1
168        })),
169    )));
170
171    commands.register(literal("pathfinderstate").executes(|ctx: &Ctx| {
172        let source = ctx.source.lock();
173        let pathfinder = source.bot.get_component::<Pathfinder>();
174        let Some(pathfinder) = pathfinder else {
175            source.reply("I don't have the Pathfinder component");
176            return 1;
177        };
178        source.reply(format!(
179            "pathfinder.is_calculating: {}",
180            pathfinder.is_calculating
181        ));
182
183        let executing_path = source.bot.get_component::<ExecutingPath>();
184        let Some(executing_path) = executing_path else {
185            source.reply("I'm not executing a path");
186            return 1;
187        };
188        source.reply(format!(
189            "is_path_partial: {}, path.len: {}, queued_path.len: {}",
190            executing_path.is_path_partial,
191            executing_path.path.len(),
192            if let Some(queued) = &executing_path.queued_path {
193                queued.len().to_string()
194            } else {
195                "n/a".to_owned()
196            },
197        ));
198        1
199    }));
200    commands.register(literal("pathfindermoves").executes(|ctx: &Ctx| {
201        let source = ctx.source.lock();
202
203        let Some(entity) = source.entity() else {
204            source.reply("You aren't in render distance!");
205            return 0;
206        };
207        let position = entity.position();
208        let position = BlockPos::from(position);
209
210        let mut edges = Vec::new();
211        let cached_world = CachedWorld::new(source.bot.world(), position);
212        let mining_cache = MiningCache::new(Some(Menu::Player(inventory::Player::default())));
213        let custom_state = CustomPathfinderStateRef::default();
214
215        azalea::pathfinder::moves::default_move(
216            &mut MovesCtx {
217                edges: &mut edges,
218                world: &cached_world,
219                mining_cache: &mining_cache,
220                custom_state: &custom_state,
221            },
222            RelBlockPos::from_origin(position, position),
223        );
224
225        if edges.is_empty() {
226            source.reply("No possible moves.");
227        } else {
228            source.reply("Moves:");
229            for (i, edge) in edges.iter().enumerate() {
230                source.reply(format!("{}) {edge:?}", i + 1));
231            }
232        }
233
234        1
235    }));
236
237    commands.register(literal("startuseitem").executes(|ctx: &Ctx| {
238        let source = ctx.source.lock();
239        source.bot.start_use_item();
240        source.reply("Ok!");
241        1
242    }));
243    commands.register(literal("maxstacksize").executes(|ctx: &Ctx| {
244        let source = ctx.source.lock();
245        let max_stack_size = source
246            .bot
247            .get_held_item()
248            .get_component::<MaxStackSize>()
249            .map_or(-1, |s| s.count);
250        source.reply(format!("{max_stack_size}"));
251        1
252    }));
253
254    commands.register(literal("dimensions").executes(|ctx: &Ctx| {
255        let source = ctx.source.lock();
256        let bot_dimensions = source.bot.dimensions();
257        source.reply(format!("{bot_dimensions:?}"));
258        1
259    }));
260
261    commands.register(literal("players").executes(|ctx: &Ctx| {
262        let source = ctx.source.lock();
263        let player_entities = source
264            .bot
265            .nearest_entities_by::<(), With<metadata::Player>>(|_: ()| true);
266        let tab_list = source.bot.tab_list();
267        for player_entity in player_entities {
268            let uuid = player_entity.uuid();
269            source.reply(format!(
270                "{} - {} ({:?})",
271                player_entity.id(),
272                tab_list.get(&uuid).map_or("?", |p| p.profile.name.as_str()),
273                uuid
274            ));
275        }
276        1
277    }));
278
279    commands.register(literal("enchants").executes(|ctx: &Ctx| {
280        let source = ctx.source.lock();
281        source.bot.with_registry_holder(|r| {
282            let enchants = &r.enchantment;
283            println!("enchants: {enchants:?}");
284        });
285        1
286    }));
287
288    commands.register(literal("attributes").executes(|ctx: &Ctx| {
289        let source = ctx.source.lock();
290        let attributes = source.bot.attributes();
291        println!("attributes: {attributes:?}");
292        1
293    }));
294
295    commands.register(literal("debugecsleak").executes(|ctx: &Ctx| {
296        let source = ctx.source.lock();
297
298        source.reply("Ok!");
299
300
301
302        source.bot.disconnect();
303
304        let ecs = source.bot.ecs.clone();
305        thread::spawn(move || {
306            thread::sleep(Duration::from_secs(1));
307            // dump the ecs
308
309            let mut ecs = ecs.write();
310
311            let report_path = env::temp_dir().join("azalea-ecs-leak-report.txt");
312            let mut report = File::create(&report_path).unwrap();
313
314            let mut query = ecs.query::<EntityRef>();
315            for entity in query.iter(& ecs) {
316                writeln!(report, "Entity: {}", entity.id()).unwrap();
317                let archetype = entity.archetype();
318                let component_count = archetype.component_count();
319
320                let component_names = archetype
321                    .components()
322                    .iter()
323                    .map(|c| ecs.components().get_info(*c).unwrap().name().to_string())
324                    .collect::<Vec<_>>();
325                writeln!(
326                    report,
327                    "- {component_count} components: {}",
328                    component_names.join(", ")
329                )
330                .unwrap();
331            }
332
333            writeln!(report).unwrap();
334
335
336            for (info, _) in ecs.iter_resources() {
337                let name = info.name().to_string();
338                writeln!(report, "Resource: {name}").unwrap();
339                // writeln!(report, "- Size: {} bytes",
340                // info.layout().size()).unwrap();
341
342                match name.as_ref() {
343                    "azalea_world::container::Worlds" => {
344                        let worlds = ecs.resource::<Worlds>();
345
346                        for (world_name, world) in &worlds.map {
347                            writeln!(report, "- Name: {world_name}").unwrap();
348                            writeln!(report, "- Reference count: {}", world.strong_count())
349                                .unwrap();
350                            if let Some(world) = world.upgrade() {
351                                let world = world.read();
352                                let chunks = &world.chunks;
353                                let chunks = (chunks as &dyn Any).downcast_ref::<WeakChunkStorage>();
354                                if let Some(chunks) = chunks {
355                                    let strong_chunks = chunks
356                                        .map
357                                        .iter()
358                                        .filter(|(_, v)| v.strong_count() > 0)
359                                        .count();
360                                    writeln!(
361                                        report,
362                                        "- Chunks: {} strongly referenced, {} in map",
363                                        strong_chunks,
364                                        chunks.map.len()
365                                    )
366                                    .unwrap();
367                                }
368                                writeln!(
369                                    report,
370                                    "- Entities: {}",
371                                    world.entities_by_chunk.len()
372                                )
373                                .unwrap();
374                            }
375                        }
376                    }
377                    "bevy_ecs::message::Messages<azalea_client::packet::game::ReceivePacketEvent>" => {
378                        let events = ecs.resource::<Messages<game::ReceiveGamePacketEvent>>();
379                        writeln!(report, "- Event count: {}", events.len()).unwrap();
380                    }
381                    "bevy_ecs::message::Messages<azalea_client::chunks::ReceiveChunkEvent>" => {
382                        let events = ecs.resource::<Messages<ReceiveChunkEvent>>();
383                        writeln!(report, "- Event count: {}", events.len()).unwrap();
384                    }
385
386                    _ => {}
387                }
388            }
389
390            println!("\x1b[1mWrote report to {}\x1b[m", report_path.display());
391        });
392
393        1
394    }));
395
396    commands.register(literal("exit").executes(|ctx: &Ctx| {
397        let source = ctx.source.lock();
398        source.reply("bye!");
399
400        source.bot.disconnect();
401
402        let source = ctx.source.clone();
403        thread::spawn(move || {
404            thread::sleep(Duration::from_secs(1));
405
406            source
407                .lock()
408                .bot
409                .ecs
410                .write()
411                .write_message(AppExit::Success);
412        });
413
414        1
415    }));
416}
Source§

impl EntityRef

Source

pub fn dimensions(&self) -> EntityDimensions

Get the bounding box dimensions for the entity, which contains its width, height, and eye height.

Also see Client::dimensions

Source§

impl EntityRef

Source

pub fn eye_position(&self) -> Vec3

Get the position of this entity’s eyes.

Also see Client::eye_position.

Examples found in repository?
azalea/examples/testbot/commands/movement.rs (line 96)
14pub fn register(commands: &mut CommandDispatcher<Mutex<CommandSource>>) {
15    commands.register(
16        literal("goto")
17            .executes(|ctx: &Ctx| {
18                let source = ctx.source.lock();
19                println!("got goto");
20                // look for the sender
21                let Some(entity) = source.entity() else {
22                    source.reply("I can't see you!");
23                    return 0;
24                };
25                let position = entity.position();
26                source.reply("ok");
27                source
28                    .bot
29                    .start_goto(BlockPosGoal(BlockPos::from(position.up(0.5))));
30                1
31            })
32            .then(literal("xz").then(argument("x", integer()).then(
33                argument("z", integer()).executes(|ctx: &Ctx| {
34                    let source = ctx.source.lock();
35                    let x = get_integer(ctx, "x").unwrap();
36                    let z = get_integer(ctx, "z").unwrap();
37                    println!("goto xz {x} {z}");
38                    source.reply("ok");
39                    source.bot.start_goto(XZGoal { x, z });
40                    1
41                }),
42            )))
43            .then(literal("radius").then(argument("radius", float()).then(
44                argument("x", integer()).then(argument("y", integer()).then(
45                    argument("z", integer()).executes(|ctx: &Ctx| {
46                        let source = ctx.source.lock();
47                        let radius = get_float(ctx, "radius").unwrap();
48                        let x = get_integer(ctx, "x").unwrap();
49                        let y = get_integer(ctx, "y").unwrap();
50                        let z = get_integer(ctx, "z").unwrap();
51                        println!("goto radius {radius}, position: {x} {y} {z}");
52                        source.reply("ok");
53                        source.bot.start_goto(RadiusGoal {
54                            pos: BlockPos::new(x, y, z).center(),
55                            radius,
56                        });
57                        1
58                    }),
59                )),
60            )))
61            .then(argument("x", integer()).then(argument("y", integer()).then(
62                argument("z", integer()).executes(|ctx: &Ctx| {
63                    let source = ctx.source.lock();
64                    let x = get_integer(ctx, "x").unwrap();
65                    let y = get_integer(ctx, "y").unwrap();
66                    let z = get_integer(ctx, "z").unwrap();
67                    println!("goto xyz {x} {y} {z}");
68                    source.reply("ok");
69                    source.bot.start_goto(BlockPosGoal(BlockPos::new(x, y, z)));
70                    1
71                }),
72            ))),
73    );
74
75    commands.register(literal("down").executes(|ctx: &Ctx| {
76        let source = ctx.source.clone();
77        tokio::spawn(async move {
78            let bot = source.lock().bot.clone();
79            let position = BlockPos::from(bot.position());
80            source.lock().reply("mining...");
81            bot.mine(position.down(1)).await;
82            source.lock().reply("done");
83        });
84        1
85    }));
86
87    commands.register(
88        literal("look")
89            .executes(|ctx: &Ctx| {
90                // look for the sender
91                let source = ctx.source.lock();
92                let Some(entity) = source.entity() else {
93                    source.reply("I can't see you!");
94                    return 0;
95                };
96                let eye_position = entity.eye_position();
97                source.bot.look_at(eye_position);
98                1
99            })
100            .then(argument("x", integer()).then(argument("y", integer()).then(
101                argument("z", integer()).executes(|ctx: &Ctx| {
102                    let pos = BlockPos::new(
103                        get_integer(ctx, "x").unwrap(),
104                        get_integer(ctx, "y").unwrap(),
105                        get_integer(ctx, "z").unwrap(),
106                    );
107                    println!("{pos:?}");
108                    let source = ctx.source.lock();
109                    source.bot.look_at(pos.center());
110                    1
111                }),
112            ))),
113    );
114
115    commands.register(
116        literal("walk").then(argument("seconds", float()).executes(|ctx: &Ctx| {
117            let mut seconds = get_float(ctx, "seconds").unwrap();
118            let source = ctx.source.lock();
119            let bot = source.bot.clone();
120
121            if seconds < 0. {
122                bot.walk(WalkDirection::Backward);
123                seconds = -seconds;
124            } else {
125                bot.walk(WalkDirection::Forward);
126            }
127
128            tokio::spawn(async move {
129                tokio::time::sleep(Duration::from_secs_f32(seconds)).await;
130                bot.walk(WalkDirection::None);
131            });
132            source.reply(format!("ok, walking for {seconds} seconds"));
133            1
134        })),
135    );
136    commands.register(
137        literal("sprint").then(argument("seconds", float()).executes(|ctx: &Ctx| {
138            let seconds = get_float(ctx, "seconds").unwrap();
139            let source = ctx.source.lock();
140            let bot = source.bot.clone();
141            bot.sprint(SprintDirection::Forward);
142            tokio::spawn(async move {
143                tokio::time::sleep(Duration::from_secs_f32(seconds)).await;
144                bot.walk(WalkDirection::None);
145            });
146            source.reply(format!("ok, sprinting for {seconds} seconds"));
147            1
148        })),
149    );
150
151    commands.register(literal("north").executes(|ctx: &Ctx| {
152        let source = ctx.source.lock();
153        source.bot.set_direction(180., 0.);
154        source.reply("ok");
155        1
156    }));
157    commands.register(literal("south").executes(|ctx: &Ctx| {
158        let source = ctx.source.lock();
159        source.bot.set_direction(0., 0.);
160        source.reply("ok");
161        1
162    }));
163    commands.register(literal("east").executes(|ctx: &Ctx| {
164        let source = ctx.source.lock();
165        source.bot.set_direction(-90., 0.);
166        source.reply("ok");
167        1
168    }));
169    commands.register(literal("west").executes(|ctx: &Ctx| {
170        let source = ctx.source.lock();
171        source.bot.set_direction(90., 0.);
172        source.reply("ok");
173        1
174    }));
175    commands.register(
176        literal("jump")
177            .executes(|ctx: &Ctx| {
178                let source = ctx.source.lock();
179                source.bot.jump();
180                source.reply("ok");
181                1
182            })
183            .then(argument("enabled", bool()).executes(|ctx: &Ctx| {
184                let jumping = get_bool(ctx, "enabled").unwrap();
185                let source = ctx.source.lock();
186                source.bot.set_jumping(jumping);
187                1
188            })),
189    );
190
191    let sneak = |ctx: &Ctx| {
192        let source = ctx.source.lock();
193        source.bot.set_crouching(!source.bot.crouching());
194        source.reply("ok");
195        1
196    };
197    let sneak_enabled = argument("enabled", bool()).executes(|ctx: &Ctx| {
198        let sneaking = get_bool(ctx, "enabled").unwrap();
199        let source = ctx.source.lock();
200        source.bot.set_crouching(sneaking);
201        1
202    });
203    commands.register(literal("sneak").executes(sneak).then(sneak_enabled.clone()));
204    commands.register(literal("crouch").executes(sneak).then(sneak_enabled));
205
206    commands.register(literal("stop").executes(|ctx: &Ctx| {
207        let source = ctx.source.lock();
208        source.bot.stop_pathfinding();
209        source.reply("ok");
210        *source.state.task.lock() = BotTask::None;
211        1
212    }));
213    commands.register(literal("forcestop").executes(|ctx: &Ctx| {
214        let source = ctx.source.lock();
215        source.bot.force_stop_pathfinding();
216        source.reply("ok");
217        *source.state.task.lock() = BotTask::None;
218        1
219    }));
220}
Source§

impl EntityRef

Source

pub fn health(&self) -> f32

Get the health of this entity, typically in the range 0..=20.

Also see Client::health.

Source§

impl EntityRef

Source

pub fn uuid(&self) -> Uuid

Get the Minecraft UUID of this entity.

Also see Client::uuid.

Examples found in repository?
azalea/examples/testbot/commands/debug.rs (line 268)
26pub fn register(commands: &mut CommandDispatcher<Mutex<CommandSource>>) {
27    commands.register(literal("ping").executes(|ctx: &Ctx| {
28        let source = ctx.source.lock();
29        source.reply("pong!");
30        1
31    }));
32    commands.register(
33        literal("say").then(argument("message", greedy_string()).executes(|ctx: &Ctx| {
34            let source = ctx.source.lock();
35            let message = get_string(ctx, "message").unwrap();
36            source.bot.chat(message);
37            1
38        })),
39    );
40
41    commands.register(literal("disconnect").executes(|ctx: &Ctx| {
42        let source = ctx.source.lock();
43        source.bot.disconnect();
44        1
45    }));
46
47    commands.register(literal("whereami").executes(|ctx: &Ctx| {
48        let source = ctx.source.lock();
49        let Some(entity) = source.entity() else {
50            source.reply("You aren't in render distance!");
51            return 0;
52        };
53        let position = entity.position();
54        source.reply(format!(
55            "You are at {}, {}, {}",
56            position.x, position.y, position.z
57        ));
58        1
59    }));
60
61    commands.register(literal("entityid").executes(|ctx: &Ctx| {
62        let source = ctx.source.lock();
63        let Some(entity) = source.entity() else {
64            source.reply("You aren't in render distance!");
65            return 0;
66        };
67        let entity_id = entity.minecraft_id();
68        source.reply(format!(
69            "Your Minecraft ID is {} and your ECS ID is {entity:?}",
70            *entity_id
71        ));
72        1
73    }));
74
75    let whereareyou = |ctx: &Ctx| {
76        let source = ctx.source.lock();
77        let position = source.bot.position();
78        source.reply(format!(
79            "I'm at {}, {}, {}",
80            position.x, position.y, position.z
81        ));
82        1
83    };
84    commands.register(literal("whereareyou").executes(whereareyou));
85    commands.register(literal("pos").executes(whereareyou));
86
87    commands.register(literal("whoareyou").executes(|ctx: &Ctx| {
88        let source = ctx.source.lock();
89        source.reply(format!(
90            "I am {} ({}, {})",
91            source.bot.username(),
92            source.bot.uuid(),
93            source.bot.entity
94        ));
95        1
96    }));
97
98    commands.register(literal("getdirection").executes(|ctx: &Ctx| {
99        let source = ctx.source.lock();
100        let direction = source.bot.direction();
101        source.reply(format!(
102            "I'm looking at {}, {}",
103            direction.y_rot(),
104            direction.x_rot()
105        ));
106        1
107    }));
108
109    commands.register(literal("health").executes(|ctx: &Ctx| {
110        let source = ctx.source.lock();
111
112        let health = source.bot.health();
113        source.reply(format!("I have {health} health"));
114        1
115    }));
116
117    commands.register(literal("lookingat").executes(|ctx: &Ctx| {
118        let source = ctx.source.lock();
119
120        let hit_result = source.bot.hit_result();
121
122        match &hit_result {
123            HitResult::Block(r) => {
124                if r.miss {
125                    source.reply("I'm not looking at anything");
126                    return 0;
127                }
128                let block_pos = r.block_pos;
129                let block = source.bot.world().read().get_block_state(block_pos);
130                source.reply(format!("I'm looking at {block:?} at {block_pos:?}"));
131            }
132            HitResult::Entity(r) => {
133                let entity_kind = **source.bot.entity_component::<EntityKindComponent>(r.entity);
134                source.reply(format!(
135                    "I'm looking at {entity_kind} ({:?}) at {}",
136                    r.entity, r.location
137                ));
138            }
139        }
140
141        1
142    }));
143
144    commands.register(literal("getblock").then(argument("x", integer()).then(
145        argument("y", integer()).then(argument("z", integer()).executes(|ctx: &Ctx| {
146            let source = ctx.source.lock();
147            let x = get_integer(ctx, "x").unwrap();
148            let y = get_integer(ctx, "y").unwrap();
149            let z = get_integer(ctx, "z").unwrap();
150            println!("getblock xyz {x} {y} {z}");
151            let block_pos = BlockPos::new(x, y, z);
152            let block = source.bot.world().read().get_block_state(block_pos);
153            source.reply(format!("BlockKind at {block_pos} is {block:?}"));
154            1
155        })),
156    )));
157    commands.register(literal("getfluid").then(argument("x", integer()).then(
158        argument("y", integer()).then(argument("z", integer()).executes(|ctx: &Ctx| {
159            let source = ctx.source.lock();
160            let x = get_integer(ctx, "x").unwrap();
161            let y = get_integer(ctx, "y").unwrap();
162            let z = get_integer(ctx, "z").unwrap();
163            println!("getfluid xyz {x} {y} {z}");
164            let block_pos = BlockPos::new(x, y, z);
165            let block = source.bot.world().read().get_fluid_state(block_pos);
166            source.reply(format!("Fluid at {block_pos} is {block:?}"));
167            1
168        })),
169    )));
170
171    commands.register(literal("pathfinderstate").executes(|ctx: &Ctx| {
172        let source = ctx.source.lock();
173        let pathfinder = source.bot.get_component::<Pathfinder>();
174        let Some(pathfinder) = pathfinder else {
175            source.reply("I don't have the Pathfinder component");
176            return 1;
177        };
178        source.reply(format!(
179            "pathfinder.is_calculating: {}",
180            pathfinder.is_calculating
181        ));
182
183        let executing_path = source.bot.get_component::<ExecutingPath>();
184        let Some(executing_path) = executing_path else {
185            source.reply("I'm not executing a path");
186            return 1;
187        };
188        source.reply(format!(
189            "is_path_partial: {}, path.len: {}, queued_path.len: {}",
190            executing_path.is_path_partial,
191            executing_path.path.len(),
192            if let Some(queued) = &executing_path.queued_path {
193                queued.len().to_string()
194            } else {
195                "n/a".to_owned()
196            },
197        ));
198        1
199    }));
200    commands.register(literal("pathfindermoves").executes(|ctx: &Ctx| {
201        let source = ctx.source.lock();
202
203        let Some(entity) = source.entity() else {
204            source.reply("You aren't in render distance!");
205            return 0;
206        };
207        let position = entity.position();
208        let position = BlockPos::from(position);
209
210        let mut edges = Vec::new();
211        let cached_world = CachedWorld::new(source.bot.world(), position);
212        let mining_cache = MiningCache::new(Some(Menu::Player(inventory::Player::default())));
213        let custom_state = CustomPathfinderStateRef::default();
214
215        azalea::pathfinder::moves::default_move(
216            &mut MovesCtx {
217                edges: &mut edges,
218                world: &cached_world,
219                mining_cache: &mining_cache,
220                custom_state: &custom_state,
221            },
222            RelBlockPos::from_origin(position, position),
223        );
224
225        if edges.is_empty() {
226            source.reply("No possible moves.");
227        } else {
228            source.reply("Moves:");
229            for (i, edge) in edges.iter().enumerate() {
230                source.reply(format!("{}) {edge:?}", i + 1));
231            }
232        }
233
234        1
235    }));
236
237    commands.register(literal("startuseitem").executes(|ctx: &Ctx| {
238        let source = ctx.source.lock();
239        source.bot.start_use_item();
240        source.reply("Ok!");
241        1
242    }));
243    commands.register(literal("maxstacksize").executes(|ctx: &Ctx| {
244        let source = ctx.source.lock();
245        let max_stack_size = source
246            .bot
247            .get_held_item()
248            .get_component::<MaxStackSize>()
249            .map_or(-1, |s| s.count);
250        source.reply(format!("{max_stack_size}"));
251        1
252    }));
253
254    commands.register(literal("dimensions").executes(|ctx: &Ctx| {
255        let source = ctx.source.lock();
256        let bot_dimensions = source.bot.dimensions();
257        source.reply(format!("{bot_dimensions:?}"));
258        1
259    }));
260
261    commands.register(literal("players").executes(|ctx: &Ctx| {
262        let source = ctx.source.lock();
263        let player_entities = source
264            .bot
265            .nearest_entities_by::<(), With<metadata::Player>>(|_: ()| true);
266        let tab_list = source.bot.tab_list();
267        for player_entity in player_entities {
268            let uuid = player_entity.uuid();
269            source.reply(format!(
270                "{} - {} ({:?})",
271                player_entity.id(),
272                tab_list.get(&uuid).map_or("?", |p| p.profile.name.as_str()),
273                uuid
274            ));
275        }
276        1
277    }));
278
279    commands.register(literal("enchants").executes(|ctx: &Ctx| {
280        let source = ctx.source.lock();
281        source.bot.with_registry_holder(|r| {
282            let enchants = &r.enchantment;
283            println!("enchants: {enchants:?}");
284        });
285        1
286    }));
287
288    commands.register(literal("attributes").executes(|ctx: &Ctx| {
289        let source = ctx.source.lock();
290        let attributes = source.bot.attributes();
291        println!("attributes: {attributes:?}");
292        1
293    }));
294
295    commands.register(literal("debugecsleak").executes(|ctx: &Ctx| {
296        let source = ctx.source.lock();
297
298        source.reply("Ok!");
299
300
301
302        source.bot.disconnect();
303
304        let ecs = source.bot.ecs.clone();
305        thread::spawn(move || {
306            thread::sleep(Duration::from_secs(1));
307            // dump the ecs
308
309            let mut ecs = ecs.write();
310
311            let report_path = env::temp_dir().join("azalea-ecs-leak-report.txt");
312            let mut report = File::create(&report_path).unwrap();
313
314            let mut query = ecs.query::<EntityRef>();
315            for entity in query.iter(& ecs) {
316                writeln!(report, "Entity: {}", entity.id()).unwrap();
317                let archetype = entity.archetype();
318                let component_count = archetype.component_count();
319
320                let component_names = archetype
321                    .components()
322                    .iter()
323                    .map(|c| ecs.components().get_info(*c).unwrap().name().to_string())
324                    .collect::<Vec<_>>();
325                writeln!(
326                    report,
327                    "- {component_count} components: {}",
328                    component_names.join(", ")
329                )
330                .unwrap();
331            }
332
333            writeln!(report).unwrap();
334
335
336            for (info, _) in ecs.iter_resources() {
337                let name = info.name().to_string();
338                writeln!(report, "Resource: {name}").unwrap();
339                // writeln!(report, "- Size: {} bytes",
340                // info.layout().size()).unwrap();
341
342                match name.as_ref() {
343                    "azalea_world::container::Worlds" => {
344                        let worlds = ecs.resource::<Worlds>();
345
346                        for (world_name, world) in &worlds.map {
347                            writeln!(report, "- Name: {world_name}").unwrap();
348                            writeln!(report, "- Reference count: {}", world.strong_count())
349                                .unwrap();
350                            if let Some(world) = world.upgrade() {
351                                let world = world.read();
352                                let chunks = &world.chunks;
353                                let chunks = (chunks as &dyn Any).downcast_ref::<WeakChunkStorage>();
354                                if let Some(chunks) = chunks {
355                                    let strong_chunks = chunks
356                                        .map
357                                        .iter()
358                                        .filter(|(_, v)| v.strong_count() > 0)
359                                        .count();
360                                    writeln!(
361                                        report,
362                                        "- Chunks: {} strongly referenced, {} in map",
363                                        strong_chunks,
364                                        chunks.map.len()
365                                    )
366                                    .unwrap();
367                                }
368                                writeln!(
369                                    report,
370                                    "- Entities: {}",
371                                    world.entities_by_chunk.len()
372                                )
373                                .unwrap();
374                            }
375                        }
376                    }
377                    "bevy_ecs::message::Messages<azalea_client::packet::game::ReceivePacketEvent>" => {
378                        let events = ecs.resource::<Messages<game::ReceiveGamePacketEvent>>();
379                        writeln!(report, "- Event count: {}", events.len()).unwrap();
380                    }
381                    "bevy_ecs::message::Messages<azalea_client::chunks::ReceiveChunkEvent>" => {
382                        let events = ecs.resource::<Messages<ReceiveChunkEvent>>();
383                        writeln!(report, "- Event count: {}", events.len()).unwrap();
384                    }
385
386                    _ => {}
387                }
388            }
389
390            println!("\x1b[1mWrote report to {}\x1b[m", report_path.display());
391        });
392
393        1
394    }));
395
396    commands.register(literal("exit").executes(|ctx: &Ctx| {
397        let source = ctx.source.lock();
398        source.reply("bye!");
399
400        source.bot.disconnect();
401
402        let source = ctx.source.clone();
403        thread::spawn(move || {
404            thread::sleep(Duration::from_secs(1));
405
406            source
407                .lock()
408                .bot
409                .ecs
410                .write()
411                .write_message(AppExit::Success);
412        });
413
414        1
415    }));
416}
Source§

impl EntityRef

Source

pub fn minecraft_id(&self) -> MinecraftEntityId

Get the Minecraft UUID of this entity.

See MinecraftEntityId for more details. For persistent identifiers, consider using Self::uuid instead.

Also see Client::minecraft_id.

Examples found in repository?
azalea/examples/testbot/commands/debug.rs (line 67)
26pub fn register(commands: &mut CommandDispatcher<Mutex<CommandSource>>) {
27    commands.register(literal("ping").executes(|ctx: &Ctx| {
28        let source = ctx.source.lock();
29        source.reply("pong!");
30        1
31    }));
32    commands.register(
33        literal("say").then(argument("message", greedy_string()).executes(|ctx: &Ctx| {
34            let source = ctx.source.lock();
35            let message = get_string(ctx, "message").unwrap();
36            source.bot.chat(message);
37            1
38        })),
39    );
40
41    commands.register(literal("disconnect").executes(|ctx: &Ctx| {
42        let source = ctx.source.lock();
43        source.bot.disconnect();
44        1
45    }));
46
47    commands.register(literal("whereami").executes(|ctx: &Ctx| {
48        let source = ctx.source.lock();
49        let Some(entity) = source.entity() else {
50            source.reply("You aren't in render distance!");
51            return 0;
52        };
53        let position = entity.position();
54        source.reply(format!(
55            "You are at {}, {}, {}",
56            position.x, position.y, position.z
57        ));
58        1
59    }));
60
61    commands.register(literal("entityid").executes(|ctx: &Ctx| {
62        let source = ctx.source.lock();
63        let Some(entity) = source.entity() else {
64            source.reply("You aren't in render distance!");
65            return 0;
66        };
67        let entity_id = entity.minecraft_id();
68        source.reply(format!(
69            "Your Minecraft ID is {} and your ECS ID is {entity:?}",
70            *entity_id
71        ));
72        1
73    }));
74
75    let whereareyou = |ctx: &Ctx| {
76        let source = ctx.source.lock();
77        let position = source.bot.position();
78        source.reply(format!(
79            "I'm at {}, {}, {}",
80            position.x, position.y, position.z
81        ));
82        1
83    };
84    commands.register(literal("whereareyou").executes(whereareyou));
85    commands.register(literal("pos").executes(whereareyou));
86
87    commands.register(literal("whoareyou").executes(|ctx: &Ctx| {
88        let source = ctx.source.lock();
89        source.reply(format!(
90            "I am {} ({}, {})",
91            source.bot.username(),
92            source.bot.uuid(),
93            source.bot.entity
94        ));
95        1
96    }));
97
98    commands.register(literal("getdirection").executes(|ctx: &Ctx| {
99        let source = ctx.source.lock();
100        let direction = source.bot.direction();
101        source.reply(format!(
102            "I'm looking at {}, {}",
103            direction.y_rot(),
104            direction.x_rot()
105        ));
106        1
107    }));
108
109    commands.register(literal("health").executes(|ctx: &Ctx| {
110        let source = ctx.source.lock();
111
112        let health = source.bot.health();
113        source.reply(format!("I have {health} health"));
114        1
115    }));
116
117    commands.register(literal("lookingat").executes(|ctx: &Ctx| {
118        let source = ctx.source.lock();
119
120        let hit_result = source.bot.hit_result();
121
122        match &hit_result {
123            HitResult::Block(r) => {
124                if r.miss {
125                    source.reply("I'm not looking at anything");
126                    return 0;
127                }
128                let block_pos = r.block_pos;
129                let block = source.bot.world().read().get_block_state(block_pos);
130                source.reply(format!("I'm looking at {block:?} at {block_pos:?}"));
131            }
132            HitResult::Entity(r) => {
133                let entity_kind = **source.bot.entity_component::<EntityKindComponent>(r.entity);
134                source.reply(format!(
135                    "I'm looking at {entity_kind} ({:?}) at {}",
136                    r.entity, r.location
137                ));
138            }
139        }
140
141        1
142    }));
143
144    commands.register(literal("getblock").then(argument("x", integer()).then(
145        argument("y", integer()).then(argument("z", integer()).executes(|ctx: &Ctx| {
146            let source = ctx.source.lock();
147            let x = get_integer(ctx, "x").unwrap();
148            let y = get_integer(ctx, "y").unwrap();
149            let z = get_integer(ctx, "z").unwrap();
150            println!("getblock xyz {x} {y} {z}");
151            let block_pos = BlockPos::new(x, y, z);
152            let block = source.bot.world().read().get_block_state(block_pos);
153            source.reply(format!("BlockKind at {block_pos} is {block:?}"));
154            1
155        })),
156    )));
157    commands.register(literal("getfluid").then(argument("x", integer()).then(
158        argument("y", integer()).then(argument("z", integer()).executes(|ctx: &Ctx| {
159            let source = ctx.source.lock();
160            let x = get_integer(ctx, "x").unwrap();
161            let y = get_integer(ctx, "y").unwrap();
162            let z = get_integer(ctx, "z").unwrap();
163            println!("getfluid xyz {x} {y} {z}");
164            let block_pos = BlockPos::new(x, y, z);
165            let block = source.bot.world().read().get_fluid_state(block_pos);
166            source.reply(format!("Fluid at {block_pos} is {block:?}"));
167            1
168        })),
169    )));
170
171    commands.register(literal("pathfinderstate").executes(|ctx: &Ctx| {
172        let source = ctx.source.lock();
173        let pathfinder = source.bot.get_component::<Pathfinder>();
174        let Some(pathfinder) = pathfinder else {
175            source.reply("I don't have the Pathfinder component");
176            return 1;
177        };
178        source.reply(format!(
179            "pathfinder.is_calculating: {}",
180            pathfinder.is_calculating
181        ));
182
183        let executing_path = source.bot.get_component::<ExecutingPath>();
184        let Some(executing_path) = executing_path else {
185            source.reply("I'm not executing a path");
186            return 1;
187        };
188        source.reply(format!(
189            "is_path_partial: {}, path.len: {}, queued_path.len: {}",
190            executing_path.is_path_partial,
191            executing_path.path.len(),
192            if let Some(queued) = &executing_path.queued_path {
193                queued.len().to_string()
194            } else {
195                "n/a".to_owned()
196            },
197        ));
198        1
199    }));
200    commands.register(literal("pathfindermoves").executes(|ctx: &Ctx| {
201        let source = ctx.source.lock();
202
203        let Some(entity) = source.entity() else {
204            source.reply("You aren't in render distance!");
205            return 0;
206        };
207        let position = entity.position();
208        let position = BlockPos::from(position);
209
210        let mut edges = Vec::new();
211        let cached_world = CachedWorld::new(source.bot.world(), position);
212        let mining_cache = MiningCache::new(Some(Menu::Player(inventory::Player::default())));
213        let custom_state = CustomPathfinderStateRef::default();
214
215        azalea::pathfinder::moves::default_move(
216            &mut MovesCtx {
217                edges: &mut edges,
218                world: &cached_world,
219                mining_cache: &mining_cache,
220                custom_state: &custom_state,
221            },
222            RelBlockPos::from_origin(position, position),
223        );
224
225        if edges.is_empty() {
226            source.reply("No possible moves.");
227        } else {
228            source.reply("Moves:");
229            for (i, edge) in edges.iter().enumerate() {
230                source.reply(format!("{}) {edge:?}", i + 1));
231            }
232        }
233
234        1
235    }));
236
237    commands.register(literal("startuseitem").executes(|ctx: &Ctx| {
238        let source = ctx.source.lock();
239        source.bot.start_use_item();
240        source.reply("Ok!");
241        1
242    }));
243    commands.register(literal("maxstacksize").executes(|ctx: &Ctx| {
244        let source = ctx.source.lock();
245        let max_stack_size = source
246            .bot
247            .get_held_item()
248            .get_component::<MaxStackSize>()
249            .map_or(-1, |s| s.count);
250        source.reply(format!("{max_stack_size}"));
251        1
252    }));
253
254    commands.register(literal("dimensions").executes(|ctx: &Ctx| {
255        let source = ctx.source.lock();
256        let bot_dimensions = source.bot.dimensions();
257        source.reply(format!("{bot_dimensions:?}"));
258        1
259    }));
260
261    commands.register(literal("players").executes(|ctx: &Ctx| {
262        let source = ctx.source.lock();
263        let player_entities = source
264            .bot
265            .nearest_entities_by::<(), With<metadata::Player>>(|_: ()| true);
266        let tab_list = source.bot.tab_list();
267        for player_entity in player_entities {
268            let uuid = player_entity.uuid();
269            source.reply(format!(
270                "{} - {} ({:?})",
271                player_entity.id(),
272                tab_list.get(&uuid).map_or("?", |p| p.profile.name.as_str()),
273                uuid
274            ));
275        }
276        1
277    }));
278
279    commands.register(literal("enchants").executes(|ctx: &Ctx| {
280        let source = ctx.source.lock();
281        source.bot.with_registry_holder(|r| {
282            let enchants = &r.enchantment;
283            println!("enchants: {enchants:?}");
284        });
285        1
286    }));
287
288    commands.register(literal("attributes").executes(|ctx: &Ctx| {
289        let source = ctx.source.lock();
290        let attributes = source.bot.attributes();
291        println!("attributes: {attributes:?}");
292        1
293    }));
294
295    commands.register(literal("debugecsleak").executes(|ctx: &Ctx| {
296        let source = ctx.source.lock();
297
298        source.reply("Ok!");
299
300
301
302        source.bot.disconnect();
303
304        let ecs = source.bot.ecs.clone();
305        thread::spawn(move || {
306            thread::sleep(Duration::from_secs(1));
307            // dump the ecs
308
309            let mut ecs = ecs.write();
310
311            let report_path = env::temp_dir().join("azalea-ecs-leak-report.txt");
312            let mut report = File::create(&report_path).unwrap();
313
314            let mut query = ecs.query::<EntityRef>();
315            for entity in query.iter(& ecs) {
316                writeln!(report, "Entity: {}", entity.id()).unwrap();
317                let archetype = entity.archetype();
318                let component_count = archetype.component_count();
319
320                let component_names = archetype
321                    .components()
322                    .iter()
323                    .map(|c| ecs.components().get_info(*c).unwrap().name().to_string())
324                    .collect::<Vec<_>>();
325                writeln!(
326                    report,
327                    "- {component_count} components: {}",
328                    component_names.join(", ")
329                )
330                .unwrap();
331            }
332
333            writeln!(report).unwrap();
334
335
336            for (info, _) in ecs.iter_resources() {
337                let name = info.name().to_string();
338                writeln!(report, "Resource: {name}").unwrap();
339                // writeln!(report, "- Size: {} bytes",
340                // info.layout().size()).unwrap();
341
342                match name.as_ref() {
343                    "azalea_world::container::Worlds" => {
344                        let worlds = ecs.resource::<Worlds>();
345
346                        for (world_name, world) in &worlds.map {
347                            writeln!(report, "- Name: {world_name}").unwrap();
348                            writeln!(report, "- Reference count: {}", world.strong_count())
349                                .unwrap();
350                            if let Some(world) = world.upgrade() {
351                                let world = world.read();
352                                let chunks = &world.chunks;
353                                let chunks = (chunks as &dyn Any).downcast_ref::<WeakChunkStorage>();
354                                if let Some(chunks) = chunks {
355                                    let strong_chunks = chunks
356                                        .map
357                                        .iter()
358                                        .filter(|(_, v)| v.strong_count() > 0)
359                                        .count();
360                                    writeln!(
361                                        report,
362                                        "- Chunks: {} strongly referenced, {} in map",
363                                        strong_chunks,
364                                        chunks.map.len()
365                                    )
366                                    .unwrap();
367                                }
368                                writeln!(
369                                    report,
370                                    "- Entities: {}",
371                                    world.entities_by_chunk.len()
372                                )
373                                .unwrap();
374                            }
375                        }
376                    }
377                    "bevy_ecs::message::Messages<azalea_client::packet::game::ReceivePacketEvent>" => {
378                        let events = ecs.resource::<Messages<game::ReceiveGamePacketEvent>>();
379                        writeln!(report, "- Event count: {}", events.len()).unwrap();
380                    }
381                    "bevy_ecs::message::Messages<azalea_client::chunks::ReceiveChunkEvent>" => {
382                        let events = ecs.resource::<Messages<ReceiveChunkEvent>>();
383                        writeln!(report, "- Event count: {}", events.len()).unwrap();
384                    }
385
386                    _ => {}
387                }
388            }
389
390            println!("\x1b[1mWrote report to {}\x1b[m", report_path.display());
391        });
392
393        1
394    }));
395
396    commands.register(literal("exit").executes(|ctx: &Ctx| {
397        let source = ctx.source.lock();
398        source.reply("bye!");
399
400        source.bot.disconnect();
401
402        let source = ctx.source.clone();
403        thread::spawn(move || {
404            thread::sleep(Duration::from_secs(1));
405
406            source
407                .lock()
408                .bot
409                .ecs
410                .write()
411                .write_message(AppExit::Success);
412        });
413
414        1
415    }));
416}
Source§

impl EntityRef

Source

pub fn attributes(&self) -> Attributes

Returns the attribute values of the entity, which can be used to determine things like its movement speed.

Source§

impl EntityRef

Source

pub fn instance_name(&self) -> WorldName

👎Deprecated:

renamed to world_name.

Source§

impl EntityRef

Source

pub fn world_name(&self) -> WorldName

Get the name of the world that the entity is in.

This can be used to check if the entity is in the same world as another entity.

Also see Client::world_name,

Source§

impl EntityRef

Source

pub fn is_alive(&self) -> bool

Returns whether the entity is alive and hasn’t despawned.

Unlike most functions in EntityRef, this one will not panic if the entity is despawned. Because of this, it may be useful to check is_alive before calling functions that request data from the world.

Also see Client::is_alive and Self::exists.

Source§

impl EntityRef

Source

pub fn exists(&self) -> bool

Returns whether the entity is in the world and hasn’t despawned.

Like Self::is_alive, this will not panic.

Also see Client::exists.

Source§

impl EntityRef

Source

pub fn physics(&self) -> Physics

Returns the complete Physics data for this entity, including velocity, bounding box, collisions, etc.

Also see Client::physics.

Source§

impl EntityRef

Source

pub fn new(client: Client, entity: Entity) -> Self

Source

pub fn id(&self) -> Entity

Returns the ECS identifier for the entity.

Examples found in repository?
azalea/examples/testbot/commands/debug.rs (line 271)
26pub fn register(commands: &mut CommandDispatcher<Mutex<CommandSource>>) {
27    commands.register(literal("ping").executes(|ctx: &Ctx| {
28        let source = ctx.source.lock();
29        source.reply("pong!");
30        1
31    }));
32    commands.register(
33        literal("say").then(argument("message", greedy_string()).executes(|ctx: &Ctx| {
34            let source = ctx.source.lock();
35            let message = get_string(ctx, "message").unwrap();
36            source.bot.chat(message);
37            1
38        })),
39    );
40
41    commands.register(literal("disconnect").executes(|ctx: &Ctx| {
42        let source = ctx.source.lock();
43        source.bot.disconnect();
44        1
45    }));
46
47    commands.register(literal("whereami").executes(|ctx: &Ctx| {
48        let source = ctx.source.lock();
49        let Some(entity) = source.entity() else {
50            source.reply("You aren't in render distance!");
51            return 0;
52        };
53        let position = entity.position();
54        source.reply(format!(
55            "You are at {}, {}, {}",
56            position.x, position.y, position.z
57        ));
58        1
59    }));
60
61    commands.register(literal("entityid").executes(|ctx: &Ctx| {
62        let source = ctx.source.lock();
63        let Some(entity) = source.entity() else {
64            source.reply("You aren't in render distance!");
65            return 0;
66        };
67        let entity_id = entity.minecraft_id();
68        source.reply(format!(
69            "Your Minecraft ID is {} and your ECS ID is {entity:?}",
70            *entity_id
71        ));
72        1
73    }));
74
75    let whereareyou = |ctx: &Ctx| {
76        let source = ctx.source.lock();
77        let position = source.bot.position();
78        source.reply(format!(
79            "I'm at {}, {}, {}",
80            position.x, position.y, position.z
81        ));
82        1
83    };
84    commands.register(literal("whereareyou").executes(whereareyou));
85    commands.register(literal("pos").executes(whereareyou));
86
87    commands.register(literal("whoareyou").executes(|ctx: &Ctx| {
88        let source = ctx.source.lock();
89        source.reply(format!(
90            "I am {} ({}, {})",
91            source.bot.username(),
92            source.bot.uuid(),
93            source.bot.entity
94        ));
95        1
96    }));
97
98    commands.register(literal("getdirection").executes(|ctx: &Ctx| {
99        let source = ctx.source.lock();
100        let direction = source.bot.direction();
101        source.reply(format!(
102            "I'm looking at {}, {}",
103            direction.y_rot(),
104            direction.x_rot()
105        ));
106        1
107    }));
108
109    commands.register(literal("health").executes(|ctx: &Ctx| {
110        let source = ctx.source.lock();
111
112        let health = source.bot.health();
113        source.reply(format!("I have {health} health"));
114        1
115    }));
116
117    commands.register(literal("lookingat").executes(|ctx: &Ctx| {
118        let source = ctx.source.lock();
119
120        let hit_result = source.bot.hit_result();
121
122        match &hit_result {
123            HitResult::Block(r) => {
124                if r.miss {
125                    source.reply("I'm not looking at anything");
126                    return 0;
127                }
128                let block_pos = r.block_pos;
129                let block = source.bot.world().read().get_block_state(block_pos);
130                source.reply(format!("I'm looking at {block:?} at {block_pos:?}"));
131            }
132            HitResult::Entity(r) => {
133                let entity_kind = **source.bot.entity_component::<EntityKindComponent>(r.entity);
134                source.reply(format!(
135                    "I'm looking at {entity_kind} ({:?}) at {}",
136                    r.entity, r.location
137                ));
138            }
139        }
140
141        1
142    }));
143
144    commands.register(literal("getblock").then(argument("x", integer()).then(
145        argument("y", integer()).then(argument("z", integer()).executes(|ctx: &Ctx| {
146            let source = ctx.source.lock();
147            let x = get_integer(ctx, "x").unwrap();
148            let y = get_integer(ctx, "y").unwrap();
149            let z = get_integer(ctx, "z").unwrap();
150            println!("getblock xyz {x} {y} {z}");
151            let block_pos = BlockPos::new(x, y, z);
152            let block = source.bot.world().read().get_block_state(block_pos);
153            source.reply(format!("BlockKind at {block_pos} is {block:?}"));
154            1
155        })),
156    )));
157    commands.register(literal("getfluid").then(argument("x", integer()).then(
158        argument("y", integer()).then(argument("z", integer()).executes(|ctx: &Ctx| {
159            let source = ctx.source.lock();
160            let x = get_integer(ctx, "x").unwrap();
161            let y = get_integer(ctx, "y").unwrap();
162            let z = get_integer(ctx, "z").unwrap();
163            println!("getfluid xyz {x} {y} {z}");
164            let block_pos = BlockPos::new(x, y, z);
165            let block = source.bot.world().read().get_fluid_state(block_pos);
166            source.reply(format!("Fluid at {block_pos} is {block:?}"));
167            1
168        })),
169    )));
170
171    commands.register(literal("pathfinderstate").executes(|ctx: &Ctx| {
172        let source = ctx.source.lock();
173        let pathfinder = source.bot.get_component::<Pathfinder>();
174        let Some(pathfinder) = pathfinder else {
175            source.reply("I don't have the Pathfinder component");
176            return 1;
177        };
178        source.reply(format!(
179            "pathfinder.is_calculating: {}",
180            pathfinder.is_calculating
181        ));
182
183        let executing_path = source.bot.get_component::<ExecutingPath>();
184        let Some(executing_path) = executing_path else {
185            source.reply("I'm not executing a path");
186            return 1;
187        };
188        source.reply(format!(
189            "is_path_partial: {}, path.len: {}, queued_path.len: {}",
190            executing_path.is_path_partial,
191            executing_path.path.len(),
192            if let Some(queued) = &executing_path.queued_path {
193                queued.len().to_string()
194            } else {
195                "n/a".to_owned()
196            },
197        ));
198        1
199    }));
200    commands.register(literal("pathfindermoves").executes(|ctx: &Ctx| {
201        let source = ctx.source.lock();
202
203        let Some(entity) = source.entity() else {
204            source.reply("You aren't in render distance!");
205            return 0;
206        };
207        let position = entity.position();
208        let position = BlockPos::from(position);
209
210        let mut edges = Vec::new();
211        let cached_world = CachedWorld::new(source.bot.world(), position);
212        let mining_cache = MiningCache::new(Some(Menu::Player(inventory::Player::default())));
213        let custom_state = CustomPathfinderStateRef::default();
214
215        azalea::pathfinder::moves::default_move(
216            &mut MovesCtx {
217                edges: &mut edges,
218                world: &cached_world,
219                mining_cache: &mining_cache,
220                custom_state: &custom_state,
221            },
222            RelBlockPos::from_origin(position, position),
223        );
224
225        if edges.is_empty() {
226            source.reply("No possible moves.");
227        } else {
228            source.reply("Moves:");
229            for (i, edge) in edges.iter().enumerate() {
230                source.reply(format!("{}) {edge:?}", i + 1));
231            }
232        }
233
234        1
235    }));
236
237    commands.register(literal("startuseitem").executes(|ctx: &Ctx| {
238        let source = ctx.source.lock();
239        source.bot.start_use_item();
240        source.reply("Ok!");
241        1
242    }));
243    commands.register(literal("maxstacksize").executes(|ctx: &Ctx| {
244        let source = ctx.source.lock();
245        let max_stack_size = source
246            .bot
247            .get_held_item()
248            .get_component::<MaxStackSize>()
249            .map_or(-1, |s| s.count);
250        source.reply(format!("{max_stack_size}"));
251        1
252    }));
253
254    commands.register(literal("dimensions").executes(|ctx: &Ctx| {
255        let source = ctx.source.lock();
256        let bot_dimensions = source.bot.dimensions();
257        source.reply(format!("{bot_dimensions:?}"));
258        1
259    }));
260
261    commands.register(literal("players").executes(|ctx: &Ctx| {
262        let source = ctx.source.lock();
263        let player_entities = source
264            .bot
265            .nearest_entities_by::<(), With<metadata::Player>>(|_: ()| true);
266        let tab_list = source.bot.tab_list();
267        for player_entity in player_entities {
268            let uuid = player_entity.uuid();
269            source.reply(format!(
270                "{} - {} ({:?})",
271                player_entity.id(),
272                tab_list.get(&uuid).map_or("?", |p| p.profile.name.as_str()),
273                uuid
274            ));
275        }
276        1
277    }));
278
279    commands.register(literal("enchants").executes(|ctx: &Ctx| {
280        let source = ctx.source.lock();
281        source.bot.with_registry_holder(|r| {
282            let enchants = &r.enchantment;
283            println!("enchants: {enchants:?}");
284        });
285        1
286    }));
287
288    commands.register(literal("attributes").executes(|ctx: &Ctx| {
289        let source = ctx.source.lock();
290        let attributes = source.bot.attributes();
291        println!("attributes: {attributes:?}");
292        1
293    }));
294
295    commands.register(literal("debugecsleak").executes(|ctx: &Ctx| {
296        let source = ctx.source.lock();
297
298        source.reply("Ok!");
299
300
301
302        source.bot.disconnect();
303
304        let ecs = source.bot.ecs.clone();
305        thread::spawn(move || {
306            thread::sleep(Duration::from_secs(1));
307            // dump the ecs
308
309            let mut ecs = ecs.write();
310
311            let report_path = env::temp_dir().join("azalea-ecs-leak-report.txt");
312            let mut report = File::create(&report_path).unwrap();
313
314            let mut query = ecs.query::<EntityRef>();
315            for entity in query.iter(& ecs) {
316                writeln!(report, "Entity: {}", entity.id()).unwrap();
317                let archetype = entity.archetype();
318                let component_count = archetype.component_count();
319
320                let component_names = archetype
321                    .components()
322                    .iter()
323                    .map(|c| ecs.components().get_info(*c).unwrap().name().to_string())
324                    .collect::<Vec<_>>();
325                writeln!(
326                    report,
327                    "- {component_count} components: {}",
328                    component_names.join(", ")
329                )
330                .unwrap();
331            }
332
333            writeln!(report).unwrap();
334
335
336            for (info, _) in ecs.iter_resources() {
337                let name = info.name().to_string();
338                writeln!(report, "Resource: {name}").unwrap();
339                // writeln!(report, "- Size: {} bytes",
340                // info.layout().size()).unwrap();
341
342                match name.as_ref() {
343                    "azalea_world::container::Worlds" => {
344                        let worlds = ecs.resource::<Worlds>();
345
346                        for (world_name, world) in &worlds.map {
347                            writeln!(report, "- Name: {world_name}").unwrap();
348                            writeln!(report, "- Reference count: {}", world.strong_count())
349                                .unwrap();
350                            if let Some(world) = world.upgrade() {
351                                let world = world.read();
352                                let chunks = &world.chunks;
353                                let chunks = (chunks as &dyn Any).downcast_ref::<WeakChunkStorage>();
354                                if let Some(chunks) = chunks {
355                                    let strong_chunks = chunks
356                                        .map
357                                        .iter()
358                                        .filter(|(_, v)| v.strong_count() > 0)
359                                        .count();
360                                    writeln!(
361                                        report,
362                                        "- Chunks: {} strongly referenced, {} in map",
363                                        strong_chunks,
364                                        chunks.map.len()
365                                    )
366                                    .unwrap();
367                                }
368                                writeln!(
369                                    report,
370                                    "- Entities: {}",
371                                    world.entities_by_chunk.len()
372                                )
373                                .unwrap();
374                            }
375                        }
376                    }
377                    "bevy_ecs::message::Messages<azalea_client::packet::game::ReceivePacketEvent>" => {
378                        let events = ecs.resource::<Messages<game::ReceiveGamePacketEvent>>();
379                        writeln!(report, "- Event count: {}", events.len()).unwrap();
380                    }
381                    "bevy_ecs::message::Messages<azalea_client::chunks::ReceiveChunkEvent>" => {
382                        let events = ecs.resource::<Messages<ReceiveChunkEvent>>();
383                        writeln!(report, "- Event count: {}", events.len()).unwrap();
384                    }
385
386                    _ => {}
387                }
388            }
389
390            println!("\x1b[1mWrote report to {}\x1b[m", report_path.display());
391        });
392
393        1
394    }));
395
396    commands.register(literal("exit").executes(|ctx: &Ctx| {
397        let source = ctx.source.lock();
398        source.reply("bye!");
399
400        source.bot.disconnect();
401
402        let source = ctx.source.clone();
403        thread::spawn(move || {
404            thread::sleep(Duration::from_secs(1));
405
406            source
407                .lock()
408                .bot
409                .ecs
410                .write()
411                .write_message(AppExit::Success);
412        });
413
414        1
415    }));
416}
Source

pub fn component<T: Component>(&self) -> MappedRwLockReadGuard<'_, T>

Get a component on the entity.

This allows you to access certain data stored about the entity that isn’t accessible in a simpler way.

See Client::component for more details.

§Panics

This will panic if the component doesn’t exist on the client. Use Self::get_component to avoid this.

§Examples
let world_name = client.component::<WorldName>();
Source

pub fn get_component<T: Component>( &self, ) -> Option<MappedRwLockReadGuard<'_, T>>

Get a component on this client, or None if it doesn’t exist.

If the component is guaranteed to be present, consider using Self::component.

See Client::component for more details.

Source

pub fn query_self<D: QueryData, R>( &self, f: impl FnOnce(QueryItem<'_, '_, D>) -> R, ) -> R

Query the ECS for data from the entity.

You can use this to mutate data on the entity.

Also see Client::query_self and Client::query_entity.

§Panics

This will panic if the entity doesn’t exist or is missing a component required by the query. Consider using Self::try_query_self to avoid this.

Source

pub fn try_query_self<D: QueryData, R>( &self, f: impl FnOnce(QueryItem<'_, '_, D>) -> R, ) -> Result<R, QueryEntityError>

Query the ECS for data from the entity, or return an error if the query fails.

Also see Self::query_self.

Source§

impl EntityRef

Source

pub fn kind(&self) -> EntityKind

Returns the type of entity that this is.

Source§

impl EntityRef

Source

pub fn attack(&self)

Attack this entity from the client that created this EntityRef.

Also see Client::attack.

Examples found in repository?
azalea/examples/testbot/killaura.rs (line 29)
9pub fn tick(bot: Client, state: State) -> eyre::Result<()> {
10    if !state.killaura {
11        return Ok(());
12    }
13    if bot.has_attack_cooldown() {
14        return Ok(());
15    }
16    let bot_position = bot.eye_position();
17
18    let nearest_entity = bot.nearest_entity_by::<&Position, (
19        With<AbstractMonster>,
20        Without<LocalEntity>,
21        Without<Dead>,
22    )>(|position: &Position| {
23        let distance = bot_position.distance_to(**position);
24        distance < 4.
25    });
26
27    if let Some(nearest_entity) = nearest_entity {
28        println!("attacking {nearest_entity:?}");
29        nearest_entity.attack();
30    }
31
32    Ok(())
33}
Source

pub fn interact(&self)

Right-click this entity from the client that created this EntityRef.

See Client::entity_interact for more information.

Source

pub fn look_at(&self)

Look at this entity from the client that created the EntityRef.

Source

pub fn distance_to_client(&self) -> f64

Returns the distance between the client’s feet position and this entity’s feet position.

Trait Implementations§

Source§

impl Clone for EntityRef

Source§

fn clone(&self) -> EntityRef

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for EntityRef

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
§

impl<T> CompatExt for T

§

fn compat(self) -> Compat<T>

Applies the [Compat] adapter by value. Read more
§

fn compat_ref(&self) -> Compat<&T>

Applies the [Compat] adapter by shared reference. Read more
§

fn compat_mut(&mut self) -> Compat<&mut T>

Applies the [Compat] adapter by mutable reference. Read more
§

impl<T> Downcast for T
where T: Any,

§

fn into_any(self: Box<T>) -> Box<dyn Any>

Converts Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.
§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Converts Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
§

fn as_any(&self) -> &(dyn Any + 'static)

Converts &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Converts &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
§

impl<T> DowncastSend for T
where T: Any + Send,

§

fn into_any_send(self: Box<T>) -> Box<dyn Any + Send>

Converts Box<Trait> (where Trait: DowncastSend) to Box<dyn Any + Send>, which can then be downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

§

impl<T> IntoResult<T> for T

§

fn into_result(self) -> Result<T, RunSystemError>

Converts this type into the system output type.
§

impl<A> Is for A
where A: Any,

§

fn is<T>() -> bool
where T: Any,

Checks if the current type “is” another type, using a TypeId equality comparison. This is most useful in the context of generic logic. Read more
§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
§

impl<T> PolicyExt for T
where T: ?Sized,

§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] only if self and other return Action::Follow. Read more
§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> TypeData for T
where T: 'static + Send + Sync + Clone,

§

fn clone_type_data(&self) -> Box<dyn TypeData>

Creates a type-erased clone of this value.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

impl<T> ConditionalSend for T
where T: Send,