Archive for the 'PHP' Category

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
29
Apr
09

[PHP] Hit Counter using MySQL Database

Little script I wrote this morning which uses a database to store number of hits on a page:

<?php
	$dbhost = '1';
	$dbuser = '2';
	$dbpass = '3';
	$conn = mysql_connect($dbhost, $dbuser, $dbpass) or die ('0');
	$dbname = '4';
	mysql_select_db($dbname);

	$page = $_SERVER['REQUEST_URI'];
	$result = mysql_query("SELECT HIT_COUNT FROM  Hit_Count WHERE Page_Name = '$page'");

	$any = false;
	while($row = mysql_fetch_array($result)) {
		$any = true;
		$counter = mysql_result($result, 0) + 1;
		$sql = "UPDATE Hit_Count SET HIT_COUNT = '$counter' WHERE Page_Name = '$page'";
		mysql_query($sql);
		echo($counter);
	}

	if($any == false) {
		$sql = "INSERT INTO Hit_Count (Page_Name, HIT_COUNT) VALUES ('$page', '1')";
		mysql_query($sql);
		echo("1");
	}

	mysql_close($conn);
?>

The script will output the current hit count, you would use the script like this:

<?php include("location/hitcount.php"); ?>

The tables set up is this:

Page_Name [text]		HIT_COUNT [int(11)]
/files/Image%20Gallery.php 	2
/ 				4
28
Apr
09

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

A much faster script than my previous version. Instead of querying each item individually, it loops through the items in the list and uses the queryNeopetItem to send the data to another php page, which pareses the items and returns the prices of each of them. When the data is returned, it is then split and the table is formatted depending on what action should be taken (light green=no data, medium green=more expensive than data, grey = neofriend only, blue = make profit)

Neopets auction highlight


And below is the source for the greasemonkey script:

// ==UserScript==
// @name           AuctionBot test v2
// @namespace      Sim0n NeoPets
// @include        http://www.neopets.com/auctions.phtml
// ==/UserScript==

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 queryNeopetItem(item, complete) {
	url = "myphpquery.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) {
	var items = text.split("\n");
	for(var i = 0;i<20;i++) {
		if(items[i] == "") {
			table[0].rows[i+1].setAttribute("bgcolor","#ccffd0");
		} else {
			var item = items[i].split("\t");
			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(table[0].rows[i+1].cells[3].innerHTML.toLowerCase().indexOf("<b>[nf]</b>") != -1) {
					table[0].rows[i+1].setAttribute("bgcolor","#aaafa0");
				} else {
					alert(table[0].rows[i+1].cells[3].innerHTML)
					table[0].rows[i+1].setAttribute("bgcolor","#00ffff");
				}
			} else {
				table[0].rows[i+1].setAttribute("bgcolor","#aaffd0");
			}
		}
	}
}
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")
queryNeopetItem(queryString, comp);

And for the php query:

<?php
	$dbhost = 'a';
	$dbuser = 'b';
	$dbpass = 'd';
	$conn = mysql_connect($dbhost, $dbuser, $dbpass) or die ('0');
	$dbname = 'e';
	mysql_select_db($dbname);

	$items = explode("|", $_GET['items']);
	for($i=0;$i<count($items);$i++) {
		$sqlQuery = "ITEM_NAME = '$items[$i]'";
		$result = mysql_query("SELECT * FROM  Neopets_Items WHERE $sqlQuery");
		$any = false;
		while($row = mysql_fetch_array($result))
  		{
			$any = true;
  			echo $row['MAX_PRICE'] . "\t" . $row['SELL_PRICE'] . "\n";
  		}
		if($any==false) {
			echo "\n";
		}
	}
	mysql_close($conn);
?> 
28
Apr
09

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

Ive been asked by somebody to create a bot for the game Neopets that will view the most recent auctions and bid upon items which on which money can be easily made. One of the constraints for this project, was that it must be made using Javascript + Greasemonkey, so no Perl or Python (or whatever it is people use to code bots on the net these days! Like I know -_-).
My initial attempt (below) uses the GM_xmlhttpRequest to query a database of items (that’s another project ^_^ – lots of faces today?), and it works very nicely, except for one small thing. Its ridiculously slow. It query the database for each of the items, and then either marks it with a green colour to indicate that it is loaded, but you will not make money off it, or will highlight the row brown to show that you will make money off the auction.
Remeber, its v. slow!
Still, here is the source code as it is a nice example of a recursive function and sending & retrieving data to other websites using Greasemonkey.

// ==UserScript==
// @name           Auc7i0nb0t t3s7
// @namespace      n30p375
// @include        http://www.neopets.com/auctions.phtml
// ==/UserScript==

