読者です 読者をやめる 読者になる 読者になる

Portal:siro

ダイレクトマーケティングブログ

同村チェッカー(議事)

Twitterでは既に垂れ流しておりましたが、晴れて正式版となったので告知記事を書きます。

同村チェッカー(議事)

概要

自分のIDと相手のIDを入れると「どの村で同村したか」が表示されます。それだけです。
エンドユーザー向けの説明は同村チェッカーのページに記述しましたので、そちらをご覧ください。

(意訳:同じこと2回書いてもあまり意味がないことに気づきました。今)

というわけで以下はどうでもいい話です。

与太話

あらすじ

もともと随分前から自分用に同村者DBというのは持っていて、そちらは最初手入力でやっていたのですが、死亡順に登録するとか地味に面倒臭いことをやっていたので段々疲れてしまいました。
そこで、数ヶ月前にエピローグのHTMLを解析してCSVファイルで吐き出す自分用のツールを作成しました。
そのときに「これ、全部の村に対して実行すれば同村チェッカー作れそうだな……」とは思っていましたが、諸々の理由*1により、暫く作成されずに放置していました。
それがたまたま先週あたりから村予定のない期間があったため、暇だからやるかなーという感じで作り始めたらできた、という感じです。

搭載機能

「同村」したか否かの判定に徹するため、村の情報とID、キャラ名以外は不要だろうと全部排除しました。
自分用同村者DBのためのツールではもうちょっと細かい情報も取得している*2のですが、実はソレも見物人周りの対応が雑だったりして即座に流用できる状態ではなかったためバッサリ。
シンプルになりましたがその分バグ対応はやりやすかったです。

各種細かい情報が必要ならば、エピローグへのリンク貼ったのでそこで見てね☆という手抜き仕様です。手抜き万歳。

ちょっと技術的な話1

PHPのSimple HTML DOMライブラリを利用しての解析です。
僕はアホなので未だにわかっていないのですが、json形式でHTMLの中身が取れるらしいです。すごいや!

こいつでのHTML解析方法はぐぐれば出てくるんですが、一応今回の話をすると、議事のエピローグ(キャスト一覧)はtableです。
tableタグはtable-tr-tdの階層構造なので、tr単位でforeach文を回してchildren取得することで中身を取得しています。

ちょっと技術的な話2

ちょっと重箱の隅のようなめんどくさいはなし。
まず、文字エンコード。議事の文字エンコードはShift-JISなのですが、僕のほうのMySQL環境はUTF-8なのです。なので、処理すべき文字列には全部エンコードをかけています。
それから前後スペース。これはtrimしています。

これで問題ないと思っていたら、問題が発生しました。ジェレミーで。
ソースちょっと工夫したら直ったので問題はないっちゃないんですが、trimかけたらジェレミーが消失してしまって、IDが名前になってしまってとあるPLさんがキャラ名になってしまったりとかげふん。

ちょっと技術的な話3

村エピからログを読み込む、だけなら割とすぐできます。
標準、陰謀、Advanceは若干レイアウトが違うのでfindの検索条件を弄る必要がありましたがそれもあんまり問題はなかったです。

でも、毎回エピローグのURL探して入力するの面倒臭い。
*3

「終了済の村一覧のHTMLを読み込むだけで自動で解析してくれないかなー」
とか思うわけです。「面倒臭がりはマに向いてる」ってどっかで聞いたことがありますがほんとそうですね。

というわけでやってみましょうと。でもこれが案外面倒臭い。
まず、エピローグのURLを特定しなければいけないのですが、終了済の村一覧からは直接エピローグに飛ぶことができません。そして、エピローグのURLは村ごとに違ってきます。
初日から芋づる式にたどっていくようなやり方は、議事国サーバーに掛かる負担を考えるとあまりいただけません*4。なので、計算で求めることにしました。


まず、終了済みの村一覧として入力されたURLを分解して、http://hogehoge/sow.cgi?の部分を取り出しておきます。これに、村番号とかの情報をくっつけてエピローグにたどりつくというとても原始的な方法で実装しています*5
村番号:幸い村番号はIDの欄から取得できるのでこれはすぐです。
エピローグ:これは、村の日数から取得します。「04日」とか書いてあるところです。
ただしこれは、地上最終日(エピローグの前日)の日付なので、これに+1しなければエピローグにたどり着けません。
phpは変数の型を自動的に決定するという仕様なので、
「04日」を読み込む(string)→「04日」を「4」に置換する(string)→「4」に「1」を足す(int)
という処理をちゃっちゃーと書いていきます*6

