自作ユーザースクリプトで定期ゲーを自分好みに

この記事は定期ゲ・樅 Advent Calendar 2020 23日目の記事です。

イントロダクション

はじめましての方ははじめまして。そうでない方はお久しぶりです。去年はNode.jsでの定期ゲーの作り方記事を書かせていただきました。もしよろしければそちらも是非よろしくお願いします。

今回の記事はググりながらならjQueryぐらいはぎりぎり……書けるかな……ぐらいの人を対象にしています。

定期ゲーをプレイしていて、もうちょっとここがこうだったら……と思うことはないでしょうか? 例えば「色が見づらいから変えてほしい」「チャットに今書いている文字数がどれぐらいか分かるようにしてほしい」「投稿したときにどういう見た目になるかプレビューがほしい」etcetc...

そういうとき運営にお問い合わせ等から要望を出すのも一つの方法ですが、自分でさくっとユーザースクリプトを書いてサイトをちょっぴり変更するという手もあります。今回の記事はその方法の解説になります。

なお以降の解説はChromeで進めていきますが、Firefoxでもほぼ同様の手順で再現可能と思われます。

拡張機能のインストール&スクリプトの管理

まずはそのために必要な拡張機能をブラウザにインストールしていきましょう。Chrome用のTampermonkeyは以下から追加できます。(Firefoxは似たような拡張機能にGreasemonkeyというものがあるのでそちらを利用します。URLはこちら

正常に追加されていればChromeのウィンドウ右上のパズルピースのようなアイコンで開けるメニュー内にTampermonkeyの項目が追加されているはずです。そのままTampermonkeyをクリックで選択してください。

スクリーンショット (145)

するとTampermonkeyのメニューが開くので、試しにそのまま「新規スクリプトを追加…」を選択してみましょう。以下のような画面が新しいタブで開くはずです。

スクリーンショット (147)

ここにコードを書き込むだけでサイトを改造できてしまいます。試しに「http://*/*」となっている箇所を「https://www.google.com/*」に、「// Your code here...」となっている箇所を「alert('Hello, world!');」と書き換えてみましょう。書き換えたらファイル>保存あるいはCtrl+Sでユーザースクリプトを保存します。

Greasemonkeyは以下のコードを入力してください。

// ==UserScript==
// @name     新しいスクリプト
// @version  1
// @match    https://www.google.com/*
// @grant    none
// ==/UserScript==

(function() {
    'use strict';

    alert('Hello, world!');
})();

この状態でGoogleにアクセスすると以下のようにアラートが出るようになるはずです。

スクリーンショット (149)

ユーザースクリプトはたったこれだけの手順で追加できます。簡単ですね。

次はユーザースクリプトの管理方法について解説します。Tampermonkeyのメニューを開き「ダッシュボード」を選択します。すると以下のように作ったり他からインストールしたスクリプトが一覧として出てきます。

スクリーンショット (150)

一覧のゴミ箱のようなアイコンからスクリプトの削除、メモ+えんぴつのようなアイコンから編集ができます。また、スクリプトの追加は上部の□で囲まれた+のアイコンからも可能です。先程作ったスクリプトはここで削除しておきましょう。

サイトの見た目を変えてみる

基本的なユーザースクリプトの管理方法を学んだところで、早速実践的なユーザースクリプトを書いていきます。今回はお試しとして以下のような定期ゲー風のサイトを用意しました。このサイトを使ってユーザースクリプトの作り方を学んでいきましょう。

アクセスすると以下のような感じになっているはずです。

スクリーンショット (151)

いろいろと気になる点はありますが…… まずは簡単なところから改造していきましょう。メッセージリストの部分のENoの色が非常に薄く見づらいので、これを濃い色に変更してみます。Tampermonkeyのメニューから「新規スクリプトを追加…」を選択してください。

ユーザースクリプトの上の部分に// ==UserScript==というような部分があると思います。この箇所で作成するユーザースクリプトがどのような名前なのか、どういうサイトで動作するのか……等々を指定できます。それぞれ意味と軽い解説は以下の通りです。これはGreasemonkeyでもほぼ同様に動作します。

// @name         スクリプトの名前。わかりやすい名前をつけましょう。
// @namespace    名前空間。作成者のサイトのURLを入れておけばいいです。
// @version      スクリプトのバージョン。書き換えるごとに順次上げていきましょう。
// @description  スクリプトの説明。わかりやすい説明を入れておきましょう。
// @author       スクリプトの作者名。
// @match        スクリプトが動作するURL。複数指定と*でのワイルドカード使用が可能。
// @grant        スクリプトの権限。基本的にはnoneで大丈夫です。

今回であればこのような感じになるでしょう。適宜書き換えてください。

// @name         Teiki Adventure ENo表示色変更
// @namespace    https://siroisakana.sakuraweb.com/
// @version      1.0
// @description  Teiki AdventureのENo表示の色を濃くする。
// @author       siroi_sakana
// @match        https://siroisakana.sakuraweb.com/dist/sample/*
// @grant        none

サンプルサイトはhttps://siroisakana.sakuraweb.com/dist/sample/(ページ)というようなURLになっているようなので、変化していく部分(ページと書いた箇所)は*にしてこのサイトのページは全て対象になるようにしています。

さて、それでは実際に書き換え……とする前に。やっぱりjQuery使いたいですよね。便利ですし。Tampermonkeyでは公開されているJavaScriptファイルを読み込むことができます。これには@requireを使用します。

// ==UserScript== ~ // ==/UserScript==の間の適当な場所に以下の行を追加してください。

// @require      https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js

これでこのユーザースクリプトが動作するときにjQueryが読み込まれて使えるようになります。文明の力は偉大ですね。

それでは気を取り直してユーザースクリプトを作っていきましょう。まずは改造したい要素のことを詳しく見ていきます。サンプルサイトのENoの箇所を右クリックして「検証(I)」を選択してください。開発者オプションが開き、該当の要素のことを詳細に確認することができます。

スクリーンショット (153)

どうやらENoを表示している要素にはenoというclassが指定されているようです。なので、enoというclassのついた要素の色を書き換えてしまえば改造できそうですね。これをコーディングしていきましょう。

jQueryでは$('セレクタ').css('プロパティ', '値');とすることでスタイルを当てはめることができます。

// Your code here...と書かれた箇所を以下のように変更してください。

$('.eno').css('color', 'red');

変更したら保存してサンプルサイトをリロードしてみましょう。ENo表記が以下のような感じに変わっているはずです。(これはこれで見づらい気もしますが、サンプルなのでわかりやすさ重視)

スクリーンショット (154)

色だけではなく太字かどうかや文字の大きさなども自由自在に変更できます。例えばトークルームの文字が小さくて見づらい、表示するフォントを変えたいなどの場合にもこのように非常にシンプルなコードで改造することができます。

文字数カウントを作ってみる

次はより機能的なユーザースクリプトを書いてみましょう。入力している文字数が分からずいつの間にか字数制限を超えてしまった……そういった事態を防ぐためにトークルームのテキスト入力欄に文字数のカウンターをつけてみます。今回は400字制限がある、ということにしましょう。

そうと決まれば改造したい要素を調べていきましょう。トークルームのテキスト入力欄を右クリックして検証します。

スクリーンショット (155)

classもidも指定されていなさそうです。今回は他に<textarea>がないので絞り込むのは容易ですが……。

定期ゲーだとclassもidも指定されていない上に<textarea>も複数あるというようなケースも多いのでセレクタの書き方を工夫する必要がある場合もあります。

例えば他の<textarea>が違うHTML内の違う階層にあるのであればセレクタを'.main-column > section > textarea'としてみたり、colsが違うのであれば属性セレクタを使って'textarea[cols=80]'としてみたり。他にも何個目の<textarea>かを指定するなど方法はいろいろあり定期ゲーによって対処方法も変わるのでそれぞれ工夫してみて下さい。

話が多少逸れましたがユーザースクリプト作成の続きをしていきましょう。新規スクリプトを追加してユーザースクリプトの設定を書いていきます。以下のような感じになるでしょう。

// ==UserScript==
// @name         Teiki Adventure トークルーム文字数カウンター
// @namespace    https://siroisakana.sakuraweb.com/
// @version      1.0
// @description  Teiki Adventureのトークルームの発言入力欄に文字数カウンターを追加する。
// @author       siroi_sakana
// @match        https://siroisakana.sakuraweb.com/dist/sample/talk.html
// @match        https://siroisakana.sakuraweb.com/dist/sample/public.html
// @grant        none
// @require      https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js
// ==/UserScript==

今回は@matchの部分がミソになります。@matchの指定を先ほどと同じようにhttps://siroisakana.sakuraweb.com/dist/sample/*としてしまうと、キャラクター設定ページにも<textarea>があるため意図しない動作になってしまいます。

サイトの一部分のページだけ動作させたい、という場合は@matchを動作させたいページごとに書くことで意図しない挙動を防ぐことができます。

設定も書けたので次はコーディングになります。どうやったら文字数カウンターを作れるかを考えてみましょう。文字数をカウントするわけですから、入力している文字数を取得するコードを書く必要がありますね。他にもサイトには当然カウンターなどはないのでページ上にカウンターを追加する処理、追加したカウンターに現在の文字数を反映する処理なども必要でしょう。

処理順にまとめると以下のようになります。

① ページ上にカウンターを追加する
② 現在の文字数を調べてカウンターに反映する関数を宣言
③ ②の関数が入力欄になにか入力するたびに作動するようにする

それでは早速コードを書いていきましょう。まずは①の処理から。カウンターは入力欄近くのほうがいいでしょうから入力欄右上に追加することにします。

jQueryでは$('セレクタ').before('追加したいHTML');とすることで指定の要素の前にコンテンツを挿入できます。以下のような感じになるでしょう。後から参照しやすいようにidを追加しています。

$('textarea').before('<div id="length-counter" style="width: 100%; display: flex; justify-content: flex-end; font-weight: bold;">0/400</div>');

次に②です。jQueryでは$('セレクタ').val()から指定の要素の入力されている内容を得ることができ、内容さえ取得してしまえばそこから.lengthで文字数を得ることができます。カウンターにはidをつけてあるので$('セレクタ').text('反映したい内容');でカウンター内の文字列を更新していきましょう。

それらを関数にまとめ、コードに起こすと以下のようになります。

   var count = function() {
       var messageLength = $('textarea').val().length;
       $('#length-counter').text(''+messageLength+'/400');
   };

最後に③です。jQueryでは$('セレクタ').keyup(作動させたい関数);で指定の要素の入力中にキーボードのキーを離したタイミングで指定の関数が作動するようにできます。「キーボードのキーを離す=なにか入力があった」ということなのでこれで入力欄に何か入力したときに②の関数を動作させることが可能です。

なお、$('セレクタ').change(関数);じゃないの?と思われるかもしれませんがこれは判定のタイミングが指定の要素から別の要素にフォーカスを移したときとなるため今回のような用途では不適です。

さて、コードに起こすと以下のようになるでしょう。

$('textarea').keyup(count);

全体としては以下のようなコードになります。カウンター、あるとかなり便利ですが実際はたった6行で実現できます。jQuery便利。(詳しい人が見たら実行速度の面で無駄が多いコードになっていますが個人用なので作る楽さ優先)

$('textarea').before('<div id="length-counter" style="width: 100%; display: flex; justify-content: flex-end; font-weight: bold;">0/400</div>');

var count = function() {
    var messageLength = $('textarea').val().length;
    $('#length-counter').text(''+messageLength+'/400');
};

$('textarea').keyup(count);

作ったら保存して実際に動作確認してみましょう。文字を入力するたびにカウンターが更新されているはずです。トークルーム・パブリックルームのページの<textarea>にはカウンターがついていてキャラクター設定ページの方にはついていないことも確認してみてください。

スクリーンショット (157)

作ったユーザースクリプトを公開する

自分のサイト等を持っており、十分にテストを行って問題がなさそうであれば作ったユーザースクリプトを公開するのもありでしょう。作ったユーザースクリプトを公開する場合、ファイル名の末尾を「.user.js」とすることでスクリプトファイルをURLから開いたときに簡単にインストールすることができるようになります。

公開するためにまずはファイルとして保存しましょう。Tampermonkeyのダッシュボード内から公開したいユーザースクリプトを開き、「ファイル>ディスクに保存」を選択します。

スクリーンショット (158)

ファイルが保存されるので、.user.jsの部分を残した状態で適当にわかりやすい名前に変更しましょう。今回は「TeikiAdventureENoColorChanger.user.js」とします。

あとはこれを自分のサイトにアップロードするだけです。以下のような感じになります。

https://siroisakana.sakuraweb.com/dist/sample/TeikiAdventureENoColorChanger.user.js

Tampermonkey/Greasemonkeyでは.user.jsで終わるスクリプトを開いたときに自動でユーザースクリプトのインストール画面が出るようになるのでこれだけで簡単にユーザースクリプトを公開できます。URLを開いてインストール画面が出ることを確認してください。(なお、内容は先程作ったスクリプトなので再インストールと出ると思います)

公開されているユーザースクリプトに更新があった際には自動でアップデートする機能もついています。便利。この機能は@versionに書かれているバージョンをベースに動作するので公開しているスクリプトに何か機能追加したり修正を行ったときはバージョンを忘れずに上げておきましょう。

おわりに

この記事の内容は以上となります。今回は定期ゲで簡単にユーザースクリプトを動かすにあたってこれぐらい知っていれば作れるだろう、というところだけ紹介しましたが、より詳しく知りたい方は以下のリンクが参考になると思います。英語ですがヘッダー部分についてより詳しく解説があります。

https://www.tampermonkey.net/documentation.php

ここまで読んでいただきありがとうございました。ユーザースクリプト作成は意外と簡単ということが伝われば幸いです。要望として上げるほどじゃないけど気になる、こういう機能がほしいという時などはぜひ挑戦してみてくださいね。それでは、良いお年を。