01
May
09

[Javascript/Php] Neopets Auction Bot Project (3)

The latest update to the auction bot.

*IF YOU WANT TO USE THIS, YOU HAVE TO CONTACT ME*
The reason for it being private, is nothing to do with me being selfish or anything, but the fact that this script queries my MySQL database between 6-10 times a minute, and I dont want it to run too slowly. Ive posted everything required to set it up here, however, if you need help, feel free to contact me (Details: my contact details -> about)

Its almost fully automated now, refreshing, opening, closing pages correctly.
There are only a few things to sort out, but to the average user these problems aren’t noticeable (check the grease monkey var for the script after running it for a while -_-)

Source for the PHP remains the same, so check the other posts.
Below is the greasemonkey script:

// ==UserScript==
// @name           Aucti0n b0t - sim0n
// @namespace      Neopets
// @description    https://sim0n.wordpress.com
// @include        http://www.neopets.com/auctions.phtml*
// ==/UserScript==

//Functions
//------------------------------
function getElementsByAttribute(oElm, strTagName, strAttributeName, strAttributeValue){
	var arrElements = (strTagName == "*" && oElm.all)? oElm.all : oElm.getElementsByTagName(strTagName);
	var arrReturnElements = new Array();
	var oAttributeValue = (typeof strAttributeValue != "undefined")? new RegExp("(^|\\s)" + strAttributeValue + "(\\s|$)") : null;
	var oCurrent;
	var oAttribute;
	for(var i=0; i<arrElements.length; i++){
		oCurrent = arrElements[i];
		oAttribute = oCurrent.getAttribute && oCurrent.getAttribute(strAttributeName);
		if(typeof oAttribute == "string" && oAttribute.length > 0){
			if(typeof strAttributeValue == "undefined" || (oAttributeValue && oAttributeValue.test(oAttribute))){
				arrReturnElements.push(oCurrent);
			}
		}
	}
	return arrReturnElements;
}
function createErrorBox(docTitle, boxHeight, content, contentSize) {
	if(docTitle != "") { document.title = docTitle };
	var size = "100px;";
	if(boxHeight != '') { size = boxHeight + "px"; }
	var darkenScreen = document.createElement('div');
	darkenScreen.setAttribute('style', 'position:fixed;left:0;top:0;width:100%;height:100%;background:#000000;opacity:0.8');
	document.body.appendChild(darkenScreen);
	var errorBox = document.createElement('div');
	var left = (document.documentElement.clientWidth /2)-150;
	errorBox.setAttribute('style', 'width:300px; ' + size + ' border:#990000 thick solid; background:#CCCCCC;padding:6px;position:fixed;left:' + left + 'px;top:100px;');
	for(var i = 1; i<contentSize; i++) {
		errorBox.appendChild(content[i]);
	}
	document.body.appendChild(errorBox);
}
function closeWindow() {
	var errorTitle = document.createElement('span');
	errorTitle.setAttribute('style', 'font-family:Georgia; text-align:center; font-weight:bold;z-index:9999');
	errorTitle.appendChild(document.createTextNode('Error'));
	var errorBold = document.createElement('b');
	var errorItalic = document.createElement('i');
	errorItalic.appendChild(document.createTextNode('dom.allow_scripts_to_close_windows'));
	errorBold.appendChild(errorItalic);

	var elemArray = {
		1 : errorTitle,
		2 : document.createElement('br'),
		3 : errorBold,
		4 : document.createTextNode(' is false.'),
		5 : document.createElement('br'),
		6 : document.createTextNode('To enable it, navigate to about:config and change the value from False to True')
	}

	createErrorBox('Close error - click for details', '', elemArray, 7);
	window.close();
}
function removeImages() {
	var images=document.images;
	for(var x=0;x<images.length;i++){
		images[x].parentNode.removeChild(images[x]);
	}
}
function parseUrl(max_price) {
	return String(document.location).substring(String(document.location).lastIndexOf("=")+1);
}
function removeBidCookie(link) {
	var curID = link.replace(/.*auction_id=(\d*).*/, "$1");
	var cur = String(GM_getValue('currentAuctions'));
	cur = cur.replace(curID + "|", "");
	GM_setValue('currentAuctions', cur);
}

