artemis-ongeki-fix-clear-st.../index.ts
2024-05-29 03:12:35 +09:00

97 lines
2.4 KiB
TypeScript

import { readFile } from 'node:fs/promises';
import { createHash } from 'node:crypto';
import mysql, { RowDataPacket } from 'mysql2/promise';
import yaml from 'yaml';
interface ArtemisProfile extends RowDataPacket {
user: number
}
interface ArtemisBest extends RowDataPacket {
musicId: number,
level: number,
clearStatus: number
}
interface ArtemisPlaylog extends RowDataPacket {
clearStatus: number
}
const fetchArtemis = async (conn: mysql.Connection, userId: number) => {
const [ bestScores ] = await conn.query<ArtemisBest[]>(
`select
musicId,
level,
clearStatus
from ongeki_score_best
where user=?`,
[userId]
);
let n = 0;
for(const best of bestScores) {
if(best.clearStatus === 1) {
continue;
}
const [ playlogs ] = await conn.query<ArtemisPlaylog[]>(
`select
clearStatus
from ongeki_score_playlog
where user=? and musicId=? and level=?
order by clearStatus desc
limit 1`,
[userId, best.musicId, best.level]
);
if(playlogs.length > 0 && playlogs[0].clearStatus === 2) {
await conn.query(
`update ongeki_score_best
set clearStatus=1
where user=? and musicId=? and level=?`,
[userId, best.musicId, best.level]
);
n += 1;
}
}
console.log(`${userId}: ${n} rows affected`)
}
const main = async () => {
if(process.argv.length < 3) {
console.log(`Usage: ${process.argv[1]} <config/core.yaml>`);
return;
}
const f = await readFile(process.argv[2]);
const cfg = yaml.parse(f.toString());
const dbConfig = cfg['database'];
let password = dbConfig['password'];
if(dbConfig['sha2_password']) {
const hash = createHash('sha256');
password = hash.update(password).digest('hex');
}
const conn = await mysql.createConnection({
host: dbConfig['host'],
user: dbConfig['username'],
port: dbConfig['port'],
database: dbConfig['name'],
password,
charset: 'utf8mb4'
});
const [ profiles ] = await conn.query<ArtemisProfile[]>(
`select user
from ongeki_profile_data`
);
for(const profile of profiles) {
await fetchArtemis(conn, profile.user);
}
conn.end();
}
main();