19
May
09

[C++] Numbers with 6 divisors where none of the divisors are primes > 5

My uncle phoned me up to day with a question:

N is a number that has exactly 6 factors.
One of the factors is 1, and another is the number itself.
None of the prime factors of N can be greater than 5
Find a method for calculating a set of vales that would suit N.

Well. To be honest, after literally hours of trying to work out how to do this, I gave up and decided to program a brute force algorithm that would do this for me:

#include "stdafx.h"
#include "math.h"

int main()
{
	//Algorithm to calculate numbers where
	//Number of divisors < 7
	//None of the prime divisors > 5
	for(int i=1;i<100;i++) {
		int dc = 0; //divisor count
		bool pc = true; //prime check
		for(int k=1;k<(i/2)+1;k++) { //loop through all the numbers up to (n/2)+1
			if(i%k==0) { //check to see if divides with no remainder
				dc++; //increase divisor count
				if(dc > 5) { //if divisor count greater than 5, then quit - this number is not valid
					dc++;
					break;
				} else { //else we need to check the divisor
					if(k>5) {//if the divisor is bigger than 5, we need to check if it is prime
						bool ip = true; //is prime?
						for(int j = 2; j <= sqrt((double)k); j++)  //loop through the possible values
							if(k % j == 0) //check remainder
								ip=false;
						if(ip==true) { //sorry, its too big to be prime. quit
							pc=false;
							break;
						}
					}
				}
			}
		}
		if(dc==5 && pc==true) //check number is prime valid and has 6 divisors
			printf("Valid Number %d, \n", i);
	}
	return 0;
}

That would produce the list of valid numbers, those being:
12 : [1, 2, 3, 4, 6, 12]
18 : [1, 2, 3, 6, 9, 18]
20 : [1, 2, 4, 5, 10, 20]
32 : [1, 2, 4, 8, 16, 32]
45 : [1, 3, 5, 9, 15, 45]
50 : [1, 2, 5, 10, 25, 50]
75 : [1, 3, 5, 15, 25, 75]

13
May
09

[C++] CBT Hook Example

Got bored of doing revision and started on a HookLib, this is an example program where I was testing using a CBT Hook.

header.h

#include "windows.h"

bool SetCBTHook(DWORD, HWND);
void RemoveCBTHook(); 

Main.cpp

#include "header.h"

#define IDC_LIST 4000

HINSTANCE	mhInstance;
HWND		mhWnd;
HWND		lvhWnd;

LRESULT CALLBACK WindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch (message)
    {
		case WM_COMMAND:
               break;
		case WM_DESTROY:
			RemoveCBTHook();
			PostQuitMessage (0); 
			break;
		default: 
			return DefWindowProc (hwnd, message, wParam, lParam);
    }
    return 0;
}

BOOL RegisterClass(wchar_t szClassName[])
{
    WNDCLASSEX wc;
    wc.hInstance =  mhInstance;
    wc.lpszClassName = (LPCWSTR)szClassName;
    wc.lpfnWndProc = WindowProc; 
    wc.style = CS_DBLCLKS;
    wc.cbSize = sizeof (WNDCLASSEX);
    wc.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wc.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor (NULL, IDC_ARROW);
    wc.lpszMenuName = NULL;
    wc.cbClsExtra = 0; 
    wc.cbWndExtra = 0;
    wc.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
    if (!RegisterClassEx (&wc))
		return 0;
	else
		return 1;
}

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPreviousInstance,LPSTR lpcmdline,int nCmdShow)
{
	MSG messages;
	mhInstance = hInstance;
	wchar_t ClassName[ ] = L"CBTHookClass";
	wchar_t WindowName[ ] = L"CBTHookWindow";
	RegisterClass(ClassName);
	mhWnd = CreateWindowEx(WS_EX_CONTROLPARENT, ClassName, WindowName, WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_VISIBLE | WS_MAXIMIZEBOX, 0, 0, 500, 500, NULL, NULL, hInstance, NULL);
	lvhWnd = CreateWindow(L"LISTBOX",L"CBTHookListBox",WS_CHILD|WS_VISIBLE|WS_VSCROLL, 2,2,490,479,mhWnd, (HMENU)IDC_LIST,hInstance, NULL );
	SetCBTHook(GetCurrentThreadId(), mhWnd);
	while (GetMessage (&messages, NULL, 0, 0))
    {
		TranslateMessage(&messages);
        DispatchMessage(&messages);
    }
    return 0;
} 

