1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

first c# bot

Discussion in 'C, C++, C#' started by Meres, Apr 2, 2010.

  1. Meres

    Meres Junior Member

    Joined:
    Oct 12, 2009
    Messages:
    142
    Likes Received:
    11
    im beginning to make my first c# bot. it is fairly standard - it will login to a site, scrape users, then message them. my c# skills are decent, however, i have never interacted with html or browsers in my projects.

    i suppose i am looking to make sure i am on the right track. for a simple bot such as this, i am planning on creating and sending a response to the login and message forms.
     
  2. mline

    mline Newbie

    Joined:
    Jan 30, 2010
    Messages:
    49
    Likes Received:
    18
    I don't know if you're familiar with HttpWebRequest and HttpWebResponse but I would highly, highly suggest going with them as opposed to using WebBrowser. With them you can thread and have much more control over your requests. They work pretty simply, almost like a browser without a physical display.

    Depending on your level of skill you may want to begin making a custom HTTP class using the Sockets namespace and integrate your own browser logic into it. Though obviously that takes a little time.

    Anyway, if you're interested in the HttpWebRequest and HttpWebResponse there is a lot of documentation.

    http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.aspx
    http://msdn.microsoft.com/en-us/library/system.net.httpwebresponse.aspx

    Full Example: http://www.codeproject.com/KB/webservices/HttpWebRequest_Response.aspx
     
    • Thanks Thanks x 3
  3. mline

    mline Newbie

    Joined:
    Jan 30, 2010
    Messages:
    49
    Likes Received:
    18
    ...You're welcome?
     
  4. Meres

    Meres Junior Member

    Joined:
    Oct 12, 2009
    Messages:
    142
    Likes Received:
    11
    thanks :D
     
  5. mline

    mline Newbie

    Joined:
    Jan 30, 2010
    Messages:
    49
    Likes Received:
    18
    Haha all good, dude. I was just fucking with you. Appreciate the official thanks, though. That was a nice touch ;)
     
  6. underplay

    underplay Newbie

    Joined:
    Jan 13, 2009
    Messages:
    27
    Likes Received:
    1
    Be glad mline directed you towards the correct information, not the shitty ass WebControl most noobs use. A friend recently asked me for some advice, he was about to hire a coder for $35/h who was going to use the WebControl for over 1000x requsts an hour...yea right.
     
  7. ShiftySituation

    ShiftySituation Power Member

    Joined:
    Apr 15, 2010
    Messages:
    621
    Likes Received:
    314
    Occupation:
    Having fun
    Location:
    Jacksonville, FL
    Using the built in WebBrowser in VS.Net isn't all that bad, exp for beginners. If you do go the way mentioned above with webRequest/Response (which I recommend too), add a WebBrowser into your project for debugging. After your get the Response string (which is all of the HTML the server returned), just use webBrowser.DocumentText = responseString; and it will give you a visual of what page you are on.

    One nice tool to have which will aid you in your webRequest/Response is called Fiddler. http://www.fiddler2.com/fiddler2/ is the website to get it and it's free. Use it to help you with headers, cookies, POST strings, ect.
     
    • Thanks Thanks x 2
  8. Meres

    Meres Junior Member

    Joined:
    Oct 12, 2009
    Messages:
    142
    Likes Received:
    11
    thanks i was just going to ask for something to monitor the data sent / recieved. im going to go with the webrequest and webresponse method.
     
  9. Meres

    Meres Junior Member

    Joined:
    Oct 12, 2009
    Messages:
    142
    Likes Received:
    11
    Ok so i am trying to login to a site using httpwebrequest. i have the request similar to the one sent from the site - a couple of problems though.

    this is the one from the site:

    Code:
    POST /account/login/post HTTP/1.1
    Accept: application/x-shockwave-flash, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, image/gif, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*
    Referer: http://www.xxx.com/
    Accept-Language: en-us
    User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)
    Content-Type: application/x-www-form-urlencoded
    Accept-Encoding: gzip, deflate
    Host: www.xxx.com
    Content-Length: 178
    Connection: Keep-Alive
    Pragma: no-cache
    Cookie: vitalmetrics=anon-21803339; _chartbeat=jwdwirranf9pcsng; __gads=ID=496d100a0767ebf8:T=1272243843:S=ALNI_MZoTVAbFKhJTylkrDMKlswkO-G_Jw; __utma=199602737.529545862.1272243826.1272250523.1272260173.4; __utmb=199602737.1.10.1272260173; __utmc=199602737; __utmz=199602737.1272250524.3.2.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=xxx
    
    login_username=test&login_password=test&lockip=on&referer=%2F&form_key%5B%5D=57be4c9e6d4588a6f9b857560a601271-1179106900%253A1272337248%253A%252FSkeleton%252FNexoskel
    this is mine:
    Code:
    POST /account/login/post HTTP/1.1
    Accept: application/x-shockwave-flash, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, image/gif, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*
    Referer: http://www.xxx.com/
    Accept-Language: en-us
    User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)
    Content-Type: application/x-www-form-urlencoded
    Accept-Encoding: gzip, deflate
    Pragma: no-cache
    Host: www.xxx.com
    Content-Length: 158
    Expect: 100-continue
    
    login_username=test&login_password=test&lockip=on&referer=%2F&form_key%5B%5D=ccd1b5b817cb2ad696efe8d1b389c22a-1179106900%253A1272352303%253A%252FSkeleton%252FNexoskel
    these are the requests copied off of fiddler.

    is there a way to specify the way the header is formed exactly by inputting a string? because i am having trouble getting the values to be exact by using the header.parameter = xxxx.

    to elaborate:

    im having trouble getting the host to come before the pragma parameter. ive set the keepalive boolean to true and it still does not show up in the header. i also set expect to null and it is showing up as 100-continue.

    thanks.
     
  10. ShiftySituation

    ShiftySituation Power Member

    Joined:
    Apr 15, 2010
    Messages:
    621
    Likes Received:
    314
    Occupation:
    Having fun
    Location:
    Jacksonville, FL
    It doesn't matter, you can even rearrange your post string and it will work. I've noticed that the protocol version set to 1.1 makes it not work sometimes. try:

    request.ProtocolVersion = new Version(1, 0);

    Make sure that if the site redirects, that you have request.AllowAutoRedirect to true.
     
    • Thanks Thanks x 1
  11. Meres

    Meres Junior Member

    Joined:
    Oct 12, 2009
    Messages:
    142
    Likes Received:
    11
    wow success :D
     
  12. Meres

    Meres Junior Member

    Joined:
    Oct 12, 2009
    Messages:
    142
    Likes Received:
    11
    alright the next issue im having is dealing with the cookies. i need to hold them and use them in requests so the server knows i am logged in to an accounts.

    ive set a cookie container to the login request, and used the same container for the next request, but it doesnt seem to stay login.

    am i missing something?
     
  13. ShiftySituation

    ShiftySituation Power Member

    Joined:
    Apr 15, 2010
    Messages:
    621
    Likes Received:
    314
    Occupation:
    Having fun
    Location:
    Jacksonville, FL
    You need to make sure you are adding the response cookies to the container and then passing that container around to each request. Every time you do a response make it look something like this.


    Code:
                    using (WebResponse dResponse = request.GetResponse())
                    {
                        HttpWebResponse httpResponse = (HttpWebResponse)dResponse;
                        try
                        {
                            request.CookieContainer.Add(httpResponse.Cookies); //this is what you need!
                        }
                        catch { /*no cookies returned */ }
                        ...
                        //decode your response stream here!
                        ...
                        //now you can use     out CookieContainer thisCookie   in your method call
                        //       so it will return the CookieContainer  and you can still
                        //       return responseString;
                        //  just set thisCookie like this
                        thisCookie = request.CookieContainer;
    
    Here is a better example, this will actually save the cookies returned to a text file.

    Code:
    using (WebResponse dResponse = request.GetResponse())
                    {
                        HttpWebResponse httpResponse = (HttpWebResponse)dResponse;
                        request.CookieContainer.Add(httpResponse.Cookies);  //I didn't do a try/catch block here because I know for a fact that this response is going to return a cookie.
                        
                        StringBuilder cookBuilder = new StringBuilder();
                        foreach (Cookie kook in request.CookieContainer.GetCookies(request.RequestUri)) 
                        {                       
                            cookBuilder.Append(kook.Name + "=" + kook.Value + "\r\n");
                        }
                        lock (this)
                        {
                            TextWriter tw = new StreamWriter(Application.StartupPath + "\\cookies\\" + clAccount + ".txt");
                            tw.Write(cookBuilder.ToString());
                            tw.Close();
                            tw.Dispose();
                        }
                        Stream responseStream = responseStream = httpResponse.GetResponseStream();
                        if (httpResponse.ContentEncoding.ToLower().Contains("gzip"))
                            responseStream = new System.IO.Compression.GZipStream(responseStream, System.IO.Compression.CompressionMode.Decompress);
                        else if (httpResponse.ContentEncoding.ToLower().Contains("deflate"))
                            responseStream = new System.IO.Compression.DeflateStream(responseStream, System.IO.Compression.CompressionMode.Decompress);
    
                        StreamReader reader = new StreamReader(responseStream, Encoding.Default);
    
                        checkAccount = reader.ReadToEnd();
    
                        httpResponse.Close();
                        responseStream.Close();
    
                        thisCookie = request.CookieContainer;
                        return checkAccount;
                    }
    
    
    That way of saving the cookie to file is kind of barbaric but as long as you know how to use it to rebuild a cookieContainer then it works, so it works for me. There is a better way to save the CookieContainer in a whole, using serialize and deserialize, but I couldn't ever get it to work.
     
    • Thanks Thanks x 1
  14. Meres

    Meres Junior Member

    Joined:
    Oct 12, 2009
    Messages:
    142
    Likes Received:
    11
    thanks for the help - i got the cookies to work. the problem was i had autoredirect set to true and it was redirecting past the response with the session cookie.

    next i will be making the messager. for now ill be doing a random message from a list, but id like to integrate some spinning in it with. {A|B|C....}. are there any functions available onnline or that u guys have that will form a string from a spun string? would save me some time...
     
  15. ShiftySituation

    ShiftySituation Power Member

    Joined:
    Apr 15, 2010
    Messages:
    621
    Likes Received:
    314
    Occupation:
    Having fun
    Location:
    Jacksonville, FL
    SENuke just added, The Best Spinner API to their program. I don't know what the requirements are but I'd imagine, to be able to use TBS withing SENuke, you'd have to have a TBS license. I'm actually going to contact the creator of TBS about adding it to my program, once I can find the creators email.

    As far as making it yourself, you'd use a combonation of string.SubString() and string.IndexOf() to find the first "{" and last "}" within that {spin|tax} and then string.Split('|') to get an array of the strings withing {spin|tax}. So you'd end up with stringArray[0] = "spin" and stringArray[1] = "tax". Next would be to get a count of all strings within that array (stringArray.Count) and then pick a random number between 0 and stringArray.Count. Use that random number to pick your stringArray[randomNumber]; It gets a lot more involved when you add ({spin|{tax|text}}) spin syntax, within spin syntax but you'd use all of the same things from above.
     
    Last edited: May 9, 2010
  16. ShiftySituation

    ShiftySituation Power Member

    Joined:
    Apr 15, 2010
    Messages:
    621
    Likes Received:
    314
    Occupation:
    Having fun
    Location:
    Jacksonville, FL
    Don't crash your app, it would be a random number between 0 and stringArray.Count - 1. Don't know why this just popped into my head but it did.
     
  17. Meres

    Meres Junior Member

    Joined:
    Oct 12, 2009
    Messages:
    142
    Likes Received:
    11
    thanks for being so thorough ;)
    ive got a basic spinner on the way - no recursive spin check yet lol.
     
  18. Meres

    Meres Junior Member

    Joined:
    Oct 12, 2009
    Messages:
    142
    Likes Received:
    11
    so the bot is functional, logs in, scrapes users, then messages them.

    now im trying to implement proxy support. so far i have set the proxy ip and port set to a webproxy object. then if there is a username / password i set those as credentials for the webproxy. finally, i use that webproxy as the proxy for all webrequests.

    it seems to work. although the requests arent showing up in fiddler when i run through the proxy. is there a way to be sure this is working properly?
     
  19. ShiftySituation

    ShiftySituation Power Member

    Joined:
    Apr 15, 2010
    Messages:
    621
    Likes Received:
    314
    Occupation:
    Having fun
    Location:
    Jacksonville, FL
    Thats because Fiddler acts as a local proxy so if you assign a proxy then it bypasses fiddler. Try using Charles Web Debugging instead of fiddler. Not sure if it will work though.
     
  20. Meres

    Meres Junior Member

    Joined:
    Oct 12, 2009
    Messages:
    142
    Likes Received:
    11
    i guess if it is bypassing it is working then.

    next id like to make it multithreaded, to allow the interface to still function while the bot is doing work, (to pause start etc.).

    currently it is all in one class, not object oriented. im probably going to have one class that will hold the functions for the bot, that will be created by the main class. i could possibly make one class for each function but they share many variables, like the session cookie etc. then ill make the shared variables static.

    if there is a better way to do this let me know.