• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

Chatroom bot

Status
Not open for further replies.
This is where I'll be posting stuff about the development of this bot, so I can get more help on it etc.

Here's some stuff I found so far:

Questions:
  1. What port does the chat use?
  2. What the heck is an "authority" and do I even need one? This part confuses me. (i.e. [user-info@]host[:port])
  3. How do I receive messages that people input?
  4. How do I "log in"?
 
Last edited:
Aha, found a kewl class. http://java.sun.com/j2se/1.5.0/docs/api/java/net/URLConnection.html

And yeah, I tried it without the authtoken thingy and it worked fine... I think...

EDIT: Okay here's what I have so far.
Code:
import java.net.*;
import java.io.*;
public class Chat {
    public String username = "Lirch";
    public String password = ""; //cropped out for security reasons
    public int channel = 1;
    public URI hiveURI;
    public URL hiveURL;
    public URLConnection hive;
    public InputStream is;
    public OutputStream os;
    
    public void connect() throws URISyntaxException, MalformedURLException, IOException {
        hiveURI = new URI("http", "//www.hiveworkshop.com/forums/apps.php?p=gochat&do=auto&channel=1&stealth=0", null);
        hiveURL = hiveURI.toURL();
        hive = hiveURL.openConnection();
        //hive.connect();
        
        hive.setDoInput(true);
        hive.setDoOutput(true);
        
        os = hive.getOutputStream();
        is = hive.getInputStream();
        
        System.out.println(hiveURL);
        System.out.println(hive.getAllowUserInteraction());
        System.out.println(hive.getPermission());
    }
}

This returns:

Code:
http://www.hiveworkshop.com/forums/apps.php?p=gochat&do=auto&channel=1&stealth=0
false
(java.net.SocketPermission www.hiveworkshop.com:80 connect,resolve)

Changing http://www.hiveworkshop.com/forums/apps.php?p=gochat&do=auto&channel=1&stealth=0 to http://chat.hiveworkshop.com/?channel=1 gives me the same thing, basically.

EDIT 2:
Okay I'm making some progress... I got the input stream and whatnot, but when I read from it, it just proceeded to give me the whole file. (i.e. what you get when you view page source)

However I did notice that the source contained the error message saying "You need to be logged in". This goes on to my next question. How do I log in?

So far:
Code:
import java.net.*;
import java.io.*;
public class Chat {
    public String username = "Lirch";
    public String password = "";
    public int channel = 1;
    public URI hiveURI;
    public URL hiveURL;
    public URLConnection hive;
    public InputStream instr;
    public BufferedReader in;
    public OutputStream out;
    
    public void connect() throws URISyntaxException, MalformedURLException, IOException {
        hiveURI = new URI("http", "//chat.hiveworkshop.com/?channel=1", null);
        hiveURL = hiveURI.toURL();
        hive = hiveURL.openConnection();
        //hive.connect();
        
        hive.setAllowUserInteraction(true);
        hive.setDoInput(true);
        hive.setDoOutput(true);
        
        out = hive.getOutputStream();
        instr = hive.getInputStream();
        in = new BufferedReader(new InputStreamReader(instr));
        
        //System.out.println(hiveURL);
        //System.out.println(hive.getPermission());
        
        String token = "";
        while (!token.equals("</html>")) {
            token = in.readLine();
            System.out.println(token);
        }
    }
}
 
Last edited:
Level 15
Joined
Jun 28, 2007
Messages
1,424
loging in is just a simple matter of getting a class that lets you enter text into html forums

a simple check of the sourse of the frontpage will tell you the fourm ids to enter into

reading messages is a simple matter of haveing the bot use a class to log all of the ghacters that pop into the frame or you can have the bot lissen to this fuction

