Initial commit
This commit is contained in:
commit
c61624bc92
3 changed files with 166 additions and 0 deletions
114
main.ts
Executable file
114
main.ts
Executable file
|
|
@ -0,0 +1,114 @@
|
|||
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<ArrayBuffer>, Uint32Array<ArrayBuffer>] {
|
||||
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");
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue