// ==UserScript==
// @name SO2文本替换
// @namespace https://game.granbluefantasy.jp/
// @version 0.1
// @description 替换文本方式汉化UI,肯定有bug,我什么都不会做的
// @author 丘某
// @match https://so2.mutoys.com/
// @grant none
// ==/UserScript==
(function() {
'use strict';
const i18n = new Map([
['ホーム', '主页'],
['お店', '店面'],
['仕入れ','市场'],
['ポイント', '点数'],
['はじめに', '介绍'],
['お知らせ', '通知'],
['注文', '预定'],
['レシピ', '配方'],
['ステータス', '状态'],
['ランキング', '排行'],
['レポート', '报告'],
['预定レポ', '订单Repo'],
['ミュート', '黑名单'],
['イベント', '活动'],
['プレミアム', '赞助'],
['ヘルプ', '帮助'],
['アカウント', '账户'],
['ログアウト', '注销'],
['メモ', '备忘录'],
['チュートリアル', '教程'],
['バージョン', '版本'],
['ショップ', '店'],
['オーナー番号', '店主编号(id)'],
['キャッチコピー', '广告标语'],
['基本ステータス', '基本状态'],
['やりなおし劵', '重做劵'],
['キャンセル', '取消'],
['外部サイト', '外部网站'],
['クイックポーション', '快速药水'],
['明るさ切替', '亮暗主题切换'],
['再同期', '再同步'],
['道路に近いとお客さんが立ち寄りやすいよ', '当道路在附近时,客户很容易进入'],
['エメラルド街', 'エメラルド街-翡翠街'],
['ルビー街', 'ルビー街-红宝石街'],
['サファイア街', 'サファイア街-蓝宝石街'],
['アメジスト街', 'アメジスト街-紫水晶街'],
['ガーネット街', 'ガーネット街-石榴石街'],
['トパーズ街', 'トパーズ街-黄玉街'],
['トパーズ郊外', 'トパーズ郊外-黄玉郊外'],
['トパーズ村', 'トパーズ村-黄玉村'],
['パール街', 'パール街-珍珠街'],
['ブルー街', 'ブルー街-蓝街'],
['レッド街', 'レッド街-红街'],
['バトル街', 'バトル街-战斗街'],
['ミミ星人街', 'ミミ星人街-咪咪星人街'],
['アジト跡地', 'アジト跡地-藏身处'],
['メリー街', 'メリー街-玛丽街'],
['イメージ', '图像'],
['メッセージ', '消息'],
['マップ', '地图'],
['店面が増えるともっと楽しくなるよ!紹介してね!', '如果添加更多商店会更有趣!请介绍!'],
['ストーリーを選んでみんなに SOLD OUT 2 を紹介しよう!', '选择一个故事并向每个人介绍SOLD OUT 2!'],
['ストーリーを選ぶ', '选择一个故事'],
['PVもあるよ!', '还有PV!'],
['初心者向けの主页を表示する', '显示面向初学者的主页'],
['ホーム', '主页'],
['ベースキャンプ', 'ベースキャンプ(营地)'],
['アトリエ', 'アトリエ'],
['テナント', 'テナント'],
['ログハウス', 'ログハウス(木屋)'],
['ショップ', 'ショップ(店)'],
['ファクトリー', 'ファクトリー(工厂)'],
['マーケット', 'マーケット(超市)'],
['可能な限り演出を簡略化します(動作が遅い時にどうぞ)', '我们将尽可能简化演出(请在速度慢的时候使用)'],
['メインカラー切替', '主要颜色切换'],
['アクセントカラー切替', '强调色切换'],
['ボタン左右入替', '按钮左右交换'],
['テキストコピー可能', '文本可选择'],
['アプリ版省エネ', 'APP版省电模式'],
['メニュー', '菜单'],
['ポップアップ', '弹出消息'],
['サウンド(要対応ブラウザ)', '声音(必需浏览器)'],
['プライバシー', '隐私'],
['いにしえの呪文をとなえよ。さすれば門は開かれるであろう。', '赞美牧师的咒语。然后门将被打开。'],
['他にもどこかでなにかが起こるかも', '某处会发生某些事情……'],
])
replaceText(document.body)
// |
// ₘₙⁿ
// ▏n
// █▏ 、⺍ 所以,不要停下來啊(指加入词条
// █▏ ⺰ʷʷィ
// █◣▄██◣
// ◥██████▋
// ◥████ █▎
// ███▉ █▎
// ◢████◣⌠ₘ℩
// ██◥█◣\≫
// ██ ◥█◣
// █▉ █▊
// █▊ █▊
// █▊ █▋
// █▏ █▙
// █
const bodyObserver = new MutationObserver(mutations => {
mutations.forEach(mutation => {
mutation.addedNodes.forEach(addedNode => replaceText(addedNode))
})
})
bodyObserver.observe(document.body, { childList: true, subtree: true })
function replaceText(node) {
nodeForEach(node).forEach(htmlnode => {
i18n.forEach((value, index) => {
// includes可直接使用 === 以提高匹配精度
const textReg = new RegExp(index, 'g')
if (htmlnode instanceof Text && htmlnode.nodeValue.includes(index))
htmlnode.nodeValue = htmlnode.nodeValue.replace(textReg, value)
else if (htmlnode instanceof HTMLInputElement && htmlnode.value.includes(index))
htmlnode.value = htmlnode.value.replace(textReg, value)
})
})
}
function nodeForEach(node) {
const list = []
if (node.childNodes.length === 0) list.push(node)
else {
node.childNodes.forEach(child => {
if (child.childNodes.length === 0) list.push(child)
else list.push(...nodeForEach(child))
})
}
return list
}
})();