// ==UserScript==
// @name SO2文本替换
// @namespace https://game.granbluefantasy.jp/
// @version 0.2
// @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版省电模式'],
['メニュー', '菜单'],
['ポップアップ', '弹出消息'],
['サウンド(要対応ブラウザ)', '声音(必需浏览器)'],
['プライバシー', '隐私'],
['いにしえの呪文をとなえよ。さすれば門は開かれるであろう。', '赞美牧师的咒语。然后门将被打开。'],
['他にもどこかでなにかが起こるかも', '某处会发生某些事情……'],
['同作業をもう一度', '同作業再次進行'],
['なにも販売していません', '我沒有在賣任何東西'],
['配方はありません', '沒有配方'],
['なにも見つかりませんでした…', '什麼都沒發現......'],
['なにも作業していません', '沒有正在進行的作業。'],
['ゲームサーバーへ接続中', '連接到遊戲服務器'],
['オーナーが入店しました', '店主已進入'],
['コンパクト', '緊湊'],
['お手伝い妖精呼び出し', '援助仙女召喚'],
['呼び出し', '召喚'],
['ゲームデータ更新を非通知', '遊戲數據更新不通知'],
['カスタマイズ', '定制'],
['既に出店している方はこちら', '如果您已經在這裡開店'],
['まだ店面を持っていない方はこちら', '如果您還沒有店面'],
['ボタンサイズ', '按鈕大小'],
['ボタン', '按鈕'],
['ヘッダ', '頂部'],
['ワイド', '寬廣'],
['タップ', '點按'],
['リスト', '列表'],
['なし', '無'],
['ゲームデータの準備中だよ', '游戏数据准备中'],
['続きをプレイする', '继续游玩'],
['Google账户でプレイ', '用Google账户玩'],
['Twitter账户でプレイ', '用Twitter账户玩'],
['Yahoo! JAPAN IDでプレイ', '用Yahoo! JAPAN ID玩'],
['新しく始める', '新的开始'],
['とにかくプレイしてみる', '无论如何先试玩一下'],
['ちょっと待ってね', '请稍等片刻'],
['なにも輸送していません', '沒有東西正在輸送'],
['実行する', '執行'],
['閉じる', '关闭'],
['範囲内のみ', '仅在范围内'],
['图像スタイル', '图像样式'],
['ロイヤリティ', '专利费'],
['経験値バーパーセント表示', '経験値百分比显示'],
['夜はこない', '无夜晚效果'],
['ずっとBGM', 'BGM后台播放'],
['スタイル', '风格'],
['オススメの進め方', '推荐的游戏进行方式'],
['へようこそ', '欢迎您'],
['「作業」の手順を覚える', '学习「作業」的流程'],
['「販売」の手順を覚える', '学习「販売」的流程'],
['「市场」の手順を覚える', '学习「市场」的流程'],
['困った時は', '遇到问题时'],
['で先輩プレイヤーに聞く', '的国际友人和群里的大佬会热心帮助你,详询Q群422877047'],
['それぞれの手順は', '请务必记住'],
['で覚えてね', '的每个步骤'],
['読まずに直感で進めてもいいよ', '你完全可以在没有阅读的情况下继续靠直觉前进'],
['全部無視して好きにやっちゃってもOK', '甚至可能忽略了所有这些并且做得一样好'],
['とりあえず「店面」と「市场」でなんとかなるから', '目前,我将管理“店面”和“市场”。'],
['急いで進めたい時は', '当着急前进时,找到旁边的'],
['アイコン', '图标'],
['を押すと', '按一下,用'],
['を使って短縮できるよ', '以缩短时间'],
['じわじわと面白くなっていくからのんびり進めてみてね!(4~5日目くらいから面白くなる人が多いみたい)', '游戏会逐渐变得有趣,所以让我们继续前进! (似乎有很多人从第4天到第5天感兴趣)'],
['詳しいことはここにも書かれているよ', '进一步的细节写在这里'],
['初心者向け主页', '初心者向主页'],
['今見ているこの画面は初心者向けに簡素化された主页画面です', '我们现在看到的这个页面是一个面向新手的简化主页'],
['資金が1,000G以上になると通常の主页画面に変わります', '当资金达到1,000 G或更高时,它将变为正常的主页面'],
])
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
}
})();