aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPinapelz <yukais@pinapelz.com>2025-07-07 22:15:43 -0700
committerPinapelz <yukais@pinapelz.com>2025-07-07 22:15:43 -0700
commit5aa678c03a3efb14f8d25b8518793a7bc9e45ba4 (patch)
tree4bdee8859d9985979a1e377c2bf979edb30ae39e
parentcde7caf247c0fe7a5f833c33532b29401d0624d7 (diff)
fix: tachi_to_tachi chuni table session structure
-rw-r--r--tachi_to_tachi/tachi_universal_export.user.js100
1 files changed, 58 insertions, 42 deletions
diff --git a/tachi_to_tachi/tachi_universal_export.user.js b/tachi_to_tachi/tachi_universal_export.user.js
index 0061638..e239037 100644
--- a/tachi_to_tachi/tachi_universal_export.user.js
+++ b/tachi_to_tachi/tachi_universal_export.user.js
@@ -160,79 +160,100 @@
// Chunithm parser
function parseChunithmScores() {
- const rows = document.querySelectorAll("table.table tbody tr");
+ const rows = document.querySelectorAll("table tbody tr");
const difficultyMap = {
- E: "Expert",
- A: "Advanced",
- B: "Basic",
- M: "Master"
+ "BASIC": "Basic",
+ "ADVANCED": "Advanced",
+ "EXPERT": "Expert",
+ "MASTER": "Master"
};
const scores = [];
- for (let i = 0; i < rows.length; i += 3) {
+ for (let i = 0; i < rows.length; i++) {
const row = rows[i];
- if (!row) continue;
+ if (!row || row.classList.contains("expandable-pseudo-row") || row.classList.contains("fake-row")) continue;
const cells = row.querySelectorAll("td");
- if (cells.length < 11) continue;
+ if (cells.length < 8) continue;
- let difficulty = cells[1].innerText.trim().replace(/\n/, " ").split(" ")[0];
- if (difficulty.length === 1) {
- difficulty = difficultyMap[difficulty] || difficulty;
- }
+ // Chart info is in first column (index 0)
+ let difficultyText = cells[0].querySelector("div.d-none.d-lg-block")?.textContent.trim() ||
+ cells[0].querySelector("div.d-lg-none")?.textContent.trim() || "";
+ let difficulty = difficultyText.split(/\s+/)[0].toUpperCase();
- const songAnchor = cells[3].querySelector("a");
- const title = songAnchor?.childNodes[0]?.textContent.trim() || "";
- const artist = songAnchor?.querySelector("small")?.textContent.trim() || "";
+ // Map single letter difficulties
+ if (difficulty === "B") difficulty = "BASIC";
+ else if (difficulty === "A") difficulty = "ADVANCED";
+ else if (difficulty === "E") difficulty = "EXPERT";
+ else if (difficulty === "M") difficulty = "MASTER";
- const scoreRank = cells[5].querySelector("strong")?.innerText.trim() || "";
- const scoreValue = parseInt(
- cells[5].innerText.replace(scoreRank, "").trim().replace(/,/g, "")
- );
+ difficulty = difficultyMap[difficulty] || difficulty;
- const judgementText = cells[6].innerText.trim();
- const parts = judgementText.split("-").map((x) => parseInt(x.trim()));
- const [jcrit, justice, attack, miss] = parts;
+ // Song info is in third column (index 2)
+ const songAnchor = cells[2].querySelector("a");
+ if (!songAnchor) continue;
- const fastSlowMatch = judgementText.match(/\(F:(\d+)\s+S:(\d+)\)/);
- const fast = fastSlowMatch ? parseInt(fastSlowMatch[1]) : undefined;
- const slow = fastSlowMatch ? parseInt(fastSlowMatch[2]) : undefined;
+ const [titleHtml, artistHtml] = songAnchor.innerHTML.split("<br>");
+ const temp = document.createElement("div");
+ temp.innerHTML = titleHtml;
+ const title = temp.textContent.trim();
+ temp.innerHTML = artistHtml || "";
+ const artist = temp.textContent.trim();
- const lamp = cells[7].innerText.trim();
+ // Score info is in fourth column (index 3)
+ const scoreText = cells[3].innerText.trim().split("\n").pop().replace(/,/g, "");
+ const scoreValue = parseInt(scoreText, 10);
+ if (isNaN(scoreValue)) continue;
+
+ // Judgements are in fifth column (index 4)
+ const judgementSpans = cells[4].querySelectorAll("span");
+ let jcrit = 0, justice = 0, attack = 0, miss = 0;
+ if (judgementSpans.length >= 4) {
+ jcrit = parseInt(judgementSpans[0].textContent) || 0;
+ justice = parseInt(judgementSpans[1].textContent) || 0;
+ attack = parseInt(judgementSpans[2].textContent) || 0;
+ miss = parseInt(judgementSpans[3].textContent) || 0;
+ }
+
+ // Lamp is in sixth column (index 5)
+ const lampText = cells[5].innerText.trim();
let clearLamp = "FAILED";
let noteLamp = "NONE";
- if (lamp.includes("FULL COMBO")) {
+ if (lampText.includes("FULL COMBO")) {
noteLamp = "FULL COMBO";
clearLamp = "CLEAR";
}
- if (lamp.includes("CLEAR")) {
+ if (lampText.includes("CLEAR")) {
clearLamp = "CLEAR";
}
- if (lamp.includes("ALL JUSTICE")) {
+ if (lampText.includes("ALL JUSTICE")) {
noteLamp = "ALL JUSTICE";
clearLamp = "CLEAR";
}
- if (lamp.includes("ALL JUSTICE CRITICAL")) {
+ if (lampText.includes("ALL JUSTICE CRITICAL")) {
noteLamp = "ALL JUSTICE CRITICAL";
clearLamp = "CLEAR";
}
- if (lamp.includes("HARD")) {
+ if (lampText.includes("HARD")) {
clearLamp = "HARD";
}
- if (lamp.includes("BRAVE")) {
+ if (lampText.includes("BRAVE")) {
clearLamp = "BRAVE";
}
- if (lamp.includes("ABSOLUTE")) {
+ if (lampText.includes("ABSOLUTE")) {
clearLamp = "ABSOLUTE";
}
- if (lamp.includes("CATASTROPHY")) {
+ if (lampText.includes("CATASTROPHY")) {
clearLamp = "CATASTROPHY";
}
- const timestampText = cells[10].innerText.trim().split("\n");
- const timestampString = timestampText[1]?.trim() || "";
- const timeAchieved = timestampString ? new Date(timestampString).getTime() : 0;
+ // Timestamp is in eighth column (index 7)
+ let timeAchieved = null;
+ const smallTags = cells[7].querySelectorAll("small");
+ if (smallTags.length > 0) {
+ timeAchieved = toUnixMillis(smallTags[0].textContent.trim());
+ }
const score = {
score: scoreValue,
@@ -251,11 +272,6 @@
timeAchieved
};
- if (fast !== undefined && slow !== undefined) {
- score.judgements.fast = fast;
- score.judgements.slow = slow;
- }
-
scores.push(score);
}
send patches to the email below
yukais@pinapelz.com
include the subject [PATCH repo_name]
pinapelz.com
homepage