mirror of
https://github.com/djhackersdev/minime.git
synced 2026-08-28 13:34:03 -05:00
Persist earned bonus tickets
This commit is contained in:
@@ -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),
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
10
src/idz/model/tickets.ts
Normal 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;
|
||||
};
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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>;
|
||||
|
||||
@@ -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
42
src/idz/world/tickets.ts
Normal 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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user