Java IRC Bot

Talk about any languages right here. Share and discuss source, but don't expect your homework to be done for you.
Post Reply
User avatar
BattousaiX
Your Senior
Posts: 933
Joined: Wed Jun 23, 2004 9:19 am

Java IRC Bot

Post by BattousaiX » Mon Dec 01, 2008 12:28 pm

Yeah It's functional, but no way near complete. Going to be working on setting up a few things and didn't really want to put too much more time in it. Maybe if Hackerthreads becomes more active as an IRC channel I'll add trivia to it at sometime, but playing trivia solo wouldn't be much fun especially after knowing the answers.

I'm pretty sure these are most recent, took down my computer and these are the latest from where I was working on it at work.

IRC.java

Code: Select all

// Regex special characters ([{\^-$|]})?*+.
 
import java.io.*;
import java.net.*;
import java.util.regex.*;
import java.sql.*;
 
 
public class IRC implements Runnable{
	String NICK="usefulbot";
	String USERNAME="useful";
	int PORT=6667;
	String SERVER="irc.tddirc.com";
	String CHANNEL="#test";
	boolean isAdmin;
	
	public void run(){
		try{
			Socket sock=new Socket(SERVER, PORT);
			BufferedWriter out=new BufferedWriter(new OutputStreamWriter(sock.getOutputStream()));
			BufferedReader in=new BufferedReader(new InputStreamReader(sock.getInputStream()));
			
			writeToServer("USER "+ USERNAME +" 8 * : " + USERNAME, out);
			writeToServer("NICK "+ NICK, out);
			writeToServer("JOIN "+ CHANNEL, out);
			
			readFromServer(out, in, sock);

		}catch(UnknownHostException e){
			System.out.println("Unknown host exception was thrown: "+e.getMessage());
		}catch(IOException e){
			System.out.println("An error occurred with i/o socket: "+e.getMessage());
		}
	}

	public void writeToChannel(String text, BufferedWriter out){
		
		try{
			out.write("PRIVMSG "+CHANNEL+" :"+text+"\n");
			out.flush();
		}catch(IOException e){
			System.out.println("Failure when trying to write to server: "+e.getMessage());
		}
	}

	public void writeToServer(String text, BufferedWriter out){
		
		try{
			out.write(text+"\n");
			out.flush();
		}catch(IOException e){
			System.out.println("Failure when trying to write to server: "+e.getMessage());
		}
	}

	// This method is used to parse the input, so that we can send requests easily to user.
	public String parseLine(String line){
		Pattern p=Pattern.compile(":\\w*!\\w*@\\w*.* PRIVMSG #\\w* :");
		Matcher m=p.matcher(line);

		if(m.find())
			return line.substring(m.end());
		return line;
	}
	
	// Consider adding a login check algorithm for verifying user is in channel before getting username.
	protected String getIRCUserName(String line){
		Pattern userPattern=Pattern.compile("^:\\w*!", Pattern.CASE_INSENSITIVE);
		Matcher user=userPattern.matcher(line);
 
		String username=null;
		if(user.find()){
			username=line.substring(user.start()+1, user.end()-1);
			return username;
		}
		return "";
	}

	public String getTimeStamp(){
		Timestamp st = new Timestamp(System.currentTimeMillis());
		String time=st.toString();
		return time.substring(0, time.indexOf("."));
	}
	
	public static void main(String args[])throws Exception{
		IRC irc=new IRC();
		Thread t=new Thread(irc);
		t.start();
	}

	public void readFromServer(BufferedWriter out, BufferedReader in, Socket sock){
		try{
			String line=null;
			while((line=in.readLine()) != null){
				String parsedLine=parseLine(line);
				System.out.println(getTimeStamp()+" "+getIRCUserName(line)+" "+parsedLine);
				
				Actions actions=new Actions();

				if(line.matches("^PING.*"))
					actions.ping(out);

				if(parsedLine.toLowerCase().matches("^!quit$"))
					actions.disconnect(sock, out, line);

				if(parsedLine.toLowerCase().matches("^!trivia$")) {
					Trivia trivia=new Trivia(out, in, sock);
				}

				if(parsedLine.toLowerCase().matches("!admin"))
					writeToChannel("is "+getIRCUserName(line)+" an admin "+isAdmin(getIRCUserName(line)), out);
				
				if(parsedLine.toLowerCase().matches("!nick \\w{1,9}"))
					actions.changeNick(parsedLine, out);

			}
		}catch(IOException e){
			System.out.println("Failed to read from server: "+e.getMessage());
		}
	}


