ドラゴンクエストのリンク集

私はドラゴンクエストが好きだ。
これだけドラゴンクエストが好きなのだから、好きを貫いてドラゴンクエストを作る人になればよかったのかもしれないけど、私にはできなかった。できなかったっていうか、最初からやろうともせずに諦めたのだ。はてなの社長さんが書いた本や、色んな人の書評を読んで「ドラゴンクエストを作っていない私は、好きを貫いていないんだ」と思い、ちょっとミジメな気持ちになった。
ドラゴンクエストは作っていないけど、それで人生に絶望して首を括るのもイヤなので、何とか前向きに考えてみた。
私はドラゴンクエストというゲーム自体も好きだけど、おそらくそれ以上に、誰かとドラゴンクエストの話をするのが好きだ。誰かがドラゴンクエストについて熱く語るのを聞いたり、私と同じように「俺はドラクエが大好きだ!」と言う人を見ると嬉しくなってくる。そして、インターネットの世界には、そんな人たちの声がいっぱい溢れている。
攻略サイトを作る人。プレイ日記を書く人。ドラクエの世界について深く考察する人。面白いネタを考える人。低レベル攻略に挑む人。縛りプレイを楽しむ人。二次創作を作る人。ファイナルファンタジーとケンカする人。
そんな人たちの声。具体的に言うと、ドラクエを好きな人が作ったページや、ドラクエ好きな人たちのコミュニティを集めて整理して、見やすい形にして、世のドラクエファンに提供するようなサービスがあったら面白いんじゃないかしら。よく考えてみると、ただの「リンク集」なのだけれど。
Googleのように、誰も見たことがないようなスゴイ技術を使って、自動的にサイトが成長していくような仕組みが作れればいいのだけど、そんなスゴイ仕組みはすぐに思いつかなかったので、とりあえず最初の一歩として、ニコニコ動画ドラクエプレイ動画を手動で集めてみました。
ドラゴンクエストのリンク集 - ニコニコ動画
せっかく作ったのにニコニコ動画がメンテナンス中で俺涙目。

釣堀に行ってきた。


釣り糸を垂れてボケーーーっとしていればいいのだろうと思っていたけど、なかなかどうして奥が深い。片時も目を離さずにウキの動きに集中していなければならないみたいだ。初心者用の堀でボケーーーーーっとしていたら、見かねた店の人がアドバイスをくれて、おかげ様で一匹だけ釣れた。やったね♪

ドラクエ3 アリアハンでアバカムを覚えてみた

ニコニコ動画のサムネイルが表示されるようになったので動画紹介。

ドラクエ3 アリアハンアバカムを覚えてみた 実践編2

http://www.nicovideo.jp/watch/sm1843900


ドラクエ3のプレイ動画。アリアハン大陸から一歩も出ることなく、魔法使いがアバカムを覚えるまでレベルを上げています。私も子供の頃にファミコン版でやってみようと思ったことがありますが、レベル12〜13で挫折しました。
ちょっと調べてみましたが、魔法使いがレベル35になるまでに必要な経験値は32万9495ポイントアリアハン大陸に出現するモンスターの中で最も経験値の高いモンスターはホイミスライム24ポイント(1人で倒した場合)です。しかしホイミスライムアリアハン大陸では一匹でしか登場しなかったような記憶があります。また、呪文が一切効かない上にホイミで回復しまくるので、ほとんど倒してないと書いてあったので、次点の「まほうつかい」(敵モンスターの方ね)が4匹まとめて出現ってのが、一番経験値が得られるパターンだと思います。(20×4=80ポイント
参考ページ

単純に毎回まほうつかい×4が出てきたとしても、戦闘回数は4119回!ものすごい数字です。こういう地味な作業を黙々と続けて最後までやり通す人っていうのは大好きです。

実践編では、いざないの洞窟入り口にある旅の扉からサマンオサにワープして、ボストロールとの戦いに挑むことになります。最後の方は「アバカム関係ねぇw」というコメントが乱れ飛びますが、主旨を忘れて興奮する内容になっています。全部見ると30分かかりますが、是非ご覧あれ。

Services_TwitterでHTTPプロキシを使いたい

ソースを読んでるだけでも楽しいCodeRepos
PHPからTwitterAPIを使うためのライブラリを見つけました。

会社にいるときにちょっと触ってみたのですが、うちの会社はプロキシサーバーを経由しないとWebに繋げないので、TwitterAPIが使えませんでした。社内LANの内側で使うためにプロキシを設定できるようにしたい。ちょっとやってみよう。

PEAR/HttpRequest.phpソースコードを見ながら、Services_Twitterソースコードに手を加えてみた。(ほとんどPEAR/HttpRequest.phpからのコピペ。いいのかなこんなんで。)

Index: src/Services/Twitter/Connector.php
===================================================================
--- src/Services/Twitter/Connector.php  (revision 3381)
+++ src/Services/Twitter/Connector.php  (working copy)
@@ -42,6 +42,30 @@
     var $_body;

     /**
+     * Proxy server
+     * @var string
+     */
+    var $_proxy_host;
+
+    /**
+     * Proxy port
+     * @var integer
+     */
+    var $_proxy_port;
+
+    /**
+     * Proxy username
+     * @var string
+     */
+    var $_proxy_user;
+
+    /**
+     * Proxy password
+     * @var string
+     */
+    var $_proxy_pass;
+
+    /**
      * Class constructor
      *
      * @access public
@@ -99,6 +123,19 @@
             }
         }

+        // Proxy authentication
+        if (!empty($this->_proxy_user)) {
+            $this->addHeader('Proxy-Authorization', 'Basic ' . base64_encode($this->_proxy_user . ':' . $this->_proxy_pass));
+        }
+
+        // RFC 2068, section 19.7.1: A client MUST NOT send the Keep-Alive
+        // connection token to a proxy server...
+        if (isset($this->_proxy_host) && !empty($this->_headers['connection']) &&
+            'Keep-Alive' == $this->_headers['connection'])
+        {
+            $this->removeHeader('connection');
+        }
+
         if (count($this->_body) > 0) {
             foreach ($this->_body as $line) {
                 $body .= $line . "\r\n";
@@ -111,6 +148,9 @@
         if (isset($url['query'])) {
             $path .= '?' . $url['query'];
         }
+        $proxy_host = isset($this->_proxy_host) ? $url['scheme'] . '://' . $url['host'] : '';
+        $proxy_port = (isset($this->_proxy_host) AND $url['port'] != 80) ? ':' . $url['port'] : '';
+        $path = $proxy_host . $proxy_port . $path;

         // definity send target
         $request .= $method . ' ' . $path . ' HTTP/1.1'."\r\n";
@@ -130,7 +170,11 @@
         $request .= $body;

         // send request
-        $fp  = fsockopen($url['host'], $url['port']);
+        if( $this->_proxy_host ) {
+            $fp  = fsockopen( $this->_proxy_host, $this->_proxy_port );
+        } else {
+            $fp  = fsockopen($url['host'], $url['port']);
+        }
         if (!$fp) return false;
         fputs($fp, $request);
         $response = '';
@@ -234,4 +278,22 @@
         return $this->_basic_auth;
     }

+
+    /**
+     * Sets a proxy to be used
+     *
+     * @param string     Proxy host
+     * @param int        Proxy port
+     * @param string     Proxy username
+     * @param string     Proxy password
+     * @access public
+     */
+    function setProxy($host, $port = 8080, $user = null, $pass = null)
+    {
+        $this->_proxy_host = $host;
+        $this->_proxy_port = $port;
+        $this->_proxy_user = $user;
+        $this->_proxy_pass = $pass;
+    }
+
 }
\ No newline at end of file
Index: src/Services/Twitter.php
===================================================================
--- src/Services/Twitter.php    (revision 3381)
+++ src/Services/Twitter.php    (working copy)
@@ -330,6 +330,30 @@
     var $_cache_dir;

     /**
+     * Proxy server
+     * @var string
+     */
+    var $_proxy_host;
+
+    /**
+     * Proxy port
+     * @var integer
+     */
+    var $_proxy_port;
+
+    /**
+     * Proxy username
+     * @var string
+     */
+    var $_proxy_user;
+
+    /**
+     * Proxy password
+     * @var string
+     */
+    var $_proxy_pass;
+
+    /**
      * class constructor
      *
      * @access public
@@ -491,6 +515,23 @@
     }

     /**
+     * Sets a proxy to be used
+     *
+     * @param string     Proxy host
+     * @param int        Proxy port
+     * @param string     Proxy username
+     * @param string     Proxy password
+     * @access public
+     */
+    function setProxy($host, $port = 8080, $user = null, $pass = null)
+    {
+        $this->_proxy_host = $host;
+        $this->_proxy_port = $port;
+        $this->_proxy_user = $user;
+        $this->_proxy_pass = $pass;
+    }
+
+    /**
      * send update request
      *
      * @access private
@@ -503,6 +544,13 @@
     {
         $req =& new Services_Twitter_Connector();

+        if( isset($this->_proxy_host) ) {
+            $req->setProxy( $this->_proxy_host
+                          , $this->_proxy_port
+                          , $this->_proxy_user
+                          , $this->_proxy_pass );
+        }
+
         if (!$this->checkAuth()) {
             $req->enableBasicAuth($this->_user, $this->_pass);
         }
@@ -605,6 +653,13 @@

         $req =& new Services_Twitter_Connector();

+        if( isset($this->_proxy_host) ) {
+            $req->setProxy( $this->_proxy_host
+                          , $this->_proxy_port
+                          , $this->_proxy_user
+                          , $this->_proxy_pass );
+        }
+
         if (!$this->checkAuth()) {
             $req->enableBasicAuth($this->_user, $this->_pass);
         }
@@ -712,6 +767,13 @@
         }

         $req =& new Services_Twitter_Connector();
+        if( isset($this->_proxy_host) ) {
+            $req->setProxy( $this->_proxy_host
+                          , $this->_proxy_port
+                          , $this->_proxy_user
+                          , $this->_proxy_pass );
+        }
+
         $req->addHeader('User-Agent', 'PHP/' . phpversion());
         $response = $req->sendRequest($url, $method);
         $response = explode("\r\n", $response);
@@ -1078,4 +1140,4 @@
             return false;
         }
     }
-}
\ No newline at end of file
+}

BlackJumboDogでプロキシサーバーを立ててテスト。無事にFriendsTimelineが取得できました。やったね!

<?php

// ソースのある場所にパスを通す。
set_include_path('.;C:\Program Files\xampp\php\PEAR;C:\work\coderepos\lang\php\Services_Twitter\src');

require_once( 'Services/Twitter.php' );

// Services_Twitterを生成して、JSONをデコードしてもらうように設定する。
$twitter = new Services_Twitter( 'drgqst', '********');
$twitter->enableJsonConvert();

// 今回追加したメソッド。プロキシサーバーをセットする。
$twitter->setProxy('localhost', 8080 );

// お友達のタイムラインを取得
$friendsTimeline = $twitter->getFriendsTimeline();

var_dump( $friendsTimeline );
?>

ところで、これってコミットしていいものなのかな・・・?
この辺の空気がまだよくわかってない。やっぱり勝手にコミットしたりしちゃマズいよね。。。作った人に連絡してみよう。そうだそうだそれがいいそうしよう。

追記

メールした。初めての人にメールするのは未だに緊張するなー。
CodeReposの文化がまだ良くわかってないのだと思う。IRCっていうのを使って誰かとお話してみようかな。ドキドキ

はてなダイアリー上でニコニコ動画のサムネイルを表示するGreasemonkey

はてなダイアリーではニコニコ動画のサムネイルが表示できないので、Greasemonkeyを使って表示させてみました。
ニコニコ動画サムネイル on はてなダイアリー インストール

詳細

ニコニコ動画のリンクを探して、サムネイルタグに置換しています。URLのリンク自動変換によって張られたリンク(href属性とテキストが同じリンク)だけを対象としています。

スクリーンショット


↑こういう感じの日記が

↑こういう感じになります。

ソース

// ==UserScript==
// @name ニコニコ動画サムネイル on はてなダイアリー
// @namespace http://d.hatena.ne.jp/drgqst/
// @description はてなダイアリーでニコニコ動画のサムネイルを表示するぐりもん
// @include http://d.hatena.ne.jp/*
// ==/UserScript==
//
// はてなダイアリーではニコニコ動画のサムネイルを表示することができません。
// なのでGreasemonkeyで無理やり表示させてしまおう。
// ニコニコ動画のURLをサムネイルに置き換えます。
//
(function(){
    // リンク要素をすべて取得。
    var links = document.getElementsByTagName('a');
    if( links == undefined ) {
        return;
    }
    
    for( var i=links.length - 1; i>=0; i-- ) {
        var link = links[i];
        var url = link.href.match( /^http\:\/\/www\.nicovideo\.jp\/watch\/(\w+)$/ );
        
        if( url && url[1] ) {
            // hrefとテキストが違う文字列の場合は置き換えない
            if( url[0] != link.innerHTML ) {
                break;
            }
            
            // iframe要素を作ってリンク要素の前に差し込む
            var iframe = document.createElement('iframe');
            iframe.width = '312';
            iframe.height = '176';
            iframe.src = 'http://www.nicovideo.jp/thumb/' + url[1];
            iframe.scrolling = 'no';
            iframe.style.border = 'solid 1px #CCC';
            iframe.frameborder = '0';
            link.parentNode.insertBefore( iframe, link );
            
            // リンク要素を消してしまう
            link.parentNode.removeChild( link );
        }
    }
})();

不具合とかありましたら、コメントで教えて下さい。

CodeReposに入りたいけど .htpasswd file って何?

という書き込みを見つけました。
http://twitter.com/noriaki/statuses/511201842
「確かに、知らない人もいるかもしれないなー」と思ったので、JavaScriptで .htpasswd file を生成してくれるようなスクリプトはないかなーと思って、Googleさんに聞いてみたら、id:amachang が既に同じことを考えていたようです。
http://buzzurl.jp/user/amachang/bm/982072

http://sahf.hp.infoseek.co.jp/laboratory/ap_md5.html
↑のページを開いてIDとパスワードを入力すると、.htpasswd file を生成してくれます。便利。