Code:
function getMessagesDone(t) {
    var data;
    do_switch();
    clearTimeout(chatTimer);
    var maindata = t.responseXML.documentElement;
    isBanned = false;
    if(maindata.childNodes.length > 0) {
        for(nk = 0; nk < maindata.childNodes.length; nk++) {
            data = maindata.childNodes[nk];
            if(data.tagName == 'banned') {
                isBanned = true;
                chatWindow.innerHTML = 'You are banned, time until unban: '+data.firstChild.nodeValue;
            }
            if(data.tagName == 'delay') {
                reloadTime = parseInt(data.firstChild.nodeValue);
                debug(reloadTime);
            }
            if(data.tagName == 'msgs') {
                if(isBanned == false && chatWindow.innerHTML.substring(0,3) == 'You') { chatWindow.innerHTML = ''; }
                for(i = 0; i < data.childNodes.length; i++) {
                    if(data.childNodes[i].tagName == 'm') {
                        // loop through messages
                        userid = unescape(data.childNodes[i].childNodes[0].firstChild.nodeValue);
                        message = unescape(data.childNodes[i].childNodes[1].firstChild.nodeValue);
                        type = unescape(data.childNodes[i].childNodes[2].firstChild.nodeValue);
                        image = unescape(data.childNodes[i].childNodes[3].firstChild.nodeValue);
                        username_slashes = unescape(data.childNodes[i].childNodes[4].firstChild.nodeValue);
                        username = unescape(data.childNodes[i].childNodes[5].firstChild.nodeValue);
                        color = unescape(data.childNodes[i].childNodes[6].firstChild.nodeValue);
                        addMessage(userid,message,type,image,username_slashes,username,color);
                    }
                }
            }
            if(data.tagName == 'cron') {
                // do cronning
                cronField.innerHTML = '';
                cronField.innerHTML = unescape(data.firstChild.nodeValue);
            }
        }
    }
    if(isBanned == false && chatWindow.innerHTML.substring(0,3) == 'You') { chatWindow.innerHTML = ''; }
    chatTimer = setTimeout("getMessages()",reloadTime);}

or you can have it tokenise the div tags that ralle has the chat mesages in
 
Level 15
Joined
Nov 1, 2004
Messages
1,058
To login, you basically need to perform an HTTP POST to the login page. It will return a cookie to you which you need to keep track of and send back to the site each time you perform more requests to http://www.hiveworkshop.com/forums/*

Next, you will need to perform an HTTP GET on the http://chat.hiveworkshop.com/?channel=1 page, which will redirect you to the http://www.hiveworkshop.com/forums/apps.php page. After that, you will receive another cookie (maybe named "PHPSESSID") that will contain your chat session information. You will need to pass that to the chat for each and every interaction with the chatroom. From then on out, you can perform HTTP GET or POST to send a message (you'll have to look at the javascript to determing the exact command), and there should be another GET request you can perform to get a JSON encoded list of the latest messages.

...at least I think it might be JSON encoded (haven't checked recently). It might just be XML or plain HTML.

Disclaimer: This is all from speculation/memory and I haven't tested this so it might be somewhat different in actuality.
 
Level 27
Joined
May 30, 2007
Messages
2,872
I think logging in might be higher priority than receiving messages? ;)

From what I gather, you need to send a POST request to "http://chat.hiveworkshop.com/?channel="+channel in order to create a session on the server, with which to interact with the chat.

This request must have 2 headers:
Code:
Content-Type: application/x-www-form-urlencoded // This is what apps.php indicates to use.
Content-Length: <length of POST data>
I am unsure if it requires a valid forum login or not.

And POST data:
Code:
userid=135851&username=Hakeem&groups=<censored?>&permissions=chat_restrict_ding&check=<definitely censored>
chat_restrict_ding
D;

Also, the current chat uses XML, and the new chat appears to be using JSON.
 
Samuraid said:
To login, you basically need to perform an HTTP POST to the login page. It will return a cookie to you which you need to keep track of and send back to the site each time you perform more requests to http://www.hiveworkshop.com/forums/*
Would the get and put methods of this do the trick?

