Version: 1.0 Made By: Tharoux Date: May 27th, 2009 Revision: May 27th, 2009 Goal: Creating a simple application that will log in Neopets and search for an item from the SW Since alot of peoples want to start programming for this forum and need help, I'll show you the basis and what you need to successfully create an application using VB.NET. I'm by no mean a professional programmer (Well, I am doing this for a living but not in VB.NET) so the code can probably be improve. Anyway, enough talking, let's get down to business. Disclaimer: I apologize for any typo, weird words, unreadable sentences: english is not my main language and I'm not perfect so if you see any problem with this tutorial, let me know so I can fix it. ->Chapter One: Requirement ->Chapter Two: HTTPWrapper ->Chapter Three: Creation Of The Form ->Chapter Four: The Coding ->Chapter Five: Using Etherdetect ->Chapter Six: Using the HTTPWrapper Request ->The End Chapter One: Requirement The first thing we need to do is get the right tool. What I'm using can be replace and if you're more familiar with other programs/code, feel free to use what you're used to. -VB.NET 2008 -Etherdetect -HttpWrapper for VB.NET (see next section) You can use any VB.NET version and it will work but this one is free for 30 days. As for Etherdetect, you can easily find a serial on the web but you can still use the program without one. Chapter Two: HTTPWrapper There's some function in VB.NET that are readily available that will do part of the job regarding http request. But since we need a complete solution handling POST/GET request, cookies and image grabbing, someone managed to create a Class that can be used with VB.NET to handle all this for us. If I remember correctly, the one provided below was posted by Mystical (not a member of here anymore). I can't remember if I made some modifications to it but I do remember that I had to fiddle with the code a bit to make it work. Code (Text): Public Class TCPWrapper Inherits System.Windows.Forms.UserControl #Region " Windows Form Designer generated code " Public Sub New() MyBase.New() 'This call is required by the Windows Form Designer. InitializeComponent() 'Add any initialization after the InitializeComponent() call End Sub 'UserControl overrides dispose to clean up the component list. Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean) If disposing Then If Not (components Is Nothing) Then components.Dispose() End If End If MyBase.Dispose(disposing) End Sub 'Required by the Windows Form Designer Private components As System.ComponentModel.IContainer 'NOTE: The following procedure is required by the Windows Form Designer 'It can be modified using the Windows Form Designer. 'Do not modify it using the code editor. <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent() components = New System.ComponentModel.Container End Sub #End Region Private colCookies As New Collection Dim strCookies As String Public LastPage As String Public Function Request(ByVal Method As String, ByVal URL As String, ByVal Referer As String) As String Dim Host As String = Nothing Dim strFile As String = Nothing Dim strPost As String = Nothing Dim pos As Integer = 0 If Referer Is Nothing Then Referer = LastPage End If If URL.Contains("http://") Then Host = URL.Substring(7) Else Host = URL End If If Host.Contains("/") Then pos = Host.IndexOf("/", 0) strFile = Host.Substring(pos) Host = Host.Substring(0, pos) Else strFile = "/" End If If Method = "POST" Then pos = strFile.IndexOf("?") If Not (pos = -1) Then strPost = strFile.Substring(pos + 1) strFile = strFile.Substring(0, pos) Else strPost = Nothing End If End If If Method = "POST2" Then pos = strFile.IndexOf("?") If Not (pos = -1) Then strPost = strFile.Substring(pos + 1) strFile = strFile.Substring(0, pos) Else strPost = "" End If End If LastPage = URL Dim ReqHeaders As String = Nothing If Method = "GET" OrElse Method = "PIC" Then ReqHeaders = "GET" + " " + strFile + " HTTP/1.1" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Host: " + Host + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US; rv:1.8.0.7) Gecko/20060909 Firefox/1.5.0.7" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Accept-Language: en-us,en;q=0.5" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Accept-Encoding: gzip, deflate" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Keep-Alive: 300" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Connection: keep-alive" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Referer: " + Referer + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Cookie: " + strCookies + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" Else ReqHeaders = "POST " + strFile + " HTTP/1.1" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Host: " + Host + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US; rv:1.8.0.7) Gecko/20060909 Firefox/1.5.0.7" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Accept-Language: en-us,en;q=0.5" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Accept-Encoding: gzip, deflate" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Keep-Alive: 300" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Connection: keep-alive" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Referer: " + Referer + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Cookie: " + strCookies + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Content-Type: application/x-www-form-urlencoded" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Content-Length: " + strPost.Length.ToString + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Connection: close" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + strPost End If If Method = "PIC" Then ReqHeaders.Replace("Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5", "Accept: image/png,*/*;q=0.5") End If Dim tcp As New System.Net.Sockets.TcpClient Dim netstream As System.Net.Sockets.NetworkStream Dim TN(1) As Long If Referer = "" Then Referer = LastPage If InStr(1, URL, "http://") <> 0 Then Host = Mid$(URL, 8) If InStr(1, Host, "/") <> 0 Then Host = Mid$(Host, 1, InStr(1, Host, "/") - 1) If InStr(1, Host, "?") <> 0 Then Host = Mid$(Host, 1, InStr(1, Host, "?") - 1) LastPage = URL Try tcp.Connect(Host, 80) Catch ex As Exception Return ex.Message End Try Dim sendbytes As Byte() sendbytes = System.Text.Encoding.ASCII.GetBytes(ReqHeaders) netstream = tcp.GetStream() netstream.Write(sendbytes, 0, sendbytes.Length) Dim sr As StreamReader = New StreamReader(netstream, Encoding.Default) Dim strHTML As String = sr.ReadToEnd Dim strParts As String() = Regex.Split(strHTML, Environment.NewLine + Environment.NewLine) strCookies = ParseCookies(strParts(0)) If strParts(0).Contains("Content-Encoding") Then strParts(1) = DecompressGzip(strParts(1)) End If Return strParts(0) + Environment.NewLine + Environment.NewLine + strParts(1) End Function Public Function DecompressGzip(ByVal compressed As String) As String Dim memStream As MemoryStream = New MemoryStream(System.Text.Encoding.Default.GetBytes(compressed)) Dim decompressStream As GZipStream = New GZipStream(memStream, CompressionMode.Decompress) Dim endBytes(4) As Byte Dim position As Integer = CType(memStream.Length, Integer) - 4 memStream.Position = position memStream.Read(endBytes, 0, 4) memStream.Position = 0 Dim buffer(BitConverter.ToInt32(endBytes, 0) + 100) As Byte Dim offset As Integer = 0 Dim total As Integer = 0 While True Dim bytesRead As Integer = decompressStream.Read(buffer, offset, 100) If bytesRead = 0 Then Exit While End If offset += bytesRead total += bytesRead End While Return Encoding.ASCII.GetString(buffer) End Function Public Function ParseCookies(ByVal Headers As String) As String ParseCookies = "" Dim reg As Regex Dim matches As MatchCollection Dim match As Match reg = New Regex("set-cookie:\s*([^=]+)=([^;]+);", RegexOptions.IgnoreCase) If reg.IsMatch(Headers) Then matches = reg.Matches(Headers) For Each match In matches Try colCookies.Add(match.Groups(1).ToString & "=" & match.Groups(2).ToString, match.Groups(1).ToString) Catch ex As Exception colCookies.Remove(match.Groups(1).ToString) colCookies.Add(match.Groups(1).ToString & "=" & match.Groups(2).ToString, match.Groups(1).ToString) End Try Next End If Dim i As Long For i = 1 To colCookies.Count Step 1 ParseCookies = ParseCookies & colCookies.Item(i).ToString & ";" Next End Function Public Function StripHeaders(ByVal strSource As String) As String Dim strParts() As String = Regex.Split(strSource, Environment.NewLine + Environment.NewLine) Return strParts(1) End Function Public Function NeoLogin(ByVal user As String, ByVal pass As String, ByRef loggedIn As Boolean) As String Dim strHTML As String = Nothing Request("GET", "http://www.neopets.com/loginpage.phtml", "http://www.google.com") Pause(1) Request("POST", "http://www.neopets.com/hi.phtml?destination=%2Findex.phtml&username=" + user, "http://www.neopets.com/loginpage.phtml") Pause(1) strHTML = Request("POST", "http://www.neopets.com/login.phtml?username=" + user + "&password=" + pass + "&destination=%2Findex.phtml", "http://www.neopets.com/hi.phtml") If strHTML.Contains("Set-Cookie: neologin=") Then loggedIn = True Return "Logged In" Else If strHTML.Contains("too many times") Then loggedIn = False Return "To Many Login Attempts" Else If strHTML.Contains("badpassword") Then loggedIn = False Return "Wrong Username/Password" Else If strHTML.Contains("frozen") Then loggedIn = False Return "Account Frozen" Else If strHTML.Contains("just a technical problem") Then loggedIn = False Return "Neopets is down for maintenance" Else loggedIn = False Return "Unknow Error" End If End If End If End If End If End Function Private Shared Sub Pause(ByVal seconds As Double) Dim num As Double = seconds * 1000 Dim t1 As DateTime = DateTime.Now Dim t2 As DateTime = DateTime.Now Dim tmDiff As TimeSpan = t2 - t1 While Convert.ToDouble(tmDiff.TotalMilliseconds.ToString) < num t2 = DateTime.Now tmDiff = t2 - t1 Application.DoEvents() End While End Sub Public Function GrabPic(ByVal strURL As String) As System.Drawing.Image Dim memStream As New MemoryStream(System.Text.Encoding.Default.GetBytes(StripHeaders(Request("GET", strURL, LastPage)))) GrabPic = Image.FromStream(memStream) Return GrabPic End Function Public Sub ClearCookies() colCookies.Clear() strCookies = Nothing End Sub Public Function GetBetween(ByVal Source As String, ByVal Start As String, ByVal Finish As String) As String Dim Result = "" Dim A = InStr(1, Source, Start) + Len(Start) If A = 0 Then Result = "" Return Result Else Dim B = InStr(A, Source, Finish) If B = 0 Then Result = "" Return Result Else Result = Mid(Source, A, B - A) Return Result End If End If End Function End Class Now, let's see what function we have in there and what you can do with them. Note that some functions are called within the class so you're never going to call them yourself. We'll see later with examples how to use them. -Function Request(): This one is used to send a command to the server. You can either use "GET". "POST" or "PIC" depending on what you need to do. -Function NeoLogin(): This function can be done manually but since it's so common, they create a function out of it to make the thing easier. -Function Pause(): Will pause for xx seconds. -Function GrabPic(): If you want to retrieve a pic from the source code, you'll use function. -Function ClearCookie(): Delete all the cookie strings kept after using the neologin function. -Function GetBetween(): Added by me. This will return a string contained between 2 others. Chapter Three: Creation Of The Form Now that we have everything we need, let's start coding. First, we need to create a new project. So in VB.NET: File --> New Project --> Select "Windows Form Application" Give it the name you want, it doesn't matter. You'll need to put 2 "textbox", a "label" and 2 "command button". We'll use the first box for the neopets username and the second one for the password. Chapter Four: The Coding We need to put some code in there to make everything work. First, double-click on the "Login" button. That will bring the code window. It's now the time to put the HTTPWrapper from the chapter 2 in our project. Copy/paste it but make sure you do it after the "End Class" already in there. Right ahead, you'll notice some errors in the "Error window" at the bottom. That's normal. VB.Net does handle all this code but not right out off the box. That's where "Imports" come into play. Basicaly, you'll tell VB.Net where to find the extra function used in the HTTPWrapper. Here's all the "Imports" you need. Imports MUST be before ALL the code in you code window. Code (Text): Imports System.Net Imports System.Text.RegularExpressions Imports System.IO Imports System.Text Imports System.IO.Compression Now, let's get back to our main form (still in the code window). You can easily find it because the class will have the name of your project you defined in chapter 3. You must understand that even if the HTTPWrapper is in the same code window, this class is not interacting with your main class. You have to create a relation between them for your main class to be able to use it. This is done using the code below. This section of code must be in your main class at the very beginning. Each time we'll have to use the HTTPWrapper, we will use this link to communicate with it. Code (Text): Private Wrapper As New TCPWrapper It's now time to do our first interaction with http://www.neopets.com. To be able to do anything, we first need to be logged in. So we'll move to the "Private Sub Button1_Click" part within our main class. The code we put there will be executed upon the successfull click of the "Login" button on our form. I will not put any confirmation of the information entered into the textbox to facilitate the reading of the code. This won't impact the process at all, it's just a safety. If you want a complete login function, you can follow THIS link containing a complete solution made by me containing all the standard validation for the login button (Field not empty, disabling of the field to prevent editing after logging in). Using the Neologin() function already coded in the HTTPWrapper is easy. This function navigate throught all the normal pages if you were trying to do it manually with your browser (loginpage.phtml --> hi.phtml --> login.phtml). The only reason they did a function is to prevent you from doing a 100 lines of codes each time. Instead, all we need is a single (!) line. Another nice thing about the HTTPWrapper is that it always return a string with the result of the operation you just ask. It's up to you to store this information in a string variable or not depending on what you want to do with the result. Code (Text): Dim Response = Wrapper.NeoLogin(TextBox1.Text, TextBox2.Text, False) In the example above, we can see that we're using the "Wrapper" keyword. Remember, this is our link between the main class and the HTTPWrapper class. We than ask the link to execute the function Neologin. What we put in parenthesis is parameters given to the HTTPWrapper to complete the operation (textbox1.text = username we input on the form, textbox2.text = password) so it can perform the login. The result will be put in the variable "Response" for further analysis. If you take a close look into the Neologin() function in the HTTPWrapper, you'll notice that all the possible answers from TnT are already coded to simplify the task. Here's what the Wrapper can return as a result of the login process: -"Logged In" -"To Many Login Attempts" -"Wrong Username/Password" -"Account Frozen" -"Neopets is down for maintenance" -"Unknow Error" Right now, the result is not displayed anywhere. We'll use the label made earlier to show the result of the operation and if everything was done perfectly, including the user/password, we should see "Logged In" in the label below the 2 textbox. Code (Text): Label1.Text = Response It's time to complete the "Logout" button. This one is easy because it's only 1 line of code to remove all the cookies. Clearing the cookie will log you out of http://www.neopets.com. To do so, return to your form (the GUI) and double-click on the "Logout" button. You'll automaticaly be redirect to the right place and all you need to put there is this. Code (Text): Wrapper.ClearCookies() Here's what your code should look like after this chapter: Code (Text): Imports System.Net Imports System.Text.RegularExpressions Imports System.IO Imports System.Text Imports System.IO.Compression Public Class Form1 Private Wrapper As New TCPWrapper Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim Response = Wrapper.NeoLogin(TextBox1.Text, TextBox2.Text, False) Label1.Text = Response End Sub Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click Wrapper.ClearCookies() End Sub End Class Public Class TCPWrapper Inherits System.Windows.Forms.UserControl #Region " Windows Form Designer generated code " Public Sub New() MyBase.New() 'This call is required by the Windows Form Designer. InitializeComponent() 'Add any initialization after the InitializeComponent() call End Sub 'UserControl overrides dispose to clean up the component list. Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean) If disposing Then If Not (components Is Nothing) Then components.Dispose() End If End If MyBase.Dispose(disposing) End Sub 'Required by the Windows Form Designer Private components As System.ComponentModel.IContainer 'NOTE: The following procedure is required by the Windows Form Designer 'It can be modified using the Windows Form Designer. 'Do not modify it using the code editor. <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent() components = New System.ComponentModel.Container End Sub #End Region Private colCookies As New Collection Dim strCookies As String Public LastPage As String Public Function Request(ByVal Method As String, ByVal URL As String, ByVal Referer As String) As String Dim Host As String = Nothing Dim strFile As String = Nothing Dim strPost As String = Nothing Dim pos As Integer = 0 If Referer Is Nothing Then Referer = LastPage End If If URL.Contains("http://") Then Host = URL.Substring(7) Else Host = URL End If If Host.Contains("/") Then pos = Host.IndexOf("/", 0) strFile = Host.Substring(pos) Host = Host.Substring(0, pos) Else strFile = "/" End If If Method = "POST" Then pos = strFile.IndexOf("?") If Not (pos = -1) Then strPost = strFile.Substring(pos + 1) strFile = strFile.Substring(0, pos) Else strPost = Nothing End If End If If Method = "POST2" Then pos = strFile.IndexOf("?") If Not (pos = -1) Then strPost = strFile.Substring(pos + 1) strFile = strFile.Substring(0, pos) Else strPost = "" End If End If LastPage = URL Dim ReqHeaders As String = Nothing If Method = "GET" OrElse Method = "PIC" Then ReqHeaders = "GET" + " " + strFile + " HTTP/1.1" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Host: " + Host + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US; rv:1.8.0.7) Gecko/20060909 Firefox/1.5.0.7" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Accept-Language: en-us,en;q=0.5" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Accept-Encoding: gzip, deflate" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Keep-Alive: 300" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Connection: keep-alive" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Referer: " + Referer + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Cookie: " + strCookies + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" Else ReqHeaders = "POST " + strFile + " HTTP/1.1" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Host: " + Host + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US; rv:1.8.0.7) Gecko/20060909 Firefox/1.5.0.7" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Accept-Language: en-us,en;q=0.5" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Accept-Encoding: gzip, deflate" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Keep-Alive: 300" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Connection: keep-alive" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Referer: " + Referer + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Cookie: " + strCookies + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Content-Type: application/x-www-form-urlencoded" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Content-Length: " + strPost.Length.ToString + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Connection: close" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + strPost End If If Method = "PIC" Then ReqHeaders.Replace("Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5", "Accept: image/png,*/*;q=0.5") End If Dim tcp As New System.Net.Sockets.TcpClient Dim netstream As System.Net.Sockets.NetworkStream Dim TN(1) As Long If Referer = "" Then Referer = LastPage If InStr(1, URL, "http://") <> 0 Then Host = Mid$(URL, 8) If InStr(1, Host, "/") <> 0 Then Host = Mid$(Host, 1, InStr(1, Host, "/") - 1) If InStr(1, Host, "?") <> 0 Then Host = Mid$(Host, 1, InStr(1, Host, "?") - 1) LastPage = URL Try tcp.Connect(Host, 80) Catch ex As Exception Return ex.Message End Try Dim sendbytes As Byte() sendbytes = System.Text.Encoding.ASCII.GetBytes(ReqHeaders) netstream = tcp.GetStream() netstream.Write(sendbytes, 0, sendbytes.Length) Dim sr As StreamReader = New StreamReader(netstream, Encoding.Default) Dim strHTML As String = sr.ReadToEnd Dim strParts As String() = Regex.Split(strHTML, Environment.NewLine + Environment.NewLine) strCookies = ParseCookies(strParts(0)) If strParts(0).Contains("Content-Encoding") Then strParts(1) = DecompressGzip(strParts(1)) End If Return strParts(0) + Environment.NewLine + Environment.NewLine + strParts(1) End Function Public Function DecompressGzip(ByVal compressed As String) As String Dim memStream As MemoryStream = New MemoryStream(System.Text.Encoding.Default.GetBytes(compressed)) Dim decompressStream As GZipStream = New GZipStream(memStream, CompressionMode.Decompress) Dim endBytes(4) As Byte Dim position As Integer = CType(memStream.Length, Integer) - 4 memStream.Position = position memStream.Read(endBytes, 0, 4) memStream.Position = 0 Dim buffer(BitConverter.ToInt32(endBytes, 0) + 100) As Byte Dim offset As Integer = 0 Dim total As Integer = 0 While True Dim bytesRead As Integer = decompressStream.Read(buffer, offset, 100) If bytesRead = 0 Then Exit While End If offset += bytesRead total += bytesRead End While Return Encoding.ASCII.GetString(buffer) End Function Public Function ParseCookies(ByVal Headers As String) As String ParseCookies = "" Dim reg As Regex Dim matches As MatchCollection Dim match As Match reg = New Regex("set-cookie:\s*([^=]+)=([^;]+);", RegexOptions.IgnoreCase) If reg.IsMatch(Headers) Then matches = reg.Matches(Headers) For Each match In matches Try colCookies.Add(match.Groups(1).ToString & "=" & match.Groups(2).ToString, match.Groups(1).ToString) Catch ex As Exception colCookies.Remove(match.Groups(1).ToString) colCookies.Add(match.Groups(1).ToString & "=" & match.Groups(2).ToString, match.Groups(1).ToString) End Try Next End If Dim i As Long For i = 1 To colCookies.Count Step 1 ParseCookies = ParseCookies & colCookies.Item(i).ToString & ";" Next End Function Public Function StripHeaders(ByVal strSource As String) As String Dim strParts() As String = Regex.Split(strSource, Environment.NewLine + Environment.NewLine) Return strParts(1) End Function Public Function NeoLogin(ByVal user As String, ByVal pass As String, ByRef loggedIn As Boolean) As String Dim strHTML As String = Nothing Request("GET", "http://www.neopets.com/loginpage.phtml", "http://www.google.com") Pause(1) Request("POST", "http://www.neopets.com/hi.phtml?destination=%2Findex.phtml&username=" + user, "http://www.neopets.com/loginpage.phtml") Pause(1) strHTML = Request("POST", "http://www.neopets.com/login.phtml?username=" + user + "&password=" + pass + "&destination=%2Findex.phtml", "http://www.neopets.com/hi.phtml") If strHTML.Contains("Set-Cookie: neologin=") Then loggedIn = True Return "Logged In" Else If strHTML.Contains("too many times") Then loggedIn = False Return "To Many Login Attempts" Else If strHTML.Contains("badpassword") Then loggedIn = False Return "Wrong Username/Password" Else If strHTML.Contains("frozen") Then loggedIn = False Return "Account Frozen" Else If strHTML.Contains("just a technical problem") Then loggedIn = False Return "Neopets is down for maintenance" Else loggedIn = False Return "Unknow Error" End If End If End If End If End If End Function Private Shared Sub Pause(ByVal seconds As Double) Dim num As Double = seconds * 1000 Dim t1 As DateTime = DateTime.Now Dim t2 As DateTime = DateTime.Now Dim tmDiff As TimeSpan = t2 - t1 While Convert.ToDouble(tmDiff.TotalMilliseconds.ToString) < num t2 = DateTime.Now tmDiff = t2 - t1 Application.DoEvents() End While End Sub Public Function GrabPic(ByVal strURL As String) As System.Drawing.Image Dim memStream As New MemoryStream(System.Text.Encoding.Default.GetBytes(StripHeaders(Request("GET", strURL, LastPage)))) GrabPic = Image.FromStream(memStream) Return GrabPic End Function Public Sub ClearCookies() colCookies.Clear() strCookies = Nothing End Sub Public Function GetBetween(ByVal Source As String, ByVal Start As String, ByVal Finish As String) As String Dim Result = "" Dim A = InStr(1, Source, Start) + Len(Start) If A = 0 Then Result = "" Return Result Else Dim B = InStr(A, Source, Finish) If B = 0 Then Result = "" Return Result Else Result = Mid(Source, A, B - A) Return Result End If End If End Function End Class Chapter Five: Using Etherdetect This program might be hard to understand at first but once you get the twist, it's quite easy. To use this program, you need to be logged in normally using your browser. To do the sniffing, you will need to perform the action yourself and than analyze the result in etherdetect to find what the browser is really doing behind the GUI. To do so, click the play button in etherdect. This will start the sniffing process. Than do what you have to do on http://www.neopets.com. In this example, I'll be searching the SW for a "bri codestone", using the "indentical to my phrase" option. When this is done, click the stop button in etherdetect. The key here is to find where's the information we want. Browse throught all entry until you see something with "GET" in it. Over time, you'll realize that TnT's ip adress is 206.220.42.181 so this narrow where you have to search to find the information you're looking for. Click on the picture below for a better view. Ok, so we've found what you're looking for, now it's time to gather data. When using the HTTPWrapper, we need 3 things: -Is it a "GET" or "POST" command -the complete URL of the page -the referer The referer is VERY important. TnT use this as a security to be sure you're not trying to cheat, and if you don't have it, the action you're trying to do will not work. In the example below, I selected the line where was the "GET" command(STEP 1). Next, you have to press the data tab at the bottom for a better view of the information(Step 2). Now, we can see that we are doing a "GET", that the url is "www.neopets.com/market.phtml?type=wizard" and that the referer (where we are coming from) is "http://www.neopets.com/index.phtml". Basicaly, this is the link to the SW main page. Click on the picture below for a better view. Here's an example with the "POST" command. It work exactly like the "GET" command. There's just 1 extra line we need to see there (all the parameters that will be sent with the "POST"). On the third line, we see all the informations that need to be sent. Here, we are doing a "POST", the url is "www.neopets.com/market.phtml?type=process_wizard&feedset=0&shopwizard=bri+codestone&table=shop&criteria=exact&min_price=0&max_price=99999" and the referer is "http://www.neopets.com/market.phtml?type=wizard". Here we can see the item we searched for (Bri codestone) and the "Identical to my phrase" option (criteria=exact).Click on the picture below for a better view. It's the same process everytime. It may get more complex depending on what you're trying to code but the step remains the same. Chapter Six: Using the HTTPWrapper Request Here's where the real interaction between your program and http://www.neopets.com will take place. In this chapter, we'll add a nice SW function to our project. We already found all the informations we need to make this happen in the last chapter so now it's only a matter of coding it. In the last chapter, I wrote about the referer playing an important part in our coding. I'll explain why and how I code my programs accordingly. I'm doing this mainly because everytime I (or any programmer) do a program, we must think about what can be done to prevent TnT from catching us. Nobody want a program with a freeze rate of 95%. And this start with how you navigate throught the URL in your programs. I always imagine myself browsing neopets in a single window: No tab, no shortcut. For every action, I think about where I'm going and how to get there. In the last chapter, we can see this. I was searching for an item from the SW but instead of just doing the search using the "POST" command with the right URL, I first navigated my way to the SW using the "GET" command with the right URL. And that's where the referer become important. When moving from page to page, you must be sure that the referer you coded is the right one, making the process as human as possible. Maybe doing all this is a waste of time, but IMO, the more human your program act, the less chance you have of getting caught. Anyway, enough talking, let's get down to business. We'll now add a textbox and a command button to our form. We'll use the textbox to ouput the result of the SW search. Now, double-click on the "Search" button to open the code window. Like I said earlier, we won't directly do the search: we'll start by navigating our way to the SW first. In the last chapter, we found that we were doing a "GET", that the url was "www.neopets.com/market.phtml?type=wizard" and that the referer was "http://www.neopets.com/index.phtml". Code (Text): Wrapper.Request("GET", "www.neopets.com/market.phtml?type=wizard", "http://www.neopets.com/index.phtml") No need to store the result in a variable since this will only display the SW main page. Since there's no important information there, we'll discard it. Now we need to do the actual search. Again refering to the last chapter, we can complete the code. This time, we will store the result in the variable "Response" because you may want to process this information after (I.E. get the price of this item). Code (Text): Dim Response = Wrapper.Request("POST", "http://www.neopets.com/market.phtml?type=process_wizard&feedset=0&shopwizard=bri+codestone&table=shop&criteria=exact&min_price=0&max_price=99999", "http://www.neopets.com/market.phtml?type=wizard") And finally, let's put the result in our textbox. Code (Text): TextBox3.Text = Response Finally, we have a complete working code and it should look like this once finished. I only put the main class since we already saw what the compete coding was in chapter 4. Code (Text): Public Class Form1 Private Wrapper As New TCPWrapper Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim Response = Wrapper.NeoLogin(TextBox1.Text, TextBox2.Text, False) Label1.Text = Response End Sub Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click Wrapper.ClearCookies() End Sub Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click Wrapper.Request("GET", "http://www.neopets.com/market.phtml?type=wizard", "http://www.neopets.com/index.phtml") Dim Response = Wrapper.Request("POST", "http://www.neopets.com/market.phtml?type=process_wizard&feedset=0&shopwizard=bri+codestone&table=shop&criteria=exact&min_price=0&max_price=99999", "http://www.neopets.com/market.phtml?type=wizard") TextBox3.Text = Response End Sub End Class The End This was just a little example of what can be done with VB.NET. The code was pretty straight foward with no validation but that was not the goal. It will be up to you to code all this. The biggest challenge when coding is to anticipate all the actions of the end-user. I don't want someone clicking something he's not suppose to, and worse, at the wrong time. Anyway, I hope this tutorial helped you to understand a little bit more how to program using the HTTPWrapper. The hardest part is getting started. Once you know how it's working, you'll realize it's pretty much the same thing everytime. If you have any questions regarding this tutorial or simply some comments, don't hesitate. I'm always ready to help ! Thanks ! <3
Seems like it took a long time to write , Well done, I hope people learn from it. I haven't seen any obvious typo. Overall it's a nice beginner tutorial, with images and full explanations.
As a suggestion, I would use TamperData for Firefox over a packet editor/sniffer. Its more intuitive to use IMO and it logs only HTTP requests coming from your Firefox browser.
Awesome guide, perfect time to write it too i'm gonna try switching from vb6 to vb.net so i can probably pick up even quicker now with the help of this also does ether detect do the same thing as live http headers ff add-on?
Thanks for the input Zer0 ! I'm not using FF so I'm not to aware of those addon I guess... regarding addons for FF, maybe you should talk to the one quoted before you
LiveHTTPHeader (http://livehttpheaders.mozdev.org/) is definitely easier and more convenient than Etherdetect
Great. Works perfectly. *Edit* Now I just need to figure out how to make the pauses random between a certain amount of seconds.
i believe ricky's module has/had a function called "makerandom". i'll see if i can find it for you edit: couldn't find it but here is a function which should (i haven't tested) return a random number Code (Text): Public Function RandomNumber(ByVal low As Int32, ByVal high As Int32) As Integer Static RandomNumGen As New System.Random Return RandomNumGen.Next(low, high+1) End Function
Holy COW! I really hope that whatever went wrong was me... I followed this guide, and could understand most of it. I encountered a problem when I tried to run it. My coding all looks like the stuff in your code boxes, but a huge problem occurred. I pressed 'debug' from the menu, then debug from the dropdown. Form1 popped up, and I hit submit. Here's what popped up in that tiny search box: Spoiler HTTP/1.1 302 Found Date: Wed, 18 Nov 2009 22:49:46 GMT Server: Apache/2.2.9 (Unix) mod_ssl/2.2.9 OpenSSL/0.9.7a PHP/5.1.6 X-Powered-By: PHP/5.1.6 Set-Cookie: nupi=0; expires=Wed, 18-Nov-2009 21:09:46 GMT; path=/; domain=.neopets.com Set-Cookie: nupid=0; expires=Wed, 18-Nov-2009 21:09:46 GMT; path=/; domain=.neopets.com Set-Cookie: npid=0; expires=Wed, 18-Nov-2009 21:09:46 GMT; path=/; domain=.neopets.com p3p: policy="http://www.neopets.com/privacy.p3p", CP="CURa ADMa DEVa TAIa OUR BUS IND UNI COM NAV INT" Location: /loginpage.phtml?destination=%2Fmarket.phtml Vary: Accept-Encoding,User-Agent Content-Encoding: gzip Content-Length: 5057 Connection: close Content-Type: text/html; charset=UTF-8 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <!-- host - neopets-web-48.811.mtvi.com //--> <html> <head> <meta name="description" content="Neopets.Com - Virtual Pet Community! Join up for free games, shops, auctions, chat and more!"> <meta name="keywords" content="pets, pet, games, game, virtual, chat, fun, prizes, play, virtual pet, kids"> <meta name="robots" content="noodp, index, follow"> <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"> <link rel="stylesheet" type="text/css" href="http://images.neopets.com/css/default.css?v=3"> <link rel="stylesheet" type="text/css" href="http://images.neopets.com/mamabar/mamabar.css"> <link rel="stylesheet" type="text/css" href="http://images.neopets.com/css/themes/000_def_f65b1.css?v=4"> <title>Neopets - Shops owned by the owners of Neopia!</title> <script id="js-framework" type="text/javascript" language="JavaScript" src="http://images.neopets.com/js/common.js?v=3"></script> <script id="js-browserdetect" type="text/javascript" language="JavaScript" src="http://images.neopets.com/js/getbrowser.js?v=1"></script> <script type="text/javascript" src="http://images.neopets.com/n.js"></script> <script type="text/javascript"> <!-- var nl = "en"; var nh = 2; var nm = 49; var ns = 46; var na = "pm"; var ncl = new Array(0, 53, 104, 137, 169, 198, 231, 265, 299, 335, 368, 397, 427); window.setInterval('nc()', 1000); function sh(i) { ol.style.clip = "rect("+ncl[i-1]+" 128 "+ncl+" 0)"; ol.style.visibility = "visible"; } function mo() { ol.style.visibility = "hidden"; } function search_handle(searchForm) { searchForm.action = "/search.phtml"; searchForm.target = ""; searchForm.method = "post"; searchForm.s.value = searchForm.q.value; searchForm.submit(); }; //--> </script> <script src="http://images.neopets.com/js/urchin.js" type="text/javascript"></script> <script type="text/javascript"> _uacct = "UA-1152868-1"; urchinTracker("/market.phtml"); </script> <!-- --></head> <body> <!-- MAMABAR CODE BLOCK --> <script type="text/javascript"> function brandMamabarMoreOver(el) { el.className = "brand-mamabar-more-link brand-mamabar-more-link-hover"; } function brandMamabarMoreOut(el) { el.className = "brand-mamabar-more-link"; } </script> <div class="brand-mamabar"> <div class="brand-mamabar-wrapper"> <ul class="brand-mamabar-list"> <li><a class="brand-mamabar-active">neopets</a></li> <li><a href="http://www.petpetpark.com/">petpet park</a></li> <li><a href="http://www.nick.com/">nick</a></li> <li><a href="http://www.teenNick.com/">teennick</a></li> <li><a href="http://www.shockwave.com/">shockwave</a></li> <li class="brand-mamabar-more-link" onmouseover="brandMamabarMoreOver(this);" onmouseout="brandMamabarMoreOut(this);"> <a class="brand-mamabar-more-a" href="#"><span>more</span></a> <div class="brand-mamabar-more-wrapper"> <ul class="brand-mamabar-more-list"> <li class="brand-mamabar-first"><a href="http://www.nickjr.com/">nickjr</a></li> <li><a href="http://www.addictinggames.com/">addictinggames</a></li> <li><a href="http://www.nicktoons.com/">nicktoons</a></li> <li><a href="http://www.nickatnite.com/">nick at nite</a></li> <li><a href="http://www.upickdaily.com/">upick daily</a></li> <li><a href="http://www.parentsconnect.com/">parents connect</a></li> <li><a href="http://www.spongebob.com/">spongebob</a></li> <li><a href="http://www.icarly.com/">icarly.com</a></li> <li><a href="http://www.troopgrid.com/">troopgrid</a></li> <li><a href="http://www.quizilla.com/">quizilla</a></li> <li><a href="http://www.nickarcade.com/">nick arcade</a></li> <li><a href="http://www.nickjrarcade.com/">nickjr arcade</a></li> <li class="brand-mamabar-last"><a href="http://www.nickjrboost.com">nickjr boost</a></li> </ul> </div> </li> </ul> <a class="brand-mamabar-logo" href="http://www.nick.com/"><img alt="Nickelodeon" src="http://images.neopets.com/mamabar/logo_nick_mini.jpg" height="18" width="100"/></a> </div> </div> <div id="main"> <script type="text/javascript" src="http://images.neopets.com/js/comscore092009.js"></script> <script type="text/javascript" src="http://images.neopets.com/js/neoads.js?v=4"></script> <div id="ban" style="height: 94px; width: 996px;"><!-- //--> <!-- --><img id='vert_slug_leaderboard' style="position: relative; left: 127px; float: left; " src="http://images.neopets.com/adslug_728.gif" /><!-- Ad object type: xml --><!-- begin ad tag (tile=1) --> <script language="JavaScript" type="text/javascript"> document.write('<script language="JavaScript" src="http://ad.doubleclick.net/adj/neopets.nol/shops/user_shops/atf_adj;sec0=shops;sec1=user_shops;sec2=en;pos=atf;tag=adj;mtype=standard;demo=null;rugrat=null;section_0=shops;section_1=user_shops;hash=2645443197d233cf6ff5e73521cec84f;world=user_shops;u=|sec0-shops|sec1-user_shops|sec2-en|pos-atf|tag-adj|mtype-standard|demo-null|rugrat-null|;tile=1;sz=728x90;ord=8879742601?" type="text/javascript"><\/script>'); </script> <noscript><a href="http://ad.doubleclick.net/jump/neopets.nol/shops/user_shops/atf_adj_standard;sec0=shops;sec1=user_shops;sec2=en;pos=atf;tag=adj;mtype=standard;demo=null;rugrat=null;section_0=shops;section_1=user_shops;hash=2645443197d233cf6ff5e73521cec84f;world=user_shops;u=|sec0-shops|sec1-user_shops|sec2-en|pos-atf|tag-adj|mtype-standard|demo-null|rugrat-null|;tile=1;sz=728x90;ord=8879742601?" target="_blank"><img src="http://ad.doubleclick.net/ad/neopets.nol/shops/user_shops/atf_adj_standard;sec0=shops;sec1=user_shops;sec2=en;pos=atf;tag=adj;mtype=standard;demo=null;rugrat=null;section_0=shops;section_1=user_shops;hash=2645443197d233cf6ff5e73521cec84f;world=user_shops;u=|sec0-shops|sec1-user_shops|sec2-en|pos-atf|tag-adj|mtype-standard|demo-null|rugrat-null|;tile=1;sz=728x90;ord=8879742601?" width="728" height="90" border="0" alt=""></a></noscript> <!-- End ad tag --> </div> <div id="header"> <table cellpadding="0" cellspacing="0" border="0"> <tr> <td width="156" height="77" rowspan="3"><a href="/index.phtml"><img src="http://images.neopets.com/transparent_spacer.gif" width="156" height="77" alt="" border="0"></a></td> <td class="eventIcon sf" align="left"> </td> <td class="user medText"> <a href="/loginpage.phtml"><b>Login to Neopets!</b></a> </td> </tr> <tr> <td colspan="2" id="navigation"> <table width="100%" cellpadding="0" cellspacing="0" border="0"> <tr> <td width="725" align="center"> <script type="text/javascript"> // Yay for Suckerfish! startList = function() { if (document.all&&document.getElementById) { navRoot = document.getElementById("template_nav"); for (i=0; i<navRoot.childNodes.length; i++) { node = navRoot.childNodes; if (node.nodeName=="LI") { node.onmouseover=function() { this.className+=" over"; } node.onmouseout=function() { this.className=this.className.replace(" over", ""); } } } } } window.onload=startList; </script> <ul id="template_nav"> <li class="nav_image"><a href="/myaccount.phtml"><img src="http://images.neopets.com/themes/000_def_f65b1/navigation/myaccount.png" alt="" border="0" width="119" height="38"></a><ul class="dropdown"> <li><a href="/myaccount.phtml">» Control Panel</a></li> <li><a href="/preferences.phtml">» Preferences</a></li> <li><a href="/userinfo.phtml">» Edit Profile</a></li> <li><a href="/neomessages.phtml">» Neomail</a></li> <li><a href="/neofriends.phtml">» Neofriends</a></li> <li><a href="/addpet.phtml">» Create a Neopet</a></li> <li><a href="/space/warehouse/prizecodes.phtml">» Redeem Code</a></li> </ul> <li class="nav_image"><a href="/customise/"><img src="http://images.neopets.com/themes/000_def_f65b1/navigation/customise.png" alt="" border="0" width="89" height="38"></a><ul class="dropdown"> <li><a href="/customise/">» Customise Neopet</a></li> <li><a href="/objects.phtml?type=inventory">» Inventory</a></li> <li><a href="/closet.phtml">» Closet</a></li> <li><a href="/neohome/"> » Neohomes</a></li> <li><a href="/neohome/shed">» Storage Shed</a></li> <li><a href="/addpet.phtml">» Create a Neopet</a></li> </ul> </li> <li class="nav_image"><a href="/games/arcade.phtml"><img src="http://images.neopets.com/themes/000_def_f65b1/navigation/games.png" alt="" border="0" width="66" height="38"></a><ul class="dropdown"> <li><a href="/games/arcade.phtml">» Games Room</a></li> <li><a href="/games/arcade_more.phtml?cat=top_rated">» Top Rated</a></li> <li><a href="/gamescores.phtml">» High Scores</a></li> <li><a href="/games/favorites.phtml">» Favourites</a></li> <li><a href="/keyquest">» Key Quest</a></li> </ul> </li> <li class="nav_image"><a href="/explore.phtml"><img src="http://images.neopets.com/themes/000_def_f65b1/navigation/explore.png" alt="" border="0" width="75" height="38"></a><ul class="dropdown"> <li><a href="/explore.phtml">» Map of Neopia</a></li> <li><a href="/help/tutorial/index.phtml">» Tutorial</a></li> <li><a href="/weather.phtml">» Weather</a></li> <li><a href="/pronounce.phtml">» Pronunciation</a></li> <li><a href="/neopedia.phtml">» Neopedia</a></li> </ul> </li> <li class="nav_image"><a href="/nf.phtml"><img src="http://images.neopets.com/themes/000_def_f65b1/navigation/news.png" alt="" border="0" width="58" height="38"></a><ul class="dropdown"> <li><a href="/nf.phtml">» New Features</a></li> <li><a href="/comingsoon.phtml">» Coming Soon</a></li> <li><a href="/ntimes/index.phtml">» Neopian Times</a></li><li><a href="/stuff.phtml">» Merch News</a></li> </ul> </li> <li class="nav_image"><a href="/petcentral.phtml"><img src="http://images.neopets.com/themes/000_def_f65b1/navigation/petcentral.png" alt="" border="0" width="95" height="38"></a><ul class="dropdown"> <li><a href="/petcentral.phtml">» Main</a></li> <li><a href="/calendar.phtml">» Calendar</a></li> <li><a href="/worldevents.phtml">» World Events</a></li> <li><a href="/pound/index.phtml">» Neopian Pound</a></li> </ul> </li> <li class="nav_image"><a href="/neoboards/index.phtml"><img src="http://images.neopets.com/themes/000_def_f65b1/navigation/boards.png" alt="" border="0" width="68" height="38"></a><ul class="dropdown"> <li><a href="/neoboards/index.phtml">» Neoboard Index</a></li> <li><a href="/neoboards/preferences.phtml">» Preferences</a></li> </ul> </li> <li class="nav_image"><a href="/objects.phtml"><img src="http://images.neopets.com/themes/000_def_f65b1/navigation/shops.png" alt="" border="0" width="62" height="38"></a><ul class="dropdown"> <li><a href="/objects.phtml">» Neopia Central</a></li> <li><a href="/market.phtml?type=wizard">» Shop Wizard</a></li> <li><a href="/market.phtml?type=your">» Your Shop</a></li> <li><a href="/auctions.phtml">» Auctions</a></li> <li><a href="/island/tradingpost.phtml">» Trading Post</a></li> <li><a href="/bank.phtml">» Bank</a></li> <li><a href="/shopping/index.phtml">» Merchandise</a></li> </ul> </li> <style type="text/css"> li.nav_image { margin-left: 0px; } </style> <li class="nav_image"><a href="/mall/index.phtml"><img src="http://images.neopets.com/themes/000_def_f65b1/navigation/ncmall.png" alt="" border="0" width="93" height="38"></a><ul class="dropdown"> <li><a href="/mall/index.phtml">» Shop</a></li> <li><a href="/mall/index.phtml?page=nc">» Get Neocash</a></li> <li><a href="/mall/index.phtml?type=11">» Neocash Cards</a></li> <li><a href="/mall/index.phtml?page=redeem_nc ">» Redeem Neocash Card</a></li> </ul> </li> </ul> </td> <td id="nst">2:49:46 pm NST</td> </tr> </table> </td> </tr> <tr> <td colspan="3" height="3"><img src="http://images.neopets.com/transparent_spacer.gif" width="1" height="3" alt="" border="0"></td> </tr> </table> </div> <div id="content"> <table width="100%" cellpadding="0" cellspacing="0" border="0"> <tr> <td align="center" class="sidebar" width="178"><script type='text/javascript' src='http://images.neopets.com/js/swfobject.js?v=2'></script> <script type='text/javascript'> var swf = new SWFObject('http://images.neopets.com/images/signup_v6.swf', 'flash_97568990881', '160', '600', '8', '#FFFFFF'); swf.addParam('quality', 'high'); swf.addParam('scale', 'exactfit'); swf.addParam('menu', 'false'); swf.addParam('allowScriptAccess', 'always'); swf.addParam('swLiveConnect', 'true'); swf.addParam('wmode', 'transparent'); swf.addVariable('sURL', '%2Freg%2Findex.phtml%3Fdestination%3D%2Fmarket.phtml'); swf.addVariable('ilang', 'en'); swf.write(); </script> <div class="sidebarModule" style="margin-bottom: 7px;"> <table width="158" cellpadding="2" cellspacing="0" border="0" class="sidebarTable"> <tr> <td valign="middle" class="sidebarHeader medText">Search Neopets</td> </tr> <tr> <td class="neofriend" align="center"> <form onSubmit="search_handle(this);" style="padding-top: 4px; padding-bottom: 4px;"> <input class="sf" type="text" name="q" maxlength="255" value="Enter search text..." style="width: 135px; color: #a5a5a5; padding: 2px;" onFocus="this.style.color='#000000'; if( this.value=='Enter search text...' ) { this.value=''; }" onBlur="if( this.value=='' ) { this.style.color='#A5A5A5'; this.value='Enter search text...'; }"><br> <input type="submit" value="Go!" class="sf"> <input type="hidden" name="client" value="pub-9208792519293771"> <input type="hidden" name="forid" value="1"> <input type="hidden" name="ie" value="ISO-8859-1"> <input type="hidden" name="oe" value="ISO-8859-1"> <input type="hidden" name="safe" value="active"> <input type="hidden" name="domains" value="www.neopets.com"> <input type="hidden" name="cof" value="GALT:#FFFFFF;GL:1;DIV:#000066;VLC:FFFFFF;AH:center;BGC:FFFFFF;LBGC:000066;ALC:FFFFFF;LC:FFFFFF;T:000000;GFNT:000066;GIMP:000077;FORID:1"> <input type="hidden" name="hl" value="en"> <input type="hidden" name="s"> </form> </td> </tr> </table> </div> </td> <td class="content"> <style type="text/css"> .bgYellow { background-color: #FFCC00; } .blistHeader { background-color: #FFCC00; font-weight: bold; font-size: 11px; color: #000000; } .blistTopic { font-size: 12px; } .blistSmall { font-size: 11px; } .topicSmall { font-weight: normal; font-size: 10px; } .topic { background-color: #FFFFFF; font-weight: normal; font-size: 12px; color: #000000; border-bottom: 1px solid #000000; } .topicPosted { background-color: #F6F6F6; font-weight: normal; font-size: 10px; color: #000000; border-bottom: 1px solid #000000; } .topicAuthor { background-color: #F6F6F6; font-weight: normal; border-right: 1px solid #000000; border-bottom: 1px solid #000000; } .blockquote { margin: 10px; } .quote { background-color: #F6F6F6; font-size: 11px; font-style: italic; border: 1px solid #000000; padding: 5px; } </style> <script language="JavaScript"> var NeoboardPens = {}; NeoboardPens.maxPostLength = 400; function insertSmiley(smiley) { document.message_form.message.value += smiley; textCounter(document.message_form.message, document.message_form.remLen, NeoboardPens.maxPostLength); document.message_form.message.focus(); return false; } var submitcount = 0; function validateNewTopic() { var missing = ""; if (message_form.topic_title.value == "") { // missing title missing += " - Title\n"; } if (message_form.message.value == "") { // if too long...trim it! missing += " - Message\n"; } if (missing != "") { alert("Please fill in the following item(s):\n" + missing); return false; } else { if (submitcount == 0) { submitcount++; return true; } else { alert("Oops, you've already submitted your post.\nPlease wait for it to go through so you don't spam. "); return false; } } } function blockMultipleReplies() { if (submitcount == 0) { submitcount++; return true; } else { alert("Oops, you've already submitted your post.\nPlease wait for it to go through so you don't spam. "); return false; } } function textCounter(field, countfield, maxlimit) { maxlimit = maxlimit || NeoboardPens.maxPostLength; if (field.value.length > maxlimit) { // if too long...trim it! field.value = field.value.substring(0, maxlimit); } else { // otherwise, update 'characters left' counter countfield.value = maxlimit - field.value.length; } } function openWin(url, height, width, scroll, menu, resize, tool, loc, status) { height = (height) ? height : 200; width = (width) ? width : 400; scroll = (scroll) ? 'yes' : 'no'; menu = (menu) ? 'yes' : 'no'; resize = (resize) ? 'yes' : 'no'; tool = (tool) ? 'yes' : 'no'; loc = (loc) ? 'yes' : 'no'; status = (status) ? 'yes' : 'no'; options = 'scrollbars='+scroll+',menubar='+menu+',height='+height+',width='+width+',resizable='+resize+',toolbar='+tool+',location='+loc+',status='+status; if (url) { var load = window.open(url,'', options); } } </script> I'm afraid I don't understand a whole lot of that XD could you tell me where I went wrong? Pretty please? Also, here's my entire code: Spoiler Imports System.Net Imports System.Text.RegularExpressions Imports System.IO Imports System.Text Imports System.IO.Compression Public Class Form1 Private Wrapper As New TCPWrapper Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim Response = Wrapper.NeoLogin(TextBox1.Text, TextBox2.Text, False) Label1.Text = Response End Sub Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click Wrapper.ClearCookies() End Sub Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click Wrapper.Request("GET", "http://www.neopets.com/market.phtml?type=wizard", "http://www.neopets.com/index.phtml") Dim Response = Wrapper.Request("POST", "http://www.neopets.com/market.phtml?type=process_wizard&feedset=0&shopwizard=bri+codestone&table=shop&criteria=exact&min_price=0&max_price=99999", "http://www.neopets.com/market.phtml?type=wizard") TextBox3.Text = Response End Sub End Class Public Class TCPWrapper Inherits System.Windows.Forms.UserControl #Region " Windows Form Designer generated code " Public Sub New() MyBase.New() 'This call is required by the Windows Form Designer. InitializeComponent() 'Add any initialization after the InitializeComponent() call End Sub 'UserControl overrides dispose to clean up the component list. Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean) If disposing Then If Not (components Is Nothing) Then components.Dispose() End If End If MyBase.Dispose(disposing) End Sub 'Required by the Windows Form Designer Private components As System.ComponentModel.IContainer 'NOTE: The following procedure is required by the Windows Form Designer 'It can be modified using the Windows Form Designer. 'Do not modify it using the code editor. <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent() components = New System.ComponentModel.Container End Sub #End Region Private colCookies As New Collection Dim strCookies As String Public LastPage As String Public Function Request(ByVal Method As String, ByVal URL As String, ByVal Referer As String) As String Dim Host As String = Nothing Dim strFile As String = Nothing Dim strPost As String = Nothing Dim pos As Integer = 0 If Referer Is Nothing Then Referer = LastPage End If If URL.Contains("http://") Then Host = URL.Substring(7) Else Host = URL End If If Host.Contains("/") Then pos = Host.IndexOf("/", 0) strFile = Host.Substring(pos) Host = Host.Substring(0, pos) Else strFile = "/" End If If Method = "POST" Then pos = strFile.IndexOf("?") If Not (pos = -1) Then strPost = strFile.Substring(pos + 1) strFile = strFile.Substring(0, pos) Else strPost = Nothing End If End If If Method = "POST2" Then pos = strFile.IndexOf("?") If Not (pos = -1) Then strPost = strFile.Substring(pos + 1) strFile = strFile.Substring(0, pos) Else strPost = "" End If End If LastPage = URL Dim ReqHeaders As String = Nothing If Method = "GET" OrElse Method = "PIC" Then ReqHeaders = "GET" + " " + strFile + " HTTP/1.1" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Host: " + Host + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US; rv:1.8.0.7) Gecko/20060909 Firefox/1.5.0.7" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Accept-Language: en-us,en;q=0.5" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Accept-Encoding: gzip, deflate" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Keep-Alive: 300" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Connection: keep-alive" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Referer: " + Referer + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Cookie: " + strCookies + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" Else ReqHeaders = "POST " + strFile + " HTTP/1.1" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Host: " + Host + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US; rv:1.8.0.7) Gecko/20060909 Firefox/1.5.0.7" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Accept-Language: en-us,en;q=0.5" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Accept-Encoding: gzip, deflate" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Keep-Alive: 300" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Connection: keep-alive" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Referer: " + Referer + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Cookie: " + strCookies + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Content-Type: application/x-www-form-urlencoded" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Content-Length: " + strPost.Length.ToString + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "Connection: close" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "" + strPost End If If Method = "PIC" Then ReqHeaders.Replace("Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5", "Accept: image/png,*/*;q=0.5") End If Dim tcp As New System.Net.Sockets.TcpClient Dim netstream As System.Net.Sockets.NetworkStream Dim TN(1) As Long If Referer = "" Then Referer = LastPage If InStr(1, URL, "http://") <> 0 Then Host = Mid$(URL, 8) If InStr(1, Host, "/") <> 0 Then Host = Mid$(Host, 1, InStr(1, Host, "/") - 1) If InStr(1, Host, "?") <> 0 Then Host = Mid$(Host, 1, InStr(1, Host, "?") - 1) LastPage = URL Try tcp.Connect(Host, 80) Catch ex As Exception Return ex.Message End Try Dim sendbytes As Byte() sendbytes = System.Text.Encoding.ASCII.GetBytes(ReqHeaders) netstream = tcp.GetStream() netstream.Write(sendbytes, 0, sendbytes.Length) Dim sr As StreamReader = New StreamReader(netstream, Encoding.Default) Dim strHTML As String = sr.ReadToEnd Dim strParts As String() = Regex.Split(strHTML, Environment.NewLine + Environment.NewLine) strCookies = ParseCookies(strParts(0)) If strParts(0).Contains("Content-Encoding") Then strParts(1) = DecompressGzip(strParts(1)) End If Return strParts(0) + Environment.NewLine + Environment.NewLine + strParts(1) End Function Public Function DecompressGzip(ByVal compressed As String) As String Dim memStream As MemoryStream = New MemoryStream(System.Text.Encoding.Default.GetBytes(compressed)) Dim decompressStream As GZipStream = New GZipStream(memStream, CompressionMode.Decompress) Dim endBytes(4) As Byte Dim position As Integer = CType(memStream.Length, Integer) - 4 memStream.Position = position memStream.Read(endBytes, 0, 4) memStream.Position = 0 Dim buffer(BitConverter.ToInt32(endBytes, 0) + 100) As Byte Dim offset As Integer = 0 Dim total As Integer = 0 While True Dim bytesRead As Integer = decompressStream.Read(buffer, offset, 100) If bytesRead = 0 Then Exit While End If offset += bytesRead total += bytesRead End While Return Encoding.ASCII.GetString(buffer) End Function Public Function ParseCookies(ByVal Headers As String) As String ParseCookies = "" Dim reg As Regex Dim matches As MatchCollection Dim match As Match reg = New Regex("set-cookie:\s*([^=]+)=([^;]+);", RegexOptions.IgnoreCase) If reg.IsMatch(Headers) Then matches = reg.Matches(Headers) For Each match In matches Try colCookies.Add(match.Groups(1).ToString & "=" & match.Groups(2).ToString, match.Groups(1).ToString) Catch ex As Exception colCookies.Remove(match.Groups(1).ToString) colCookies.Add(match.Groups(1).ToString & "=" & match.Groups(2).ToString, match.Groups(1).ToString) End Try Next End If Dim i As Long For i = 1 To colCookies.Count Step 1 ParseCookies = ParseCookies & colCookies.Item(i).ToString & ";" Next End Function Public Function StripHeaders(ByVal strSource As String) As String Dim strParts() As String = Regex.Split(strSource, Environment.NewLine + Environment.NewLine) Return strParts(1) End Function Public Function NeoLogin(ByVal user As String, ByVal pass As String, ByRef loggedIn As Boolean) As String Dim strHTML As String = Nothing Request("GET", "http://www.neopets.com/loginpage.phtml", "http://www.google.com") Pause(1) Request("POST", "http://www.neopets.com/hi.phtml?destination=%2Findex.phtml&username=" + user, "http://www.neopets.com/loginpage.phtml") Pause(1) strHTML = Request("POST", "http://www.neopets.com/login.phtml?username=" + user + "&password=" + pass + "&destination=%2Findex.phtml", "http://www.neopets.com/hi.phtml") If strHTML.Contains("Set-Cookie: neologin=") Then loggedIn = True Return "Logged In" Else If strHTML.Contains("too many times") Then loggedIn = False Return "To Many Login Attempts" Else If strHTML.Contains("badpassword") Then loggedIn = False Return "Wrong Username/Password" Else If strHTML.Contains("frozen") Then loggedIn = False Return "Account Frozen" Else If strHTML.Contains("just a technical problem") Then loggedIn = False Return "Neopets is down for maintenance" Else loggedIn = False Return "Unknow Error" End If End If End If End If End If End Function Private Shared Sub Pause(ByVal seconds As Double) Dim num As Double = seconds * 1000 Dim t1 As DateTime = DateTime.Now Dim t2 As DateTime = DateTime.Now Dim tmDiff As TimeSpan = t2 - t1 While Convert.ToDouble(tmDiff.TotalMilliseconds.ToString) < num t2 = DateTime.Now tmDiff = t2 - t1 Application.DoEvents() End While End Sub Public Function GrabPic(ByVal strURL As String) As System.Drawing.Image Dim memStream As New MemoryStream(System.Text.Encoding.Default.GetBytes(StripHeaders(Request("GET", strURL, LastPage)))) GrabPic = Image.FromStream(memStream) Return GrabPic End Function Public Sub ClearCookies() colCookies.Clear() strCookies = Nothing End Sub Public Function GetBetween(ByVal Source As String, ByVal Start As String, ByVal Finish As String) As String Dim Result = "" Dim A = InStr(1, Source, Start) + Len(Start) If A = 0 Then Result = "" Return Result Else Dim B = InStr(A, Source, Finish) If B = 0 Then Result = "" Return Result Else Result = Mid(Source, A, B - A) Return Result End If End If End Function End Class
I'm glad you tried this tutorial First, I just want to clear something. The code you got after clicking "search" is the kind of code you'll receive everytime. In fact, that simply the source code of the web page. If you take all this code and put it in an HTML file and open it, you'll see the page just like you can in your browser. This beeing said, your code is perfectly fine. The reason you didn't receive the proper SW code with the "bri codestone" price is simply because you weren't logged in to neopets.com in the program. Try to log, then wait for the message "logged in" and then press the "search" button to receive the information. The code will look pretty similar to the one posted here but will contains the precious data we need to go on after. If you have any more question, lemme know
Another question... how do I open my saved project? a wee bit embarrassing, but I don't know how lol. I saved it as 'Bri Codestone' to my desktop. Three icons appeared... clicking any of them will only bring up the code or an error saying it doesn't know what program to use
*grumbles* I hate file endings. Thank you for the help, but I've decided to just re-do the whole thing this weekend, and I'll also take a look at opening projects this weekend lol
You're missing "End Class" at the end of the class. You probably erased it by mistake. Or simply send me the zipped project by pm, I'll take a look
Yep, you need it at the end. Btw, I checked the wrapper class in the first post and the "End Class" is there Code (Text): Class sub end sub sub end sub end class
Well, I changed this Public Class Form1 Private Wrapper As New TCPWrapper To Public Class VJUG Private W As New TCPWrapper Of course I switch the name wrapper with w everywhere else. xD VJUG = Violent_'s Username Grabber