Initial commit
This commit is contained in:
commit
c61624bc92
3 changed files with 166 additions and 0 deletions
10
deno.json
Executable file
10
deno.json
Executable file
|
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"tasks": {
|
||||||
|
"dev": "deno run --watch main.ts"
|
||||||
|
},
|
||||||
|
"imports": {
|
||||||
|
"@std/assert": "jsr:@std/assert@1",
|
||||||
|
"@std/cli": "jsr:@std/cli@^1.0.28",
|
||||||
|
"@zip-js/zip-js": "jsr:@zip-js/zip-js@^2.8.26"
|
||||||
|
}
|
||||||
|
}
|
||||||
42
deno.lock
generated
Executable file
42
deno.lock
generated
Executable file
|
|
@ -0,0 +1,42 @@
|
||||||
|
{
|
||||||
|
"version": "5",
|
||||||
|
"specifiers": {
|
||||||
|
"jsr:@std/assert@1": "1.0.19",
|
||||||
|
"jsr:@std/cli@*": "1.0.28",
|
||||||
|
"jsr:@std/cli@^1.0.28": "1.0.28",
|
||||||
|
"jsr:@std/fmt@^1.0.9": "1.0.9",
|
||||||
|
"jsr:@std/internal@^1.0.12": "1.0.12",
|
||||||
|
"jsr:@zip-js/zip-js@^2.8.26": "2.8.26"
|
||||||
|
},
|
||||||
|
"jsr": {
|
||||||
|
"@std/assert@1.0.19": {
|
||||||
|
"integrity": "eaada96ee120cb980bc47e040f82814d786fe8162ecc53c91d8df60b8755991e",
|
||||||
|
"dependencies": [
|
||||||
|
"jsr:@std/internal"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"@std/cli@1.0.28": {
|
||||||
|
"integrity": "74ef9b976db59ca6b23a5283469c9072be6276853807a83ec6c7ce412135c70a",
|
||||||
|
"dependencies": [
|
||||||
|
"jsr:@std/fmt",
|
||||||
|
"jsr:@std/internal"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"@std/fmt@1.0.9": {
|
||||||
|
"integrity": "2487343e8899fb2be5d0e3d35013e54477ada198854e52dd05ed0422eddcabe0"
|
||||||
|
},
|
||||||
|
"@std/internal@1.0.12": {
|
||||||
|
"integrity": "972a634fd5bc34b242024402972cd5143eac68d8dffaca5eaa4dba30ce17b027"
|
||||||
|
},
|
||||||
|
"@zip-js/zip-js@2.8.26": {
|
||||||
|
"integrity": "2b78bfa2c5d43766c9a487fc0274981d45732de41bb5b82433d29d235be67191"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"workspace": {
|
||||||
|
"dependencies": [
|
||||||
|
"jsr:@std/assert@1",
|
||||||
|
"jsr:@std/cli@^1.0.28",
|
||||||
|
"jsr:@zip-js/zip-js@^2.8.26"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
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