idz: Fix loadTopTen

This commit is contained in:
BemaniWitch
2021-02-03 23:43:43 +00:00
committed by Tau
parent acbda4e6bd
commit b23e9af2ea
8 changed files with 50 additions and 4 deletions
+2 -2
View File
@@ -37,7 +37,7 @@ import {
loadTeamRanking4, loadTeamRanking4,
} from "./loadTeamRanking"; } from "./loadTeamRanking";
import { loadTopTen1 } from "./loadTopTen1"; import { loadTopTen1 } from "./loadTopTen1";
import { loadTopTen2 } from "./loadTopTen2"; import { loadTopTen2, loadTopTen3 } from "./loadTopTen2";
import { lockGarage1, lockGarage2 } from "./lockGarage"; import { lockGarage1, lockGarage2 } from "./lockGarage";
import { lockProfile1, lockProfile2 } from "./lockProfile"; import { lockProfile1, lockProfile2 } from "./lockProfile";
import { saveExpedition1, saveExpedition2 } from "./saveExpedition"; import { saveExpedition1, saveExpedition2 } from "./saveExpedition";
@@ -205,7 +205,7 @@ const funcList210: ReaderFn[] = [
loadTeam2, loadTeam2,
loadTeamRanking2, loadTeamRanking2,
loadTeamRanking4, loadTeamRanking4,
loadTopTen2, loadTopTen3,
lockGarage2, lockGarage2,
lockProfile2, lockProfile2,
lockProfileExtend2, lockProfileExtend2,
+1
View File
@@ -24,6 +24,7 @@ export function loadTopTen1(buf: Buffer): LoadTopTenRequest {
return { return {
type: "load_top_ten_req", type: "load_top_ten_req",
version: 1,
field_2: buf.readUInt16LE(0x0002), // Bitmask selector field_2: buf.readUInt16LE(0x0002), // Bitmask selector
selectors, selectors,
field_C4: buf.readUInt8(0x00c4), // Boolean, true if profile ID is set field_C4: buf.readUInt8(0x00c4), // Boolean, true if profile ID is set
+32
View File
@@ -24,6 +24,7 @@ export function loadTopTen2(buf: Buffer): LoadTopTenRequest {
return { return {
type: "load_top_ten_req", type: "load_top_ten_req",
version: 1,
field_2: buf.readUInt16LE(0x0002), // Bitmask selector field_2: buf.readUInt16LE(0x0002), // Bitmask selector
selectors, selectors,
field_C4: buf.readUInt8(0x00f4), // Boolean, true if profile ID is set field_C4: buf.readUInt8(0x00f4), // Boolean, true if profile ID is set
@@ -33,3 +34,34 @@ export function loadTopTen2(buf: Buffer): LoadTopTenRequest {
teamId: teamId !== 0xffffffff ? (teamId as ExtId<Team>) : undefined, teamId: teamId !== 0xffffffff ? (teamId as ExtId<Team>) : undefined,
}; };
} }
loadTopTen3.msgCode = 0x012c;
loadTopTen3.msgLen = 0x0110;
export function loadTopTen3(buf: Buffer): LoadTopTenRequest {
const selectors = new Array<LoadTopTenRequestSelector>();
for (let i = 0; i < 40; i++) {
selectors.push({
routeNo: (buf.readUInt16LE(0x0004 + 2 + 2 * i) >> 1) as RouteNo,
minTimestamp: new Date(
buf.readUInt32LE(0x0054 + 4 + 4 * i) * 1000 + 1000
),
});
}
const profileId = buf.readUInt32LE(0x00fc);
const teamId = buf.readUInt32LE(0x0100);
return {
type: "load_top_ten_req",
version: 2,
field_2: buf.readUInt16LE(0x0004), // Bitmask selector
selectors,
field_C4: buf.readUInt8(0x00f8), // Boolean, true if profile ID is set
field_C5: buf.readUInt8(0x00f9), // Always zero
field_C6: buf.readUInt16LE(0x00fa),
aimeId: profileId !== 0 ? (profileId as AimeId) : undefined,
teamId: teamId !== 0xffffffff ? (teamId as ExtId<Team>) : undefined,
};
}
+2 -1
View File
@@ -38,6 +38,7 @@ import { loadServerList } from "./loadServerList";
import { loadStocker1, loadStocker2 } from "./loadStocker"; import { loadStocker1, loadStocker2 } from "./loadStocker";
import { loadTeamRanking1, loadTeamRanking2 } from "./loadTeamRanking"; import { loadTeamRanking1, loadTeamRanking2 } from "./loadTeamRanking";
import { loadTopTen } from "./loadTopTen1"; import { loadTopTen } from "./loadTopTen1";
import { loadTopTen2 } from "./loadTopTen2";
import { saveExpedition1, saveExpedition2 } from "./saveExpedition"; import { saveExpedition1, saveExpedition2 } from "./saveExpedition";
import { saveGarage1, saveGarage2 } from "./saveGarage"; import { saveGarage1, saveGarage2 } from "./saveGarage";
import { saveNewCar1, saveNewCar2 } from "./saveNewCar"; import { saveNewCar1, saveNewCar2 } from "./saveNewCar";
@@ -347,7 +348,7 @@ function encode210(res: Response): Buffer {
return loadTeamRanking1(res); return loadTeamRanking1(res);
case "load_top_ten_res": case "load_top_ten_res":
return loadTopTen(res); return loadTopTen2(res);
case "lock_profile_extend_res": case "lock_profile_extend_res":
return lockProfileExtend1(res); return lockProfileExtend1(res);
+9 -1
View File
@@ -18,10 +18,18 @@ export async function loadTopTen(
} }
const { routeNo, minTimestamp } = selector; const { routeNo, minTimestamp } = selector;
const src = await w.timeAttack().loadTop(routeNo, minTimestamp, 10); var src = await w
.timeAttack()
.loadTop(req.version, routeNo, minTimestamp, 10);
// Hacky solution but force full reload per course if there's an updated time.
// Otherwise, the updated time will replace the top 1 record.
if (src.length === 0) { if (src.length === 0) {
continue; continue;
} else {
src = await w
.timeAttack()
.loadTop(req.version, routeNo, new Date(100), 10);
} }
const dest = new Array<LoadTopTenResponseRow>(); const dest = new Array<LoadTopTenResponseRow>();
+1
View File
@@ -143,6 +143,7 @@ export interface TopTenResult {
export interface TimeAttackRepository { export interface TimeAttackRepository {
loadTop( loadTop(
version: number,
routeNo: Model.RouteNo, routeNo: Model.RouteNo,
minTimestamp: Date, minTimestamp: Date,
limit: number limit: number
+1
View File
@@ -9,6 +9,7 @@ export interface LoadTopTenRequestSelector {
export interface LoadTopTenRequest { export interface LoadTopTenRequest {
type: "load_top_ten_req"; type: "load_top_ten_req";
version: number;
field_2: number; field_2: number;
selectors: LoadTopTenRequestSelector[]; selectors: LoadTopTenRequestSelector[];
field_C4: number; field_C4: number;
+2
View File
@@ -25,6 +25,7 @@ export class SqlTimeAttackRepository implements TimeAttackRepository {
constructor(private readonly _txn: Transaction) {} constructor(private readonly _txn: Transaction) {}
async loadTop( async loadTop(
version: number,
routeNo: RouteNo, routeNo: RouteNo,
minTimestamp: Date, minTimestamp: Date,
limit: number limit: number
@@ -54,6 +55,7 @@ export class SqlTimeAttackRepository implements TimeAttackRepository {
// case that we probably don't need to worry about. // case that we probably don't need to worry about.
.join("idz_team_member tm", { "ta.profile_id": "tm.id" }) .join("idz_team_member tm", { "ta.profile_id": "tm.id" })
.join("idz_team t", { "tm.team_id": "t.id" }) .join("idz_team t", { "tm.team_id": "t.id" })
.where("p.version", version)
.where("ta.route_no", routeNo) .where("ta.route_no", routeNo)
.where(sql.gt("ta.timestamp", minTimestamp)) .where(sql.gt("ta.timestamp", minTimestamp))
.orderBy(["ta.total_time asc", "ta.timestamp asc"]) .orderBy(["ta.total_time asc", "ta.timestamp asc"])