-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(clientdb): add initial clientdb implementation
- Loading branch information
Showing
11 changed files
with
235 additions
and
0 deletions.
There are no files selected for viewing
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import { IoSource, openStream } from '@wowserhq/io'; | ||
import ClientDbRecord from './ClientDbRecord.js'; | ||
import * as dbIo from './io.js'; | ||
|
||
interface Constructor<T> { | ||
new (...args: any[]): T; | ||
} | ||
|
||
class ClientDb<T extends ClientDbRecord> { | ||
#RecordClass: Constructor<T>; | ||
|
||
#minId = 0xfffffff; | ||
#maxId = 0; | ||
|
||
#recordCount = 0; | ||
|
||
#records: T[]; | ||
#recordsById: Record<number, T>; | ||
|
||
constructor(RecordClass: Constructor<T>) { | ||
this.#RecordClass = RecordClass; | ||
} | ||
|
||
get records() { | ||
return this.#records; | ||
} | ||
|
||
load(source: IoSource): ClientDb<T> { | ||
const stream = openStream(source); | ||
|
||
const header = dbIo.header.read(stream); | ||
|
||
this.#recordCount = header.recordCount; | ||
|
||
const records = new Array(this.#recordCount); | ||
const recordsById = {}; | ||
|
||
for (let i = 0; i < this.#recordCount; i++) { | ||
const record = new this.#RecordClass().load(stream); | ||
|
||
this.#minId = record.id < this.#minId ? record.id : this.#minId; | ||
this.#maxId = record.id > this.#maxId ? record.id : this.#maxId; | ||
|
||
records[i] = record; | ||
recordsById[record.id] = record; | ||
} | ||
|
||
this.#records = records; | ||
this.#recordsById = recordsById; | ||
|
||
stream.close(); | ||
|
||
return this; | ||
} | ||
|
||
getRecord(id: number): T { | ||
if (id < this.#minId || id > this.#maxId) { | ||
return null; | ||
} | ||
|
||
return this.#recordsById[id]; | ||
} | ||
|
||
getRecordByIndex(index: number) { | ||
if (index < 0 || index >= this.#recordCount) { | ||
return null; | ||
} | ||
|
||
return this.#records[index]; | ||
} | ||
} | ||
|
||
export default ClientDb; | ||
export { ClientDb }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import { IoSource, IoType, openStream } from '@wowserhq/io'; | ||
|
||
class ClientDbRecord { | ||
id: number; | ||
|
||
#recordIo: IoType; | ||
|
||
constructor(recordIo: IoType) { | ||
this.#recordIo = recordIo; | ||
} | ||
|
||
load(source: IoSource) { | ||
const stream = openStream(source); | ||
|
||
const record = this.#recordIo.read(stream); | ||
|
||
for (const [key, value] of Object.entries(record)) { | ||
this[key] = value; | ||
} | ||
|
||
return this; | ||
} | ||
} | ||
|
||
export default ClientDbRecord; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import * as io from '@wowserhq/io'; | ||
import { IoType } from '@wowserhq/io'; | ||
|
||
const header: IoType = io.struct({ | ||
magic: io.string({ size: 4, terminate: false }), | ||
recordCount: io.uint32le, | ||
fieldCount: io.uint32le, | ||
recordSize: io.uint32le, | ||
stringBlockSize: io.uint32le, | ||
}); | ||
|
||
export { header }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import * as io from '@wowserhq/io'; | ||
import ClientDbRecord from '../ClientDbRecord.js'; | ||
|
||
const recordIo = io.struct({ | ||
id: io.int32le, | ||
num: io.int32le, | ||
time: io.array(io.int32le, { size: 16 }), | ||
data: io.array(io.float32le, { size: 16 }), | ||
}); | ||
|
||
class LightFloatBandRecord extends ClientDbRecord { | ||
num: number; | ||
time: number[]; | ||
data: number[]; | ||
|
||
constructor() { | ||
super(recordIo); | ||
} | ||
} | ||
|
||
export default LightFloatBandRecord; | ||
export { LightFloatBandRecord }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import * as io from '@wowserhq/io'; | ||
import ClientDbRecord from '../ClientDbRecord.js'; | ||
|
||
const recordIo = io.struct({ | ||
id: io.int32le, | ||
num: io.int32le, | ||
time: io.array(io.int32le, { size: 16 }), | ||
data: io.array(io.int32le, { size: 16 }), | ||
}); | ||
|
||
class LightIntBandRecord extends ClientDbRecord { | ||
num: number; | ||
time: number[]; | ||
data: number[]; | ||
|
||
constructor() { | ||
super(recordIo); | ||
} | ||
} | ||
|
||
export default LightIntBandRecord; | ||
export { LightIntBandRecord }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import * as io from '@wowserhq/io'; | ||
import ClientDbRecord from '../ClientDbRecord.js'; | ||
|
||
const recordIo = io.struct({ | ||
id: io.int32le, | ||
highlightSky: io.int32le, | ||
lightSkyboxId: io.int32le, | ||
glow: io.float32le, | ||
waterShallowAlpha: io.float32le, | ||
waterDeepAlpha: io.float32le, | ||
oceanShallowAlpha: io.float32le, | ||
oceanDeepAlpha: io.float32le, | ||
flags: io.int32le, | ||
}); | ||
|
||
class LightParamsRecord extends ClientDbRecord { | ||
highlightSky: number; | ||
lightSkyboxId: number; | ||
glow: number; | ||
waterShallowAlpha: number; | ||
waterDeepAlpha: number; | ||
oceanShallowAlpha: number; | ||
oceanDeepAlpha: number; | ||
flags: number; | ||
|
||
constructor() { | ||
super(recordIo); | ||
} | ||
} | ||
|
||
export default LightParamsRecord; | ||
export { LightParamsRecord }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import * as io from '@wowserhq/io'; | ||
import ClientDbRecord from '../ClientDbRecord.js'; | ||
|
||
const recordIo = io.struct({ | ||
id: io.int32le, | ||
continentId: io.int32le, | ||
gameCoords: io.array(io.float32le, { size: 3 }), | ||
gameFalloffStart: io.float32le, | ||
gameFalloffEnd: io.float32le, | ||
lightParamsId: io.array(io.int32le, { size: 8 }), | ||
}); | ||
|
||
class LightRecord extends ClientDbRecord { | ||
continentId: number; | ||
gameCoords: number[]; | ||
gameFalloffStart: number; | ||
gameFalloffEnd: number; | ||
lightParamsId: number[]; | ||
|
||
constructor() { | ||
super(recordIo); | ||
} | ||
} | ||
|
||
export default LightRecord; | ||
export { LightRecord }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
export * from './record/LightRecord.js'; | ||
export * from './record/LightFloatBandRecord.js'; | ||
export * from './record/LightIntBandRecord.js'; | ||
export * from './record/LightParamsRecord.js'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { describe, expect, test } from 'vitest'; | ||
import ClientDb from '../../lib/clientdb/ClientDb.js'; | ||
import LightRecord from '../../lib/clientdb/record/LightRecord.js'; | ||
|
||
describe('ClientDb', () => { | ||
describe('load', () => { | ||
test('should load blp from valid file', () => { | ||
const dbc = new ClientDb(LightRecord).load('./fixture/clientdb/Light.dbc'); | ||
const record = dbc.getRecordByIndex(1); | ||
|
||
expect(record.id).toBe(2); | ||
expect(record.lightParamsId).toEqual([14, 15, 494, 15, 4, 0, 0, 0]); | ||
}); | ||
}); | ||
}); |