Persist earned bonus tickets

This commit is contained in:
Tau
2019-04-16 15:38:12 -04:00
parent bef0cc7fc9
commit 81cb172571
12 changed files with 103 additions and 1 deletions

View File

@@ -35,6 +35,15 @@ export function saveProfile(buf: Buffer): SaveProfileRequest {
coursePlays.set(i, buf.readUInt16LE(0x04c0 + 2 * i));
}
const freeCar = {
validFrom: buf.readUInt32LE(0x0138),
};
const freeContinue = {
validFrom: buf.readUInt32LE(0x0038),
validTo: buf.readUInt32LE(0x003c),
};
return {
type: "save_profile_req",
profileId: buf.readUInt32LE(0x0004) as Id<Profile>,
@@ -63,6 +72,21 @@ export function saveProfile(buf: Buffer): SaveProfileRequest {
music: buf.readUInt16LE(0x0140),
lastMileageReward: buf.readUInt32LE(0x013c),
},
tickets: {
freeCar:
freeCar.validFrom !== 0
? {
validFrom: new Date(freeCar.validFrom * 1000),
}
: undefined,
freeContinue:
freeContinue.validFrom !== 0 && freeContinue.validTo !== 0
? {
validFrom: new Date(freeContinue.validFrom * 1000),
validTo: new Date(freeContinue.validTo * 1000),
}
: undefined,
},
settings: {
music: buf.readUInt16LE(0x045a),
pack: buf.readUInt32LE(0x0034),

View File

@@ -54,6 +54,17 @@ export function loadProfile2(res: LoadProfileResponse2) {
buf.writeUInt16LE(playCount, 0x0460 + 2 * courseId);
}
const { freeCar, freeContinue } = res.tickets;
if (freeCar) {
buf.writeUInt32LE((freeCar.validFrom.getTime() / 1000) | 0, 0x01e4);
}
if (freeContinue) {
buf.writeUInt32LE((freeContinue.validFrom.getTime() / 1000) | 0, 0x03dc);
buf.writeUInt32LE((freeContinue.validTo.getTime() / 1000) | 0, 0x03e0);
}
buf.writeUInt16LE(0x0065, 0x0000);
buf.writeUInt8(res.unlocks.cup, 0x00b4);
buf.writeUInt16LE(res.unlocks.gauges, 0x00b8);

View File

@@ -4,7 +4,6 @@ import { Profile } from "../model/profile";
import { Settings } from "../model/settings";
import { Story } from "../model/story";
import { Team } from "../model/team";
import { TimeAttackScore } from "../model/timeAttack";
import { Unlocks } from "../model/unlocks";
import { CreateProfileRequest } from "../request/createProfile";
import { GenericResponse } from "../response/generic";
@@ -46,6 +45,7 @@ export async function createProfile(
w.settings().save(profile.id, settings),
w.story().save(profile.id, story),
w.unlocks().save(profile.id, unlocks),
w.tickets().save(profile.id, {}),
]);
return {

View File

@@ -20,6 +20,7 @@ export async function loadProfile(
const story = await w.story().load(profile.id);
const timeAttack = await w.timeAttack().loadAll(profile.id);
const unlocks = await w.unlocks().load(profile.id);
const tickets = await w.tickets().load(profile.id);
return {
type: "load_profile_v2_res",
@@ -41,5 +42,6 @@ export async function loadProfile(
carCount,
story,
unlocks,
tickets,
};
}

View File

@@ -30,6 +30,7 @@ export async function saveProfile(
w.titles().saveAll(req.profileId, req.titles),
w.unlocks().save(req.profileId, req.unlocks),
w.settings().save(req.profileId, req.settings),
w.tickets().save(req.profileId, req.tickets),
]);
return {

View File

@@ -6,5 +6,6 @@ export { Profile } from "./profile";
export { Settings } from "./settings";
export { Story } from "./story";
export { Team } from "./team";
export { Tickets } from "./tickets";
export { TimeAttackScore } from "./timeAttack";
export { Unlocks } from "./unlocks";

10
src/idz/model/tickets.ts Normal file
View File

@@ -0,0 +1,10 @@
export interface Tickets {
freeCar?: {
validFrom: Date;
// Valid To cannot be controlled, it is always 14 days after issue date.
};
freeContinue?: {
validFrom: Date;
validTo: Date;
};
}

View File

@@ -4,6 +4,7 @@ import { MissionState } from "../model/mission";
import { Profile } from "../model/profile";
import { Settings } from "../model/settings";
import { Story } from "../model/story";
import { Tickets } from "../model/tickets";
import { Unlocks } from "../model/unlocks";
export interface SaveProfileRequest {
@@ -22,5 +23,6 @@ export interface SaveProfileRequest {
car: Car;
story: Story;
unlocks: Unlocks;
tickets: Tickets;
settings: Settings;
}

View File

@@ -5,6 +5,7 @@ import { MissionState } from "../model/mission";
import { Profile } from "../model/profile";
import { Settings } from "../model/settings";
import { Story } from "../model/story";
import { Tickets } from "../model/tickets";
import { TimeAttackScore } from "../model/timeAttack";
import { Unlocks } from "../model/unlocks";
@@ -28,5 +29,6 @@ export interface LoadProfileResponse2 {
carCount: number;
story: Story;
unlocks: Unlocks;
tickets: Tickets;
// giga TODO
}

View File

@@ -84,6 +84,8 @@ export interface World {
// Also not a facet. w/e one step at a time.
story(): FacetRepository<Model.Story>;
tickets(): FacetRepository<Model.Tickets>;
timeAttack(): TimeAttackRepository;
titles(): FlagRepository<Model.TitleCode>;

View File

@@ -6,6 +6,7 @@ import { CarRepositoryImpl } from "./car";
import { CoursePlaysRepositoryImpl } from "./coursePlays";
import { World } from "./defs";
import { ProfileRepositoryImpl } from "./profile";
import { TicketsRepositoryImpl } from "./tickets";
import { TimeAttackRepositoryImpl } from "./timeAttack";
import * as Model from "../model";
@@ -49,6 +50,10 @@ class WorldImpl implements World {
return new FacetRepositoryImpl<Model.Story>(this._root, "story");
}
tickets() {
return new TicketsRepositoryImpl(this._root);
}
timeAttack() {
return new TimeAttackRepositoryImpl(this._root);
}

42
src/idz/world/tickets.ts Normal file
View File

@@ -0,0 +1,42 @@
import { loadJson, saveJson } from "./_util";
import { FacetRepository } from "./defs";
import { Tickets } from "../model/tickets";
import { Id, Profile } from "../model";
interface TicketsJson {
freeCar?: {
validFrom: string;
// Valid To cannot be controlled, it is always 14 days after issue date.
};
freeContinue?: {
validFrom: string;
validTo: string;
};
}
export class TicketsRepositoryImpl implements FacetRepository<Tickets> {
private readonly _path: string;
constructor(root: string) {
this._path = root + "/tickets.json";
}
async load(profileId: Id<Profile>): Promise<Tickets> {
const json: TicketsJson = await loadJson(this._path);
return {
freeCar: json.freeCar && {
validFrom: new Date(json.freeCar.validFrom),
},
freeContinue: json.freeContinue && {
validFrom: new Date(json.freeContinue.validFrom),
validTo: new Date(json.freeContinue.validTo),
},
};
}
save(profileId: Id<Profile>, tickets: Tickets): Promise<void> {
// Date objects stringify to ISO8601 so this does this right thing.
return saveJson(this._path, tickets);
}
}