26 changed files with 862 additions and 2 deletions
@ -1 +1,3 @@ |
|||
node_modules/ |
|||
node_modules/ |
|||
packages/bridge-server/data/data.db |
|||
packages/bridge-server/upload |
|||
Binary file not shown.
@ -0,0 +1,26 @@ |
|||
import { Column, Model, Table, HasMany, ForeignKey, BelongsTo } from "sequelize-typescript"; |
|||
import { Racer } from "src/racers/racer.model"; |
|||
import { Race } from "src/races/race.model"; |
|||
|
|||
@Table |
|||
export class RaceResult extends Model { |
|||
@ForeignKey(() => Race) |
|||
@Column |
|||
raceId: number; |
|||
|
|||
@BelongsTo(() => Race) |
|||
race: Race |
|||
|
|||
@ForeignKey(() => Racer) |
|||
@Column |
|||
racerId: number; |
|||
|
|||
@BelongsTo(() => Racer) |
|||
racer: Racer |
|||
|
|||
@Column |
|||
replayPath: string; |
|||
|
|||
@Column |
|||
time: number; |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
import { Module } from '@nestjs/common'; |
|||
import { SequelizeModule } from '@nestjs/sequelize'; |
|||
import { RaceResult } from './race-result.model'; |
|||
import { RaceResultsService } from './race-results.service'; |
|||
|
|||
@Module({ |
|||
imports: [SequelizeModule.forFeature([RaceResult])], |
|||
providers: [RaceResultsService], |
|||
exports: [SequelizeModule, RaceResultsService] |
|||
}) |
|||
export class RaceResultsModule {} |
|||
@ -0,0 +1,18 @@ |
|||
import { Test, TestingModule } from '@nestjs/testing'; |
|||
import { RaceResultsService } from './race-results.service'; |
|||
|
|||
describe('RaceResultsService', () => { |
|||
let service: RaceResultsService; |
|||
|
|||
beforeEach(async () => { |
|||
const module: TestingModule = await Test.createTestingModule({ |
|||
providers: [RaceResultsService], |
|||
}).compile(); |
|||
|
|||
service = module.get<RaceResultsService>(RaceResultsService); |
|||
}); |
|||
|
|||
it('should be defined', () => { |
|||
expect(service).toBeDefined(); |
|||
}); |
|||
}); |
|||
@ -0,0 +1,4 @@ |
|||
import { Injectable } from '@nestjs/common'; |
|||
|
|||
@Injectable() |
|||
export class RaceResultsService {} |
|||
@ -0,0 +1,14 @@ |
|||
import { Column, Model, Table, HasMany } from "sequelize-typescript"; |
|||
import { RaceResult } from "src/race-results/race-result.model"; |
|||
|
|||
@Table |
|||
export class Racer extends Model { |
|||
@Column |
|||
name: string; |
|||
|
|||
@Column |
|||
gameHandle: string; |
|||
|
|||
@HasMany(() => RaceResult) |
|||
results: RaceResult[]; |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
import { Module } from '@nestjs/common'; |
|||
import { SequelizeModule } from '@nestjs/sequelize'; |
|||
import { Racer } from './racer.model'; |
|||
import { RacersService } from './racers.service'; |
|||
|
|||
@Module({ |
|||
imports: [SequelizeModule.forFeature([Racer])], |
|||
providers: [RacersService], |
|||
exports: [SequelizeModule, RacersService] |
|||
}) |
|||
export class RacersModule {} |
|||
@ -0,0 +1,18 @@ |
|||
import { Test, TestingModule } from '@nestjs/testing'; |
|||
import { RacersService } from './racers.service'; |
|||
|
|||
describe('RacersService', () => { |
|||
let service: RacersService; |
|||
|
|||
beforeEach(async () => { |
|||
const module: TestingModule = await Test.createTestingModule({ |
|||
providers: [RacersService], |
|||
}).compile(); |
|||
|
|||
service = module.get<RacersService>(RacersService); |
|||
}); |
|||
|
|||
it('should be defined', () => { |
|||
expect(service).toBeDefined(); |
|||
}); |
|||
}); |
|||
@ -0,0 +1,4 @@ |
|||
import { Injectable } from '@nestjs/common'; |
|||
|
|||
@Injectable() |
|||
export class RacersService {} |
|||
@ -0,0 +1,34 @@ |
|||
import { Column, Model, Table, HasMany, HasOne, ForeignKey, BelongsTo } from "sequelize-typescript"; |
|||
import { RaceResult } from "src/race-results/race-result.model"; |
|||
import { Season } from "src/seasons/season.model"; |
|||
|
|||
@Table |
|||
export class Race extends Model { |
|||
@Column |
|||
mapName: string; |
|||
|
|||
@Column |
|||
mapURL: string; |
|||
|
|||
@Column |
|||
mapUID: string; |
|||
|
|||
@Column |
|||
mapImgUrl: string; |
|||
|
|||
@Column |
|||
startDate: Date; |
|||
|
|||
@Column |
|||
endDate: Date; |
|||
|
|||
@HasMany(() => RaceResult) |
|||
results: RaceResult[]; |
|||
|
|||
@ForeignKey(() => Season) |
|||
@Column |
|||
seasonId: number; |
|||
|
|||
@BelongsTo(() => Season) |
|||
season: Season; |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
import { Module } from '@nestjs/common'; |
|||
import { SequelizeModule } from '@nestjs/sequelize'; |
|||
import { Race } from './race.model'; |
|||
import { RacesService } from './races.service'; |
|||
|
|||
@Module({ |
|||
imports: [SequelizeModule.forFeature([Race])], |
|||
providers: [RacesService], |
|||
exports: [SequelizeModule, RacesService] |
|||
}) |
|||
export class RacesModule {} |
|||
@ -0,0 +1,18 @@ |
|||
import { Test, TestingModule } from '@nestjs/testing'; |
|||
import { RacesService } from './races.service'; |
|||
|
|||
describe('RacesService', () => { |
|||
let service: RacesService; |
|||
|
|||
beforeEach(async () => { |
|||
const module: TestingModule = await Test.createTestingModule({ |
|||
providers: [RacesService], |
|||
}).compile(); |
|||
|
|||
service = module.get<RacesService>(RacesService); |
|||
}); |
|||
|
|||
it('should be defined', () => { |
|||
expect(service).toBeDefined(); |
|||
}); |
|||
}); |
|||
@ -0,0 +1,4 @@ |
|||
import { Injectable } from '@nestjs/common'; |
|||
|
|||
@Injectable() |
|||
export class RacesService {} |
|||
@ -0,0 +1,23 @@ |
|||
import { Column, Model, Table, HasMany, ForeignKey, BelongsTo } from "sequelize-typescript"; |
|||
import { Racer } from "src/racers/racer.model"; |
|||
import { Season } from "src/seasons/season.model"; |
|||
|
|||
@Table |
|||
export class SeasonStanding extends Model { |
|||
@ForeignKey(() => Season) |
|||
@Column |
|||
seasonId: number; |
|||
|
|||
@BelongsTo(() => Season) |
|||
season: Season |
|||
|
|||
@ForeignKey(() => Racer) |
|||
@Column |
|||
racerId: number; |
|||
|
|||
@BelongsTo(() => Racer) |
|||
racer: Racer |
|||
|
|||
@Column |
|||
points: number; |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
import { Module } from '@nestjs/common'; |
|||
import { SequelizeModule } from '@nestjs/sequelize'; |
|||
import { SeasonStanding } from './season-standing.model'; |
|||
import { SeasonStandingsService } from './season-standings.service'; |
|||
|
|||
@Module({ |
|||
imports: [SequelizeModule.forFeature([SeasonStanding])], |
|||
providers: [SeasonStandingsService], |
|||
exports: [SequelizeModule, SeasonStandingsService] |
|||
}) |
|||
export class SeasonStandingsModule {} |
|||
@ -0,0 +1,18 @@ |
|||
import { Test, TestingModule } from '@nestjs/testing'; |
|||
import { SeasonStandingsService } from './season-standings.service'; |
|||
|
|||
describe('SeasonStandingsService', () => { |
|||
let service: SeasonStandingsService; |
|||
|
|||
beforeEach(async () => { |
|||
const module: TestingModule = await Test.createTestingModule({ |
|||
providers: [SeasonStandingsService], |
|||
}).compile(); |
|||
|
|||
service = module.get<SeasonStandingsService>(SeasonStandingsService); |
|||
}); |
|||
|
|||
it('should be defined', () => { |
|||
expect(service).toBeDefined(); |
|||
}); |
|||
}); |
|||
@ -0,0 +1,4 @@ |
|||
import { Injectable } from '@nestjs/common'; |
|||
|
|||
@Injectable() |
|||
export class SeasonStandingsService {} |
|||
@ -0,0 +1,21 @@ |
|||
import { Column, HasMany, Model, Table } from "sequelize-typescript"; |
|||
import { Race } from "src/races/race.model"; |
|||
import { SeasonStanding } from "src/season-standings/season-standing.model"; |
|||
|
|||
@Table |
|||
export class Season extends Model { |
|||
@Column |
|||
title: string; |
|||
|
|||
@Column |
|||
subTitle: string; |
|||
|
|||
@Column |
|||
startingDate: Date; |
|||
|
|||
@HasMany(() => Race) |
|||
races: Race[] |
|||
|
|||
@HasMany(() => SeasonStanding) |
|||
standings: SeasonStanding[]; |
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
import { Module } from '@nestjs/common'; |
|||
import { SequelizeModule } from '@nestjs/sequelize'; |
|||
import { Season } from './season.model'; |
|||
import { SeasonsController } from './seasons.controller'; |
|||
import { SeasonsService } from './seasons.service'; |
|||
|
|||
@Module({ |
|||
imports: [SequelizeModule.forFeature([Season])], |
|||
providers: [SeasonsService], |
|||
controllers: [SeasonsController], |
|||
exports: [SequelizeModule, SeasonsService] |
|||
}) |
|||
export class SeasonsModule {} |
|||
@ -0,0 +1,18 @@ |
|||
import { Test, TestingModule } from '@nestjs/testing'; |
|||
import { SeasonsService } from './seasons.service'; |
|||
|
|||
describe('SeasonsService', () => { |
|||
let service: SeasonsService; |
|||
|
|||
beforeEach(async () => { |
|||
const module: TestingModule = await Test.createTestingModule({ |
|||
providers: [SeasonsService], |
|||
}).compile(); |
|||
|
|||
service = module.get<SeasonsService>(SeasonsService); |
|||
}); |
|||
|
|||
it('should be defined', () => { |
|||
expect(service).toBeDefined(); |
|||
}); |
|||
}); |
|||
@ -0,0 +1,21 @@ |
|||
import { Injectable } from '@nestjs/common'; |
|||
import { InjectModel } from '@nestjs/sequelize'; |
|||
import { Season } from './season.model'; |
|||
//import { SeasonStanding } from 'src/season-standings/season-standing.model';
|
|||
//import { Race } from 'src/races/race.model';
|
|||
|
|||
@Injectable() |
|||
export class SeasonsService { |
|||
constructor( |
|||
@InjectModel(Season) private seasonModel: typeof Season, |
|||
) |
|||
{} |
|||
|
|||
async findAll() { |
|||
//return this.seasonModel.findAll();
|
|||
} |
|||
|
|||
async findOne(id: number) { |
|||
//return this.seasonModel.findOne({ where: {id: id}}/*, include:[Race, SeasonStanding] }*/)
|
|||
} |
|||
} |
|||
@ -0,0 +1,78 @@ |
|||
class gbxHeader { |
|||
|
|||
has_magic = true |
|||
version = -1 |
|||
format = -1 |
|||
compressionofRefTable = -1 |
|||
compressionofRefBody = -1 |
|||
compressionTextFlag = '' |
|||
id = -1 |
|||
userData = [] |
|||
numNodes = 0 |
|||
|
|||
is_vaild = false |
|||
|
|||
parse(buff) |
|||
{ |
|||
let header_magic = buff.readString(3); |
|||
|
|||
if (header_magic != 'GBX') |
|||
{ |
|||
console.log("Header Magic Mismatch: " + header_magic); |
|||
return |
|||
} |
|||
this.has_magic = true |
|||
|
|||
this.version = buff.readUInt16(); |
|||
console.log(this.version) |
|||
|
|||
if (this.version < 5 || this.version >7 ) |
|||
{ |
|||
console.log("Unsupported version") |
|||
return; |
|||
} |
|||
|
|||
this.format = buff.readInt8(); |
|||
if (this.format != 66) |
|||
{ |
|||
console.log("Unsupported format") |
|||
return; |
|||
} |
|||
|
|||
this.compressionofRefTable = buff.readInt8(); |
|||
|
|||
if (this.compressionofRefTable != 67 && this.compressionofRefTable != 85) |
|||
{ |
|||
console.log("Unsupported compression format, Ref") |
|||
return; |
|||
} |
|||
|
|||
this.compressionofRefBody = buff.readInt8(); |
|||
if (this.compressionofRefBody != 67 && this.compressionofRefBody != 85) |
|||
{ |
|||
console.log("Unsupported compression format, Body") |
|||
return; |
|||
} |
|||
|
|||
this.compressionTextFlag = ''; |
|||
if (this.version >= 4) |
|||
{ |
|||
this.compressionTextFlag = buff.readString(1); |
|||
} |
|||
|
|||
this.id = buff.readUInt32(); |
|||
console.log(this.id) |
|||
|
|||
if (this.version >=6) |
|||
{ |
|||
this.userData = buff.readBytes(); |
|||
} |
|||
|
|||
this.numNodes = buff.readUInt32(); |
|||
|
|||
this.is_vaild = true |
|||
} |
|||
} |
|||
|
|||
|
|||
module.exports = gbxHeader; |
|||
@ -0,0 +1,384 @@ |
|||
interface ChunkInfo { |
|||
dwId: number; |
|||
dwSize: number; |
|||
dwOffset: number; |
|||
} |
|||
|
|||
|
|||
class gbxReplay { |
|||
|
|||
CHUNKS_OFFSET = 17; |
|||
HEADER_OFFSET = 21; |
|||
UNASSIGNED = 0xFFFFFFFF; |
|||
|
|||
mapUID = ""; |
|||
environment = ""; |
|||
author = ""; |
|||
bestTime = this.UNASSIGNED; |
|||
gamerHandle = "" |
|||
login = "" |
|||
titleId = "" |
|||
|
|||
calcChunkOffset(num) { |
|||
return (((num) * 8) + this.HEADER_OFFSET) |
|||
} |
|||
|
|||
isNumber(id) { return (((id) & 0xC0000000) == 0)} |
|||
isString(id) { return (((id) & 0xC0000000) != 0)} |
|||
isUnassigned(id) {return ((id) == this.UNASSIGNED)} |
|||
getIndex(id) {return ((id) & 0x3FFFFFFF)} |
|||
|
|||
parseReplayChunk(buff, chunkInfo) { |
|||
buff.seek(0+chunkInfo.dwOffset); |
|||
let version = buff.readUInt32(); |
|||
let isVSK = version >= 9999 ? true : false; |
|||
|
|||
let idList = { version: 0, index: 0, list:[]} |
|||
|
|||
if( chunkInfo.dwSize <= 4) { |
|||
return; |
|||
} |
|||
|
|||
if((!isVSK && version >= 3) || (isVSK && version >= 10000)) |
|||
{ |
|||
let result = this.readIdentifier(buff, idList); |
|||
if(result.read > 0) |
|||
{ |
|||
this.mapUID = result.str; |
|||
console.log("MapUID:\t " + this.mapUID) |
|||
} |
|||
|
|||
result = this.readIdentifier(buff, idList); |
|||
if(result.read > 0) |
|||
{ |
|||
this.environment = result.str; |
|||
console.log("Environ:\t " + this.environment) |
|||
} |
|||
|
|||
result = this.readIdentifier(buff, idList) |
|||
if (result.read > 0) |
|||
{ |
|||
this.author = result.str; |
|||
console.log("Author:\t " + this.author) |
|||
} |
|||
|
|||
this.bestTime = buff.readUInt32(); |
|||
console.log("BestTime:\t " + this.bestTime); |
|||
|
|||
result = buff.readNadeoString(); |
|||
if (result.read > 0) |
|||
{ |
|||
this.gamerHandle = result.str; |
|||
console.log("Gamer Handle:\t " + this.gamerHandle) |
|||
} |
|||
|
|||
if((!isVSK && version >= 6) || (isVSK && version >= 10000)) |
|||
{ |
|||
result = buff.readNadeoString(); |
|||
if (result.read > 0) |
|||
{ |
|||
this.login = result.str; |
|||
console.log("Login:\t " + this.login) |
|||
} |
|||
|
|||
if((!isVSK && version >= 8) || (isVSK && version >= 10000)) |
|||
{ |
|||
buff.seek(buff.readPos+1); |
|||
result = this.readIdentifier(buff, idList) |
|||
if (result.read > 0) |
|||
{ |
|||
this.titleId = result.str; |
|||
console.log("titleId:\t " + this.titleId) |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
parseAuthorChunk(buff, chunkInfo) { |
|||
|
|||
} |
|||
|
|||
parseCommunityChunk(buff, chunkInfo) { |
|||
|
|||
} |
|||
|
|||
parse(buff) |
|||
{ |
|||
buff.seek(0+this.CHUNKS_OFFSET); |
|||
let numChunks = buff.readUInt32(); |
|||
|
|||
if(numChunks == 0) { |
|||
return true; |
|||
} |
|||
else if (numChunks > 0xff) { |
|||
return false; |
|||
} |
|||
|
|||
let chunkId, chunkSize = 0; |
|||
let chunkOffset = this.calcChunkOffset(numChunks) |
|||
let chunkVersion: ChunkInfo; |
|||
let chunkCommunity: ChunkInfo; |
|||
let chunkAuthor: ChunkInfo; |
|||
|
|||
for (let counter = 1; counter <= numChunks; counter++) { |
|||
chunkId = buff.readUInt32(); |
|||
chunkSize = buff.readUInt32(); |
|||
|
|||
chunkSize &= 0x7FFFFFFF; |
|||
|
|||
switch (chunkId){ |
|||
case 0x03093000: // (TM)
|
|||
case 0x2403F000: // (VSK, TM)
|
|||
chunkVersion.dwId = chunkId; |
|||
chunkVersion.dwSize = chunkSize; |
|||
chunkVersion.dwOffset = chunkOffset; |
|||
chunkOffset += chunkSize; |
|||
break; |
|||
case 0x03093001: // (TM)
|
|||
case 0x2403F001: // (VSK, TM)
|
|||
chunkCommunity.dwId = chunkId; |
|||
chunkCommunity.dwSize = chunkSize; |
|||
chunkCommunity.dwOffset = chunkOffset; |
|||
chunkOffset += chunkSize; |
|||
//OutputTextFmt(hwndCtl, szOutput, _countof(szOutput), g_szChunk, dwCouter, dwChunkId, dwChunkSize);
|
|||
break; |
|||
|
|||
case 0x03093002: // (MP)
|
|||
chunkAuthor.dwId = chunkId; |
|||
chunkAuthor.dwSize = chunkSize; |
|||
chunkAuthor.dwOffset = chunkOffset; |
|||
chunkOffset += chunkSize; |
|||
//OutputTextFmt(hwndCtl, szOutput, _countof(szOutput), g_szChunk, dwCouter, dwChunkId, dwChunkSize);
|
|||
break; |
|||
|
|||
default: |
|||
chunkOffset += chunkSize; |
|||
//OutputTextFmt(hwndCtl, szOutput, _countof(szOutput), g_szChunk, dwCouter, dwChunkId, dwChunkSize);
|
|||
} |
|||
} |
|||
|
|||
if (chunkVersion.dwSize > 0) { |
|||
this.parseReplayChunk(buff, chunkVersion); |
|||
} |
|||
|
|||
if (chunkCommunity.dwSize > 0) { |
|||
this.parseCommunityChunk(buff, chunkCommunity); |
|||
} |
|||
|
|||
if (chunkAuthor.dwSize > 0) { |
|||
this.parseAuthorChunk(buff, chunkAuthor); |
|||
} |
|||
} |
|||
|
|||
readIdentifier(buff, idList) |
|||
{ |
|||
if ( idList.version < 3 ) |
|||
{ |
|||
idList.version = buff.readUInt32(); |
|||
|
|||
if (idList.version < 2) |
|||
{ |
|||
return {read:-1, str:""}; |
|||
} |
|||
} |
|||
|
|||
let id = buff.readUInt32(); |
|||
if(this.isUnassigned(id)) |
|||
{ |
|||
return {read:0, str:""}; |
|||
} |
|||
|
|||
if(this.isNumber(id)) |
|||
{ |
|||
return this.getCollectionString(id); |
|||
} |
|||
|
|||
if(idList.version == 2) |
|||
{ |
|||
return buff.readNadeoString(); |
|||
} |
|||
|
|||
if(this.isString(id) && this.getIndex(id) == 0) |
|||
{ |
|||
let result = buff.readNadeoString(); |
|||
|
|||
if (result.read > 0 && idList.index < 8) |
|||
{ |
|||
idList.list[idList.index] = result.str; |
|||
idList.index++; |
|||
} |
|||
|
|||
return result; |
|||
} |
|||
|
|||
let index = this.getIndex(id); |
|||
if( index == 0 || index > 8) |
|||
{ |
|||
return {read:0, str:""}; |
|||
} |
|||
|
|||
let latest = idList.list[idList.index-1]; |
|||
return {read:latest.length, str:latest}; |
|||
} |
|||
|
|||
getCollectionString(id) |
|||
{ |
|||
let outString = "" |
|||
switch (id) |
|||
{ |
|||
case 0: // Speed
|
|||
outString = "Desert"; |
|||
break; |
|||
case 1: // Alpine
|
|||
outString = "Snow"; |
|||
break; |
|||
case 2: // Rally
|
|||
outString = "Rally"; |
|||
break; |
|||
case 3: // Island
|
|||
outString = "Island"; |
|||
break; |
|||
case 4: // Bay
|
|||
outString = "Bay"; |
|||
break; |
|||
case 5: // Coast
|
|||
outString = "Coast"; |
|||
break; |
|||
case 6: // StadiumMP4
|
|||
outString = "Stadium"; |
|||
break; |
|||
case 7: // Basic
|
|||
outString = "Basic"; |
|||
break; |
|||
case 8: // Plain
|
|||
outString = "Plain"; |
|||
break; |
|||
case 9: // Moon
|
|||
outString = "Moon"; |
|||
break; |
|||
case 10: // Toy
|
|||
outString = "Toy"; |
|||
break; |
|||
case 11: // Valley
|
|||
outString = "Valley"; |
|||
break; |
|||
case 12: // Canyon
|
|||
outString = "Canyon"; |
|||
break; |
|||
case 13: // Lagoon
|
|||
outString = "Lagoon"; |
|||
break; |
|||
case 14: // Deprecated_Arena
|
|||
outString = "Arena"; |
|||
break; |
|||
case 15: // TMTest8
|
|||
outString = "TMTest8"; |
|||
break; |
|||
case 16: // TMTest9
|
|||
outString = "TMTest9"; |
|||
break; |
|||
case 17: // TMCommon
|
|||
outString = "TMCommon"; |
|||
break; |
|||
case 18: // Canyon4
|
|||
outString = "Canyon4"; |
|||
break; |
|||
case 19: // Canyon256
|
|||
outString = "Canyon256"; |
|||
break; |
|||
case 20: // Valley4
|
|||
outString = "Valley4"; |
|||
break; |
|||
case 21: // Valley256
|
|||
outString = "Valley256"; |
|||
break; |
|||
case 22: // Lagoon4
|
|||
outString = "Lagoon4"; |
|||
break; |
|||
case 23: // Lagoon256
|
|||
outString = "Lagoon256"; |
|||
break; |
|||
case 24: // Stadium4
|
|||
outString = "Stadium4"; |
|||
break; |
|||
case 25: // Stadium256
|
|||
outString = "Stadium256"; |
|||
break; |
|||
case 26: // Stadium
|
|||
outString = "Stadium"; |
|||
break; |
|||
case 27: // Voxel
|
|||
outString = "Voxel"; |
|||
break; |
|||
case 100: // History
|
|||
outString = "History"; |
|||
break; |
|||
case 101: // Society
|
|||
outString = "Society"; |
|||
break; |
|||
case 102: // Galaxy
|
|||
outString = "Galaxy"; |
|||
break; |
|||
case 103: // QMTest1
|
|||
outString = "QMTest1"; |
|||
break; |
|||
case 104: // QMTest2
|
|||
outString = "QMTest2"; |
|||
break; |
|||
case 105: // QMTest3
|
|||
outString = "QMTest3"; |
|||
break; |
|||
case 200: // Gothic
|
|||
outString = "Gothic"; |
|||
break; |
|||
case 201: // Paris
|
|||
outString = "Paris"; |
|||
break; |
|||
case 202: // Storm
|
|||
outString = "Storm"; |
|||
break; |
|||
case 203: // Cryo
|
|||
outString = "Cryo"; |
|||
break; |
|||
case 204: // Meteor
|
|||
outString = "Meteor"; |
|||
break; |
|||
case 205: // Meteor4
|
|||
outString = "Meteor4"; |
|||
break; |
|||
case 206: // Meteor256
|
|||
outString = "Meteor256"; |
|||
break; |
|||
case 207: // SMTest3
|
|||
outString = "SMTest3"; |
|||
break; |
|||
case 299: // SMCommon
|
|||
outString = "SMCommon"; |
|||
break; |
|||
case 10000: // Vehicles
|
|||
outString = "Vehicles"; |
|||
break; |
|||
case 10001: // Orbital
|
|||
outString = "Orbital"; |
|||
break; |
|||
case 10002: // Actors
|
|||
outString = "Actors"; |
|||
break; |
|||
case 10003: // Common
|
|||
outString = "Common"; |
|||
break; |
|||
case this.UNASSIGNED: |
|||
outString = "_Unassigned"; |
|||
break; |
|||
default: |
|||
{ |
|||
return {read:0, str:""}; |
|||
} |
|||
} |
|||
|
|||
return {read:outString.length, str:outString} |
|||
} |
|||
} |
|||
|
|||
module.exports = gbxReplay; |
|||
@ -0,0 +1,75 @@ |
|||
class NadeoStringResult { |
|||
read: number; |
|||
str: string; |
|||
} |
|||
|
|||
class Advancablebuffer { |
|||
readPos: number = 0; |
|||
internalBuffer: Buffer; |
|||
littleEndian: boolean = true |
|||
|
|||
constructor(buffer: Buffer, useBigEndian: boolean) |
|||
{ |
|||
this.internalBuffer = buffer; |
|||
this.readPos = 0; |
|||
this.littleEndian = !useBigEndian; |
|||
} |
|||
|
|||
seek(seekPos: number): void |
|||
{ |
|||
this.readPos = seekPos |
|||
} |
|||
|
|||
readString(numBytes: number): string |
|||
{ |
|||
let t = this.internalBuffer.subarray(this.readPos, this.readPos+=numBytes); |
|||
return t.toString(); |
|||
} |
|||
|
|||
readInt8(): number |
|||
{ |
|||
let value = this.internalBuffer.readInt8(this.readPos); |
|||
this.readPos += 1; |
|||
return value; |
|||
} |
|||
|
|||
readUInt16(): number |
|||
{ |
|||
let value = this.littleEndian ? this.internalBuffer.readUInt16LE(this.readPos) : this.internalBuffer.readUInt16BE(this.readPos); |
|||
this.readPos += 2; |
|||
return value; |
|||
} |
|||
|
|||
readUInt32(): number |
|||
{ |
|||
let value = this.littleEndian ? this.internalBuffer.readUInt32LE(this.readPos) : this.internalBuffer.readUInt32BE(this.readPos); |
|||
this.readPos += 4; |
|||
return value; |
|||
} |
|||
|
|||
readBytes(): Buffer |
|||
{ |
|||
let length = this.readUInt32() |
|||
let sub = this.internalBuffer.subarray(this.readPos, this.readPos+=length); |
|||
return sub; |
|||
} |
|||
|
|||
readNadeoString(): NadeoStringResult |
|||
{ |
|||
let length = this.readUInt32() |
|||
if(length >= 0xFFFF) |
|||
{ |
|||
return {read:-1, str:""}; |
|||
} |
|||
|
|||
if (length == 0) |
|||
{ |
|||
return {read:0, str:""}; |
|||
} |
|||
|
|||
let outString = this.readString(length); |
|||
return {read:outString.length, str:outString}; |
|||
} |
|||
} |
|||
|
|||
module.exports = {Advancablebuffer, NadeoStringResult}; |
|||
Loading…
Reference in new issue