[BMS] LR2IRを拡張するTampermonkeyスクリプトを作りました [LR2, LR2IR-Helper, Tampermonkey]
背景
当スクリプトは以下を参考に作ったTampermonkey用スクリプトです。現在、ribbit.xyzが鯖落ちしており、譜面ビューアへのリンクも有志のミラーサイトにする必要がありました。
機能
bmsid, MD5, 譜面ビューアへのリンクをページ上部に表示するようにします。
MD5を含むURLでのアクセス(LR2本体や難易度表からのアクセス)の場合高速に動きます。外部へこのbmsidのMD5を問い合わせる必要がないからです。
bmsidで曲ページに来ている場合、外部にMD5の値を問い合わせる必要があるため読み込み中…と出てきます。MD5が不明な譜面の場合には譜面へのリンクは得られません。2024/8くらいまでの譜面ならbmsidとmd5のマッピングができていますが、今後新規に増えていく譜面はbmsidでのアクセスだと変換できません。
導入方法
まずTampermonkey拡張機能を導入してください。ChromeやChrome系であるブラウザ(Edge, Vivaldi)なら使うことができます。この拡張機能は、ユーザーが作ったスクリプトをブラウザで実行することができるというものです。
以下のスクリプトをダウンロードするか、コピペして導入してください。
// ==UserScript==
// @name LR2IR-Helper
// @namespace
// @version 2024-09-05
// @description これ(https://github.com/ladymade-star/LR2IR-Helper)を参考にBMS Score Viewerのミラーサイトにリンクするように変更
// @author マンハッタンカフェ
// @match http://www.dream-pro.info/~lavalse/LR2IR/search.cgi*
// @icon
// @grant none
// ==/UserScript==
(function() {
'use strict';
// 曲ページ「更新履歴」リンクのGETパラメータからbmsidを取得
let bmsid;
const a = document.getElementsByTagName("a");
for (let i = 0; i < a.length; i++) {
if (a[i].innerText == "更新履歴") {
bmsid = new URL(a[i].href).searchParams.get('bmsid');
}
}
// 現在のウィンドウのGETパラメータを取得
const params = new URL(window.location.href).searchParams;
let bmsmd5 = params.get('bmsmd5');
//bmsidかbmsmd5が取得できている場合は曲ページと判定
if (bmsid || bmsmd5) {
// LERIR-Helperの<H3>見出しを作る
const h3_element = document.createElement('h3');
h3_element.textContent = 'LR2IR-Helper';
// テーブルを作る
const table_element = document.createElement("table");
// bmsid
const bmsid_tr_element = document.createElement("tr");
const bmsid_th_element = document.createElement("th");
bmsid_th_element.textContent = "bmsid";
bmsid_th_element.width = "15%";
const bmsid_td_element = document.createElement("td");
bmsid_td_element.id = "bmsid_td";
const bmsid_a_element = document.createElement("a");
bmsid_a_element.href = "http://www.dream-pro.info/~lavalse/LR2IR/search.cgi?mode=ranking&bmsid=" + bmsid;
bmsid_a_element.textContent = bmsid;
bmsid_td_element.appendChild(bmsid_a_element);
bmsid_tr_element.appendChild(bmsid_th_element);
bmsid_tr_element.appendChild(bmsid_td_element);
table_element.appendChild(bmsid_tr_element);
// bmsmd5
const bmsmd5_tr_element = document.createElement("tr");
const bmsmd5_th_element = document.createElement("th");
bmsmd5_th_element.textContent = "bmsmd5";
bmsmd5_th_element.width = "15%";
const bmsmd5_td_element = document.createElement("td");
const bmsmd5_a_element = document.createElement("a");
bmsmd5_td_element.id = "bmsmd5_td";
bmsmd5_td_element.appendChild(bmsmd5_a_element);
bmsmd5_tr_element.appendChild(bmsmd5_th_element);
bmsmd5_tr_element.appendChild(bmsmd5_td_element);
table_element.appendChild(bmsmd5_tr_element);
// BMS Score Viewer
const viewer_tr_element = document.createElement("tr");
const viewer_th_element = document.createElement("th");
viewer_th_element.textContent = "BMS Score Viewer";
viewer_th_element.width = "15%";
const viewer_td_element = document.createElement("td");
const viewer_a_element = document.createElement("a");
viewer_td_element.id = "viewer_td";
viewer_td_element.appendChild(viewer_a_element);
viewer_tr_element.appendChild(viewer_th_element);
viewer_tr_element.appendChild(viewer_td_element);
table_element.appendChild(viewer_tr_element);
const h3 = document.querySelectorAll("h3");
// 見出しとテーブルを追加、LR2IRに登録されているかどうかで分岐
if (!document.querySelectorAll("h3").length){
// 「この曲は登録されていません。」の場合
document.getElementById("search").after(table_element)
document.getElementById("search").after(h3_element)
} else {
// 登録されている場合
h3[0].before(h3_element);
h3[0].before(table_element);
}
// GETパラメータの状態で分岐
if (bmsmd5) {
// LR2から飛んできているなど、GETでパラメータbmsmd5がセットされている場合
// bmsmd5
bmsmd5_a_element.href = "http://www.dream-pro.info/~lavalse/LR2IR/search.cgi?mode=ranking&bmsmd5=" + bmsmd5;
bmsmd5_a_element.textContent = bmsmd5;
// BMS Score Viewer
viewer_a_element.href = "https://bms-score-viewer.pages.dev/view?md5=" + bmsmd5;
viewer_a_element.textContent = "https://bms-score-viewer.pages.dev/view?md5=" + bmsmd5;
} else {
// bmsmd5がセットされていない場合(=bmsidで曲ページに来ている)
bmsmd5_a_element.textContent = "読み込み中...";
viewer_a_element.textContent = "読み込み中...";
(async() => {
const url = "https://script.google.com/macros/s/AKfycby-nDrmsJ70lmA8oNf9Yw1nwwto-w6nThdiu90Tm7VbX7im7xqCb1_WyL5e6Jk_V2VhSA/exec?method=getmd5&bmsid=" + bmsid;
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`レスポンスステータス: ${response.status}`);
}
bmsmd5 = await response.text();
// bmsmd5
bmsmd5_a_element.href = "http://www.dream-pro.info/~lavalse/LR2IR/search.cgi?mode=ranking&bmsmd5=" + bmsmd5;
bmsmd5_a_element.textContent = bmsmd5;
// BMS Score Viewer
viewer_a_element.href = "https://bms-score-viewer.pages.dev/view?md5=" + bmsmd5;
viewer_a_element.textContent = "https://bms-score-viewer.pages.dev/view?md5=" + bmsmd5;
} catch (error) {
console.error(error.message);
}
})();
}
}
})();
詳細な導入方法
まず、ダッシュボードを開く
つぎに、ダッシュボード画面へダウンロードした「LR2IR-Helper-2024-09-05.user.js」をドラッグアンドドロップする
「インストール」ボタンを押せばOK
おまけ
bmsid-md5のマッピング情報スプシ
上記スプシのGAS(bmsidでmd5を検索してreturn)
function test() {
const sheetId = "1RCrvKGHAkIfsAx5PV7-2W0d080DBUMwPvahmmL48T68"; // スプレッドシートのIDを指定
const sheetName = "data"; // シート名を指定
Logger.log(getMd5ByBmsId(sheetId, sheetName, 307669));
Logger.log(getMd5ByBmsId(sheetId, sheetName, 148141));
Logger.log(getMd5ByBmsId(sheetId, sheetName, 0));
}
function doGet(e) {
// シートのIDと名前を指定
const sheetId = "1RCrvKGHAkIfsAx5PV7-2W0d080DBUMwPvahmmL48T68"; // スプレッドシートのIDを指定
const sheetName = "data"; // シート名を指定
// GETパラメータを取得
const method = e.parameter.method;
const bmsid = e.parameter.bmsid;
switch (method) {
case 'getmd5':
// bmsidがnullまたはundefinedの場合は「illegal access」を返す
if (!bmsid) {
return ContentService.createTextOutput("illegal access");
}
// bmsidに対応するmd5を取得
const md5 = getMd5ByBmsId(sheetId, sheetName, bmsid);
// レスポンスをTEXT形式で返す
return ContentService.createTextOutput(md5);
default:
// 未対応のmethodの場合「illegal access」を返す
return ContentService.createTextOutput("illegal access");
}
}
function getMd5ByBmsId(sheetId, sheetName, bmsid) {
// スプレッドシートをIDで取得
const spreadsheet = SpreadsheetApp.openById(sheetId);
// シートを名前で取得
const sheet = spreadsheet.getSheetByName(sheetName);
// A列(bmsid列)を範囲として取得
const range = sheet.getRange("A:A");
// TextFinderを使ってbmsidを完全一致で検索
const textFinder = range.createTextFinder(bmsid).matchEntireCell(true);
const foundCell = textFinder.findNext();
// bmsidが見つかった場合、対応するmd5を返す
if (foundCell) {
const row = foundCell.getRow();
return sheet.getRange(row, 2).getValue(); // B列(md5列)を返す
}
// bmsidが見つからない場合
return "not found";
}