This is great For those of you using a MacBook, ruby may be natively installed on your computer. In that case, it's so simple to use. To see if you have Ruby installed open up a Terminal window and type:
ruby -v
Should you have Ruby installed, a version will be displayed. To run this program without having to download an executable, copy the portion of code referenced, paste it in a TextEdit window (makes sure to convert to plain text!) and save the file with a .rb extension. Open a terminal window and navigate to wherever you saved the file (cd = show directories; ls = list files) and once you are in the folder where you saved the .rb file, type ruby (NAME OF YOUR FILE).rb. The script will begin to run automatically!
Sorry if this is double post information.. I don't ever see a lot of love for the mac users. Thanks for the program! Lots of programming handiwork.. much appreciated.
I made a slightly edited version of this script that fixes the crashing in the bank account part. Now you don't have to do it manually! Also added some features that make this bot more legit, such as a predefined delay and using an actual user agent as default.
To use the edited script, copy paste this into a text editor and save it as altador.rb (or anything you like) in the file Documents.
Macs: Go to your terminal and navigate to the file path (use the command "cd Documents" if you saved this script in your Documents file) and type "ruby altador.rb" into your terminal. Then, you will be prompted for your username if all goes well.
Windows: I'm not as familiar with Windows, but I think this is how it goes. First download ruby here: http://rubyinstaller.org
Once you have ruby downloaded, open the ruby file and click on "Start Command Prompt with Ruby". A command line will pop up. Navigate to your file path (use the command "cd Documents" if you saved the script in your Documents file) and use the command "ruby altador.rb" into the command line. If all goes well, you will be prompted for your username.
Mac version of script:
Spoiler
#!/usr/bin/env ruby
require 'cgi'
require 'net/http'
class Array #nitrowuzhear #cellos #hashtag
def +(other)
(0...self.size).map { |i| self[i] + other[i] }
end
end
def get(url)
sleep Delay
Conn.get(url, Headers).body
end
def post(url, data = {})
sleep Delay
data = data.is_a?(String) ? data : data.zip.flatten(1).map { |e| e * '=' } * '&'
Conn.post(url, data, Headers)
end
def plot(which, spellbook = false)
data = get STAR_DATA
coords = data.split(':')[0].split('|').map { |d| d.split(',')[0..1].map &:to_i }
map = {
'sleeper' => [[0, 0], [40, -30], [80, -60], [120, -60], [160, -30], [200, 0]],
'dreamer' => [[0, 0], [60, -20], [120, 0], [130, 40], [190, 60], [110, -90]],
'rise' => [[0, 0], [20, 60], [80, 80], [160, 0], [140, -60], [80, -80]],
'farmer' => [[0, 0], [140, -30], [10, -80], [120, -60], [160, -70], [80, 60]],
'dancer' => [[0, 0], [60, -30], [120, 0], [0, 140], [60, 170], [120, 140]],
'wave' => [[0, 0], [50, 70], [170, 40], [200, 0], [190, -90], [140, -10]],
'gladiator' => [[0, 0], [70, 30], [140, 0], [40, -120], [70, -140], [100, -120]],
'collector' => [[0, 0], [10, -50], [100, -130], [100, 10], [190, -50], [200, 0]],
'thief' => [[0, 0], [40, 40], [20, -40], [40, -80], [-50, -10], [-60, 120]],
'gatherer' => [[0, 0], [40, -70], [-30, -140], [10, -200], [110, -170], [120, -90]],
'protector' => [[0, 0], [-70, 0], [70, 0], [0, -70], [0, 70], [-130, 90]],
'hunter' => [[0, 0], [10, -140], [120, -60], [160, -190], [170, -20], [200, 0]]
}
connect = {
'sleeper' => [[0, 1], [1, 2], [3, 4], [4, 5]],
'dreamer' => [[0, 1], [1, 2], [2, 3], [3, 4], [5]],
'rise' => [[0, 1], [1, 2], [3, 4], [4, 5]],
'farmer' => [[0, 1], [1, 5], [1, 4], [2, 3], [3, 4]],
'dancer' => [[0, 1], [1, 2], [3, 4], [4, 5]],
'wave' => [[0, 1], [1, 2], [2, 3], [3, 4], [4, 5]],
'gladiator' => [[0, 1], [1, 2], [2, 5], [3, 4], [4, 5], [0, 3]],
'collector' => [[0, 1], [0, 3], [2, 3], [3, 5], [4, 5]],
'thief' => [[0, 1], [0, 2], [0, 4], [1, 5], [2, 3], [4, 5]],
'gatherer' => [[0, 1], [2, 3], [2, 5], [3, 4], [4, 5]],
'protector' => [[0, 1], [0, 2], [0, 3], [0, 4], [1, 3], [1, 4], [2, 3], [2, 4], [5]],
'hunter' => [[0, 1], [0, 4], [1, 2], [1, 3], [2, 4], [3, 4], [4, 5]]
}
found = coords.map do |c|
(seek = map[which].map { |m| m + c }).all? { |k| coords.include? k } ? seek : nil
end.compact[0]
x = found.map { |f| f[0] }.reduce(:+).abs
x = x.to_s.split(//).map(&:to_i).reduce(:+) if x > 99
y = found.map { |f| f[1] }.reduce(:+).abs
y = y.to_s.split(//).map(&:to_i).reduce(:+) if y > 99
return [x, y] if spellbook
qs = connect[which].map { |e| [e, e.reverse].uniq }.flatten(1).map do |c|
c.map { |i| found[i] * ',' } * ';'
end * '|'
get PLOT_DATA + CGI.escape(qs)
end
username = (print 'Username: '; gets.chomp)
password = (print 'Password: '; gets.chomp)
puts "\nProxy is of the form #.#.#.#:#, leave blank for none."
proxy = (print 'Proxy: '; gets.chomp)
puts "\nYou should use your actual User-Agent if playing on your own IP address."
puts 'Using Firefox 25.0 (Macintosh) user agent.'
user_agent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:25.0) Gecko/20100101 Firefox/25.0"
puts "\nHow long should the program wait (in seconds) between requests?"
puts 'Currently delay is 2 seconds to make it look more legit. You can use 0, but >=2 is recommended.'
Delay = 2
if proxy.empty?
Conn = Net::HTTP.start('www.neopets.com')
else
Conn = Net::HTTP::Proxy(*proxy.split(':')).start('www.neopets.com')
end
Headers = {'User-Agent' => user_agent.empty? ? 'Mozilla/5.001 (windows; U; NT4.0; en-US; rv:1.0) Gecko/25250101' : user_agent}
resp = post '/login.phtml', 'username' => username, 'password' => password
cookie = resp.get_fields('Set-Cookie').map { |c| c.split(';')[0] } * ';'
Headers['Cookie'] = cookie
ARCHIVES = '/altador/archives.phtml'
ARCHIVIST = '/altador/archives.phtml?archivist=1'
BANK = '/process_bank.phtml'
BASEMENT = '/altador/hallofheroes.phtml?basement=1'
CLOUDS = '/altador/clouds.phtml'
COLOSSEUM = '/altador/colosseum.phtml'
COUNCIL = '/altador/council.phtml'
DOCKS = '/altador/docks.phtml'
DONNY = '/winter/brokentoys.phtml'
FARM = '/altador/farm.phtml'
GET_BOOK = '/altador/archives.phtml?archivist=1&get_book=1&acpcont=1'
GET_ROCK = '/altador/quarry.phtml?get_rock=1&acpcont=1'
HALL = '/altador/hallofheroes.phtml'
JANITOR = '/altador/hallofheroes.phtml?janitor=1'
PETPET = '/altador/petpet.phtml?ppheal=1'
PLOT_DATA = '/altador/astro.phtml?star_submit='
PUSH_BUTTON = '/altador/hallofheroes.phtml?janitor=1&push_button=1'
QUARRY = '/altador/quarry.phtml'
SHOP = '/objects.phtml?type=shop&obj_type='
STAIRS = '/altador/hallofheroes.phtml?stairs=1'
STAR_DATA = '/altador/astro.phtml?get_star_data=1'
TOMB = '/altador/tomb.phtml'
VIEW_STATUE = '/altador/hallofheroes.phtml?view_statue_id='
WALL = '/altador/wall.phtml'
step_finder = {
'begin' => "I'm Finneus",
'get_book' => "perhaps there's a book",
'replace_book' => "stabilise this table",
'get_oil' => "would someone print",
'join_astro' => "opened? What a marvel!",
'sleeper_act' => "you've joined the Astronomy Club",
'sleeper_plot' => "front of that old tomb?",
'dreamer_act' => "Her eyes, in fact?",
'dreamer_plot' => "floating in the clouds?",
'rise_act' => "seems to concern Psellia",
'rise_plot' => "conspires to bring us wisdom",
'farmer_act' => "Ah, Siyana.",
'farmer_plot' => "in a pattern of wheat",
'dancer_act' => "bringing us foodstuffs",
'dancer_plot' => "underground dancing establishment",
'wave_act' => "those dancing ruffians",
'wave_plot' => "And the waves, too",
'gladiator_act' => "revealed by the sea",
'gladiator_plot' => "on a drinking vessel?",
'collector_act' => "And found at the Colosseum",
'collector_plot' => "an item relating to money",
'thief_act' => "suspected: Gordos",
'thief_plot' => "my poor Meepit plushie",
'find_petpet' => "constellation found on a dagger",
'gatherer_act' => "What a poor little Vaeolus!",
'gatherer_plot' => "get back to his owner",
'protector_act' => "Gatherer, protector of Petpets",
'protector_plot' => "someone with nothing to hide",
'open_ceiling' => "we come to Jerdana",
'basement' => "We may as well get this over with.",
'hunter_act' => "probably isn't in the same",
'hunter_plot' => "but simple physical mechanics",
'book_of_ages' => "each of the twelve Heroes",
'spellbook' => "I'd overlooked that drawing of",
'finish' => "well-deserved vacation"
}
puts 'Determining your current step...'
status = get(ARCHIVIST)[/<IMG.+?altador.+?DIV><BR>(.+?)<cen/, 1]
steps = step_finder.keys
current = steps.find { |s| status.include? step_finder[s] }
steps.shift steps.index(current)
while step = steps.shift
case step
when 'begin'
post "#{PUSH_BUTTON}&acpcont=1"
puts 'Pushed button.'
when 'get_book'
post GET_BOOK
puts 'Got book.'
when 'replace_book'
post GET_BOOK
post GET_ROCK
puts 'Got rock.'
post GET_BOOK
puts 'Replaced book.'
when 'get_oil'
puts 'Finding the oil...'
get HALL
html = get JANITOR
unless html[/put some on the button/]
get PUSH_BUTTON
statue, oil_link = rand(1..12), nil
puts "Refreshing statue #{statue}..."
until (oil_link = html[/action='(.+?soh=.+?)'/, 1])
html = get "#{VIEW_STATUE}#{statue}"
end
get oil_link
end
puts 'Oiled the statue.'
get PUSH_BUTTON
post "#{PUSH_BUTTON}&acpcont=1"
when 'join_astro'
post ARCHIVES, 'board' => 6, 'join_club' => 1
puts 'Joined the Astronomy Club.'
when 'sleeper_act'
html = get TOMB
get html[/href="([^<>]+?thv=.+?)"/, 1]
puts 'Activated the Sleeper constellation.'
get ARCHIVIST
when 'sleeper_plot'
plot 'sleeper'
puts 'Plotted the Sleeper constellation.'
when 'dreamer_act'
html = get CLOUDS
get html[/href="([^<>]+?chv=.+?)"/, 1]
puts 'Activated the Dreamer constellation.'
get ARCHIVIST
when 'dreamer_plot'
plot 'dreamer'
puts 'Plotted the Dreamer constellation.'
when 'rise_act'
html = get TOMB
get html[/href="([^<>]+?acvhv=.+?)"/, 1]
html = get "#{VIEW_STATUE}11"
html = get html[/href="([^<>]+?vwhv=.+?)"/, 1]
get html[/href="([^<>]+?rhv=.+?)"/, 1]
puts 'Activated the First to Rise constellation.'
get ARCHIVIST
when 'rise_plot'
plot 'rise'
puts 'Plotted the First to Rise constellation.'
when 'farmer_act'
html = get FARM
html = get html[/href="([^<>]+?windmill=.+?)"/, 1]
html = get html[/href="([^<>]+?umhv=.+?)"/, 1]
html = get html[/href="([^<>]+?vfhv=.+?)"/, 1]
get html[/href="([^<>]+?wfhv=.+?)"/, 1]
puts 'Activated the Farmer constellation.'
get ARCHIVIST
when 'farmer_plot'
plot 'farmer'
puts 'Plotted the Farmer constellation.'
when 'dancer_act'
html = get "#{ARCHIVES}?board=7"
get html[/href="([^<>]+?swhv=.+?)"/, 1]
puts 'Activated the Dancer constellation.'
get ARCHIVIST
when 'dancer_plot'
plot 'dancer'
puts 'Plotted the Dancer constellation.'
when 'wave_act'
html = get DOCKS
get html[/href="([^<>]+?wchv=.+?)"/, 1]
puts 'Activated the Wave constellation.'
get ARCHIVIST
when 'wave_plot'
plot 'wave'
puts 'Plotted the Wave constellation.'
when 'gladiator_act'
get "#{ARCHIVES}?board=6"
puts 'Got a broken astrolabe.'
html = get DONNY
get (url = html[/href="([^<>]+?repair_id=.+?)"/, 1])
post DONNY, 'repair_id' => url.split('=')[1], 'confirm' => 1
puts 'Fixed the broken astrolabe.'
html = get COLOSSEUM
puts 'Finding the Punch Club Grarrl...'
links = html.scan(/href="([^<>]+?pchv=.+?)"/).flatten.shuffle
html, arch = '487738fe33.gif', 0
while html.include? '487738fe33.gif'
puts "Trying arch ##{arch += 1}..."
html = get($punch_club = links.pop)
end
puts 'Found him! Going to Punch Club...'
html = get "#{$punch_club}&pc_go=1"
bowls, found = html.scan(/punch1=(.+?)"/), nil
puts '27 bowl combinations, this might take a bit...'
found = nil
[*(0..26)].shuffle.each_with_index do |n, c|
puts "Trying combination ##{c + 1}..."
qs, perm = [], [n / 9, n / 3 % 3, n % 3].map { |i| bowls[i] }
perm.each_with_index { |p, i| qs << "punch#{i + 1}=#{p[0]}"}
html = get "#{$punch_club}&pc_go=1&#{qs * '&'}"
break if (found = html[/href="([^<>]+?gchv=.+?)"/, 1])
end
html = get found
get html[/href="([^<>]+?olhv=.+?)"/, 1]
puts 'Activated the Gladiator constellation... finally.'
get ARCHIVIST
when 'gladiator_plot'
plot 'gladiator'
puts 'Plotted the Gladiator constellation.'
when 'collector_act'
found = nil
(94..96).each do |id|
html = get "#{SHOP}#{id}"
cur = html[/inventory.phtml">(.+?)</, 1].gsub(/[^\d]/, '').to_i
amount = html[/at <b>(.+?)%</, 1].gsub('.', '').to_i
if cur != amount
puts "You have #{cur} NP right now."
puts "Setting your NP to #{amount}..."
post BANK, 'type' => (cur < amount ? 'withdraw' : 'deposit'), 'amount' => (cur - amount).abs
end
html = get "#{SHOP}#{id}"
break if (found = html[/href="([^<>]+?gohv=.+?)"/, 1])
end
get found
puts 'Activated the Collector constellation.'
get ARCHIVIST
when 'collector_plot'
plot 'collector'
puts 'Plotted the Collector constellation.'
when 'thief_act'
puts 'Lots of jumping around for the Meepit part, might take a bit...'
get "#{ARCHIVES}?lclenny=1"
html = get ARCHIVIST
html = get html[/href="([^<>]+?distract=.+?)"/, 1]
get html[/href="([^<>]+?steal=.+?)"/, 1]
get "#{ARCHIVES}?lclenny=1"
html = get ARCHIVES
html = get html[/href="([^<>]+?goarch=.+?)"/, 1]
3.times { html = get html[/href="([^<>]+?cmhv=.+?)"/, 1] }
html = get (url = html[/href="([^<>]+?closet=.+?)"/, 1])
post ARCHIVES, 'closet' => url.split('=')[-1], 'hide_box' => 1
html = get ARCHIVIST
html = get html[/href="([^<>]+?distract=.+?)"/, 1]
get html[/href="([^<>]+?steal=.+?)"/, 1]
html = get "#{ARCHIVES}?lclenny=1&acpcont=1"
get html[/href="([^<>]+?rdhv=.+?)"/, 1]
puts 'Activated the Thief constellation.'
get ARCHIVIST
when 'thief_plot'
plot 'thief'
puts 'Plotted the Thief constellation.'
get "#{ARCHIVES}?board=7"
when 'find_petpet'
puts 'Looking for the Vaeolus...'
[FARM, DOCKS, QUARRY].each do |loc|
found = get(loc)[/href="([^<>]+?pphv=.+?)"/, 1]
get("/altador/#{found}") if found
end
get ARCHIVIST
when 'gatherer_act'
puts 'Vaeolus-curing time.'
get PETPET
html = get "#{ARCHIVES}?board=5"
if (url = html[/href="([^<>]+?bmhv=.+?)"/, 1])
get "#{url}&acpcont=1"
puts 'Got medicine.'
end
if $punch_club
puts 'Remembered Punch Club arch from last time.'
else
html = get COLOSSEUM
puts 'Gotta find the Punch Club arch...'
links = html.scan(/href="([^<>]+?pchv=.+?)"/).flatten.shuffle
html, arch = '487738fe33.gif', 0
while html.include? '487738fe33.gif'
puts "Trying arch ##{arch += 1}..."
html = get($punch_club = links.pop)
end
puts 'Found it!'
end
html = get "#{$punch_club}&pc_go=1"
if (url = html[/href="([^<>]+?sphv=.+?)"/, 1])
get "#{url}&acpcont=1"
puts 'Got blueberry pie.'
end
tomb = get(TOMB)[/href="([^<>]+?tehv=.+?)"/, 1]
html, i = 'dc697034c4.gif', 0
puts 'Refreshing at the blob...'
while html.include? 'dc697034c4.gif'
html = get tomb
if (i += 1) > 35
have_bandage = true
puts 'I guess you already have it.'
break
end
end
unless have_bandage
html = get (url = html[/href="([^<>]+?gbhv=.+?)"/, 1])
puts "Got bandage."
get "#{url}&acpcont=1"
end
html = get PETPET
until html.include? 'b1022d8a5a.gif'
act = html[/act_(.)/, 1]
links = html.split('300"')[1].split('<c')[0].scan(/href="(.+?)"/).flatten
html = get (url = links['bacd'.index(act)])
puts case act
when 'a' then 'Bandaged the Vaeolus.'
when 'b' then 'Fed the Vaeolus.'
when 'c' then 'Medicated the Vaeolus.'
else 'Waited for the Vaeolus.'
end
delay = 60 - html[/ns = (\d+)/, 1].to_i
puts "Sleeping for #{delay} seconds..."
sleep delay
puts "after sleep"
html = get html.split('300"')[1].split('<c')[0].scan(/href="(.+?)"/).flatten[-1]
end
get html[/href="([^<>]+?pchv=.+?)"/, 1]
puts 'Activated the Gatherer constellation.'
get "#{ARCHIVES}?board=6"
get ARCHIVIST
when 'gatherer_plot'
plot 'gatherer'
puts 'Plotted the Gatherer constellation.'
when 'protector_act'
html = get QUARRY
html = get WALL
html = get html[/href="([^<>]+?sdhv=.+?)"/, 1]
html = get(url = html[/href="([^<>]+?tnhv=.+?)"/, 1])
get "#{url}&acpcont=1"
get FARM
switches, i = %w[r1v1 r1v2 r2v3 r2v4 r2s1 r3s2 r3s3 r3s4], 0
puts 'Gonna throw a whole bunch of switches, this will take a while...'
until html.include? '611538397c.gif'
s, i = switches.sample, i + 1
html = get "/altador/plant.phtml?room=#{s[1]}&act=#{s}"
puts '.' * (i / 10) if i % 10 == 0
end
puts 'Done throwing switches.'
html = get WALL
html = get html[/href="([^<>]+?sdhv=.+?)"/, 1]
html = get html[/href="([^<>]+?tnhv=.+?)"/, 1]
html = get html[/href="([^<>]+?olhv=.+?)"/, 1]
puts 'Activated the Protector constellation.'
get ARCHIVIST
when 'protector_plot'
resp = plot 'protector'
puts 'Plotted the Protector constellation.'
when 'open_ceiling'
html = get STAIRS
trip = html[/"trip" value="(.+?)"/, 1]
html = post(HALL, 'trip' => trip).body
get html[/href="([^<>]+?hohv=.+?)"/, 1]
puts 'Opened the roof.'
get ARCHIVIST
when 'basement'
get JANITOR
get BASEMENT
puts 'Activated the basement.'
when 'hunter_act'
html = get QUARRY
if (url = html[/href="([^<>]+?brhv=.+?)"/, 1])
html = get url
post QUARRY, 'brhv' => url.split('=')[1], 'go_buy_rock' => 1
puts 'Bought a rock.'
end
get JANITOR
get "#{BASEMENT}&gear=0"
get HALL
get "#{BASEMENT}&gear=0"
html = get QUARRY
if (url = html[/href="([^<>]+?trhv=.+?)"/, 1])
html = get url
html = get html[/href="([^<>]+?srhv=.+?)"/, 1]
html = get html[/href="([^<>]+?gthv=.+?)"/, 1]
puts 'Got another rock. You so silly, JubJubs.'
end
html = get "#{ARCHIVES}?board=1"
html = get "#{ARCHIVES}?board=1&circus=1"
html = get "#{ARCHIVES}?board=1&juggle=1"
html = get QUARRY
if (url = html[/href="([^<>]+?jjhv=.+?)"/, 1])
html = get url
post QUARRY, 'jjhv' => url.split('=')[1], 'r3hv' => html[/"r3hv" value="(.+?)"/, 1]
puts 'Got the third rock.'
end
puts "Time to jam some gears."
begin
html, offset, gears = '', 0, [*(0..9)].shuffle
until html[/MAP/]
gear = gears.pop
get "#{BASEMENT}&gear=#{gear}"
html = get PUSH_BUTTON
if html[/stupid rocks and such/]
puts 'The Janitor reset the roof. Trying again...'
raise ArgumentError
end
moved = html[/_r(\d+)_/, 1].to_i / 5
if (4..6) === moved - offset
offset += moved
puts "Gear #{gear} was a success."
else
puts "We don't need gear #{gear}."
get "#{BASEMENT}&gear=#{gear}"
end
end
rescue ArgumentError
retry
end
get html[/href="([^<>]+?olhv=.+?)"/, 1]
puts 'Activated the Hunter constellation.'
when 'hunter_plot'
plot 'hunter'
puts 'Plotted the Hunter constellation.'
when 'book_of_ages'
html = get "#{ARCHIVIST}&examine_book=1&view_page=53"
get html[/href="([^<>]+?dfhv=.+?)"/, 1]
puts "Clicked the Darkest Faerie's flame hands."
get ARCHIVIST
when 'spellbook'
html = get ARCHIVES
html = get html[/href="([^<>]+?goarch=.+?)"/, 1]
url = html[/href="([^<>]+?cmhv=.+?)"/, 1]
x, y = plot 'sleeper', true
html = get url.gsub(/arcx=\d+&arcy=\d+/, "arcx=#{x}&arcy=#{y}")
puts 'Found your archive room, now to find the book...'
links, i = html.scan(/href="([^<>]+?read_book=.+?)"/).flatten.shuffle, 0
until html[/52,143/]
puts "Trying book ##{i += 1}..."
html = get(data = links.pop)
end
puts 'Found it! Casting spell #29884...'
resp = post ARCHIVES, "#{data.split('?')[1]}&spell_id=29884"
html = get "#{VIEW_STATUE}6"
html = get html[/href="([^<>]+?necklace=.+?)"/, 1]
puts 'Placed the necklace!'
post COUNCIL, 'ephv' => html[/\?ephv=(.+?)'/, 1]
when 'finish'
html = get COUNCIL
get html[/href="([^<>]+?prhv=.+?)"/, 1]
puts 'Mission complete! We hope you enjoyed your stay.'
gets
end
end
Windows version of script
Spoiler
#!/usr/bin/env ruby
require 'cgi'
require 'net/http'
class Array #nitrowuzhear #cellos #hashtag
def +(other)
(0...self.size).map { |i| self[i] + other[i] }
end
end
def get(url)
sleep Delay
Conn.get(url, Headers).body
end
def post(url, data = {})
sleep Delay
data = data.is_a?(String) ? data : data.zip.flatten(1).map { |e| e * '=' } * '&'
Conn.post(url, data, Headers)
end
def plot(which, spellbook = false)
data = get STAR_DATA
coords = data.split(':')[0].split('|').map { |d| d.split(',')[0..1].map &:to_i }
map = {
'sleeper' => [[0, 0], [40, -30], [80, -60], [120, -60], [160, -30], [200, 0]],
'dreamer' => [[0, 0], [60, -20], [120, 0], [130, 40], [190, 60], [110, -90]],
'rise' => [[0, 0], [20, 60], [80, 80], [160, 0], [140, -60], [80, -80]],
'farmer' => [[0, 0], [140, -30], [10, -80], [120, -60], [160, -70], [80, 60]],
'dancer' => [[0, 0], [60, -30], [120, 0], [0, 140], [60, 170], [120, 140]],
'wave' => [[0, 0], [50, 70], [170, 40], [200, 0], [190, -90], [140, -10]],
'gladiator' => [[0, 0], [70, 30], [140, 0], [40, -120], [70, -140], [100, -120]],
'collector' => [[0, 0], [10, -50], [100, -130], [100, 10], [190, -50], [200, 0]],
'thief' => [[0, 0], [40, 40], [20, -40], [40, -80], [-50, -10], [-60, 120]],
'gatherer' => [[0, 0], [40, -70], [-30, -140], [10, -200], [110, -170], [120, -90]],
'protector' => [[0, 0], [-70, 0], [70, 0], [0, -70], [0, 70], [-130, 90]],
'hunter' => [[0, 0], [10, -140], [120, -60], [160, -190], [170, -20], [200, 0]]
}
connect = {
'sleeper' => [[0, 1], [1, 2], [3, 4], [4, 5]],
'dreamer' => [[0, 1], [1, 2], [2, 3], [3, 4], [5]],
'rise' => [[0, 1], [1, 2], [3, 4], [4, 5]],
'farmer' => [[0, 1], [1, 5], [1, 4], [2, 3], [3, 4]],
'dancer' => [[0, 1], [1, 2], [3, 4], [4, 5]],
'wave' => [[0, 1], [1, 2], [2, 3], [3, 4], [4, 5]],
'gladiator' => [[0, 1], [1, 2], [2, 5], [3, 4], [4, 5], [0, 3]],
'collector' => [[0, 1], [0, 3], [2, 3], [3, 5], [4, 5]],
'thief' => [[0, 1], [0, 2], [0, 4], [1, 5], [2, 3], [4, 5]],
'gatherer' => [[0, 1], [2, 3], [2, 5], [3, 4], [4, 5]],
'protector' => [[0, 1], [0, 2], [0, 3], [0, 4], [1, 3], [1, 4], [2, 3], [2, 4], [5]],
'hunter' => [[0, 1], [0, 4], [1, 2], [1, 3], [2, 4], [3, 4], [4, 5]]
}
found = coords.map do |c|
(seek = map[which].map { |m| m + c }).all? { |k| coords.include? k } ? seek : nil
end.compact[0]
x = found.map { |f| f[0] }.reduce(:+).abs
x = x.to_s.split(//).map(&:to_i).reduce(:+) if x > 99
y = found.map { |f| f[1] }.reduce(:+).abs
y = y.to_s.split(//).map(&:to_i).reduce(:+) if y > 99
return [x, y] if spellbook
qs = connect[which].map { |e| [e, e.reverse].uniq }.flatten(1).map do |c|
c.map { |i| found[i] * ',' } * ';'
end * '|'
get PLOT_DATA + CGI.escape(qs)
end
username = (print 'Username: '; gets.chomp)
password = (print 'Password: '; gets.chomp)
puts "\nProxy is of the form #.#.#.#:#, leave blank for none."
proxy = (print 'Proxy: '; gets.chomp)
puts "\nYou should use your actual User-Agent if playing on your own IP address."
puts 'Using Chrome 32.0 (Windows) user agent.'
user_agent = "Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1667.0 Safari/537.36"
puts "\nHow long should the program wait (in seconds) between requests?"
puts 'Currently delay is 2 seconds to make it look more legit. You can use 0, but >=2 is recommended.'
Delay = 2
if proxy.empty?
Conn = Net::HTTP.start('www.neopets.com')
else
Conn = Net::HTTP::Proxy(*proxy.split(':')).start('www.neopets.com')
end
Headers = {'User-Agent' => user_agent.empty? ? 'Mozilla/5.001 (windows; U; NT4.0; en-US; rv:1.0) Gecko/25250101' : user_agent}
resp = post '/login.phtml', 'username' => username, 'password' => password
cookie = resp.get_fields('Set-Cookie').map { |c| c.split(';')[0] } * ';'
Headers['Cookie'] = cookie
ARCHIVES = '/altador/archives.phtml'
ARCHIVIST = '/altador/archives.phtml?archivist=1'
BANK = '/process_bank.phtml'
BASEMENT = '/altador/hallofheroes.phtml?basement=1'
CLOUDS = '/altador/clouds.phtml'
COLOSSEUM = '/altador/colosseum.phtml'
COUNCIL = '/altador/council.phtml'
DOCKS = '/altador/docks.phtml'
DONNY = '/winter/brokentoys.phtml'
FARM = '/altador/farm.phtml'
GET_BOOK = '/altador/archives.phtml?archivist=1&get_book=1&acpcont=1'
GET_ROCK = '/altador/quarry.phtml?get_rock=1&acpcont=1'
HALL = '/altador/hallofheroes.phtml'
JANITOR = '/altador/hallofheroes.phtml?janitor=1'
PETPET = '/altador/petpet.phtml?ppheal=1'
PLOT_DATA = '/altador/astro.phtml?star_submit='
PUSH_BUTTON = '/altador/hallofheroes.phtml?janitor=1&push_button=1'
QUARRY = '/altador/quarry.phtml'
SHOP = '/objects.phtml?type=shop&obj_type='
STAIRS = '/altador/hallofheroes.phtml?stairs=1'
STAR_DATA = '/altador/astro.phtml?get_star_data=1'
TOMB = '/altador/tomb.phtml'
VIEW_STATUE = '/altador/hallofheroes.phtml?view_statue_id='
WALL = '/altador/wall.phtml'
step_finder = {
'begin' => "I'm Finneus",
'get_book' => "perhaps there's a book",
'replace_book' => "stabilise this table",
'get_oil' => "would someone print",
'join_astro' => "opened? What a marvel!",
'sleeper_act' => "you've joined the Astronomy Club",
'sleeper_plot' => "front of that old tomb?",
'dreamer_act' => "Her eyes, in fact?",
'dreamer_plot' => "floating in the clouds?",
'rise_act' => "seems to concern Psellia",
'rise_plot' => "conspires to bring us wisdom",
'farmer_act' => "Ah, Siyana.",
'farmer_plot' => "in a pattern of wheat",
'dancer_act' => "bringing us foodstuffs",
'dancer_plot' => "underground dancing establishment",
'wave_act' => "those dancing ruffians",
'wave_plot' => "And the waves, too",
'gladiator_act' => "revealed by the sea",
'gladiator_plot' => "on a drinking vessel?",
'collector_act' => "And found at the Colosseum",
'collector_plot' => "an item relating to money",
'thief_act' => "suspected: Gordos",
'thief_plot' => "my poor Meepit plushie",
'find_petpet' => "constellation found on a dagger",
'gatherer_act' => "What a poor little Vaeolus!",
'gatherer_plot' => "get back to his owner",
'protector_act' => "Gatherer, protector of Petpets",
'protector_plot' => "someone with nothing to hide",
'open_ceiling' => "we come to Jerdana",
'basement' => "We may as well get this over with.",
'hunter_act' => "probably isn't in the same",
'hunter_plot' => "but simple physical mechanics",
'book_of_ages' => "each of the twelve Heroes",
'spellbook' => "I'd overlooked that drawing of",
'finish' => "well-deserved vacation"
}
puts 'Determining your current step...'
status = get(ARCHIVIST)[/<IMG.+?altador.+?DIV><BR>(.+?)<cen/, 1]
steps = step_finder.keys
current = steps.find { |s| status.include? step_finder[s] }
steps.shift steps.index(current)
while step = steps.shift
case step
when 'begin'
post "#{PUSH_BUTTON}&acpcont=1"
puts 'Pushed button.'
when 'get_book'
post GET_BOOK
puts 'Got book.'
when 'replace_book'
post GET_BOOK
post GET_ROCK
puts 'Got rock.'
post GET_BOOK
puts 'Replaced book.'
when 'get_oil'
puts 'Finding the oil...'
get HALL
html = get JANITOR
unless html[/put some on the button/]
get PUSH_BUTTON
statue, oil_link = rand(1..12), nil
puts "Refreshing statue #{statue}..."
until (oil_link = html[/action='(.+?soh=.+?)'/, 1])
html = get "#{VIEW_STATUE}#{statue}"
end
get oil_link
end
puts 'Oiled the statue.'
get PUSH_BUTTON
post "#{PUSH_BUTTON}&acpcont=1"
when 'join_astro'
post ARCHIVES, 'board' => 6, 'join_club' => 1
puts 'Joined the Astronomy Club.'
when 'sleeper_act'
html = get TOMB
get html[/href="([^<>]+?thv=.+?)"/, 1]
puts 'Activated the Sleeper constellation.'
get ARCHIVIST
when 'sleeper_plot'
plot 'sleeper'
puts 'Plotted the Sleeper constellation.'
when 'dreamer_act'
html = get CLOUDS
get html[/href="([^<>]+?chv=.+?)"/, 1]
puts 'Activated the Dreamer constellation.'
get ARCHIVIST
when 'dreamer_plot'
plot 'dreamer'
puts 'Plotted the Dreamer constellation.'
when 'rise_act'
html = get TOMB
get html[/href="([^<>]+?acvhv=.+?)"/, 1]
html = get "#{VIEW_STATUE}11"
html = get html[/href="([^<>]+?vwhv=.+?)"/, 1]
get html[/href="([^<>]+?rhv=.+?)"/, 1]
puts 'Activated the First to Rise constellation.'
get ARCHIVIST
when 'rise_plot'
plot 'rise'
puts 'Plotted the First to Rise constellation.'
when 'farmer_act'
html = get FARM
html = get html[/href="([^<>]+?windmill=.+?)"/, 1]
html = get html[/href="([^<>]+?umhv=.+?)"/, 1]
html = get html[/href="([^<>]+?vfhv=.+?)"/, 1]
get html[/href="([^<>]+?wfhv=.+?)"/, 1]
puts 'Activated the Farmer constellation.'
get ARCHIVIST
when 'farmer_plot'
plot 'farmer'
puts 'Plotted the Farmer constellation.'
when 'dancer_act'
html = get "#{ARCHIVES}?board=7"
get html[/href="([^<>]+?swhv=.+?)"/, 1]
puts 'Activated the Dancer constellation.'
get ARCHIVIST
when 'dancer_plot'
plot 'dancer'
puts 'Plotted the Dancer constellation.'
when 'wave_act'
html = get DOCKS
get html[/href="([^<>]+?wchv=.+?)"/, 1]
puts 'Activated the Wave constellation.'
get ARCHIVIST
when 'wave_plot'
plot 'wave'
puts 'Plotted the Wave constellation.'
when 'gladiator_act'
get "#{ARCHIVES}?board=6"
puts 'Got a broken astrolabe.'
html = get DONNY
get (url = html[/href="([^<>]+?repair_id=.+?)"/, 1])
post DONNY, 'repair_id' => url.split('=')[1], 'confirm' => 1
puts 'Fixed the broken astrolabe.'
html = get COLOSSEUM
puts 'Finding the Punch Club Grarrl...'
links = html.scan(/href="([^<>]+?pchv=.+?)"/).flatten.shuffle
html, arch = '487738fe33.gif', 0
while html.include? '487738fe33.gif'
puts "Trying arch ##{arch += 1}..."
html = get($punch_club = links.pop)
end
puts 'Found him! Going to Punch Club...'
html = get "#{$punch_club}&pc_go=1"
bowls, found = html.scan(/punch1=(.+?)"/), nil
puts '27 bowl combinations, this might take a bit...'
found = nil
[*(0..26)].shuffle.each_with_index do |n, c|
puts "Trying combination ##{c + 1}..."
qs, perm = [], [n / 9, n / 3 % 3, n % 3].map { |i| bowls[i] }
perm.each_with_index { |p, i| qs << "punch#{i + 1}=#{p[0]}"}
html = get "#{$punch_club}&pc_go=1&#{qs * '&'}"
break if (found = html[/href="([^<>]+?gchv=.+?)"/, 1])
end
html = get found
get html[/href="([^<>]+?olhv=.+?)"/, 1]
puts 'Activated the Gladiator constellation... finally.'
get ARCHIVIST
when 'gladiator_plot'
plot 'gladiator'
puts 'Plotted the Gladiator constellation.'
when 'collector_act'
found = nil
(94..96).each do |id|
html = get "#{SHOP}#{id}"
cur = html[/inventory.phtml">(.+?)</, 1].gsub(/[^\d]/, '').to_i
amount = html[/at <b>(.+?)%</, 1].gsub('.', '').to_i
if cur != amount
puts "You have #{cur} NP right now."
puts "Setting your NP to #{amount}..."
post BANK, 'type' => (cur < amount ? 'withdraw' : 'deposit'), 'amount' => (cur - amount).abs
end
html = get "#{SHOP}#{id}"
break if (found = html[/href="([^<>]+?gohv=.+?)"/, 1])
end
get found
puts 'Activated the Collector constellation.'
get ARCHIVIST
when 'collector_plot'
plot 'collector'
puts 'Plotted the Collector constellation.'
when 'thief_act'
puts 'Lots of jumping around for the Meepit part, might take a bit...'
get "#{ARCHIVES}?lclenny=1"
html = get ARCHIVIST
html = get html[/href="([^<>]+?distract=.+?)"/, 1]
get html[/href="([^<>]+?steal=.+?)"/, 1]
get "#{ARCHIVES}?lclenny=1"
html = get ARCHIVES
html = get html[/href="([^<>]+?goarch=.+?)"/, 1]
3.times { html = get html[/href="([^<>]+?cmhv=.+?)"/, 1] }
html = get (url = html[/href="([^<>]+?closet=.+?)"/, 1])
post ARCHIVES, 'closet' => url.split('=')[-1], 'hide_box' => 1
html = get ARCHIVIST
html = get html[/href="([^<>]+?distract=.+?)"/, 1]
get html[/href="([^<>]+?steal=.+?)"/, 1]
html = get "#{ARCHIVES}?lclenny=1&acpcont=1"
get html[/href="([^<>]+?rdhv=.+?)"/, 1]
puts 'Activated the Thief constellation.'
get ARCHIVIST
when 'thief_plot'
plot 'thief'
puts 'Plotted the Thief constellation.'
get "#{ARCHIVES}?board=7"
when 'find_petpet'
puts 'Looking for the Vaeolus...'
[FARM, DOCKS, QUARRY].each do |loc|
found = get(loc)[/href="([^<>]+?pphv=.+?)"/, 1]
get("/altador/#{found}") if found
end
get ARCHIVIST
when 'gatherer_act'
puts 'Vaeolus-curing time.'
get PETPET
html = get "#{ARCHIVES}?board=5"
if (url = html[/href="([^<>]+?bmhv=.+?)"/, 1])
get "#{url}&acpcont=1"
puts 'Got medicine.'
end
if $punch_club
puts 'Remembered Punch Club arch from last time.'
else
html = get COLOSSEUM
puts 'Gotta find the Punch Club arch...'
links = html.scan(/href="([^<>]+?pchv=.+?)"/).flatten.shuffle
html, arch = '487738fe33.gif', 0
while html.include? '487738fe33.gif'
puts "Trying arch ##{arch += 1}..."
html = get($punch_club = links.pop)
end
puts 'Found it!'
end
html = get "#{$punch_club}&pc_go=1"
if (url = html[/href="([^<>]+?sphv=.+?)"/, 1])
get "#{url}&acpcont=1"
puts 'Got blueberry pie.'
end
tomb = get(TOMB)[/href="([^<>]+?tehv=.+?)"/, 1]
html, i = 'dc697034c4.gif', 0
puts 'Refreshing at the blob...'
while html.include? 'dc697034c4.gif'
html = get tomb
if (i += 1) > 35
have_bandage = true
puts 'I guess you already have it.'
break
end
end
unless have_bandage
html = get (url = html[/href="([^<>]+?gbhv=.+?)"/, 1])
puts "Got bandage."
get "#{url}&acpcont=1"
end
html = get PETPET
until html.include? 'b1022d8a5a.gif'
act = html[/act_(.)/, 1]
links = html.split('300"')[1].split('<c')[0].scan(/href="(.+?)"/).flatten
html = get (url = links['bacd'.index(act)])
puts case act
when 'a' then 'Bandaged the Vaeolus.'
when 'b' then 'Fed the Vaeolus.'
when 'c' then 'Medicated the Vaeolus.'
else 'Waited for the Vaeolus.'
end
delay = 60 - html[/ns = (\d+)/, 1].to_i
puts "Sleeping for #{delay} seconds..."
sleep delay
puts "after sleep"
html = get html.split('300"')[1].split('<c')[0].scan(/href="(.+?)"/).flatten[-1]
end
get html[/href="([^<>]+?pchv=.+?)"/, 1]
puts 'Activated the Gatherer constellation.'
get "#{ARCHIVES}?board=6"
get ARCHIVIST
when 'gatherer_plot'
plot 'gatherer'
puts 'Plotted the Gatherer constellation.'
when 'protector_act'
html = get QUARRY
html = get WALL
html = get html[/href="([^<>]+?sdhv=.+?)"/, 1]
html = get(url = html[/href="([^<>]+?tnhv=.+?)"/, 1])
get "#{url}&acpcont=1"
get FARM
switches, i = %w[r1v1 r1v2 r2v3 r2v4 r2s1 r3s2 r3s3 r3s4], 0
puts 'Gonna throw a whole bunch of switches, this will take a while...'
until html.include? '611538397c.gif'
s, i = switches.sample, i + 1
html = get "/altador/plant.phtml?room=#{s[1]}&act=#{s}"
puts '.' * (i / 10) if i % 10 == 0
end
puts 'Done throwing switches.'
html = get WALL
html = get html[/href="([^<>]+?sdhv=.+?)"/, 1]
html = get html[/href="([^<>]+?tnhv=.+?)"/, 1]
html = get html[/href="([^<>]+?olhv=.+?)"/, 1]
puts 'Activated the Protector constellation.'
get ARCHIVIST
when 'protector_plot'
resp = plot 'protector'
puts 'Plotted the Protector constellation.'
when 'open_ceiling'
html = get STAIRS
trip = html[/"trip" value="(.+?)"/, 1]
html = post(HALL, 'trip' => trip).body
get html[/href="([^<>]+?hohv=.+?)"/, 1]
puts 'Opened the roof.'
get ARCHIVIST
when 'basement'
get JANITOR
get BASEMENT
puts 'Activated the basement.'
when 'hunter_act'
html = get QUARRY
if (url = html[/href="([^<>]+?brhv=.+?)"/, 1])
html = get url
post QUARRY, 'brhv' => url.split('=')[1], 'go_buy_rock' => 1
puts 'Bought a rock.'
end
get JANITOR
get "#{BASEMENT}&gear=0"
get HALL
get "#{BASEMENT}&gear=0"
html = get QUARRY
if (url = html[/href="([^<>]+?trhv=.+?)"/, 1])
html = get url
html = get html[/href="([^<>]+?srhv=.+?)"/, 1]
html = get html[/href="([^<>]+?gthv=.+?)"/, 1]
puts 'Got another rock. You so silly, JubJubs.'
end
html = get "#{ARCHIVES}?board=1"
html = get "#{ARCHIVES}?board=1&circus=1"
html = get "#{ARCHIVES}?board=1&juggle=1"
html = get QUARRY
if (url = html[/href="([^<>]+?jjhv=.+?)"/, 1])
html = get url
post QUARRY, 'jjhv' => url.split('=')[1], 'r3hv' => html[/"r3hv" value="(.+?)"/, 1]
puts 'Got the third rock.'
end
puts "Time to jam some gears."
begin
html, offset, gears = '', 0, [*(0..9)].shuffle
until html[/MAP/]
gear = gears.pop
get "#{BASEMENT}&gear=#{gear}"
html = get PUSH_BUTTON
if html[/stupid rocks and such/]
puts 'The Janitor reset the roof. Trying again...'
raise ArgumentError
end
moved = html[/_r(\d+)_/, 1].to_i / 5
if (4..6) === moved - offset
offset += moved
puts "Gear #{gear} was a success."
else
puts "We don't need gear #{gear}."
get "#{BASEMENT}&gear=#{gear}"
end
end
rescue ArgumentError
retry
end
get html[/href="([^<>]+?olhv=.+?)"/, 1]
puts 'Activated the Hunter constellation.'
when 'hunter_plot'
plot 'hunter'
puts 'Plotted the Hunter constellation.'
when 'book_of_ages'
html = get "#{ARCHIVIST}&examine_book=1&view_page=53"
get html[/href="([^<>]+?dfhv=.+?)"/, 1]
puts "Clicked the Darkest Faerie's flame hands."
get ARCHIVIST
when 'spellbook'
html = get ARCHIVES
html = get html[/href="([^<>]+?goarch=.+?)"/, 1]
url = html[/href="([^<>]+?cmhv=.+?)"/, 1]
x, y = plot 'sleeper', true
html = get url.gsub(/arcx=\d+&arcy=\d+/, "arcx=#{x}&arcy=#{y}")
puts 'Found your archive room, now to find the book...'
links, i = html.scan(/href="([^<>]+?read_book=.+?)"/).flatten.shuffle, 0
until html[/52,143/]
puts "Trying book ##{i += 1}..."
html = get(data = links.pop)
end
puts 'Found it! Casting spell #29884...'
resp = post ARCHIVES, "#{data.split('?')[1]}&spell_id=29884"
html = get "#{VIEW_STATUE}6"
html = get html[/href="([^<>]+?necklace=.+?)"/, 1]
puts 'Placed the necklace!'
post COUNCIL, 'ephv' => html[/\?ephv=(.+?)'/, 1]
when 'finish'
html = get COUNCIL
get html[/href="([^<>]+?prhv=.+?)"/, 1]
puts 'Mission complete! We hope you enjoyed your stay.'
gets
end
end
Any questions/comments feel free to ask
Woot! Nice job! Too bad I already did it manually when I was bored . Oh well, I hope others find it useful. +rep!
Is there any way you can add a screenshot of the command prompt for the windows version? it keeps giving me errors and I'm sure it's just something dumb that I'm doing...
When you copy paste, check if there are any really weird symbols at the very very end. Sometimes that happens for me and that will screw things up. This script works fine when I copied pasted the windows script into my windows VM.
I checked the end and there wasn't any weird symbols :\, this is the error that I get.
Banned from trading - Do not trade with this member!
801 posts
Posted 07 April 2014 - 10:25 PM
@nitro
Hey! Dying to use this. I've got mac and ruby installed apparently. Okay, I've saved the code as a rb file but I have no idea where to go next. Would love if you could walk me through this
Wow at my mistake as well, beyond tired, my bad, thank you!
that's pretty embarrassing considering that means I did wrong at least 5 times last night and this morning.
First, download the Ruby installer (I chose 1.9.3, as it was mentioned as 'stable' on the Ruby website and includes all of the packages you'll need for this script). Run the .exe file and install Ruby on your machine.
This step is very important: You must click Start > Programs and navigate to the newly created Ruby folder in your programs list. There you will find the "Start Command Prompt With Ruby."
Once the command prompt is started, you navigate to wherever you saved altador.rb (or whatever you called it). Once you're in that folder, type "ruby altador.rb" (without the quotes and whatever your named your .rb file) and it will ask you for your Username/Password and then start working for you.
Make sure when you save the script in notepad that you change the file type to "All Files" instead of ".txt files" before you save the .rb or you will get a rb.txt extension and your script will fail.
Feel free to PM if you have any more questions!
EDIT: Note that if at ANY time your internet connection drops, this script will error and fail. Once you are reconnected to a network, restart the script (ruby altador.rb) and it will pick up where it left off. Also, it's advised that you do NOT browse Neopets while this script is running, as it uses your native browser and you may encounter errors.
PS: Nitro.. you rock. Thanks so much for this update!!