//Main Page Functions
//------------------------------
function queryNeopetItem(item, complete) {
	//Create a httpRequest, the php script returns a list of items max price + sell price
	//Format:
	//maxprice[0]	sellprice[0]
	//maxprice[1]	sellprice[1]
	//maxprice[n-1]	sellprice[n-1]
	//maxprice[n]	sellprice[n]
	//complete is a function that parses the responseText
	url = "http://myhost.com/queryv2.php?items=" + item;
	GM_xmlhttpRequest({
		method: "POST",
		url: url,
		headers:{'Content-type':'application/x-www-form-urlencoded'},
		data:encodeURI(""),
		onload: function(xhr) { complete(xhr.responseText); }
	});
}
function comp(text) {
	//Splits each line
	var items = text.split("\n");
	//We only want 20 lines (20 items per page)
	for(var i = 0;i<20;i++) {
		if(items[i] == "" || String(items[i]) == "undefined") {
			//Item not in database
			table[0].rows[i+1].setAttribute("bgcolor","#ccffd0");
		} else {
			//Split max/min price
			var item = items[i].split("\t");
			//Get the items current price, check its less
			var cur_price = table[0].rows[i+1].cells[6].innerHTML.replace(/<b>(\d*)<\/b> NP/, "$1");
			if(Number(cur_price)<=Number(item[0])) {
				//If it is less, check if its a NF auction or not
				if(table[0].rows[i+1].cells[3].innerHTML.toLowerCase().indexOf("<b>[nf]</b>") != -1) {
					//If it is, ignore it
					table[0].rows[i+1].setAttribute("bgcolor","#aaafa0");
				} else {
					//Else, open the page in a new tab
					table[0].rows[i+1].setAttribute("bgcolor","#00ffff");
					doAuction(table[0].rows[i+1].cells[2].getElementsByTagName('a')[0], item[0]);
				}
			} else {
				table[0].rows[i+1].setAttribute("bgcolor","#aaffd0");
			}
		}
	}
}
function doAuction(link, max_price) {
	//Used to open the selected auction in a new tab with max price in the url
	var curID = link.href.replace(/.*auction_id=(\d*)/, "$1");
	var cur = String(GM_getValue('currentAuctions'));
	if(cur=="undefined") {cur="";}
	if(cur.indexOf(curID) == -1) {
		var x = cur + curID + "|";
		GM_setValue('currentAuctions', x);
		GM_openInTab(link.href + "&maxprice=" + max_price);
		GM_log("Opened: " + curID);
	}
}

//Script testing
//------------------------------

