Skip to content

Commit

Permalink
webworker client
Browse files Browse the repository at this point in the history
  • Loading branch information
lesleyrs committed Jul 14, 2024
1 parent 21ffed7 commit f98a682
Show file tree
Hide file tree
Showing 21 changed files with 360 additions and 56 deletions.
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,12 @@ bz2.js
bz2.wasm

!/test/resources/*

# flip ignores and provide files below to host webworker on github

# /src/public/data/players
# /src/public/data/src

/src/public/data/*
/src/public/LoginThread.js
/src/public/worker.js
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,15 @@
**Jagex has never had any source code leaks.**
</div>

## Web Worker server

Set `world=999` in the client URL to start a server on login. Locally this takes only a few seconds but on github pages it will take around 3-4 minutes. Saves will load from `data/players` and a save dialog will open on logout, but you should save them to `src/public/data/players` instead.

To update server code run the following in the server:
1. `npm run build`, then copy `data` dir from server to `src/public` in client
2. `npm run bundle`, this copies worker.js and LoginThread.js to `../Client2/src/public`
3. To host on github see [.gitignore](.gitignore)

## Site Index

### Client
Expand Down
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,15 @@
"build": "npm run asc && webpack --mode=production --node-env=production",
"build:dev": "npm run asc && webpack --mode=development",
"build:prod": "npm run asc && webpack --mode=production --node-env=production",
"dev": "npm run asc && webpack-dev-server --hot --watch",
"dev": "npm run asc && webpack-dev-server --hot",
"lint": "eslint . --ext .ts",
"lint:fix": "eslint . --ext .ts --fix",
"format": "prettier src/**/*.{js,ts} --write",
"prepare": "husky install",
"test": "npm run asc && jest",
"asc": "asc --target release --optimizeLevel 3 --converge",
"local": "npm run asc && npm run build:dev && npx serve public"
"local": "npm run build:dev && npx serve public",
"prod": "npm run build && npx http-server -c-1"
},
"repository": {
"type": "git",
Expand All @@ -68,8 +69,7 @@
"lint-staged": {
"src/**/*.{js,ts}": [
"npm run format",
"npm run lint:fix",
"git add"
"npm run lint:fix"
]
}
}
21 changes: 15 additions & 6 deletions src/js/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import VarpType from './jagex2/config/VarpType';
import AnimBase from './jagex2/graphics/AnimBase';
import AnimFrame from './jagex2/graphics/AnimFrame';
import Tile from './jagex2/dash3d/type/Tile';
import ClientWorkerStream from './jagex2/io/ClientWorkerStream';

