-
-
Save notklaatu/c66c88c87814d491eef6c6aae84d4cc2 to your computer and use it in GitHub Desktop.
Simple IRC Bot
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.*; | |
import java.net.*; | |
import java.util.*; | |
public abstract class IRCMessageLoop implements Runnable { | |
Socket server; | |
OutputStream out; | |
String theChannel; | |
IRCMessageLoop(String serverName, int port) { | |
try | |
{ | |
server = new Socket(serverName, port); | |
out = server.getOutputStream(); | |
} | |
catch (IOException info) | |
{} | |
} | |
void send(String text) { | |
byte[] bytes = (text + "\r\n").getBytes(); | |
try { | |
out.write(bytes); | |
} | |
catch (IOException info) | |
{} | |
} | |
void nick(String nickname) { | |
String msg = "NICK " + nickname; | |
send(msg); | |
} | |
void user(String username, String hostname, String servername, String realname) { | |
String msg = "USER " + username + " " + hostname + " " + servername + " :" + realname; | |
send(msg); | |
} | |
abstract void ignite(); | |
void joinOnStart(String channel) { | |
theChannel = channel; | |
} | |
void join(String channel) { | |
String msg = "JOIN " + channel; | |
send(msg); | |
} | |
void part(String channel) { | |
String msg = "PART " + channel; | |
send(msg); | |
} | |
void privmsg(String to, String text) { | |
String msg = "PRIVMSG " + to + " :" + text; | |
send(msg); | |
} | |
void pong(String server) { | |
String msg = "PONG " + server; | |
send(msg); | |
} | |
void quit(String reason) { | |
String msg = "QUIT :Quit: " + reason; | |
send(msg); | |
} | |
void processMessage(String ircMessage) { | |
Message msg = Parse.message(ircMessage); | |
if (msg.command.equals("privmsg")) { | |
String target, content; | |
if (msg.content.equals("\001VERSION\001")) { | |
privmsg(msg.nickname, "Prototype IRC Client (Built to learn)"); | |
return; | |
} | |
System.out.println(msg.nickname + ": " + msg.content); | |
} | |
else if (msg.command.equals("001")) { | |
ignite(); | |
return; | |
} | |
else if (msg.command.equals("ping")) { | |
pong(msg.content); | |
} | |
} | |
public void run() { | |
InputStream stream = null; | |
try | |
{ | |
stream = server.getInputStream(); | |
MessageBuffer messageBuffer = new MessageBuffer(); | |
byte[] buffer = new byte[512]; | |
int count; | |
while (true) { | |
count = stream.read(buffer); | |
if (count == -1) | |
break; | |
messageBuffer.append(Arrays.copyOfRange(buffer, 0, count)); | |
while (messageBuffer.hasCompleteMessage()) { | |
String ircMessage = messageBuffer.getNextMessage(); | |
System.out.println("\"" + ircMessage + "\""); | |
processMessage(ircMessage); | |
} | |
} | |
} | |
catch (IOException info) | |
{ | |
quit("error in messageLoop"); | |
info.printStackTrace(); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Message { | |
public String origin; | |
public String nickname; | |
public String command; | |
public String target; | |
public String content; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class MessageBuffer { | |
String buffer; | |
public MessageBuffer() { | |
buffer = ""; | |
} | |
public void append(byte[] bytes) { | |
buffer += new String(bytes); | |
} | |
public boolean hasCompleteMessage() { | |
if (buffer.contains("\r\n")) | |
return true; | |
else | |
return false; | |
} | |
public String getNextMessage() { | |
int index = buffer.indexOf("\r\n"); | |
String message = ""; | |
if (index > -1) { | |
message = buffer.substring(0, index); | |
buffer = buffer.substring(index + 2); | |
} | |
return message; | |
} | |
public static void main(String[] args) { | |
MessageBuffer buf = new MessageBuffer(); | |
buf.append("blah\r\nblah blah\r\nblah blah oh uh".getBytes()); | |
while (buf.hasCompleteMessage()) { | |
System.out.println("\"" + buf.getNextMessage() + "\""); | |
} | |
buf.append(" blah\r\n".getBytes()); | |
while (buf.hasCompleteMessage()) { | |
System.out.println("\"" + buf.getNextMessage() + "\""); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// this class only parses messages it understands. if a message is not understood | |
// the origin and command are extracted and parsing halts. | |
class Parse { | |
static Message message(String ircMessage) { | |
Message message = new Message(); | |
int spIndex; | |
if (ircMessage.startsWith(":")) { | |
spIndex = ircMessage.indexOf(' '); | |
if (spIndex > -1) { | |
message.origin = ircMessage.substring(1, spIndex); | |
ircMessage = ircMessage.substring(spIndex + 1); | |
int uIndex = message.origin.indexOf('!'); | |
if (uIndex > -1) { | |
message.nickname = message.origin.substring(0, uIndex); | |
} | |
} | |
} | |
spIndex = ircMessage.indexOf(' '); | |
if (spIndex == -1) { | |
message.command = "null"; | |
return message; | |
} | |
message.command = ircMessage.substring(0, spIndex).toLowerCase(); | |
ircMessage = ircMessage.substring(spIndex + 1); | |
// parse privmsg params | |
if (message.command.equals("privmsg")) { | |
spIndex = ircMessage.indexOf(' '); | |
message.target = ircMessage.substring(0, spIndex); | |
ircMessage = ircMessage.substring(spIndex + 1); | |
if (ircMessage.startsWith(":")) { | |
message.content = ircMessage.substring(1); | |
} | |
else { | |
message.content = ircMessage; | |
} | |
} | |
// parse quit/join | |
if (message.command.equals("quit") || message.command.equals("join")) { | |
if (ircMessage.startsWith(":")) { | |
message.content = ircMessage.substring(1); | |
} | |
else { | |
message.content = ircMessage; | |
} | |
} | |
// parse ping params | |
if (message.command.equals("ping")) { | |
spIndex = ircMessage.indexOf(' '); | |
if (spIndex > -1) { | |
message.content = ircMessage.substring(0, spIndex); | |
} | |
else { | |
message.content = ircMessage; | |
} | |
} | |
return message; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class SimpleIrcClient extends IRCMessageLoop { | |
SimpleIrcClient(String server, int port) { | |
super(server, port); | |
} | |
@Override | |
public void ignite() { | |
join(theChannel); | |
privmsg("#test", "Hello and bye bye."); | |
quit("bye bye"); | |
} | |
public static void main(String[] args) { | |
SimpleIrcClient client = new SimpleIrcClient("server", 6667); | |
client.nick("nick"); | |
client.user("catherine", "null", "null", "real name"); | |
client.joinOnStart("#test"); | |
client.run(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment