summaryrefslogtreecommitdiff
path: root/server/frob/itemsXML.ts
blob: 0a8e117dd56970e239d5e931f713ac1ab7c77c1e (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
83
84
85
86
87
import { DOMParser, Element } from "https://deno.land/x/deno_dom@v0.1.2-alpha3/deno-dom-wasm.ts";

class itemsXML {
    private repo: string = "";
    private encoder: TextEncoder;
    private decoder: TextDecoder;
    private items_by_name: Map<string, number> = new Map();
    private items_by_id: Map<number, any> = new Map();

    constructor (repo: string = "client-data") {
        this.repo = repo;
        this.encoder = new TextEncoder();
        this.decoder = new TextDecoder("utf-8");
    }

    async init () {
        console.log("Fetching items xml files from client-data...");

        await this.fetchFile("items.xml");
    }

    private async fetchFile (path: string) {
        const raw = await Deno.readFile(`${this.repo}/${path}`);
        const xml = this.decoder.decode(raw);

        await this.parseXML(path, xml);
    }

    private async parseXML (path: string, xml: string) {
        Deno.write(Deno.stdout.rid, this.encoder.encode(`                                                                            \r⌛ parsing ${path}...`));

        const domparser = new DOMParser();

        if (xml.startsWith("<?")) {
            // remove the xml doctype
            xml = xml.split("\n").slice(1).join("\n");
        }

        if (xml.startsWith("<items>\n  <its:")) {
            // translation stuff
            xml = "<items>\n" + xml.split("\n").slice(7).join("\n");
        }

        const root = domparser.parseFromString(xml, "text/html")!;

        if (root) {
            const items = root.querySelectorAll("item");
            const includes = root.querySelectorAll("include");

            for (const el of includes) {
                const tag: Element = el as Element;
                await this.fetchFile(tag.attributes.name);
            }

            for (const el of items) {
                const tag: Element = el as Element;

                const item = {
                    id: +tag.attributes.id,
                    name: tag.attributes.name,
                    type: tag.attributes.type,
                };

                this.items_by_id.set(item.id, item);
                this.items_by_name.set(item.name, item.id);
            }
        }
    }

    getItem (item: string | number) {
        if (typeof item === "string") {
            const id = this.items_by_name.get(item);

            if (id) {
                return this.items_by_id.get(id) || null;
            }
        } else if (typeof item === "number") {
            return this.items_by_id.get(item) || null;
        }

        return null;
    }
}

export {
    itemsXML,
}