// noinspection JSSuspiciousNameCombination
export abstract class Client extends GameShell {
Expand Down Expand Up @@ -105,7 +106,7 @@ export abstract class Client extends GameShell {
protected db: Database | null = null;
protected loopCycle: number = 0;
protected archiveChecksums: number[] = [];
protected stream: ClientStream | null = null;
protected stream: ClientStream | ClientWorkerStream | null = null;
protected in: Packet = Packet.alloc(1);
protected out: Packet = Packet.alloc(1);
protected loginout: Packet = Packet.alloc(1);
Expand Down Expand Up @@ -710,8 +711,10 @@ export abstract class Client extends GameShell {
protected loadArchive = async (filename: string, displayName: string, crc: number, progress: number): Promise<Jagfile> => {
let retry: number = 5;
let data: Int8Array | undefined = await this.db?.cacheload(filename);
if (data && Packet.crc32(data) !== crc) {
data = undefined;
if (GameShell.getParameter('world') !== '999') {
if (data && Packet.crc32(data) !== crc) {
data = undefined;
}
}

if (data) {
Expand Down Expand Up @@ -741,13 +744,19 @@ export abstract class Client extends GameShell {

protected setMidi = async (name: string, crc: number, length: number): Promise<void> => {
let data: Int8Array | undefined = await this.db?.cacheload(name + '.mid');
if (data && crc !== 12345678 && Packet.crc32(data) !== crc) {
data = undefined;
if (GameShell.getParameter('world') !== '999') {
if (data && crc !== 12345678 && Packet.crc32(data) !== crc) {
data = undefined;
}
}

if (!data) {
try {
data = await downloadUrl(`${Client.httpAddress}/${name}_${crc}.mid`);
if (GameShell.getParameter('world') !== '999') {
data = await downloadUrl(`${Client.httpAddress}/${name}_${crc}.mid`);
} else {
data = await downloadUrl(`data/pack/client/songs/${name}.mid`);
}
if (length !== data.length) {
data = data.slice(0, length);
}
Expand Down
2 changes: 1 addition & 1 deletion src/js/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ async function world(): Promise<void> {
if (GameShell.getParameter('world').length === 0) {
GameShell.setParameter('world', '1');
}
if (window.location.hostname === 'localhost' && GameShell.getParameter('world') === '0') {
if (GameShell.getParameter('world') === '0' || GameShell.getParameter('world') === '999') {
localConfiguration();
} else {
await liveConfiguration(window.location.protocol.startsWith('https'));
Expand Down
41 changes: 33 additions & 8 deletions src/js/game.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ import FloType from './jagex2/config/FloType';
import {setupConfiguration} from './configuration';
import Tile from './jagex2/dash3d/type/Tile';
import DirectionFlag from './jagex2/dash3d/DirectionFlag';
import ClientWorkerStream from './jagex2/io/ClientWorkerStream';

// noinspection JSSuspiciousNameCombination
class Game extends Client {
Expand All @@ -81,9 +82,25 @@ class Game extends Client {
await Bzip.load(await (await fetch('bz2.wasm')).arrayBuffer());
this.db = new Database(await Database.openDatabase());

const checksums: Packet = new Packet(new Uint8Array(await downloadUrl(`${Client.httpAddress}/crc`)));
for (let i: number = 0; i < 9; i++) {
this.archiveChecksums[i] = checksums.g4;
if (Game.getParameter('world') !== '999') {
const checksums: Packet = new Packet(new Uint8Array(await downloadUrl(`${Client.httpAddress}/crc`)));
for (let i: number = 0; i < 9; i++) {
this.archiveChecksums[i] = checksums.g4;
}
} else {
const archives: string[] = ['config', 'crc', 'interface', 'media', 'models', 'sounds', 'textures', 'title', 'wordenc'];
try {
const responses: Response[] = await Promise.all(archives.map((url: string): Promise<Response> => fetch(`${Client.clientversion}/archives/${url}`, {cache: 'no-cache'})));
if (responses.some((response: Response): boolean => response.ok === false)) {
throw new Error();
}
const data: ArrayBuffer[] = await Promise.all(responses.map((response: Response): Promise<ArrayBuffer> => response.arrayBuffer()));
for (let i: number = 0; i < data.length; i++) {
await this.db?.cachesave(archives[i], new Int8Array(data[i]));
}
} catch (e) {
console.error(e);
}
}

if (!Client.lowMemory) {
Expand Down Expand Up @@ -836,7 +853,11 @@ class Game extends Client {
this.loginMessage1 = 'Connecting to server...';
await this.drawTitleScreen();
}
this.stream = new ClientStream(await ClientStream.openSocket({host: Client.serverAddress, port: 43594 + Client.portOffset}));
if (Game.getParameter('world') !== '999') {
this.stream = new ClientStream(await ClientStream.openSocket({host: Client.serverAddress, port: 43594 + Client.portOffset}));
} else {
this.stream = new ClientWorkerStream();
}
await this.stream?.readBytes(this.in.data, 0, 8);
this.in.pos = 0;
this.serverSeed = this.in.g8;
Expand Down Expand Up @@ -5034,8 +5055,10 @@ class Game extends Client {
let data: Int8Array | undefined;
if (landCrc !== 0) {
data = await this.db?.cacheload(`m${mapsquareX}_${mapsquareZ}`);
if (data && Packet.crc32(data) !== landCrc) {
data = undefined;
if (Game.getParameter('world') !== '999') {
if (data && Packet.crc32(data) !== landCrc) {
data = undefined;
}
}
if (!data) {
this.sceneState = 0;
Expand All @@ -5049,8 +5072,10 @@ class Game extends Client {
}
if (locCrc !== 0) {
data = await this.db?.cacheload(`l${mapsquareX}_${mapsquareZ}`);
if (data && Packet.crc32(data) !== locCrc) {
data = undefined;
if (Game.getParameter('world') !== '999') {
if (data && Packet.crc32(data) !== locCrc) {
data = undefined;
}
}
if (!data) {
this.sceneState = 0;
Expand Down
Loading

0 comments on commit f98a682

Please sign in to comment.