CBTHook.cpp

#include "header.h"
#include <stdlib.h>
#include <sstream>
#include <string>


HHOOK	CBT_HOOK_ID;
HWND	hWnd;

using namespace std;

std::wstring StringToWString(const std::string& s)
{
	std::wstring temp(s.length(),L' ');
	std::copy(s.begin(), s.end(), temp.begin());
	return temp; 
}

void AddItem(LPCWSTR text) {
	SendDlgItemMessage(hWnd, 4000, LB_ADDSTRING, 0, (LPARAM)text);
}

void AddHWND(WPARAM hwnd) {
	ostringstream oss;
	oss << hex << (int)hwnd;
	wstring Message = L" ---Window Handle: 0x" + StringToWString(oss.str());
	AddItem(Message.c_str());
}

//void AddRECT(RECT rect) {
//	string out;
//	ostringstream oss;
//	oss << rect.top;
//	out = oss.str();
//	oss << rect.bottom;
//	out = out + ", " + oss.str();
//	oss << rect.left;
//	out = out + ", " + oss.str();
//	oss << rect.right;
//	out = out + ", " + oss.str();
//	wstring Message = L"Window Moved/Resized: " + StringToWString(out);
//}

static LRESULT CALLBACK CBTHookProc(int nCode, WPARAM wParam, LPARAM lParam)   
{  
	if(nCode > 0) {
		CBT_CREATEWND	*CBTHOOKCREATE;
		RECT			*CBTRECTPTR;
		RECT			CBTRECT;
		wstring			Message;
		
		switch (nCode)
		{
			case HCBT_ACTIVATE:
				AddItem(L"Window Activated");
			case HCBT_CREATEWND:
				CBTHOOKCREATE = (CBT_CREATEWND*) lParam;
				AddItem(L"Window Created");
				Message = L" ---Window Name: ";
				if(!IsBadReadPtr(CBTHOOKCREATE->lpcs, 1)) {
					if(!IsBadReadPtr(CBTHOOKCREATE->lpcs->lpszName, 1))
						Message = Message + CBTHOOKCREATE->lpcs->lpszName;
				}
				AddItem(Message.c_str());

				Message = L" ---Window Class: ";
				if(!IsBadReadPtr(CBTHOOKCREATE->lpcs, 1)) {
					if(!IsBadReadPtr(CBTHOOKCREATE->lpcs->lpszClass, 1))
						Message = Message + CBTHOOKCREATE->lpcs->lpszClass;
				}
				AddItem(Message.c_str());
				AddHWND(wParam);
			case HCBT_DESTROYWND:
				AddItem(L"Window Destroyed");
			case HCBT_MINMAX:
				switch(lParam)
				{
				case SW_HIDE:
					AddItem(L"Window Hidden");
					break;
				case SW_MAXIMIZE:
					AddItem(L"Window Maximized");
					break;
				case SW_MINIMIZE:
					AddItem(L"Window Minimized");
					break;
				case SW_RESTORE:
					AddItem(L"Window Restored");
					break;
				case SW_SHOW:
					AddItem(L"Window Shown");
					break;
				case SW_SHOWDEFAULT:
					AddItem(L"Window Shown Default");
					break;
				case SW_SHOWMINIMIZED:
					AddItem(L"Window Shown Minimized");
					break;
				case SW_SHOWMINNOACTIVE:
					AddItem(L"Window Shown Minimized (Not Active)");
					break;
				case SW_SHOWNA:
					AddItem(L"Window Shown (Not Active)");
					break;
				case SW_SHOWNOACTIVATE:
					AddItem(L"Window Shown (Not Active)");
					break;
				case SW_SHOWNORMAL:
					AddItem(L"Window Shown");
					break;
				}
				AddHWND(wParam);
			case HCBT_MOVESIZE:
				//CBTRECTPTR = (RECT*) lParam;
				//memcpy(&CBTRECT, CBTRECTPTR, sizeof(RECT));
				//AddRECT(CBTRECT);
				break;
		}
	}
	return CallNextHookEx(CBT_HOOK_ID, nCode, wParam, lParam);  
}

