SO2文本替换

替换文本方式汉化UI,肯定有bug,我什么都不会做的

目前為 2019-01-10 提交的版本,檢視 最新版本

// ==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
    }
})();