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