stricter typescript rules

This commit is contained in:
Skillbert
2023-03-17 02:59:59 +01:00
parent b86909289a
commit 76b28a88b1
10 changed files with 54 additions and 117 deletions

View File

@@ -2,7 +2,7 @@ import { parse } from "../opdecoder";
import { appearanceUrl, avatarStringToBytes, avatarToModel } from "./avatar"; import { appearanceUrl, avatarStringToBytes, avatarToModel } from "./avatar";
import * as THREE from "three"; import * as THREE from "three";
import { ThreejsSceneCache, mergeModelDatas, ob3ModelToThree, mergeNaiveBoneids, constModelsIds } from '../3d/modeltothree'; import { ThreejsSceneCache, mergeModelDatas, ob3ModelToThree, mergeNaiveBoneids, constModelsIds } from '../3d/modeltothree';
import { ModelModifications, constrainedMap, TypedEmitter } from '../utils'; import { ModelModifications, constrainedMap, TypedEmitter, CallbackPromise } from '../utils';
import { boundMethod } from 'autobind-decorator'; import { boundMethod } from 'autobind-decorator';
import { resolveMorphedObject, modifyMesh, MapRect, ParsemapOpts, parseMapsquare, mapsquareModels, mapsquareToThreeSingle, ChunkData, TileGrid, mapsquareSkybox, generateLocationMeshgroups, PlacedMesh } from '../3d/mapsquare'; import { resolveMorphedObject, modifyMesh, MapRect, ParsemapOpts, parseMapsquare, mapsquareModels, mapsquareToThreeSingle, ChunkData, TileGrid, mapsquareSkybox, generateLocationMeshgroups, PlacedMesh } from '../3d/mapsquare';
import { AnimationClip, AnimationMixer, Group, Material, Mesh, MeshBasicMaterial, Object3D, Skeleton, SkeletonHelper, SkinnedMesh, Texture, Vector2 } from "three"; import { AnimationClip, AnimationMixer, Group, Material, Mesh, MeshBasicMaterial, Object3D, Skeleton, SkeletonHelper, SkinnedMesh, Texture, Vector2 } from "three";
@@ -156,11 +156,11 @@ export async function materialToModel(sceneCache: ThreejsSceneCache, modelid: nu
export class RSModel extends TypedEmitter<{ loaded: undefined, animchanged: number }> implements ThreeJsSceneElementSource { export class RSModel extends TypedEmitter<{ loaded: undefined, animchanged: number }> implements ThreeJsSceneElementSource {
model: Promise<{ modeldata: ModelData, mesh: Object3D, nullAnim: AnimationClip }>; model: Promise<{ modeldata: ModelData, mesh: Object3D, nullAnim: AnimationClip }>;
loaded: { modeldata: ModelData, mesh: Object3D, nullAnim: AnimationClip, matUvAnims: { tex: Texture, v: Vector2 }[] } | null = null; loaded: { modeldata: ModelData, mesh: Object3D, nullAnim: AnimationClip, matUvAnims: { tex: Texture, v: Vector2 }[] } | null = null;
cache: ThreejsSceneCache; cache!: ThreejsSceneCache;
rootnode = new THREE.Group(); rootnode = new THREE.Group();
nullAnimLoaded: (clip: AnimationClip) => void; nullAnimPromise = { clip: null as AnimationClip | null, prom: new CallbackPromise<AnimationClip>() };
anims: Record<number, { clip: AnimationClip | null, prom: Promise<AnimationClip> }> = { anims: Record<number, { clip: AnimationClip | null, prom: Promise<AnimationClip> }> = {
"-1": { clip: null, prom: new Promise(d => this.nullAnimLoaded = d) } "-1": this.nullAnimPromise
}; };
mountedanim: AnimationClip | null = null; mountedanim: AnimationClip | null = null;
mixer = new AnimationMixer(this.rootnode); mixer = new AnimationMixer(this.rootnode);
@@ -232,8 +232,8 @@ export class RSModel extends TypedEmitter<{ loaded: undefined, animchanged: numb
} }
}); });
let nullAnim = new AnimationClip(undefined, undefined, []); let nullAnim = new AnimationClip(undefined, undefined, []);
this.nullAnimLoaded(nullAnim); this.nullAnimPromise.clip = nullAnim;
this.anims[-1].clip = nullAnim; this.nullAnimPromise.prom.done(nullAnim);
this.rootnode.add(mesh); this.rootnode.add(mesh);
this.loaded = { mesh, modeldata, nullAnim, matUvAnims }; this.loaded = { mesh, modeldata, nullAnim, matUvAnims };

