idz: Fix loadTopTen
This commit is contained in:
@@ -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,
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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>();
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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"])
|
||||||
|
|||||||
Reference in New Issue
Block a user