MyMiniCity巡回用rubyスクリプト

| コメント(0) | トラックバック(0)

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

トラックバック(0)

トラックバックURL: https://horijp.com/mt/mt-tb.cgi/1948

コメントする

ウェブページ

Powered by Movable Type 7.8.2

このブログ記事について

このページは、masashiが2008年5月27日 22:34に書いたブログ記事です。

ひとつ前のブログ記事は「国は保険業務から撤退せよ?」です。

次のブログ記事は「動画サイトへ不正投稿した人を99.9999%特定する技術」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。