require 'libhttpclient'
require 'mountycreds'
class Mounty
def self.lastinstance
@@lastinstance
end
def self.play
@@lastinstance = Mounty.new
@@lastinstance.login
@@lastinstance
end
def self.play_noact
@@lastinstance = Mounty.new
@@lastinstance.login_noact
@@lastinstance
end
attr_reader :http_client
def d(*args)
puts args if $VERBOSE
end
SITE_URL = 'http://games.mountyhall.com/'
def initialize
@http_client = HttpClient.new(SITE_URL)
@status = {}
@caracs = {}
@comps = {}
@sorts = {}
@caracs_bm = {}
@http_ctx = {}
end
class SessionExpired < RuntimeError ; end
def get(url)
ret = @http_client.get(url, (rand(8) == 0) ? (1+rand(40)) : (rand(6)))
raise SessionExpired if @http_client.cur_url =~ /SessionExpired/i
case url
when /play_menu.php$/i
@shortcuts = ret.parse('a').map { |e| $1.to_i if e['href'] =~ /ToDo=(\d+)&/ }.compact
save_ctx :menu
when /play_action.php$/i
save_ctx :action
end
hst = @http_client.status_save
begin
ret.parse('frame').each { |e|
@http_client.status_restore hst
@http_client.fetch_next_now
get e['src']
}
rescue
ensure
@http_client.status_restore hst
end
ret
end
def post(url, values)
@http_client.post(url, values, (rand(4) == 1) ? (3+rand(15)) : rand(4), (rand(5) == 1) ? (3+rand(25)) : rand(4))
end
def save_ctx(c)
@http_ctx[c] = @http_client.status_save
end
def set_ctx(c)
if not @http_ctx[c]
puts "no ctx #{c} ??", @http_client.history, caller
return
end
@http_client.status_restore @http_ctx[c]
end
def show(*a)
puts get_text(*a), '-'
end
def get_text(p = nil, onlyform = true, onlystr = true)
p ||= @http_client.curpage
txt = p.get_text(onlyform, onlystr).reject { |l|
l =~ /\[refresh\] \[logout\]|\[contact.*\[heure serveur.*\[page g|- il y a actuellement .* tr.*lls connect/i
}.join.chomp
if txt == '' and onlyform
txt = get_text p, false, onlystr
end
txt
end
# cree un tableau de tableaux
# chaque tableau represente une ligne d'une
# les changements de sont representes par un tableau vide
def show_table_content(p=nil, verbose=true)
p ||= @http_client.curpage
show = showonly = false
arr = []
p.parse.each { |e|
case e.type
when 'table'
# separation de tables
arr << [] if arr.last and not arr.last.empty? and arr.last != [[]]
when 'tr'
# nouveau tableau
case e['class']
when 'mh_tdpage'
arr << []
show = true
when 'mh_tdtitre'
arr << []
show = showonly = true
else
if show
if showonly
s = arr.pop.join ' '
else
s = arr.last.join ' '
end
puts s if verbose
show = showonly = false
end
end
when '/tr'
# fin du tableau, affichage
if show
if showonly
s = arr.pop.join ' '
else
s = arr.last.join ' '
end
puts s if not showonly or not s.include? 'Heure Serveur' if verbose
show = showonly = false
end
when 'td'
# nouvel element du tableau :
# cree un array ou on entasse les Strings
arr.last << [] if show
when '/td'
# met une chaine dans le tableau du
arr.last << arr.last.pop.join(' ') if show
when 'String'
arr.last.last << e['content'] if show
end
}
arr.pop if arr.last and arr.last.empty?
arr
end
def get_confirm(p = @http_client.curpage)
if not pd = @http_client.post_allowed[0]
puts 'already used?'
elsif pd.method == 'post'
post pd.url, pd.vars
else
get HttpServer.get_form_url(pd.url, pd.vars)
end
end
attr_accessor :curlogin
def refresh
profil
get '/mountyhall/Play.php'
show
get_confirm
profil
nz = @http_client.cache['/mountyhall/MH_Play/Play_news.php']
puts get_text(nz, false).grep(/essagerie/)
show_table_content nz
puts
self
end
def login_noact
login false
end
def activate
set_ctx :action
get 'Activate_DLA.php'
show false
get_confirm
show false
profil
self
end
attr_reader :unreadmsg
def login(act = true, resumeonly=false)
if not curlogin
lg, ps, psr = mountycreds
@curlogin = lg
end
@@lastinstance = self
@unreadmsg = 0
@cookiefile = '.mounty.cookie.' << @curlogin
if File.exist?(@cookiefile)
puts 'reuse cookie'
@http_client.loadcookies(@cookiefile)
@http_client.get_url_allowed << '/mountyhall/MH_Play/Play.php'
begin
get '/mountyhall/MH_Play/Play.php'
profil
return self
rescue SessionExpired, SystemCallError
puts 'session expired'
File.unlink @cookiefile
end
get '/mountyhall/MH_Play/PlayStart.php'
else
get '/' if not @http_client.cur_url.to_s.include? '/mountyhall/MH_Play/PlayStart.php'
end
return if resumeonly
d 'logging in'
post('/mountyhall/MH_Play/PlayStart.php',
{'as_Login' => lg, 'as_Pwd' => ps,
'ai_design' => '20', 'ab_activation' => (act ? '1' : '0'),
'as_Action' => 'Entrer dans le Monde Souterrain'})
@http_client.savecookies(@cookiefile)
txt = get_text.to_a.reject { |l| l.chomp.empty? }
puts txt
if txt =~ /Vous avez .* TU./
puts '', 'OH SHI-', ''
logout rescue nil
return login(act, resumeonly)
end
get_confirm or puts("venin kill ?", txt.inspect)
profil
nz = @http_client.cache['/mountyhall/MH_Play/Play_news.php']
iline = get_text(nz, false).grep(/essagerie/).first
puts iline
@unreadmsg = iline[/\d+ non lu/].to_i
show_table_content nz
puts
self
end
def logout
d 'logout'
profil
get '/mountyhall/Logout.php'
File.unlink @cookiefile rescue nil
end
def menu_get(*a)
return @http_client.curpage if a.length == 1 and a.first == @http_client.cur_url
set_ctx :menu
get(*a)
end
def use_action(n, h=actions(false))
if @shortcuts and @shortcuts.include? n
return menu_get("/mountyhall/MH_Play/Play_action.php?ai_ToDo=#{n}&as_Action=ACTION!")
end
n = n.to_s
raise "invalid action #{n} not in #{h.inspect}" unless h[n]
set_ctx :action
get HttpServer.get_form_url('/mountyhall/MH_Play/Play_action.php', [['x', rand(40)], ['y', rand(20)], ['as_Action', 'ACTION !!'], ['as_SelectName', h[n]], ['as_Action2', ''], ['ai_ToDo', n]])
end
def toggle_shortcut(n, h=actions(false))
set_ctx :action
h.values.each { |v| v.sub!(/^( )([^ ])/, '\1 \2') } # fix sort != comp
n = n.to_s
get HttpServer.get_form_url('/mountyhall/MH_Play/Play_action.php', [['as_Action', 'ACTION !!'],['as_SelectName', h[n]],['as_Action2', 'Shortcuts'],['ai_ToDo', n]])
end
def actions(verbose=true)
p = @http_client.cache['/mountyhall/MH_Play/Play_action.php']
acts = {}
idx = nil
p.parse.each { |e|
case e.type
when 'optgroup'
puts '', e['label'] if verbose
when 'option'
idx = e['value'] unless e['value'].empty?
print idx.ljust(4) if idx and verbose
when 'String'
acts[idx] = e['content'] if idx
idx = nil
puts e['content'] if verbose
end
}
acts
end
end