From 48959907298456379c8a89a2518b275680df6d3f Mon Sep 17 00:00:00 2001 From: AnthonyDuan Date: Sun, 18 Jan 2026 07:55:52 +0800 Subject: [PATCH] fix: Fix leaderboard freeze and AJAX submission issues - Fixed fetchData async/await to use proper Promise pattern - Added basedir prefix to API URLs - Fixed submitToLeaderboard to use XMLHttpRequest with CSRF token --- public/src/js/leaderboard_ui.js | 11 +++++------ public/src/js/scoresheet.js | 35 ++++++++++++++++++++++----------- 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/public/src/js/leaderboard_ui.js b/public/src/js/leaderboard_ui.js index 74e8003..d6a10e9 100644 --- a/public/src/js/leaderboard_ui.js +++ b/public/src/js/leaderboard_ui.js @@ -43,9 +43,8 @@ class LeaderboardUI { this.songSelect.leaderboardActive = false } - async fetchData(songId, difficulty) { - try { - const response = await loader.ajax(`api/leaderboard/get?song_id=${songId}&difficulty=${difficulty}`) + fetchData(songId, difficulty) { + loader.ajax(gameConfig.basedir + `api/leaderboard/get?song_id=${songId}&difficulty=${difficulty}`).then(response => { const data = JSON.parse(response) if (data.status === 'ok') { this.leaderboardData = data.leaderboard @@ -57,10 +56,10 @@ class LeaderboardUI { const viewHeight = this.height - this.headerHeight - this.padding * 2 this.maxScroll = Math.max(0, totalHeight - viewHeight) } - } catch (e) { - console.error(e) + }).catch(e => { + console.error("Leaderboard fetch error:", e) this.loading = false - } + }) } draw(ctx, winW, winH, pixelRatio) { diff --git a/public/src/js/scoresheet.js b/public/src/js/scoresheet.js index 967d020..dd34646 100644 --- a/public/src/js/scoresheet.js +++ b/public/src/js/scoresheet.js @@ -995,20 +995,31 @@ class Scoresheet { hash: song.hash } - loader.ajax("api/leaderboard/submit", request => { - request.open("POST", "api/leaderboard/submit") - request.setRequestHeader("Content-Type", "application/json") - request.send(JSON.stringify(body)) - }).then(response => { - var data = JSON.parse(response) - if (data.status === "ok" && data.new_record && data.rank) { - this.leaderboardResult = { - rank: data.rank + loader.getCsrfToken().then(token => { + var request = new XMLHttpRequest() + request.open("POST", gameConfig.basedir + "api/leaderboard/submit") + pageEvents.load(request).then(() => { + if (request.status === 200) { + try { + var data = JSON.parse(request.response) + if (data.status === "ok" && data.new_record && data.rank) { + this.leaderboardResult = { + rank: data.rank + } + assets.sounds["se_results_crown"].play() + } + } catch (e) { + console.error("Leaderboard response parse error:", e) + } } - assets.sounds["se_results_crown"].play() - } + }).catch(e => { + console.error("Leaderboard submit failed:", e) + }) + request.setRequestHeader("Content-Type", "application/json;charset=UTF-8") + request.setRequestHeader("X-CSRFToken", token) + request.send(JSON.stringify(body)) }).catch(e => { - console.error("Leaderboard submit failed", e) + console.error("Failed to get CSRF token:", e) }) }