bool SetCBTHook(DWORD ThreadID, HWND ThisMainWindow) {
	hWnd = ThisMainWindow;
	HHOOK CBT_HOOK_ID = ::SetWindowsHookEx(WH_CBT, CBTHookProc, 0, ThreadID);
	MessageBox(NULL, L"Hey", L"There", 1);
	if(CBT_HOOK_ID)
		return true;
	else
		return false;
}

void RemoveCBTHook() {
	UnhookWindowsHookEx(CBT_HOOK_ID);
} 

Its just a quick throw-together of setting a cbt hook on your window, the HookLib exports the hook function, allowing you to hook any process/the entire system.
Also note that the IsBadReadPtr is just there to ensure that the structure returned by the hook is valid, as sometimes it isnt causing the function to die.

09
May
09

[C++] Read External Treeview

After quite some time and a lot of research, I finally got it to work. The method is summarised below:

xProcess = eXternal Process
Find xProc Window
Find Treeview in window
Get xProcess ID
Set Debug Privelages
Open xProcess
Allocate Memory in xProc
Get Root Node
Loop:
	Create and fill TVITEM structure
	Write TVITEM to xprocess
	Send GET_ITEM to get Node name
	Read string from xprocess memory
	print
	Get Next Node
Free Memory
Close Handle

I also had some trouble in some processes with trying to open them, so the code includes a setDebug function that changes your privileges and is used in the printTreeviewNodes function before attempting to open the process. Below is the code, including an example of how to use it (Using Teamspeak 2 as a target program):

// Read External Treeview.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "windows.h"
#include "commctrl.h"
#include <iostream>

using namespace std;

bool setDebug() {
	HANDLE hToken;
	if(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
		TOKEN_PRIVILEGES tp;
		LUID luid;
		TOKEN_PRIVILEGES tpPrevious;
		DWORD cbPrevious = sizeof(TOKEN_PRIVILEGES);
		if(LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid)) {
			tp.PrivilegeCount = 1;
			tp.Privileges[0].Luid = luid;
			tp.Privileges[0].Attributes = 0;
			if(AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), &tpPrevious, &cbPrevious)) {
				tpPrevious.PrivilegeCount = 1;
				tpPrevious.Privileges[0].Luid = luid;
				tpPrevious.Privileges[0].Attributes |= (SE_PRIVILEGE_ENABLED);
				if(AdjustTokenPrivileges( hToken, FALSE, &tpPrevious, cbPrevious, NULL, NULL )) {
					CloseHandle(hToken);
					return true;
				}
			}
		}
	}
	CloseHandle(hToken);
	return false;
}

void printTreeviewNodes(HWND treeview) {
	DWORD pID;
	GetWindowThreadProcessId(treeview, &pID);
	if(pID) {
		if(setDebug()) {
			HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, pID);
			if(hProcess) {
			/*
				Memory allocation:
			   0---------|---------|----------------14F
				 TVITEM    rBuffer       pszText
				  (28)      (28)          (FF)
			*/
				DWORD remoteBuffer = (DWORD)::VirtualAllocEx(hProcess, NULL, 335, MEM_COMMIT, PAGE_READWRITE);
				if(remoteBuffer) {
					HTREEITEM Root = (HTREEITEM)::SendMessage(treeview, TVM_GETNEXTITEM, TVGN_ROOT, 0);
					while(Root) {
						TVITEM tvItem;
						tvItem.mask = TVIF_TEXT;
						tvItem.hItem = Root;
						tvItem.pszText = (LPWSTR)remoteBuffer + sizeof(TVITEM);
						tvItem.cchTextMax = 255;
						if(WriteProcessMemory(hProcess, (LPVOID)remoteBuffer, (LPCVOID)&tvItem, sizeof(TVITEM), 0)) {
							SendMessage(treeview, TVM_GETITEM, 0, remoteBuffer);
							wchar_t bytRtn[255];
							int rAdd = remoteBuffer + sizeof(TVITEM)*2;
							if(ReadProcessMemory(hProcess, (LPCVOID)rAdd, (LPVOID)&bytRtn, 255, 0)) {
								wcout << bytRtn << endl;
							}
							Root = (HTREEITEM)::SendMessage(treeview, TVM_GETNEXTITEM, TVGN_NEXTVISIBLE, (LPARAM)Root);
						}
					}
					VirtualFreeEx(hProcess, (LPVOID)remoteBuffer, 335, MEM_RELEASE);
				}
			}
			CloseHandle(hProcess);
		}
	}
}