How do I know I'm redirected?
After that, you will receive another cookie (maybe named "PHPSESSID") that will contain your chat session information.
How do I know that the server sends me something?
(you'll have to look at the javascript to determing the exact command),
This goes in the header of the cookie I'm sending back, right?
This request must have 2 headers:
Code:
Content-Type: application/x-www-form-urlencoded // This is what apps.php indicates to use.
Content-Length: <length of POST data>
I am unsure if it requires a valid forum login or not.
The java command needs a Map. (is that like a 2D ArrayList? I've never used maps before...) (Thanks for explaining this, wyrmlord!)

Do those basically go in like this?

Code:
HashMap postMap = new HashMap();
ArrayList<String> contentType = new ArrayList<String>();
    contentType.add("application/x-www-form-urlencoded");
ArrayList<String> contentLength = new ArrayList<String>();
    contentLength.add("" + message.length());    //message is the String with the message to send :P
postMap.put("Content-Type:", contentType);
postMap.put("Content-Length:", contentLength);

cookie.get(hiveURI, postMap);    //cookie is a CookieHandler, hiveURI is a URI

And POST data:
Code:
userid=135851&username=Hakeem&groups=<censored?>&permissions=chat_restrict_ding&check=<definitely censored>
What are some examples of groups/permissions/checks?
 
Last edited:
Level 15
Joined
Nov 1, 2004
Messages
1,058
Would the get and put methods of this do the trick?
Not sure actually. I've always dealt with cookie and all other HTTP data as one single entity (cookies simply reside in the HTTP header).

How do I know I'm redirected? How do I know that the server sends me something?
If you are redirected, then you will generally get an HTTP response code 302 and a header that looks like this:
Code:
Location: http://www.hiveworkshop.com/some-URL-to-which-you-are-being-redirected

The server will never push something out to you over standard HTTP of it's own will. It only sends data as a response to a request you make. So things will always start with you making an HTTP request (GET/POST/HEAD), and then immediately reading the response the server sends.
 
Level 27
Joined
May 30, 2007
Messages
2,872
What are some examples of groups/permissions/checks?
You can find those in the form found in apps.php, and I recommend not posting them.

Okay, first thing first, you should focus on making a successful HTTP request. If you cannot find a class for HTTP connections, I can help you with sending a raw request using sockets.
 
If you are redirected, then you will generally get an HTTP response code 302 and a header that looks like this:
Code:
Location: http://www.hiveworkshop.com/some-URL-to-which-you-are-being-redirected

The server will never push something out to you over standard HTTP of it's own will. It only sends data as a response to a request you make. So things will always start with you making an HTTP request (GET/POST/HEAD), and then immediately reading the response the server sends.
Oh so I request that page, then it responds with the 302?

Okay, first thing first, you should focus on making a successful HTTP request. If you cannot find a class for HTTP connections, I can help you with sending a raw request using sockets.
http://java.sun.com/j2se/1.5.0/docs/api/java/net/HttpURLConnection.html Would this work?
 
Level 15
Joined
Nov 1, 2004
Messages
1,058
Oh so I request that page, then it responds with the 302?
I must amend my previous statements. Most servers will respond with a 302 code. Hiveworkshop responds with a 301.

302 and 301 are practically the same: both are redirect codes.
 
Level 11
Joined
Oct 13, 2005
Messages
233
I've been looking at index.html in order to get a clue as exactly what I need to HTTP POST to the login page. While I think I've found everything necessary, I'm a bit confused as to how generate values for some of them. Here's what I've found out so far:
  • vb_login_username = username obtained from the username textbox
  • vb_login_password = password obtained from password textbox, however, after taking a look at vbulletin's md5 javascript file, it appears this is being set to 0 when the script finishes. Here's why I'm thinking so:
    index.html snippet
    HTML:
    <form action="login.php?do=login" method="post" onsubmit="md5hash(vb_login_password, vb_login_md5password, vb_login_md5password_utf, 0)">
    vbulletin_md5.js snippet
    Code:
    function md5hash(B,A,E,C)
    {
        if(navigator.userAgent.indexOf("Mozilla/")==0&&parseInt(navigator.appVersion)>=4)
        {
    	var D=hex_md5(str_to_ent(trim(B.value)));
    	A.value=D;
    	if(E)
    	{
    	    D=hex_md5(trim(B.value));
    	    E.value=D
    	}
    	[b]if(!C)   //C is zero when this function appears to be called
    	{
    	    B.value=""
    	}[/b]
        }
        return true
    };
  • vb_login_md5password = As shown in the snippet above, this is var D. Looks like the password trimmed of surrounding spaces, gone through the str_to_ent function, and then converted to an md5 hash. Both trimming and str_to_end are not an issue at all, my only concern is that the md5 algorithm a Java class I found uses is exactly the same as the one used here. The Java class I found, at least, seems to follow an ISO standard for how it's done so I'm hoping for the best.
  • vb_login_md5password_utf = appears to be the same as md5password, but without the str_to_ent function being called on it before being converted to md5
  • s = "" Apparently, there's a value with a null value as I've found in index.html
    HTML:
    <input type="hidden" name="s" value="" />
    I'm really wondering if there is anything more to it.
  • cookieuser = appears it will either be set to 1 or 0 based on if the checkbox is selected. I'm just assuming I'd want this set to 1. Again, found in index.html
    HTML:
    <input type="checkbox" name="cookieuser" value="1" tabindex="103" id="cb_cookieuser_navbar" accesskey="c" />
  • do = "login" This by default seems to be set to login though I'm wondering if this is changed anywhere I may have noticed or if it's fine as is. index.html
    HTML:
    <input type="hidden" name="do" value="login" />
  • securitytoken = A fairly long alphanumeric string. It appears to vary and I haven't tested whether this is between browsers or simply every time I view the page. This is the part that I am completely clueless about and could use help on how this value is generated or if I really need it

Finally, I noticed Hakeem mentioned request headers in order to enter the chat. I'm wondering if logging in would require headers like he mentioned as well. It would also be nice to know if I didn't actually need to have a valid login to get into the chat but instead simply needed to submit certain information that Hakeem showed. Also, how exactly would I be able to view the actual .php files that are on the server. Since php is server side and not included in the page source, I don't happen to know how to view the php files or even if I can.
 
Code:
public void login() throws ProtocolException, IOException {
        //the variables vB wants
        String vb_login_username = "", vb_login_password = "", vb_login_md5password = "", vb_login_md5password_utf = "", cookieuser = "", securitytoken = "";
        
        //set the variables
        vb_login_username = username + ""; //the +"" part makes a new instance instead of using
        vb_login_password = password + ""; //the same one as the password/username variables
        try {
            vb_login_md5password = encrypt(password, false);
        } catch (NoSuchAlgorithmException e) { System.out.println(e.getMessage()); }
        try {
            vb_login_md5password_utf = encrypt(password, true);
        } catch (NoSuchAlgorithmException e) { System.out.println(e.getMessage()); }
        cookieuser = "1";
        securitytoken = "1326c99506a80b48ba40754596efd221"; //snipped from my cookies
        
                
        //set the request properties
        httpConn.setRequestProperty("vb_login_username", vb_login_username);
        httpConn.setRequestProperty("vb_login_password", vb_login_password);
        httpConn.setRequestProperty("vb_login_md5password", vb_login_md5password);
        httpConn.setRequestProperty("vb_login_md5password_utf", vb_login_md5password_utf);
        httpConn.setRequestProperty("cookieuser", cookieuser);
        httpConn.setRequestProperty("do", "login");
        httpConn.setRequestProperty("securitytoken", securitytoken);
        
        httpConn.setRequestMethod("POST");
               
        
        //urlConn.setRequestMethod("POST");
        System.out.println(httpConn.getResponseCode() + ": " + httpConn.getResponseMessage());
        for (int a = 0; a < 10; a++) {
            System.out.println(httpConn.getHeaderFieldKey(a) + "  " + httpConn.getHeaderField(a));
        }
        
    }
    
    /**
     * encrypts the string to MD5
     * 
     * @param plaintext The string to be encrypted
     * @param useUTF Should it do the UTF thingy?
     * @returns the encrypted string
     */
    public String encrypt(String plaintext, boolean useUTF) throws NoSuchAlgorithmException, UnsupportedEncodingException{
        MessageDigest md = null;
        try {
            md = MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException e) { System.out.println(e.getMessage()); }
        if (useUTF) {
            try {
                md.update(plaintext.getBytes("UTF-8"));
            } catch (UnsupportedEncodingException e) { System.out.println(e.getMessage()); }
        }
        byte raw[] = md.digest(); //step 4
        String hash = (new BASE64Encoder()).encode(raw); //step 5
        
        return hash; //step 6
    }

I still get a 411: Length Required response from the server :/
 
Level 15
Joined
Jun 28, 2007
Messages
1,424
uhhm well let me just point out the way im doing my bot maby it will give you guys some perspective

im useing python to command links (a text based browser use on ubuntu sudo apt-get install links to get it) since python is python i can use its web classes to tap into the power of links to send text to the hive via python

also useing python gives me more options in commands and such and i can bypass most of the javascript stuffs

only issue i have is my laptop is a fireball and it burns my legs off if i use it for mroe than 20 minuts at a time
 
uhhm well let me just point out the way im doing my bot maby it will give you guys some perspective

im useing python to command links (a text based browser use on ubuntu sudo apt-get install links to get it) since python is python i can use its web classes to tap into the power of links to send text to the hive via python

also useing python gives me more options in commands and such and i can bypass most of the javascript stuffs

only issue i have is my laptop is a fireball and it burns my legs off if i use it for mroe than 20 minuts at a time

Uh-huh. Prove it.
 
Level 15
Joined
Jun 28, 2007
Messages
1,424

Attachments

  • Screenshot.png
    Screenshot.png
    210.9 KB · Views: 114
Level 15
Joined
Jun 28, 2007
Messages
1,424
yep but olny for a second
python has a cookie jar lib that handles cookies

i still need to refine my socket scripts and get it to type messages and get a account for it to use then my bot will be ownage

Code:
import os, cookielib, urllib2

#============================
url = "http://www.hiveworkshop.com/resources_new/chat/"

import urllib2
from cookielib import CookieJar, DefaultCookiePolicy
policy = DefaultCookiePolicy(
    rfc2965=True, blocked_domains=["ads.net", ".ads.net"])
cj = CookieJar(policy)
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
r = opener.open(url)

print r.readlines()

this is what i have so far on the connecing side sitll no Authensystem the old one read my ff cookies
 
Last edited:
Level 15
Joined
Jun 28, 2007
Messages
1,424
not a good one but im now breakin all of the unsaid rules and im useing firefox as a base for my bot


well im haveing issues now it looks like i cant post my login data in python

im gonna write a dignsatic serch script but it looks like i cant login.....

hmm ok it seems that when it gets to the apps.php it wont redriect becaucse there is a open chat button that it wants me to post to to continue

(ps if this wont work i still have outher options but those involve the dark side of python last time i used that it didnt turn out to well.....)
 
Last edited:
Sorry for bump, but I has another question.

Code:
$vbulletin->input->clean_array_gpc('p', array(
		'vb_login_username'        => TYPE_STR,
		'vb_login_password'        => TYPE_STR,
		'vb_login_md5password'     => TYPE_STR,
		'vb_login_md5password_utf' => TYPE_STR,
		'postvars'                 => TYPE_BINARY,
		'cookieuser'               => TYPE_BOOL,
		'logintype'                => TYPE_STR,
		'cssprefs'                 => TYPE_STR,
	));

Where do I find the values for "postvars" and "cssprefs"?
 
Status
Not open for further replies.
Top