//Some function from google - kinda overkill, but meh.
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 queryNeopetItem(item, complete) {
	url = "url to my item query page.php?item=" + item;
	GM_xmlhttpRequest({
		method: "POST",
		url: url,
		headers:{'Content-type':'application/x-www-form-urlencoded'},
		data:encodeURI(""),
		onload: function(xhr) { complete(xhr.responseText); }
	});
}
var x = 1;
var table = getElementsByAttribute(document.body, "table", "align", "center");
var item_name = table[0].rows[x].cells[2].innerHTML.replace(/<a href=\".*\">(.*)<\/a>/, "$1");
function comp(text) {
	var ta = text.split("\n");
	max_price = ta[1];
	sell_price = ta[2];
	if(x<table[0].rows.length) {
		item_name = table[0].rows[x].cells[2].innerHTML.replace(/<a href=\".*\">(.*)<\/a>/, "$1");
		queryNeopetItem(item_name, comp)
		table[0].rows[x-1].setAttribute("bgcolor","#ccffd0");
		if(ta[1].indexOf("www.mywebhostsname.com") == -1) {
			var str = table[0].rows[x-1].cells[6].innerHTML.replace(/<b>(\d*)<\/b> NP/, "$1");
			if(Number(str)<=Number(max_price)) {
				table[0].rows[x-1].setAttribute("bgcolor","#dc9423");
			}
		}
		x++;
	} else {
		item_name = table[0].rows[x-1].cells[2].innerHTML.replace(/<a href=\".*\">(.*)<\/a>/, "$1");
		table[0].rows[x-1].setAttribute("bgcolor","#ccffd0");
		if(ta[1].indexOf("www.mywebhostsname.com") == -1) {
			var str = table[0].rows[x-1].cells[6].innerHTML.replace(/<b>(\d*)<\/b> NP/, "$1");
			if(str<=max_price) {
				table[0].rows[x-1].setAttribute("bgcolor","#dc9423");
			}
		}
		table[0].appendChild(document.createTextNode("Complete"));
	}
}
queryNeopetItem(item_name, comp);

url to my item query page.php?item is a page that querys the database and returns the items details (Max Price and Sell Price). The above function is recursive, as queryNeopetItem calls the function comp (which parses the text returned from the httpRequest) which, in turn calls queryNeopetItem again, until all the rows items have been queried.

<php
	$dbhost = 'x';
	$dbuser = 'y';
	$dbpass = 'z';
	$conn = mysql_connect($dbhost, $dbuser, $dbpass) or die ('0');
	$dbname = 'a';
	mysql_select_db($dbname);

	$item = $_GET['item'];
	$max = $_GET['max'];
	$sell = $_GET['sell']; 

	$sqlQuery = "";

		if($item != "") {
			$sqlQuery = "ITEM_NAME = '$item'";
		}
		if($max != "") {
			if($sqlQuery != "") {
				$sqlQuery = $sqlQuery . " AND MAX_PRICE = '$max'";
			} else {
				$sqlQuery = "MAX_PRICE = '$max'";
		}
		}
		if($sell != "") {
			if($sqlQuery != "") {
				$sqlQuery = $sqlQuery . " AND SELL_PRICE = '$sell'";
			} else {
				$sqlQuery = "SELL_PRICE = '$sell'";
			}
		}

		$result = mysql_query("SELECT * FROM  Neopets_Items WHERE $sqlQuery");

		while($row = mysql_fetch_array($result))
  		{
  			echo $row['ITEM_NAME'] . "\n" . $row['MAX_PRICE'] . "\n" . $row['SELL_PRICE'];
  		}

	mysql_close($conn);
?> 

That code is kind of overkill for the query that the script makes, however it also allows you to query by a combination of the items properties which will be used later on in the project (probably)

12
Apr
09

[PHP/XML] Image Gallery

Wrote a function today to parse an XML file to create an image gallery table:
http://sim0n.net46.net/files/Image%20Gallery.php

The XML files structure is set up like this, similar to that of an RSS feed:

<?xml version="1.0" encoding="iso-8859-1"?&gt;
<channel>
	<thumb></thumb>
	<name>sim0n Gallery RSS</name>
	<date></date>
	<description>sim0n Gallery RSS</description>
	<link>https://sim0n.wordpress.com</link>
	<item>
		<thumb>Clouds_thm.jpg</thumb>
		<name>Clouds - Seamless 1 Tile</name>
		<date>12 April 2009</date>
		<description><![CDATA[A 1-image seamless tile that can be used as a repeating texture or background]]></description>
		<link>Clouds.html</link>
	</item>
	<item>
		<thumb>Meadow_thm.jpg</thumb>
		<name>Meadow - Seamless 2 Tile</name>
		<date>12 April 2009</date>
		<description><![CDATA[A 2-image seamless tile that can be used as a repeating texture or background]]></description>
		<link>Meadow.html</link>
	</item>
</channel>

It turned out quite nicely, now all i need to do is implement an easy way for me to add items to the gallery, shouldn’t be too hard.