Skip to main content

MiningCache

Struct MiningCache 

Source
pub struct MiningCache { /* private fields */ }

Implementations§

Source§

impl MiningCache

Source

pub fn new(inventory_menu: Option<Menu>) -> Self

Examples found in repository?
azalea/examples/testbot/commands/debug.rs (line 212)
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 strong_chunks = world
353                                    .chunks
354                                    .map
355                                    .iter()
356                                    .filter(|(_, v)| v.strong_count() > 0)
357                                    .count();
358                                writeln!(
359                                    report,
360                                    "- Chunks: {} strongly referenced, {} in map",
361                                    strong_chunks,
362                                    world.chunks.map.len()
363                                )
364                                .unwrap();
365                                writeln!(
366                                    report,
367                                    "- Entities: {}",
368                                    world.entities_by_chunk.len()
369                                )
370                                .unwrap();
371                            }
372                        }
373                    }
374                    "bevy_ecs::message::Messages<azalea_client::packet::game::ReceivePacketEvent>" => {
375                        let events = ecs.resource::<Messages<game::ReceiveGamePacketEvent>>();
376                        writeln!(report, "- Event count: {}", events.len()).unwrap();
377                    }
378                    "bevy_ecs::message::Messages<azalea_client::chunks::ReceiveChunkEvent>" => {
379                        let events = ecs.resource::<Messages<ReceiveChunkEvent>>();
380                        writeln!(report, "- Event count: {}", events.len()).unwrap();
381                    }
382
383                    _ => {}
384                }
385            }
386
387            println!("\x1b[1mWrote report to {}\x1b[m", report_path.display());
388        });
389
390        1
391    }));
392
393    commands.register(literal("exit").executes(|ctx: &Ctx| {
394        let source = ctx.source.lock();
395        source.reply("bye!");
396
397        source.bot.disconnect();
398
399        let source = ctx.source.clone();
400        thread::spawn(move || {
401            thread::sleep(Duration::from_secs(1));
402
403            source
404                .lock()
405                .bot
406                .ecs
407                .write()
408                .write_message(AppExit::Success);
409        });
410
411        1
412    }));
413}
Source

pub fn cost_for(&self, block: BlockState) -> f32

Source

pub fn is_liquid(&self, block: BlockState) -> bool

Source

pub fn is_falling_block(&self, block: BlockState) -> bool

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
§

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, 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<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,