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 * as THREE from "three";
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 { 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";
@@ -156,11 +156,11 @@ export async function materialToModel(sceneCache: ThreejsSceneCache, modelid: nu
export class RSModel extends TypedEmitter<{ loaded: undefined, animchanged: number }> implements ThreeJsSceneElementSource {
model: Promise<{ modeldata: ModelData, mesh: Object3D, nullAnim: AnimationClip }>;
loaded: { modeldata: ModelData, mesh: Object3D, nullAnim: AnimationClip, matUvAnims: { tex: Texture, v: Vector2 }[] } | null = null;
cache: ThreejsSceneCache;
cache!: ThreejsSceneCache;
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> }> = {
"-1": { clip: null, prom: new Promise(d => this.nullAnimLoaded = d) }
"-1": this.nullAnimPromise
};
mountedanim: AnimationClip | null = null;
mixer = new AnimationMixer(this.rootnode);
@@ -232,8 +232,8 @@ export class RSModel extends TypedEmitter<{ loaded: undefined, animchanged: numb
}
});
let nullAnim = new AnimationClip(undefined, undefined, []);
this.nullAnimLoaded(nullAnim);
this.anims[-1].clip = nullAnim;
this.nullAnimPromise.clip = nullAnim;
this.nullAnimPromise.prom.done(nullAnim);
this.rootnode.add(mesh);
this.loaded = { mesh, modeldata, nullAnim, matUvAnims };

View File

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

View File

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

2
src/cache/index.ts vendored
View File

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

View File

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

View File

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

View File

@@ -41,7 +41,7 @@ export const cacheMajors = {
achievements: 57,
index: 255
}
} as const;
//represents the largest build number that this application is aware off
//is used as default value when a cache is considered "current"
@@ -53,7 +53,7 @@ export const cacheMapFiles = {
squares: 3,
squaresWater: 4,
square_nxt: 5
}
} as const;
export const cacheConfigPages = {
mapunderlays: 1,
@@ -69,7 +69,7 @@ export const cacheConfigPages = {
npcs_old: 9,
items_old: 10,
spotanim_old: 13
}
} as const;
export const lastLegacyBuildnr = 377;
//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;
subfile: number;
action: FileAction;
source: CacheFileSource;
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];
}
/*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>> {
protected listeners: { [key in keyof T]?: Set<(v: T[key]) => 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());
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": {
"moduleResolution": "node",
"module": "ESNext",
"lib": [ "ESNext","DOM"],
"lib": [
"ESNext",
"DOM"
],
"target": "ES2020",
"sourceMap": false,
"alwaysStrict": true,
@@ -14,8 +17,14 @@
"rootDir": "./src",
"esModuleInterop": true,
"experimentalDecorators": true,
"resolveJsonModule": true
"resolveJsonModule": true,
"noImplicitThis": true,
"strictFunctionTypes": true,
"strictPropertyInitialization":true
},
"exclude": [ "node_modules", "./generated"],
"exclude": [
"node_modules",
"./generated"
],
"compileOnSave": false
}