int _tmain(int argc, _TCHAR* argv[])
{
	HWND tsmhWnd = FindWindow(L"TMainForm", L"TeamSpeak 2");
	tsmhWnd = FindWindowEx(tsmhWnd, NULL, L"TPanel", NULL);
	HWND tsTVhWnd = FindWindowEx(tsmhWnd, NULL, L"TTreeView", NULL);
	printTreeviewNodes(tsTVhWnd);
	return 0;
}

If anybody has a better method than this or any comments, I’d be more than happy for input ^^

05
May
09

[VB.Net] FindWindowsIndexOf – .Netish Version

A more .net style function for getting a window using an indexOf:

    ''API Imports
    <Runtime.InteropServices.DllImport("user32.dll", CharSet:=Runtime.InteropServices.CharSet.Auto)> Private Shared Sub GetClassName(ByVal hWnd As System.IntPtr, ByVal lpClassName As System.Text.StringBuilder, ByVal nMaxCount As Integer)
    End Sub
    <Runtime.InteropServices.DllImport("user32.dll", CharSet:=Runtime.InteropServices.CharSet.Auto)> Private Shared Function FindWindow(ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
    End Function

    ''FoundWindow stricture
    Public Structure FoundWindow
        Dim strWindowName As String
        Dim strClassName As String
        Dim hWnd As IntPtr
    End Structure

    ''' <summary>
    ''' This function is used to loop through all running processes, checking their main windows to see which ones contain a specific string
    ''' </summary>
    ''' <param name="strIndexOf">The string that you wish to check for in the window captions</param>
    ''' <param name="boolCase">Whether the function is should check for case</param>
    ''' <returns>A list of FoundWindow's containing the window name, class and handle</returns>
    ''' <remarks>As this function only loops through running processes main windows, it may miss some windows.</remarks>
    Public Function FindWindowsIndexOf(ByVal strIndexOf As String, ByVal boolCase As Boolean) As List(Of FoundWindow)
        Dim foundWindows As New List(Of FoundWindow)
        If boolCase = False Then
            strIndexOf = strIndexOf.ToLower
        End If
        For Each p As Process In Process.GetProcesses
            Dim windowCaption As String = p.MainWindowTitle
            If boolCase = False Then
                windowCaption = windowCaption.ToLower
            End If
            If windowCaption.IndexOf(strIndexOf) > -1 Then
                Dim foundWindow As New FoundWindow
                foundWindow.hWnd = FindWindow(vbNullString, p.MainWindowTitle)
                foundWindow.strWindowName = p.MainWindowTitle
                Dim sbClassName As New System.Text.StringBuilder("", 256)
                GetClassName(foundWindow.hWnd, sbClassName, 256)
                foundWindow.strClassName = sbClassName.ToString
                foundWindows.Add(foundWindow)
            End If
        Next
        Return foundWindows
    End Function

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        For Each fWnd As FoundWindow In FindWindowsIndexOf("TeST", False)
            Debug.WriteLine(fWnd.strWindowName & " : " & fWnd.hWnd.ToString)
        Next
    End Sub

Same as the last function, you can choose whether or not the function is case sensitive.

05
May
09

[VB.Net] FindWindowsIndexOf – API Version

Somebody on VBForums was asking how to do something similar to this, so after answering his question, I created this fairly useful function – for windows that names change each time you load them up or something…

    ''API Declarations
    Private Declare Function EnumWindows Lib "user32" (ByVal lpEnumFunc As EnumWindowProc, ByVal lParam As IntPtr) As Integer
    Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Integer, ByVal lpString As System.Text.StringBuilder, ByVal cch As Integer) As Integer
    Private Declare Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" (ByVal hwnd As Integer) As Integer
    <Runtime.InteropServices.DllImport("user32.dll", CharSet:=Runtime.InteropServices.CharSet.Auto)> Private Shared Sub GetClassName(ByVal hWnd As System.IntPtr, ByVal lpClassName As System.Text.StringBuilder, ByVal nMaxCount As Integer)
    End Sub

    ''EnumWindow Callback Delegate Function
    Private Delegate Function EnumWindowProc(ByVal hwnd As Integer, ByVal lParam As IntPtr) As Boolean

    ''Found Window Structures
    Public Structure FoundWindows
        Dim boolCase As Boolean
        Dim strFindWindow As String
        Dim lstFoundWindows As List(Of FoundWindow)
    End Structure
    Public Structure FoundWindow
        Dim strWindowName As String
        Dim strClassName As String
        Dim hWnd As IntPtr
    End Structure

    ''' <summary>
    ''' ''EnumWindow Callback Function
    ''' </summary>
    ''' <param name="hwnd">Current windows handle</param>
    ''' <param name="lParam">Contains the FoundWindows structure</param>
    ''' <returns>The function passes the currently found windows in the lParam using a GCHandle to reform the data</returns>
    ''' <remarks>This function is called for each of the windows found, and is where the indexOf is called</remarks>
    Public Function EnumWindowsProc(ByVal hwnd As Integer, ByVal lParam As IntPtr) As Boolean
        Dim foundWindows As FoundWindows = CType(System.Runtime.InteropServices.GCHandle.FromIntPtr(lParam).Target, FoundWindows)
        Dim windowTitle As String = foundWindows.strFindWindow
        Dim wndTxtLen As Integer = GetWindowTextLength(hwnd)
        If Not wndTxtLen = 0 Then
            Dim sb As New System.Text.StringBuilder("", wndTxtLen + 1)
            GetWindowText(hwnd, sb, sb.Capacity)
            Dim windowCaption As String = sb.ToString
            If foundWindows.boolCase = False Then
                windowCaption = windowCaption.ToLower
                windowTitle = windowTitle.ToLower
            End If
            If windowCaption.IndexOf(windowTitle) > -1 Then
                Dim foundWindow As New FoundWindow
                foundWindow.hWnd = CType(hwnd, IntPtr)
                Dim sbClassName As New System.Text.StringBuilder("", 256)
                GetClassName(foundWindow.hWnd, sbClassName, 256)
                foundWindow.strClassName = sbClassName.ToString
                foundWindow.strWindowName = sb.ToString
                foundWindows.lstFoundWindows.Add(foundWindow)
            End If
        End If
        Return True
    End Function

    ''' <summary>
    ''' This function is used to loop through all open windows and check which ones contain a specific string
    ''' </summary>
    ''' <param name="strIndexOf">The string that you wish to check for in the window captions</param>
    ''' <param name="boolCase">Whether the function is should check for case</param>
    ''' <returns>A FoundWindows structure containing a list of FoundWindow</returns>
    ''' <remarks>The FoundWindows structure also contains the strIndexOf that was used to search the windows caption</remarks>
    Public Function FindWindowsIndexOf(ByVal strIndexOf As String, ByVal boolCase As Boolean) As FoundWindows
        Dim foundWindows As New FoundWindows
        foundWindows.boolCase = boolCase
        foundWindows.strFindWindow = strIndexOf
        foundWindows.lstFoundWindows = New List(Of FoundWindow)
        Dim ListHandle As System.Runtime.InteropServices.GCHandle = System.Runtime.InteropServices.GCHandle.Alloc(foundWindows)
        Try
            EnumWindows(AddressOf EnumWindowsProc, System.Runtime.InteropServices.GCHandle.ToIntPtr(ListHandle))
        Finally
            If ListHandle.IsAllocated Then ListHandle.Free()
        End Try
        Return foundWindows
    End Function

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        For Each fWnd As FoundWindow In FindWindowsIndexOf("Test", True).lstFoundWindows
            Debug.WriteLine(fWnd.strWindowName & " : " & fWnd.hWnd.ToString)
        Next
    End Sub

The function can check for casing as well. For example if you are running two windows one named “test” and another named “Test” if you use the function like this:

FindWindowsIndexOf("Test", True)

It will only return one window, however if you set the boolCase to false:

FindWindowsIndexOf("Test", False)

It will return both windows

03
May
09

[VB.Net] The beginnings of a Neopets bot

Ive decided that I’ve had enough of javascript, and so im going to move to VB.net to attempt to create a better bot. The auction bot itself, is, very good. However, now I want an autobuyer, and I cant get that to work in javascript as firefox doesn’t want to display the image when haggling..

Ive decided to do it using a webbrowser control, for ease of accessing the elements on the page, and below is a quick example of logging into neopets.

    Private Enum Bot_State
        Initial
        LogIn
        LoggingIn1
        LoggingIn2
        LoggingIn3
        LoggedIn
    End Enum

    Dim State As Bot_State = Bot_State.Initial
    Dim Username As String = "username"
    Dim Password As String = "password"

    ''web = System.Windows.Forms.WebBrowser
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        web.Navigate("http://neopets.com")
    End Sub

    Private Sub web_DocumentCompleted(ByVal sender As Object, ByVal e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs) Handles web.DocumentCompleted
        Select Case State
            Case Bot_State.Initial
                If web.Document.Body.InnerHtml.IndexOf("Login") <> -1 Then
                    State = Bot_State.LogIn
                    web.Navigate(web.Url.AbsoluteUri & "/loginpage.phtml")
                Else
                    State = Bot_State.LoggedIn
                End If
            Case Bot_State.LogIn
                Dim UserTB As HtmlElement = web.Document.GetElementById("txtUsername")
                UserTB.SetAttribute("value", Username)
                UserTB.Parent().Parent().Parent().Parent().DomElement.Submit()
                State = Bot_State.LoggingIn1
            Case Bot_State.LoggingIn1
                State = Bot_State.LoggingIn2
            Case Bot_State.LoggingIn2
                Dim PageInput As HtmlElementCollection = web.Document.GetElementsByTagName("input")
                For Each elem As HtmlElement In PageInput
                    If elem.GetAttribute("name") = "password" Then
                        elem.SetAttribute("value", Password)
                        elem.Parent().Parent().Parent().Parent().DomElement.Submit()
                    End If
                Next
                State = Bot_State.LoggingIn3
            Case Bot_State.LoggingIn3
                If web.Url.AbsoluteUri.IndexOf("index") Then
                    State = Bot_State.LoggedIn
                Else
                    State = Bot_State.LogIn
                    web.Navigate(web.Url.AbsoluteUri & "/loginpage.phtml")
                End If
        End Select
    End Sub
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.

29
Apr
09

[Note] Neopets Autobidder Progress

This is the current workup for the neopets auction bot:

Currently, i have all the complex coding done, just have to work out the last few bugs here and there, and then decide how to integrate the bot with an auto stocker (wether to pass the sell price from url to url, until it reaches the stock, or to just query again later on).

Main Auction Page
Create list of items to query
Send request to php
Return list of items maxprice & sell price
Parse list
Loop through each row
Check if item is in list
If it is, check if its a NF only auction
If its not, check to see if maxprice is less than the current price
If it is, check to see if the page is on the ignore list
If it isnt, open the page in a new tab with max price as an url paramater (possibly also sell price?)
Add opened page to ignore list (greasemonkey var?)
Wait between 7 and 15 seconds, refresh page

Bid Page
Parse max price from url
Get username from page
Check to see if the auction is over/invalid/too expensive
If it is, close the page
If it isnt, Check to see if the last bidder was the user
If it is, refresh the page
If it isnt,
modify the form to pass the maxprice in the url when submitted (possibly also sell price)
submit the bid

Bid Submission
Parse max price from url
Check if bid successful (find BID SUCCESSFUL)
If yes,
find link on page (loop through ‘a’ elements)
modify link to pass the maxprice in the url when submitted (possibly also sell price)
If no, check reason
If not enough money, close
If need to wait, history back
If bid twice in a row, back : (Sorry, you are not allowed to bid on an auction two times in a row)

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);
?>