Skip to content

Commit 1c30196

Browse files
committed
fix: removal of name history API causes empty data file
1 parent f61f8b7 commit 1c30196

File tree

5 files changed

+66
-19
lines changed

5 files changed

+66
-19
lines changed

src/helper.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ export async function download (apiPath: string, dest: string): Promise<void> {
2323
}
2424

2525
export function writeJSON (dest: string, data: never): void {
26-
fs.writeFile(dest, JSON.stringify(data), (err) => {
26+
fs.outputFile(dest, JSON.stringify(data), (err) => {
2727
if (err) {
28-
logger.WriteJSON.error('CREATE', dest, err)
28+
logger.WriteJSON.error('CREATE', dest, err.toString())
2929
} else {
3030
logger.WriteJSON.info('CREATE', dest)
3131
}

src/index.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,14 @@ void async function main () {
4141
const prompt = await confirm('Do you want to clean the output folder?')
4242
if (prompt) {
4343
try {
44-
fs.emptyDirSync(outputDir)
44+
// Clean output dir
45+
for (const f of fs.readdirSync(outputDir)) {
46+
// ...but keep players.json as we need the name history in it
47+
// This file will be re-generated anyway
48+
if (f !== 'players.json') {
49+
fs.removeSync(path.join(outputDir, f))
50+
}
51+
}
4552
} catch (err) {
4653
throw new Error(err)
4754
}

src/utils.ts

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ import {defaultSkin, delay, download, mergeStats, writeJSON} from './helper'
1111
import * as logger from './logger'
1212

1313
const config = loadConfig()
14+
const outputDir = config.resolve(config.render.output)
15+
const playersPath = path.join(outputDir, 'players.json')
16+
const oldPlayers: NSPlayerInfoData[] | null = fs.existsSync(playersPath) ? fs.readJsonSync(playersPath) : null
1417

1518
export default class Utils {
1619
apiLimited: boolean
@@ -111,11 +114,10 @@ export default class Utils {
111114
}
112115
logger.PlayerData.info('READ', datafile)
113116
const uuidShort = uuid.replace(/-/g, '')
114-
let history
115-
try {
116-
history = await this.getNameHistory(uuidShort)
117-
} catch (error) {
118-
return reject()
117+
let history = oldPlayers?.find(p => p.uuid === uuidShort)?.names ?? null
118+
if (!history) {
119+
const name = await this.getCurrentName(uuid)
120+
history = name ? [{name, detectedAt: Date.now()}] : null
119121
}
120122
if (history && history[0]) {
121123
let lived: number | undefined
@@ -169,19 +171,15 @@ export default class Utils {
169171
}
170172
}
171173

172-
async getNameHistory (uuid: LongUuid): Promise<McNameHistory | null> {
173-
const apiNameHistory = `https://api.mojang.com/user/profiles/${uuid}/names`
174-
let history
174+
async getCurrentName (uuid: LongUuid): Promise<string | null> {
175+
const apiProfile = `https://sessionserver.mojang.com/session/minecraft/profile/${uuid}`
176+
let profile
175177
try {
176-
history = await this.getMojangAPI<McNameHistory>(apiNameHistory)
178+
profile = await this.getMojangAPI<McPlayerProfile | ''>(apiProfile)
179+
return profile === '' ? null : profile.name
177180
} catch (err) {
178181
return null
179182
}
180-
if (!history) return null
181-
// The order of the response data from Mojang API is uncertain,
182-
// so manually sort it (to descending order) for making sure.
183-
history.sort((a, b) => (b.changedToAt || 0) - (a.changedToAt || 0))
184-
return history
185183
}
186184

187185
async getMojangAPI <T> (apiPath: string): Promise<T> {
@@ -239,11 +237,17 @@ export default class Utils {
239237
}
240238

241239
async createPlayerData (uuid: LongUuid, banned = false): Promise<NSPlayerStatsJson> {
242-
const playerpath = path.join(config.get<string>('render.output'), uuid.replace(/-/g, ''))
240+
const uuidShort = uuid.replace(/-/g, '')
241+
const playerpath = path.join(config.get<string>('render.output'), uuidShort)
243242
let data
244243
try {
245244
if (fs.existsSync(path.join(playerpath, 'stats.json'))) {
246245
data = JSON.parse(fs.readFileSync(path.join(playerpath, 'stats.json'), 'utf-8'))
246+
// Name data is currently updated only in players.json
247+
// so we need to duplicate it into stats.json
248+
const playerInfo = oldPlayers!.find(p => p.uuid === uuidShort)!
249+
data.data.playername = playerInfo.playername
250+
data.data.names = playerInfo.names
247251
} else {
248252
data = await this.getPlayerTotalData(uuid)
249253
}

types/minecraft.d.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,34 @@ interface McNameHistoryRecord {
3333
}
3434

3535
type McNameHistory = McNameHistoryRecord[]
36+
37+
interface McPlayerProfile {
38+
id: ShortUuid
39+
name: PlayerName
40+
legacy?: true
41+
properties: [
42+
{
43+
name: 'textures'
44+
value: string
45+
signature?: string
46+
}
47+
]
48+
}
49+
50+
interface McPlayerTextures {
51+
timestamp: UTCTimestamp
52+
profileId: ShortUuid
53+
profileName: PlayerName
54+
signatureRequired?: true
55+
textures: {
56+
SKIN?: {
57+
url: string
58+
metadata?: {
59+
model: 'slim'
60+
}
61+
}
62+
CAPE?: {
63+
url: string
64+
}
65+
}
66+
}

types/nyaa-stats.d.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@ interface NSPlayerStatsJson {
4545
data: NSPlayerInfoData
4646
}
4747

48+
interface NSPlayerNameHistoryRecord {
49+
name: PlayerName
50+
detectedAt: UTCTimestamp
51+
}
52+
4853
interface NSPlayerInfoData {
4954
uuid: LongUuid
5055
uuid_short: ShortUuid
@@ -53,7 +58,7 @@ interface NSPlayerInfoData {
5358
time_last?: UTCTimestamp
5459
time_lived?: number
5560
playername: PlayerName
56-
names: McNameHistory
61+
names: Array<McNameHistoryRecord | NSPlayerNameHistoryRecord>
5762
banned?: boolean
5863
lastUpdate: UTCTimestamp
5964
}

0 commit comments

Comments
 (0)