//Script
//------------------------------
var url = String(document.location);
if(url.indexOf('placebid') == -1 && url.indexOf('bids') == -1) {

	//The main auction page - Create list of items
	removeImages();
	var table = getElementsByAttribute(document.body, "table", "align", "center");
	var queryString = "";
	for(var i=1;i<table[0].rows.length - 1;i++) {
		queryString = queryString + table[0].rows[i].cells[2].innerHTML.replace(/<a href=\".*\">(.*)<\/a>/, "$1") + "|";
	}
	queryString = queryString + table[0].rows[table[0].rows.length-1].cells[2].innerHTML.replace(/<a href=\".*\">(.*)<\/a>/, "$1")
	//Query the database
	queryNeopetItem(queryString, comp);

	var minTime = 6;
	var maxTime = 10;
	var PERIOD = (maxTime * 1000 - minTime * 1000) * Math.random() + minTime * 1000;
	setTimeout('location.reload(true)', PERIOD);

} else if(url.indexOf('bids') != -1 && url.indexOf('maxprice') != -1) {

	//Place bid
	if ((window.find("Time Left in Auction :  Closed" , false, true) == false) && (window.find("Oops! - Invalid Auction ID") == false)) {
		//Valid auction
		var max_price = parseUrl();
		var name = getElementsByAttribute(document.getElementById('header'), 'td', 'class', 'user medText')[0].firstChild.nextSibling.textContent;
		var table = getElementsByAttribute(document.body, 'table', 'cellpadding', 4)[0];
		var lastbidder = "";
		if(table) {
			lastbidder = table.rows[1].cells[0].textContent.substring(1);
		}
		if(lastbidder==name) {
			//If last bidder was user reload after 2 seconds
			setTimeout('location.reload(true)', 3);
		} else {
			//Else, check to make sure its worth paying for
			if(Number(document.getElementsByName('amount')[0].value) <= Number(max_price)) {
				//Modify the form to add our max price
				var forms = document.getElementsByTagName("form");
				for(var i=0;i<forms.length;i++) {
					if(forms[i].getAttribute('action') == "auctions.phtml?type=placebid") {
						forms[i].setAttribute('action', "auctions.phtml?type=placebid&maxprice=" + max_price)
					}
				}
				//Submit the form
				var button = getElementsByAttribute(document.body, 'input', 'value', 'Place a Bid')[0];
				button.form.submit();
			} else {
				//too expensive */.
				GM_log("Closed: " + url);
				removeBidCookie(url)
				closeWindow();
			}
		}
	} else {
		// Will need to add in checking later on for who won the bid */.
		removeBidCookie(url);
		GM_log("Closed: " + url);
		closeWindow();
	}
} else if(url.indexOf('placebid') != -1) {

	//After placing bid
	var max_price = parseUrl();
	if(document.body.innerHTML.indexOf("BID SUCCESSFUL") != -1) {
		//Bid worked
		var link = document.getElementsByTagName('a');
		var s = 'http://www.neopets.com/auctions.phtml?type=bids&auction_id='
		for(var i = 0; i < link.length; i++) {
			var str = link[i].href;
			str = str.substr(0, 59)
			if(str == s) { document.location = link[i].href + "&maxprice=" + max_price; }
		}
	} else if(document.body.innerHTML.indexOf("The current asking price for this item") != -1) {
		//Bid not enough error
		var link = document.getElementsByTagName('a');
		var s = 'http://www.neopets.com/auctions.phtml?type=bids&auction_id='
		for(var i = 0; i < link.length; i++) {
			var str = link[i].href;
			str = str.substr(0, 59)
			if(str == s) { document.location = link[i].href + "&maxprice=" + max_price; }
		}
	} else if(document.body.innerHTML.indexOf("You must wait a few more seconds") != -1) {
		//Too fast
		history.go(-1);
	} else if(document.body.innerHTML.indexOf("You don't have enough money to place that bid") != -1 || document.body.innerHTML.indexOf("This auction is closed") != -1 || document.body.innerHTML.indexOf("Invalid Auction ID") != -1) {
		//Not enough money or auction is over */.
		closeWindow();
	}

}

Theres also a clue in this post as to how you can easily access my host if you want, its kinda… obvious.

Remember, this isnt the final product. Its still being worked on.

Advertisements

2 Responses to “[Javascript/Php] Neopets Auction Bot Project (3)”


  1. 1 Hunson
    May 7, 2009 at 11:19 pm

    Hey dude, I’m new o coding and stuff, but I’m really interested in knowing how to work your bot! I’ve been loggin in Neopets for a couple of days now endlessly trying to get a good deal, this might just be the ticket to get my life back to normal. šŸ˜›

    Any help is appreciated ^^

    p/s: will it be caught?

    • 2 sim0n
      May 8, 2009 at 1:12 pm

      I have been using the bot on a few accounts for a while now, and no, I have not had my account frozen. To use this, your going to need to have a database containing a list of items, and their max prices in. The bot will then query this database for the items in the auction page – if the item is found, it will then either start bidding on the item, or just ignore the item.
      If you dont have access to a MySQL database, you could just as easily set up a list of items in the script by doing something like:
      var itemArray = {
      0 : ‘Starry Paint Brush Plushie xxx xxx,
      1 : ‘Tai-Kai Codestone xxx xxx’,
      2 : ‘Christmas Paint Brush xxx xxx’,
      3 : ‘Vo Codestone xxx xxx’,
      4 : ‘Har Codestone xxx xxx’,
      5 : ‘Two Dubloon Coin xxx xxx’,
      6 : ‘Mau Codestone xxx xxx’,
      }
      Where xxx xxx is your max buy price and sell price, respectively.
      Then modifying the queryNeopetItem(…) function to look at your list of items instead.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


%d bloggers like this: