MyMiniCityを巡回するrubyのスクリプトを公開します。
以下のようになっています(たぶん)
- List.txtに記載された街を順番に巡回
※http://mhori.myinicity.com/なら、「mhori」と記載。街ごとに改行 - xmlを取得できない場合はpopでアクセス
- 巡回リストの上2つでアクセス前後のxmlを比較し、有効にアクセスできたかを確認。有効でない場合はスクリプトを打ち切り
- env、sec、ind、traの優先順位でアクセス
- レベル6で街の状態が完璧な場合、popとcomのどちらかでアクセス(乱数で選択)
※私が動かしている時はpopだけにしてますが - Flashのデータをダウンロードしないので、ブラウザで巡回するよりも速い
- 人口、工場、道路、警官、公園、商店の合計で街の規模を見ている
rubyスクリプトが「mmc.rb」の場合、ダイヤルアップで巡回を繰り返すなら、
rasdial ダイヤルアップに登録したエントリ名 プロバイダのユーザーID パスワード ruby mmc.rb rasdial /dというバッチファイルを作って繰り返せば自動巡回君のできあがりです。
ダイヤルアップではなく、ルータを再起動してIPを切り替える場合はロケットマウスのようなものをうまく使えば楽ができるんじゃないかと思います。
ちなみにこのrubyスクリプトを使う場合、rubygemsとhapricotが必要です。
また、コマンドプロンプトが使えないと動きません。
従ってem-oneのようにコマンドプロンプトが使えない端末ではうまく動きません。
<余談>
mortscriptを使ってem-oneでどうにかならんか、とか考えたけどうまくできてない罠(苦笑
em-one単体でうまく巡回する方法があったら教えてくださいませ。
また、perlとかjavaとかwshでやったらこうなるぜ、みたいなのがあったら是非。
コマンドプロンプトじゃなくて、GUIでやれるぜ、みたいなのも是非(ぉぃ
</余談>
前置きはこれぐらいにしてスクリプトはこんなふうになってます。
#!/usr/bin/ruby require 'rubygems' require 'hpricot' require 'net/http' opt = ["/", "/ind", "/tra", "/sec", "/env", "/com"] path, = ARGV number = 0 checkpoint = 2 #アクセス前後でxmlを比較する街の数 cpcounter = 0 printf "---\n" IO.foreach("List.txt") do |line| checkflug = 0 number = number + 1 city = line.strip host = sprintf("%s.myminicity.com",city) http = Net::HTTP.new(host,80) doc = Hpricot(http.get("/xml").body) name = doc.search("name").inner_text if name == "" #nameが空=xmlを読めなかった場合はpopでアクセス printf "No. %s \"%s\"\n",number,city printf "URL: http://%s%s\n",host,opt[0] begin #mmcサーバにアクセス printf "Return value: %s\n",http.get(opt[0]+"?",{'Cookie'=>'X-Ref-Ok=1'}).message rescue Timeout::Error => e puts ' caught ' + e retry end else region = doc.search("region").inner_text ranking = doc.search("ranking").inner_text.to_i population = doc.search("population").inner_text.to_i incomes = doc.search("incomes").inner_text.to_i unemployment = doc.search("unemployment").inner_text.to_i transport = doc.search("transport").inner_text.to_i jam = 100 - transport criminality = doc.search("criminality").inner_text.to_i pollution = doc.search("pollution").inner_text.to_i bases = sprintf("%s",doc.search("bases")).delete("<>/\"[a-z] *").split(/=/) ind = bases[5].delete("\n").to_i tra = bases[3].delete("\n").to_i sec = bases[4].delete("\n").to_i env = bases[2].delete("\n").to_i com = bases[1].delete("\n").to_i sum = population + ind + tra + sec + env + com printf "No. %s \"%s\" in %s\n",number,name,region printf "規模:%d, 順位:%d位, 人口:%d人, 資産:%deuro\n",sum,ranking,population,incomes printf "失業:%d%%, 交通:%d%%, 犯罪:%d%%, 汚染:%d%%\n",unemployment,transport,criminality,pollution printf "工場:%d, 道路:%d, 警官:%d, 公園:%d, 商店:%d\n",ind,tra,sec,env,com if population < 50 #レベル1の場合 i = 0 #アクセス方法をpopにする elsif population >= 50 && population < 100 #レベル2の場合 if unemployment > 0 #失業率が0より大きい場合 i = 1 #アクセス方法をindにする else i = 0 #アクセス方法をpopにする end elsif population >= 100 && population < 300 #レベル3の場合 if jam > 0 || unemployment > 0 if jam > unemployment i = 2 #アクセス方法をtraにする else i = 1 #アクセス方法をindにする end else i = 0 #アクセス方法をpopにする end elsif population >= 300 && population < 500 #レベル4の場合 if criminality > 0 || jam > 0 || unemployment > 0 if [criminality, jam, unemployment].max == criminality i = 3 #アクセス方法をsecにする elsif [criminality, jam, unemployment].max == unemployment i = 1 #アクセス方法をindにする else i = 2 #アクセス方法をtraにする end else i = 0 #アクセス方法をpopにする end elsif population >= 500 && population < 1000 #レベル5の場合 if pollution > 0 || criminality > 0 || jam > 0 || unemployment > 0 if [pollution, criminality, jam, unemployment].max == pollution i = 4 #アクセス方法をenvにする elsif [pollution, criminality, jam, unemployment].max == criminality i = 3 #アクセス方法をsecにする elsif [pollution, criminality, jam, unemployment].max == unemployment i = 1 #アクセス方法をindにする else i = 2 #アクセス方法をtraにする end else i = 0 #アクセス方法をpopにする end else if pollution > 0 || criminality > 0 || jam > 0 || unemployment > 0 #レベル6の場合 if [pollution, criminality, jam, unemployment].max == pollution i = 4 #アクセス方法をenvにする elsif [pollution, criminality, jam, unemployment].max == criminality i = 3 #アクセス方法をsecにする elsif [pollution, criminality, jam, unemployment].max == unemployment i = 1 #アクセス方法をindにする else i = 2 #アクセス方法をtraにする end else i = 5 * rand(2) #アクセス方法をpopかcomのどちらかにする(popに限定する場合は0にする) end end end printf "URL: http://%s%s\n",host,opt[i] sleep 2 #mmcサーバに負荷をかけすぎるといけないので2秒待つ begin #mmcサーバにアクセス printf "Return value: %s\n",http.get(opt[i]+"?",{'Cookie'=>'X-Ref-Ok=1'}).message rescue Timeout::Error => e puts ' caught ' + e retry end if cpcounter < checkpoint #アクセスに成功したか確認する場合はxmlを取得する sleep 2 #mmcサーバに負荷をかけすぎるといけないので2秒待つ doc = Hpricot(http.get("/xml").body) name_after = doc.search("name").inner_text if name_after == "" #nameが空=xmlを読めなかった場合はチェックフラグを0にする checkflug = 0 else #nameが空でない=xmlを読めた場合はxmlデータを整理し、チェックフラグを1にする ranking_after = doc.search("ranking").inner_text.to_i population_after = doc.search("population").inner_text.to_i incomes_after = doc.search("incomes").inner_text.to_i unemployment_after = doc.search("unemployment").inner_text.to_i transport_after = doc.search("transport").inner_text.to_i criminality_after = doc.search("criminality").inner_text.to_i pollution_after = doc.search("pollution").inner_text.to_i bases = sprintf("%s",doc.search("bases")).delete("<>/\"[a-z] *").split(/=/) ind_after = bases[5].delete("\n").to_i tra_after = bases[3].delete("\n").to_i sec_after = bases[4].delete("\n").to_i env_after = bases[2].delete("\n").to_i com_after = bases[1].delete("\n").to_i ranking_inc = ranking_after - ranking population_inc = population_after - population incomes_inc = incomes_after - incomes unemployment_inc = unemployment_after - unemployment transport_inc = transport_after - transport criminality_inc = criminality_after - criminality pollution_inc = pollution_after - pollution ind_inc = ind_after - ind tra_inc = tra_after - tra sec_inc = sec_after - sec env_inc = env_after - env com_inc = com_after - com sum_after = population_after + ind_after + tra_after + sec_after + env_after + com_after sum_inc = sum_after - sum printf "規模:%d(%+d), ",sum_after,sum_inc printf "順位:%d位(%dup), ",ranking_after,-ranking_inc printf "人口:%d人(%+d), ",population_after,population_inc printf "資産:%deuro(%+d)\n",incomes_after,incomes_inc printf "失業:%d%%(%+d%%), ",unemployment_after,unemployment_inc printf "交通:%d%%(%+d%%), ",transport_after,transport_inc printf "犯罪:%d%%(%+d%%), ",criminality_after,criminality_inc printf "汚染:%d%%(%+d%%)\n",pollution_after,pollution_inc printf "工場:%d(%+d), 道路:%d(%+d), ",ind_after,ind_inc,tra_after,tra_inc printf "警官:%d(%+d), 公園:%d(%+d), ",sec_after,sec_inc,env_after,env_inc printf "商店:%d(%+d)\n",com_after,com_inc cpcounter = cpcounter + 1 checkflug = 1 end end end printf "---\n" if checkflug == 1 #アクセス前後でxmlを取得した場合、有効性をチェック if i == 0 #popでアクセスしたが人口が増えていない場合はスクリプトを終了 if population_inc <= 0 break end elsif i == 1 #indでアクセスしたが工場が増えていない場合はスクリプトを終了 if ind_inc <= 0 break end elsif i == 2 #traでアクセスしたが道路が増えていない場合はスクリプトを終了 if tra_inc <= 0 break end elsif i == 3 #secでアクセスしたが警官が増えていない場合はスクリプトを終了 if sec_inc <= 0 break end elsif i == 4 #envでアクセスしたが公園が増えていない場合はスクリプトを終了 if env_inc <= 0 break end elsif i == 5 #comでアクセスしたが商店が増えていない場合はスクリプトを終了 if com_inc <= 0 break end end end sleep 3 #mmcサーバに負荷をかけすぎるといけないので3秒待つ end localtime = Time.now.strftime("%a, %d %b %Y %H:%M:%S +0900") printf "At %s\n",localtime
- checkpoint を2にしているのは、1だとたまたま同じアクセス方法を取っている人がいると誤判定してしまうからです。mmcサーバが不調でxmlが取りにくい場合は0にしても良いかも
- wait(sleep)をあちこちに入れてますが、回線状況やmmcサーバの調子に応じて適宜調整してください
- rand(2)は0か1を返します。popもcomもいらんからindかtraかsecかenvで、なんて人がいたらif分で切り分けてi = 1 + rand(4)なんてすると良いでしょう(これだと i が1?4の整数になる)
- mmcサーバにアクセスしようとして失敗した場合、リトライを試みるようになっていますが、mmcサーバが重たいとスクリプトが途中でタイムアウトしてこけます。うまく処理する方法をご存じの方がいらっしゃいましたら教えてやってください。
元々rubyって使ったことが無くて良く分かってません。そんなやつが人が作ったものを改造してたらこんな感じの長ったらしい見にくいスクリプトになってしまいました(^^ゞ
コメントする