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って使ったことが無くて良く分かってません。そんなやつが人が作ったものを改造してたらこんな感じの長ったらしい見にくいスクリプトになってしまいました(^^ゞ

コメントする