あとはこれらをくっつければエピローグURLの完成


だったら楽だったのになあ…www

ちょっと技術的な話4

議事には、廃村という機能があります。
プロローグで人が集まらなかった場合、バグ発生・長期間の鯖落ちによる村のリセット・荒らし・その他村たて人の意向など管理者が廃村すべきと判断した場合に、村は廃村され、村の日数も何日進んだかに関係なく「廃村」となります。

「廃村の村は終了村一覧からの読み込みじゃなくて、個別に対応する」というのも一応考えたのですが、実はそれなりに多いんですよね。廃村。

なので、廃村に関しては、日数を読み取った時に「廃村」であれば、1日(プロローグ)で終了した村と判断して、1+1=2日目をエピローグと判断して取得を行っています。



……進行中廃村の場合、エピローグは2日目ではなくなりますが、それはエラーが帰ってくるので、そういう場合は諦めて村エピURLを自分で取ってきて処理してます。

技術的な話まとめ

というわけで、今のところ「エピローグのURLを入力すると解析する」「終了済村一覧のURLを入力するとエピローグのURLを生成して解析する」って2つの機能があります。というお話でした。
しろぼっとはソースコードを公開しましたが、今回のはちょっと雑すぎるのでソースコードの公開はご容赦ください……。

これから実装したいこと1

あんなこといいなーできたr(JASRAC

とりあえず、今一番の課題はコレ。
「終了済みの村一覧巡回するの面倒臭いなあ」

作ってから気づいたんです。
終了済の村一覧巡回するのもめんどくせえ!!!!!!!1!!111


というわけでここ自動化するためにちょっとアルゴリズムを考えます。
1.予め終了済の村一覧URLを保持しておく
2.どの村をチェックするか決める
 一番上からn村って処理よりは、一度DBに「どの村まで登録を終えているか」を問い合わせたほうが議事に余計なアクセスしなくて済みそう。
3.チェックプログラムを自動で回す←これどうしようかな

crontabの空きがないんですよねぶっちゃk*7
しろぼっとにやらせるかなあ……。要は、トリガーさえあればいいし。

しろぼっとにやらせる→エラーが出た場合はシロにリプライ飛ばす
この方向で詳細仕様詰めてみます。

これから実装したいこと2

UI関係。デザインするのも面倒でこう、CSS自サイトから流用してるレベルなので当然UIとかなんも考えられてないのでどうにかしたい。

1.ページ分割*8
検索結果が膨大になったときのページ分割です。
でもぶっちゃけ膨大になるほうが稀なのでこれは別に要らないかなと思ったり

2.検索条件のカスタマイズ
ページ分割をしない代わりにこちらを実装すべきかなと。
たとえば、対象のサーバーを指定するとか(チェックボックス式にしたいなー)
部分一致検索に対応するとか(IDの字が難しい人とか、IDうろ覚えな人とか)
自分のキャラも一緒に表示させるとか

そういうカスタムができると利便性上がりますよねーたぶん。

3.ソート・フィルタ
今、これすごく適当で、ORDER BY…たぶん州・村番号固定なんですよね。
これを並べ替えるとか、フィルタ掛けて特定の条件だけにするとか。
そゆこともしたいなーでもどうやってやるのかなーjQueryですか? 調べることからはじめます。

4.検索結果件数くらい出力しろよ
サーセン

こんなもんかなー

とりあえず中の人的な思考はこんなもんですが。
アレ実装しろよ!とか、コレどうなってるの?とかありましたら、適当に聞いてください、あいあいさ。

*1:ぶっちゃけ面倒臭かっただけです

*2:役職、陣営、生存日数、死因くらいは

*3:ってことを標準鯖のデータ取り込みの時に気づきました。perjury100村はエピURL手入力でも問題なくいけましたけど、200件は軽く心が折れそうです

*4:参考までに、エピローグを解析してDBへの登録が完了するまで1〜2秒掛かります。お互いのサーバのレスポンスの問題です

*5:もっとうまい方法あれば教えてください先生

*6:そしてここでやたらと時間が掛かりました。正規表現があんまり得意じゃないのです

*7:サーバ都合の話

*8:ななころさん「実装するとめんどいよ」シロ「ですよねー」