View File

@@ -22,6 +22,7 @@ export class ParsedTexture {
if (texture instanceof ImageData) { if (texture instanceof ImageData) {
this.filesize = texture.data.byteLength; this.filesize = texture.data.byteLength;
this.type = "imagedata"; this.type = "imagedata";
this.mipmaps = 1;
this.cachedImageDatas = [Promise.resolve(texture)]; this.cachedImageDatas = [Promise.resolve(texture)];
} else { } else {
this.filesize = texture.byteLength; this.filesize = texture.byteLength;
@@ -36,34 +37,35 @@ export class ParsedTexture {
let offset = 0; let offset = 0;
//peek first bytes of first image file //peek first bytes of first image file
let foundtype = false; let extraoffset = 0
for (let extraoffset = 0; extraoffset <= 1; extraoffset++) { while (true) {
let byte0 = texture.readUInt8(extraoffset + offset + 1 + 4 + 0); let byte0 = texture.readUInt8(extraoffset + offset + 1 + 4 + 0);
let byte1 = texture.readUInt8(extraoffset + offset + 1 + 4 + 1); let byte1 = texture.readUInt8(extraoffset + offset + 1 + 4 + 1);
if (byte0 == 0 && byte1 == 0) { if (byte0 == 0 && byte1 == 0) {
//has no header magic, but starts by writing the width in uint32 BE, any widths under 65k have 0x0000xxxx //has no header magic, but starts by writing the width in uint32 BE, any widths under 65k have 0x0000xxxx
this.type = "bmpmips"; this.type = "bmpmips";
break;
} else if (byte0 == 0x44 && byte1 == 0x44) { } else if (byte0 == 0x44 && byte1 == 0x44) {
//0x44445320 "DDS " //0x44445320 "DDS "
this.type = "dds"; this.type = "dds";
break;
} else if (byte0 == 0x89 && byte1 == 0x50) { } else if (byte0 == 0x89 && byte1 == 0x50) {
//0x89504e47 ".PNG" //0x89504e47 ".PNG"
this.type = "png"; this.type = "png";
break;
} else if (byte0 == 0xab && byte1 == 0x4b) { } else if (byte0 == 0xab && byte1 == 0x4b) {
//0xab4b5458 "«KTX" //0xab4b5458 "«KTX"
this.type = "ktx"; this.type = "ktx";
} else { break;
} else if (extraoffset++ <= 1) {
continue; continue;
} }
foundtype = true;
if (extraoffset == 1) {
let numtexs = texture.readUint8(offset++);
//TODO figure this out further
}
break;
} if (!foundtype) {
throw new Error(`failed to detect texture`); throw new Error(`failed to detect texture`);
} }
if (extraoffset == 1) {
let numtexs = texture.readUint8(offset++);
//TODO figure this out further
}
this.mipmaps = texture.readUInt8(offset++); this.mipmaps = texture.readUInt8(offset++);
if (this.type == "bmpmips") { if (this.type == "bmpmips") {

View File

@@ -4,7 +4,7 @@ import * as net from "net";
import fetch from "node-fetch"; import fetch from "node-fetch";
import { crc32 } from "../libs/crc32util"; import { crc32 } from "../libs/crc32util";
import { FileParser } from "../opdecoder"; import { FileParser } from "../opdecoder";
import { delay } from "../utils"; import { CallbackPromise, delay } from "../utils";
import { cacheMajors } from "../constants"; import { cacheMajors } from "../constants";
const maxblocksize = 102400; const maxblocksize = 102400;
@@ -96,7 +96,7 @@ function trackDataUsage(len: number) {
class DownloadSocket { class DownloadSocket {
pending: PendingFile[] = []; pending: PendingFile[] = [];
ready: Promise<void>; ready = new CallbackPromise();
socket: net.Socket; socket: net.Socket;
config: ParsedClientconfig; config: ParsedClientconfig;
@@ -148,8 +148,8 @@ class DownloadSocket {
} }
async run() { async run() {
this.ready = this.connect(); await this.connect();
await this.ready; this.ready.done();
while (true) { while (true) {
let bytesread = 0; let bytesread = 0;
try { var chunk = await this.getChunk(1 + 4); } try { var chunk = await this.getChunk(1 + 4); }
@@ -235,7 +235,6 @@ export class CacheDownloader extends DirectCacheFileSource {
configPromise: Promise<ParsedClientconfig>; configPromise: Promise<ParsedClientconfig>;
socket: DownloadSocket | null = null; socket: DownloadSocket | null = null;
socketPromise: Promise<DownloadSocket> | null = null; socketPromise: Promise<DownloadSocket> | null = null;
pending: PendingFile[];
constructor() { constructor() {
super(true); super(true);

2
src/cache/index.ts vendored
View File

@@ -328,7 +328,7 @@ export abstract class CacheFileSource {
export abstract class DirectCacheFileSource extends CacheFileSource { export abstract class DirectCacheFileSource extends CacheFileSource {
indexMap = new Map<number, Promise<CacheIndexFile>>(); indexMap = new Map<number, Promise<CacheIndexFile>>();
requiresCrc: boolean; requiresCrc: boolean;
xteakeys: XteaTable | null; xteakeys: XteaTable | null = null;
constructor(needscrc: boolean) { constructor(needscrc: boolean) {
super(); super();

View File

@@ -5,7 +5,6 @@ import { CacheFileSource, CacheIndex, CacheIndexFile, SubFile } from "./index";
export class RawFileLoader extends CacheFileSource { export class RawFileLoader extends CacheFileSource {
cachedir: string; cachedir: string;
writable: boolean;
virtualMajor: number; virtualMajor: number;
index: CacheIndex[]; index: CacheIndex[];
files = new Map<number, string>(); files = new Map<number, string>();

View File

@@ -4,8 +4,6 @@ import type { WorkerPackets } from "./sqlitewasmworker";
export class WasmGameCacheLoader extends cache.CacheFileSource { export class WasmGameCacheLoader extends cache.CacheFileSource {
cachedir: string;
writable: boolean;
indices = new Map<number, Promise<cache.CacheIndexFile>>(); indices = new Map<number, Promise<cache.CacheIndexFile>>();
dbfiles: Record<string, Blob> = {}; dbfiles: Record<string, Blob> = {};
worker: Worker; worker: Worker;

View File

@@ -41,7 +41,7 @@ export const cacheMajors = {
achievements: 57, achievements: 57,
index: 255 index: 255
} } as const;
//represents the largest build number that this application is aware off //represents the largest build number that this application is aware off
//is used as default value when a cache is considered "current" //is used as default value when a cache is considered "current"
@@ -53,7 +53,7 @@ export const cacheMapFiles = {
squares: 3, squares: 3,
squaresWater: 4, squaresWater: 4,
square_nxt: 5 square_nxt: 5
} } as const;
export const cacheConfigPages = { export const cacheConfigPages = {
mapunderlays: 1, mapunderlays: 1,
@@ -69,7 +69,7 @@ export const cacheConfigPages = {
npcs_old: 9, npcs_old: 9,
items_old: 10, items_old: 10,
spotanim_old: 13 spotanim_old: 13
} } as const;
export const lastLegacyBuildnr = 377; export const lastLegacyBuildnr = 377;
//unclear if there ended up beign overlap with (public) rs2 since this was 12 years after rs2 release //unclear if there ended up beign overlap with (public) rs2 since this was 12 years after rs2 release

View File

@@ -91,7 +91,6 @@ export class FileEdit {
minor: number; minor: number;
subfile: number; subfile: number;
action: FileAction; action: FileAction;
source: CacheFileSource;
before: Buffer | Loadable | null; before: Buffer | Loadable | null;
after: Buffer | Loadable | null; after: Buffer | Loadable | null;
constructor(action: FileAction, type: CacheEditType, major: number, minor: number, subfile: number, before: Buffer | Loadable | null, after: Buffer | Loadable | null) { constructor(action: FileAction, type: CacheEditType, major: number, minor: number, subfile: number, before: Buffer | Loadable | null, after: Buffer | Loadable | null) {

View File

@@ -368,90 +368,6 @@ export function packedHSL2HSL(hsl: number) {
return [h, s, l]; return [h, s, l];
} }
/*function packedHSL2RGBAArray(hsl)
{
var packedRGBA = packedHSL2RGBA(hsl);
var rgba = [];
rgba.push((packedRGBA ) & 0xFF);
rgba.push((packedRGBA >> 8) & 0xFF);
rgba.push((packedRGBA >> 16) & 0xFF);
rgba.push((packedRGBA >> 24) & 0xFF);
return rgba;
}*/
// https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_model_view_projection#Perspective_matrix
export function getProjectionMatrix(fieldOfViewInRadians: number, aspectRatio: number, near: number, far: number) {
var f = 1.0 / Math.tan(fieldOfViewInRadians / 2);
var rangeInv = 1 / (near - far);
return [
f / aspectRatio, 0, 0, 0,
0, f, 0, 0,
0, 0, (near + far) * rangeInv, -1,
0, 0, near * far * rangeInv * 2, 0
];
}
export namespace Matrix4x4Utils {
export function mul(a: number[], b: number[]) {
var c: number[] = [];
for (var y = 0; y < 4; ++y) {
for (var x = 0; x < 4; ++x) {
var sum = 0;
for (var n = 0; n < 4; ++n) {
sum += a[n + y * 4] * b[x + n * 4];
}
c.push(sum);
}
}
return c;
}
export function identity() {
return [
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0
];
}
export function translation(x: number, y: number, z: number) {
return [
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
x, y, z, 1.0
];
}
export function rotation(axis: "x" | "y" | "z", angle: number) {
var a = 0, b = 0;
if (axis == "x") {
a = 1;
b = 2;
}
else if (axis == "y") {
a = 0;
b = 2;
}
else if (axis == "z") {
a = 0;
b = 1;
}
else
//TODO throw here?
return; // Incorrect axis parameter, ya basic!
var matrix = this.identity();
matrix[a + a * 4] = Math.cos(angle);
matrix[b + b * 4] = Math.cos(angle);
matrix[b + a * 4] = -Math.sin(angle);
matrix[a + b * 4] = Math.sin(angle);
return matrix;
}
}
export class TypedEmitter<T extends Record<string, any>> { export class TypedEmitter<T extends Record<string, any>> {
protected listeners: { [key in keyof T]?: Set<(v: T[key]) => void> } = {}; protected listeners: { [key in keyof T]?: Set<(v: T[key]) => void> } = {};
on<K extends keyof T>(event: K, listener: (v: T[K]) => void) { on<K extends keyof T>(event: K, listener: (v: T[K]) => void) {
@@ -474,4 +390,19 @@ export class TypedEmitter<T extends Record<string, any>> {
let listeners = this.listeners[event] ?? (this.listeners[event] = new Set()); let listeners = this.listeners[event] ?? (this.listeners[event] = new Set());
listeners.forEach(cb => cb(value)); listeners.forEach(cb => cb(value));
} }
} }
export class CallbackPromise<T = void> extends Promise<T> {
done!: (v: T) => void;
err!: (e: Error) => void;
constructor(exe = (done: (v: T) => void, err: (e: Error) => void) => { }) {
//tmp vars since i can't access this during the super callback
let tmpdone: (v: T) => void;
let tmperr: (e: Error) => void;
super((done, err) => { tmpdone = done; tmperr = err; return exe(done, err); });
this.done = tmpdone!;
this.err = tmperr!;
}
}
globalThis.promhack = CallbackPromise;

View File

@@ -2,7 +2,10 @@
"compilerOptions": { "compilerOptions": {
"moduleResolution": "node", "moduleResolution": "node",
"module": "ESNext", "module": "ESNext",
"lib": [ "ESNext","DOM"], "lib": [
"ESNext",
"DOM"
],
"target": "ES2020", "target": "ES2020",
"sourceMap": false, "sourceMap": false,
"alwaysStrict": true, "alwaysStrict": true,
@@ -14,8 +17,14 @@
"rootDir": "./src", "rootDir": "./src",
"esModuleInterop": true, "esModuleInterop": true,
"experimentalDecorators": true, "experimentalDecorators": true,
"resolveJsonModule": true "resolveJsonModule": true,
"noImplicitThis": true,
"strictFunctionTypes": true,
"strictPropertyInitialization":true
}, },
"exclude": [ "node_modules", "./generated"], "exclude": [
"node_modules",
"./generated"
],
"compileOnSave": false "compileOnSave": false
} }