aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org/chrisoft/trashyaddon/commands/MapDumpCommand.java
blob: b09c9be19f7c54442033ce576e49e12cff80811d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
package org.chrisoft.trashyaddon.commands;

import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import meteordevelopment.meteorclient.MeteorClient;
import meteordevelopment.meteorclient.commands.Command;
import net.minecraft.command.CommandSource;
import net.minecraft.component.DataComponentTypes;
import net.minecraft.component.type.MapIdComponent;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.decoration.ItemFrameEntity;
import net.minecraft.client.MinecraftClient;
import net.minecraft.entity.Entity;
import net.minecraft.item.FilledMapItem;
import net.minecraft.item.map.MapState;
import net.minecraft.util.Util;

import java.io.File;
import java.io.FileOutputStream;
import java.nio.ByteOrder;
import java.util.zip.GZIPOutputStream;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.Vector;

import static com.mojang.brigadier.Command.SINGLE_SUCCESS;

public class MapDumpCommand extends Command {
    private final MinecraftClient mc = MinecraftClient.getInstance();
    public MapDumpCommand() {
        super("md", "Dump all maps in view distance.");
    }

    @Override
    public void build(LiteralArgumentBuilder<CommandSource> builder) {
        builder.executes(context -> {
            int nmaps = 0;
            Vector<ByteBuffer> bufs = new Vector<>();
            for (Entity e : mc.world.getEntities()) {
                if (e.getType() != EntityType.ITEM_FRAME && e.getType() != EntityType.GLOW_ITEM_FRAME)
                    continue;
                ItemFrameEntity ife = (ItemFrameEntity) e;
                MapIdComponent idc = ife.getMapId(ife.getHeldItemStack());
                if (idc == null)
                    continue;
                int id = idc.id();
                MapState mapState = FilledMapItem.getMapState(idc, mc.world);
                if (mapState == null)
                    continue;
                String name = ife.getHeldItemStack().contains(DataComponentTypes.CUSTOM_NAME) ? ife.getHeldItemStack().getName().getString() : "";
                byte[] u8name = name.getBytes(StandardCharsets.UTF_8);
                int bsz = 4 + 4 + u8name.length + 16384;
                ByteBuffer buf = ByteBuffer.allocate(bsz);
                buf.order(ByteOrder.LITTLE_ENDIAN);
                buf.putInt(id);
                buf.putInt(u8name.length  | (mapState.locked ? 0x80000000 : 0));
                buf.put(u8name);
                buf.put(mapState.colors);
                bufs.add(buf);
                ++nmaps;
            }
            info("Maps found: " + nmaps);
            try {
                File dirpath = new File(MeteorClient.FOLDER, "mapman");
                if (!dirpath.isDirectory())
                    dirpath.mkdir();
                File dumppath = new File(dirpath, "md-" + Util.getFormattedCurrentTime() + ".gz");
                FileOutputStream fo = new FileOutputStream(dumppath);
                GZIPOutputStream output = new GZIPOutputStream(fo);
                for (ByteBuffer buf : bufs)
                    output.write(buf.array());
                output.close();
                fo.close();
                info("Maps dumped to " + dumppath.toString());
            }
            catch (Exception e) {
                error("Cannot write output:" + e.getMessage());
                return 0;
            }
            return SINGLE_SUCCESS;
        });
    }
}