Skip to content

Instantly share code, notes, and snippets.

@Nakilon
Last active September 18, 2016 16:02
Show Gist options
  • Save Nakilon/be3edb74a7943407aba243fd473cf4cc to your computer and use it in GitHub Desktop.
Save Nakilon/be3edb74a7943407aba243fd473cf4cc to your computer and use it in GitHub Desktop.
azona bot
source "https://rubygems.org"
gem "net_http_utils", ?0, gist: "97549ceb58d21e1fcbc0e6cdaf92fce8"
gem "nokogiri"
gem "byebug"
GIT
remote: https://gist.github.com/97549ceb58d21e1fcbc0e6cdaf92fce8.git
revision: 54c47ab3f9665f3e35a8e94fdd267e3743c736a9
specs:
net_http_utils (0)
GEM
remote: https://rubygems.org/
specs:
byebug (9.0.5)
mini_portile2 (2.1.0)
nokogiri (1.6.8)
mini_portile2 (~> 2.1.0)
pkg-config (~> 1.1.7)
pkg-config (1.1.7)
PLATFORMS
ruby
DEPENDENCIES
byebug
net_http_utils (= 0)!
nokogiri
BUNDLED WITH
1.12.5
STDOUT.sync = true
require "pp"
require "byebug"
require "logger"
logger = Logger.new "log.txt"
logger.formatter = proc do |severity, datetime, progname, msg|
template = "#{severity[0]} #{datetime.strftime "%y%m%d%H%M%S"} %s\n"
puts template % msg
template % msg.inspect
end
logger.level = ENV["LOGLEVEL"] ? Logger.const_get(ENV["LOGLEVEL"]) : Logger::WARN
t = ENV["LOGLEVEL"]
ENV["LOGLEVEL"] = ENV["LOGLEVEL_NETHTTPUTILS"]
require "net_http_utils"
ENV["LOGLEVEL"] = t
c = cp1251utf8 = lambda do |str|
Encoding::Converter.new("Windows-1251", "UTF-8", invalid: :replace, undef: :replace, replace: "").convert str
end
login, pass = File.read("password").split
logger.warn cookie = NetHTTPUtils.get_response("http://azona.ru/entrance.php", :post, form: {"login"=>login, "pass"=>pass})["set-cookie"]
require "nokogiri"
# pp Nokogiri::HTML t.body
# puts t.body.scan(/location\.href\s*=.{100}/m)
post = lambda do |php, fn, *fa|
# post = lambda do |php, fn, id = nil|
# path = "http://azona.ru/#{php}.php?fn=#{fn}&#{fa.map{ |i| "fa[]=" + URI.escape(i.to_s) }.join ?&}"
path = "http://azona.ru/#{php}.php?fn=#{fn}&#{fa.map{ |arg| "fa[]=#{arg}" }.join ?&}"
# path = "http://azona.ru/#{php}.php?fn=#{fn}&fa[]=#{id}"
NetHTTPUtils.request_data(
path,
# form: [["fn", fn]] + fa.map{ |i| ["fa[]", i] },
header: {
"Cookie" => cookie,
# "Referer" => path,
# "Content-Type" => "application/x-www-form-urlencoded",
},
)
end
max_allowed_level_to_attack = 6
mass = nil
loop do
zone = c.call NetHTTPUtils.request_data("http://azona.ru/zone.php", :post, form: {fn: "a_refr"}, header: {"Cookie" => cookie})
logger.info zone
next logger.warn "dead?" if zone == "location.href='locat.php'"
if zone == "location.href='battle.php'"
logger.info "battle: auto"
next post["battle", "a_auto_"]
end
zone.scan(/"a_gettool\((\d+),\\'([^\\,]+)\\',(\d+)/) do |id, name, num|
mass = nil
logger.warn "take: '#{name}' [#{num}]"
# post["zone", "a_gettool", id, name, num]
post["zone", "a_gettool", id]
end
zone.scan(/"a_getingrid\((\d+)\)\\"><br>• Поднять предмет <img src=[^>]+>(.+? x\d)</) do |id, name_and_num|
mass = nil
logger.warn "take: '#{name_and_num}'"
post["zone", "a_getingrid", id]
end
# fail unless setogr = zone[/(?<=;top\.setogr\()\d+(?=\))/]
abort zone unless zone[/(?<=;top\.sethp\()\d+,\d+,\d+(\.\d+)?(?=\))/]
sethp = $&.split(?,).map(&:to_f)
if sethp[2] >= 10 && c[post["inv", "a_refr_vesh", "30"]][/;add_ve\((\d+),\d+,0,"Антирад",0,1,"rad25\./]
logger.warn "antirad because of #{sethp}"
post["inv", "a_use", $1, login]
end
if sethp[0] < sethp[1] / 1.5
logger.info "recovering health #{sethp}"
sleep 5
next
end unless ENV["IGNORE_LOW_HP"]
goal = nil
unless mass
t = Nokogiri::HTML(NetHTTPUtils.request_data("http://azona.ru/inv.php", header: {"Cookie" => cookie})).at("#mass").text
mass = t[/\A\d+/].to_i, t[/(?<=:)\d+/].to_i
fail if mass[1].zero?
end
coords = lambda do
fail unless / \((-?\d+),(-?\d+)\)/ =~ zone
$~.captures.map &:to_i
end
if mass[0] >= mass[1] || ENV["IGNORE_LOW_WEIGHT"]
x, y = coords[]
if [x, y] == [0, 0]
sold_anything = false
[
[ 0, 3, "Жало комара", "жала комара", "не голоден"],
[-1, 5, "Клык мутособаки", "несколько клыков", "прокусил мне ногу"],
].each do |tab, m, quest, get, set|
if 0 < n = c[post["inv", "a_refr_vesh", tab, "1", "99"]].
scan(/;add_ve\((\d+),(\d+),\d,"([^"]+)",\d,\d,"[^"]+",\d+,\d,\d,\d,\d,\d,\d,\d,\d,\d,\d,\d,"",\d,\d,\d,"\d",\d,\d,\d+,"",\d,\d,\d+\)/).
map{ |id, n, name| n.to_i if name == quest }.compact.inject(0, :+) / m
logger.warn "selling '#{quest} x#{m}' x #{n}"
n.times do |i|
nil until c[NetHTTPUtils.request_data("http://azona.ru/bar.php?getquest=1", header: {"Cookie" => cookie})][get]
fail unless c[NetHTTPUtils.request_data("http://azona.ru/bar.php?setquest=1", header: {"Cookie" => cookie})][set]
sold_anything = true
end
end
end
c[post["inv", "a_ingrid"]].scan(/;add_ingrid\((\d+),"([^"]+)",(\d+),/) do |id, name, n|
logger.warn "storing: '#{name} x#{n}'"
fail unless c[post["storage", "a_prod_ingrid", id, n]]["Успешно сдано."]
sold_anything = true
end
c[post["inv", "a_refr_vesh", 7]].scan(/;add_ve\((\d+),1,0,"([^"]+)",0,(\d+),/) do |id, name, lvl|
next unless [
[/\A(Амулет несчастий|Бусины|Маленький браслет|Печень мутокрысы|Чешуя гусеницы|Шип)$/, 1..6],
].any? do |name_p, lvl_p|
name_p === name && lvl_p === lvl.to_i
end
logger.warn "storing: #{name} [#{lvl}]"
fail unless c[post["storage", "a_prod", id]][" успешно "]
sold_anything = true
end
abort "failed to sell anything" unless sold_anything
mass = nil
else
logger.warn "I am full -- heading to 'Выход из Зоны'"
goal = {
name: "(default) Выход из Зоны",
x: [[0 - x + 3, 1].max, 5].min,
y: [[0 - y + 3, 1].max, 5].min,
}
end
end
evaluate = lambda do |vector| # vector has have 1 more element at the end in case of local mobs
case vector[:type]
when "2" ; next # location
when "1" ; nil # mob
when "0" # player
logger.info "spotted #{vector}"
next
else ; fail "unknown type : #{vector}"
end
score = case "#{vector[:name]} #{vector[:lvl]}"
when "Гамма-комарик 1" ; 3 ; next
when "Радиоактивный червь 1" ; 1 ; next
when "Огромная гусеница 1" ; 2 ; next
when /\AМутокрыс [12]$/ ; next
when "Большой мутокрыс 3" ; next
when "Мутособака 6" ; 5
when "Клыкастая мутособака 6",
/\AСталкер \((юнец|неопытный|молодой)\) \d+$/,
/\AВоенный \((рядовой|капрал|сержант)\) \d+$/,
/\AБандит \((юнец|неопытный|молодой)\) \d+$/
vector[:lvl]
else ; fail "unknown creature : '#{vector[:name]} #{vector[:lvl]}'"
end
[ score, vector ] unless vector[:lvl] > max_allowed_level_to_attack
end
goal ||= (
_, t = zone.scan(/;al2\(([1-5]),([1-5]),'([^']+)',(\d+),(\d+),/).
map{ |x, y, name, lvl, type| {name: name, type: type, lvl: lvl.to_i, x: x.to_i, y: y.to_i} }.
map(&evaluate).compact.shuffle.min_by{ |score, vector| [-score, (3 - vector[:x]).abs + (3 - vector[:y]).abs] }
t || (
x, y = coords[]
logger.info "nothing to chase -- heading to 'Опора ЛЭП'"
{
name: "(default) Знак",
x: [[-2 - x + 3, 1].max, 5].min,
y: [[ 8 - y + 3, 1].max, 5].min,
}
# logger.info "nothing to chase -- heading to 'Знак'"
# {
# name: "(default) Знак",
# x: [[ 0 - x + 3, 1].max, 5].min,
# y: [[-7 - y + 3, 1].max, 5].min,
# }
# logger.info "nothing to chase -- heading to 'Выход из Зоны'"
# {
# name: "(default) Выход из Зоны",
# x: [[0 - x + 3, 1].max, 5].min,
# y: [[0 - y + 3, 1].max, 5].min,
# }
# logger.warn "nothing to chase -- setting the goal to 'Одинокий колодец'"
# goal = [0, "(default) Покосившийся туалет", 0, 0,
# [[-4 - $1.to_i + 3, 1].max, 5].min,
# [[ 3 - $2.to_i + 3, 1].max, 5].min,
# ]
)
)
steps = []
from, to = [goal[:x]-1, 2].sort; steps += [4, 4, nil, 3, 3][from..to].compact
from, to = [goal[:y]-1, 2].sort; steps += [1, 1, nil, 2, 2][from..to].compact
if steps.empty?
_, goal = zone.scan(/;al\((\d+),'([^']+)',(\d+),'','',\d+,\d+,(\d+),/).
map{ |id, name, lvl, type| {name: name, type: type, lvl: lvl.to_i, x: 3, y: 3, id: id} }.
map(&evaluate).compact.min_by{ |score, vector| [-score, (3 - vector[:x]).abs + (3 - vector[:y]).abs] }
next (logger.error "nothing to do at #{coords[]}"; sleep 5) unless goal
logger.info "attack: ##{goal[:id]}: #{goal[:name]} [#{goal[:lvl]}]"
post["zone", "a_attackmob", goal[:id]]
else
logger.info "heading: '#{goal[:name]}' at (#{goal[:x]},#{goal[:y]})"
post["zone", "a_go", steps.sample]
sleep 1
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment