import { parseArgs } from "jsr:@std/cli/parse-args"; import { BlobReader, BlobWriter, ZipReader, } from "@zip-js/zip-js"; async function* parseResponseChunked(response: Response) { const lengthHeader = response.headers.get('Content-Length'); if (!lengthHeader) { throw Error("Invalid header"); } const length = parseInt(lengthHeader); if (!length) { throw Error('Content-Length header not found'); } const buffer = new ArrayBuffer(length); const view = new DataView(buffer); const responseBody = response.body; if (!responseBody) { throw Error("Invalid body"); } const reader = responseBody.getReader(); let offset = 0; let a = 0; let s = 0; for (; ;) { const { done, value } = await reader.read(); if (done) { if (offset < length) throw Error('Content-Length mismatch'); break; } if (!value) { continue; } new Uint8Array(buffer, offset, value.length).set(value); offset += value.length; if (offset > length) { throw Error('Content-Length mismatch'); } for (; offset - a >= 4 && (s = view.getUint32(a, true), !(offset - a < 4 + s));) { yield buffer.slice(4 + a, 4 + a + s); a += s + 4; } } } function reader(buffer: ArrayBuffer): [Float32Array, Uint32Array] { const view = new DataView(buffer); let offset = 0; const n = view.getUint32(offset, true); offset += 4; const i = view.getUint32(offset, true); offset += 4; const o = new Float32Array(buffer.slice(offset, offset + 4 * n)); offset += 4 * n; const a = new Uint32Array(buffer.slice(offset, offset + 4 * i)); offset += 4 * i; return [o, a]; } if (import.meta.main) { const flags = parseArgs(Deno.args, { string: ["map"], }); const url = new URL("https://assets.thecdn.io/"); const mapIds = new Map([ ["perimeter", "9fdba452-9beb-41a4-9100-19a6948e3587"], ["outpost", "4a5b068f-2bcc-4c19-ac2c-33f4fadba063"], ["diremarsh", "8a7afd32-1c1e-4e9e-8649-80a1415d08ba"], ]); let mapId: string | undefined; if (flags.map && (mapId = mapIds.get(flags.map))) { url.pathname = `${mapId}.chunks`; const response = await fetch(url); for await (const chunk of parseResponseChunked(response)) { const zipFileReader = new BlobReader(new Blob([chunk])); const zipReader = new ZipReader(zipFileReader); const firstEntry = (await zipReader.getEntries()).shift(); if (!firstEntry || firstEntry.directory) { throw new Error("Invalid zip"); } const dataWriter = new BlobWriter(); const data = await firstEntry.getData(dataWriter); await zipReader.close(); const parsedData = reader(await data.arrayBuffer()); const [positions, indeces] = parsedData; for (let i = 0; i < positions.length; i += 3) { const chunk = positions.slice(i, i + 3); const [x, y, z] = chunk; console.log("v", `${x} ${y} ${z}`); } for (let i = 0; i < indeces.length; i += 2) { const chunk = indeces.slice(i, i + 2); const [v1, v2] = chunk; console.log("l", `${v1} ${v2}`); } } } else { throw new Error("Unknown map"); } }