	public boolean isAdmin(String username){
		ConnectionPool pool=new ConnectionPool();		
		String user=getIRCUserName(username);
		System.out.println("Username "+username.toUpperCase());

		try{
			Connection conn=DriverManager.getConnection(pool.getUrl(), pool.getUsername(), pool.getPassword());
			Statement stmt=conn.createStatement();
			stmt.executeQuery("SELECT AUTH FROM USERS WHERE USERNAME='"+username.toLowerCase()+"';");
			ResultSet rs=stmt.getResultSet();

			String auth=null;
			while(rs.next())
				auth=rs.getString("AUTH");

			rs.close();
			stmt.close();
			
			if(auth==null){
				isAdmin=false;
				return isAdmin;
			}

			System.out.println("Auth: "+auth);

			if((auth.matches("admin")))
				isAdmin=true;
		}catch(SQLException e){
			System.out.println("SQL Exception occurred: "+e.getMessage());
		}
		return isAdmin;
	}
}

Actions.java

Code: Select all

import java.io.*;
import java.net.*;
import java.util.*;
import java.util.regex.*;
import java.sql.*;

public class Actions{
	IRC irc=new IRC();

	public void disconnect(Socket sock, BufferedWriter out, String line){
		if(irc.isAdmin(irc.getIRCUserName(line))){
			try{
				irc.writeToChannel("Goodbye everyone", out);
				sock.close();
			}catch(IOException e){
				System.out.println("An error occurred when trying to close socket: "+e.getMessage());
			}
		}else{
			irc.writeToChannel(irc.getIRCUserName(line)+" is not an admin", out);
		}
	}

	public void ping(BufferedWriter out){
		try{
			out.write("PONG "+irc.CHANNEL+"\n");
			out.flush();
		}catch(IOException e){
			System.out.println("Error while trying to ping: "+e.getMessage());
		}
	}

	public void changeNick(String parsedLine, BufferedWriter out){
		StringTokenizer st=new StringTokenizer(parsedLine, " ");
		st.nextToken();  // Tokens should be !NICK, followed by username, we only care about second token.
		String username=st.nextToken();

		irc.writeToServer("NICK "+username, out);
	}
 }
Maybe I'll continue again after I get BSD working properly. I can't seem to find much time to do stuff when at home. :(

User avatar
NoUse
time traveller
Posts: 2624
Joined: Thu Aug 28, 2003 10:46 pm
Location: /pr0n/fat

Re: Java IRC Bot

Post by NoUse » Mon Dec 01, 2008 9:14 pm

Good shit man. I feel that IRC bots are a good way to practice your socket programming.
And I will strike down upon thee with great vengeance and furious anger
those who would attempt to poison and destroy my brothers.
And you will know my name is the Lord
when I lay my vengeance upon thee.

User avatar
BattousaiX
Your Senior
Posts: 933
Joined: Wed Jun 23, 2004 9:19 am

Re: Java IRC Bot

Post by BattousaiX » Tue Dec 02, 2008 1:52 pm

Thanks. The logic started getting hazy for me.

Going to need to invest some time in reading threading and synchronization before coming back to this.

KuroSaru
n00b
Posts: 2
Joined: Mon Nov 17, 2008 1:31 pm

Re: Java IRC Bot

Post by KuroSaru » Wed Dec 03, 2008 10:29 am

IRC Bots can be fun.

The Logic if you are making a bot that runs on mulitple servers is simple really

Main Program Loads list of irc servers ip's and channels, open a new thread for each of them. and then just waits for them to all closed/exit.

Each Thread, is a contanst read loop really. because your waiting for the ping pong cmmand alot. any commands that are run should also be places as there own threads otherwise while it is proforming any long tasks it is not detecting the ping pong commands.
................................

Anyway nice work on your bot so far :)

Post Reply