Skip to content

Instantly share code, notes, and snippets.

@StefanoBelli
Last active May 26, 2016 15:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save StefanoBelli/700167e92097cd23a24cb803dba7f81b to your computer and use it in GitHub Desktop.
Save StefanoBelli/700167e92097cd23a24cb803dba7f81b to your computer and use it in GitHub Desktop.
Just some fun w/ Java..
package lightirc;
import java.awt.Color;
import java.awt.Font;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileNotFoundException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.net.InetAddress;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import java.security.NoSuchAlgorithmException;
import java.util.Scanner;
import java.util.HashMap;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JButton;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JLabel;
import javax.swing.KeyStroke;
import javax.swing.ScrollPaneConstants;
import javax.swing.Action;
import javax.swing.AbstractAction;
import javax.swing.text.DefaultCaret;
import javax.swing.JCheckBox;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class LightIRC //main class
{
/**
* @param args
*/
public static void main(String[] args)
{
if(args.length > 0) {
if(args[0].equals("--gui")) {
gui();
} else {
cli(args);
}
} else {
System.err.println("Not enough arguments");
}
}
private static void gui()
{
GuiConnectFrame gcd = new GuiConnectFrame();
gcd.populate();
gcd.setVisible(true);
}
/**
* @param args
*/
private static void cli(String[] args)
{
HashMap<String,String> hm = argParser(args);
if (hm == null) {
return;
}
try {
Sockets s;
if(hm.get("ssl").equals("--ssl")) {
s = new SSLSock(hm.get("url"), Integer.parseInt(hm.get("port")));
} else {
s = new Sock(hm.get("url"), Integer.parseInt(hm.get("port")));
}
s.write("NICK "+hm.get("nick"));
s.write("USER "+hm.get("usern")+" 8 * : A simple IRC client");
Thread thr = new Thread() {
@Override
public void run()
{
String lnnext,date;
Calendar calendar = Calendar.getInstance();
SimpleDateFormat datef = new SimpleDateFormat("y/M/d HH:mm:ss");
String timedate = datef.format(calendar.getTime());
System.out.println("[CLIENT] Started session: "+timedate);
System.out.println("[CLIENT] Connecting to: "+s.getHostname());
System.out.println("[CLIENT] IP Address: "+s.getIpAddr());
System.out.println("[CLIENT] Port(L<->R): "+s.getLocalPort()+"<->"+s.getPort());
System.out.println("[CLIENT] Nickname: "+hm.get("nick"));
System.out.println("[CLIENT] Username: "+hm.get("usern"));
System.out.println("+-----------------------------------+");
while(true) {
lnnext=s.read();
if(lnnext.contains("PING")) {
try {
s.write("PONG "+ lnnext.substring(5));
}catch(IOException ioe) {
s.endConnection();
return;
}
} else {
System.out.println("[IRC] "+lnnext);
}
}
}
};
Thread thr1 = new Thread() {
@Override
public void run()
{
Scanner scr = new Scanner(System.in);
String chan = "NiC";
while(true) {
//add function w/ other cmds
System.out.print("-["+chan+"]-> ");
if(scr.hasNextLine()) {
try {
String str = scr.nextLine();
if(str.contains("/join")) {
if((chan = Command.join(s,str)) == null){
System.err.println("[ERROR] Error while joining chan!");
}
} else if(str.contains("/irccmd")) {
if(Command.irccmd(s,str) < 0) {
System.err.println("[ERROR] Error while sending command!");
}
} else {
s.write("PRIVMSG "+chan+" :"+str);
}
}catch(IOException ioe) {
s.endConnection();
return;
}
}
}
}
};
thr.start();
thr1.start();
} catch (UnknownHostException e) {
System.err.println("Unknown host!");
} catch(IOException e) {
System.err.println("I/O Exception!");
} catch(NoSuchAlgorithmException algexcp) {
System.err.println("No such algorithm");
}
}
/**
* @param args
* @return hmap
*/
private static HashMap<String,String> argParser(String[] args)
{
HashMap<String,String> hmap = new HashMap<>(4);
if(args.length > 5 || args.length < 3) {
return null;
}
hmap.put("url", args[0]);
hmap.put("port", args[1]);
hmap.put("nick", args[2]);
if(args.length == 3) {
hmap.put("usern", args[2]);
} else {
hmap.put("usern", args[3]);
}
if(args.length == 5) {
hmap.put("ssl", args[4]);
} else {
hmap.put("ssl", "null");
}
return hmap;
}
}
class GuiConnectFrame extends JFrame implements ActionListener
{
private boolean ssl;
private JButton connectBtn, exitBtn;
private JLabel lirc, lport, lnick, lusern;
private JTextField tirc, tport, tnick, tusern;
private JCheckBox chssl;
private File f;
GuiConnectFrame() //Initialize window
{
super("Connect to IRC");
this.setSize(300,300);
this.setLocation(500,150);
this.setResizable(false);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setLayout(null); //manual widget positioning
if(System.getProperty("os.name").equals("Linux")) {
String fcfg = System.getenv("HOME")+"/.lirc.conf";
f = new File(fcfg);
if(! f.exists()) {
try {
if(! f.createNewFile()) {
System.err.println("File creation error! (Not fatal)");
}
} catch(IOException ioe) {
System.err.println("Error while creating new file!");
}
}
} else {
f=null;
}
}
private void createWidgets() {
lirc = new JLabel("IRC Srv:");
lport = new JLabel("IRC Port:");
lnick = new JLabel("Nickname:");
lusern = new JLabel("User:");
tirc = new JTextField();
tport = new JTextField();
tnick = new JTextField();
tusern = new JTextField();
connectBtn = new JButton("Connect!");
exitBtn = new JButton("Exit");
chssl = new JCheckBox("SSL");
lirc.setSize(70, 20);
lport.setSize(70, 35);
lnick.setSize(100, 50);
lusern.setSize(70, 65);
connectBtn.setSize(100, 20);
exitBtn.setSize(100, 20);
tirc.setSize(150, 20);
tport.setSize(150, 20);
tnick.setSize(150, 20);
tusern.setSize(150, 20);
chssl.setSize(150,20);
lirc.setLocation(2, 1);
lport.setLocation(2, 40);
lnick.setLocation(2, 80);
lusern.setLocation(2, 125);
connectBtn.setLocation(2, 250);
exitBtn.setLocation(198, 250);
tirc.setLocation(140, 1);
tport.setLocation(140, 50);
tnick.setLocation(140, 100);
tusern.setLocation(140, 150);
chssl.setLocation(1,180);
}
private void eventInitializer()
{
exitBtn.setActionCommand("exit");
exitBtn.addActionListener(this);
connectBtn.setActionCommand("connectIrc");
connectBtn.addActionListener(this);
tirc.addActionListener(actionEvent -> tport.requestFocusInWindow());
tport.addActionListener(actionEvent -> tnick.requestFocusInWindow());
tnick.addActionListener(actionEvent -> tusern.requestFocusInWindow());
tusern.addActionListener(actionEvent -> doConnect());
chssl.setActionCommand("sslToggleChecked");
chssl.addActionListener(this);
}
private void parseFile()
{
if(!System.getProperty("os.name").equals("Linux")) {
return;
}
String[] reqArgs = new String[5];
String[] reqValues = new String[5];
Scanner scrFile;
int i = 0;
try {
scrFile = new Scanner(f);
}catch(FileNotFoundException ffe) {
System.err.println("File not found!");
return;
}
try {
while(scrFile.hasNextLine()) {
String completeStr;
String[] splittedStr;
completeStr = scrFile.nextLine();
splittedStr = completeStr.split(" = ");
reqArgs[i] = splittedStr[0];
reqValues[i] = splittedStr[1];
i++;
}
} catch(ArrayIndexOutOfBoundsException arroutexcp) {
System.err.println("Catched exception: ArrayIndexOutOfBoundsException <-- this wasn't expected!");
}
scrFile.close();
try {
for (i = 0; i <= reqArgs.length-1; i++) {
if (reqArgs[i].equals("IrcSrv")) {
tirc.setText(reqValues[i]);
}
if(reqArgs[i].equals("IrcPort")) {
tport.setText(reqValues[i]);
}
if(reqArgs[i].equals("IrcNick")) {
tnick.setText(reqValues[i]);
}
if(reqArgs[i].equals("IrcUsern")) {
tusern.setText(reqValues[i]);
}
if(reqArgs[i].equals("IrcSsl")) {
if(reqValues[i].equals("true")) {
chssl.setSelected(true);
ssl=true;
} else if(reqValues[i].equals("false")) {
chssl.setSelected(false);
ssl=false;
} else {
System.err.println("!! Check config file, wrong value @ IrcSsl");
chssl.setSelected(false);
ssl=false;
}
}
}
} catch(NullPointerException npexcp) {
System.err.println("Catched exception: NullPointerException <-- this wasn't expected!");
} catch(ArrayIndexOutOfBoundsException arroutexcp) {
System.err.println("Catched exception: ArrayIndexOutOfBoundsException <-- this wasn't expected!");
}
}
/**
* @param ae
*/
@Override
public void actionPerformed(ActionEvent ae)
{
String cmdActionPerformed = ae.getActionCommand();
if(cmdActionPerformed.equals("exit")) {
this.dispose();
System.exit(0);
} else if(cmdActionPerformed.equals("connectIrc")) {
doConnect();
} else if(cmdActionPerformed.equals("sslToggleChecked")) {
ssl = !ssl;
}
}
private void doConnect()
{
System.out.println(ssl);
String irc,nick,usern,sPort;
int port;
Sockets s;
if((irc=tirc.getText()).isEmpty() ||
(nick=tnick.getText()).isEmpty() ||
(sPort=tport.getText()).isEmpty()) {
JDialog jd = new JDialog();
jd.setTitle("Empty fields");
jd.setLocation(550,175);
jd.setSize(240,100);
jd.setResizable(false);
jd.getContentPane().add(new JLabel("One or more fields are empty!"));
jd.setVisible(true);
return;
}
if((usern=tusern.getText()).isEmpty()) {
usern = nick;
}
// do stuffs about cfg
try {
FileOutputStream fout = new FileOutputStream(f,false);
fout.write(("IrcSrv = "+irc+'\n').getBytes());
fout.write(("IrcPort = "+sPort+'\n').getBytes());
fout.write(("IrcNick = "+nick+'\n').getBytes());
fout.write(("IrcUsern = "+usern+'\n').getBytes());
if(ssl) {
fout.write(("IrcSsl = true\n").getBytes());
} else {
fout.write(("IrcSsl = false\n").getBytes());
}
fout.close();
} catch(FileNotFoundException fexcp) {
System.err.println("Trying to open non-existing file!");
} catch(IOException ioexcp) {
System.err.println("Error while writing bytes to file...");
}
try {
port = Integer.parseInt(sPort);
}catch(NumberFormatException nexcp){
JDialog jd = new JDialog();
jd.setTitle("Not a number!");
jd.setLocation(550,175);
jd.setSize(290,100);
jd.setResizable(false);
jd.getContentPane().add(new JLabel("Exception: You must type number!!"));
jd.setVisible(true);
return;
}
try {
if(ssl) {
s = new SSLSock(irc,port);
} else {
s = new Sock(irc,port);
}
s.write("NICK " + nick);
s.write("USER " + usern + " 8 * : A simple IRC client");
} catch(UnknownHostException uhe) {
JDialog jd = new JDialog();
jd.setTitle("Host unreachable!");
jd.setLocation(550,175);
jd.setSize(220,100);
jd.setResizable(false);
jd.getContentPane().add(new JLabel("Unknown host!"));
jd.setVisible(true);
return;
} catch(IOException ioe) {
JDialog jd = new JDialog();
jd.setTitle("I/O Error!");
jd.setLocation(550,175);
jd.setSize(270,100);
jd.setResizable(false);
jd.getContentPane().add(new JLabel("General I/O Exception!"));
jd.setVisible(true);
return;
} catch(IllegalArgumentException iaexcp) {
JDialog jd = new JDialog();
jd.setTitle("Illegal Argument");
jd.setLocation(550,175);
jd.setSize(290,100);
jd.setResizable(false);
jd.getContentPane().add(new JLabel("Check port range!!"));
jd.setVisible(true);
return;
} catch(NoSuchAlgorithmException algexcp) {
JDialog jd = new JDialog();
jd.setTitle("SSL Error");
jd.setLocation(550,175);
jd.setSize(290,100);
jd.setResizable(false);
jd.getContentPane().add(new JLabel("No Such Algorithm"));
jd.setVisible(true);
algexcp.printStackTrace();
return;
}
this.dispose();
GuiMainIrc ircMainWindow = new GuiMainIrc(s,nick,usern);
//other code here
ircMainWindow.populate();
ircMainWindow.setVisible(true);
}
void populate()
{
createWidgets();
parseFile();
eventInitializer();
this.getContentPane().add(lirc);
this.getContentPane().add(lport);
this.getContentPane().add(lnick);
this.getContentPane().add(lusern);
this.getContentPane().add(connectBtn);
this.getContentPane().add(exitBtn);
this.getContentPane().add(tirc);
this.getContentPane().add(tport);
this.getContentPane().add(tnick);
this.getContentPane().add(tusern);
this.getContentPane().add(chssl);
}
}
class GuiMainIrc extends JFrame implements ActionListener {
private final Sockets s;
private JTextArea showMsg;
private JTextField sendMsg;
private JButton btnSendMsg;
private JScrollPane jsp;
private String chan="";
private final String nick;
private final String usern;
/**
* @param s
* @param nick
* @param usern
*/
GuiMainIrc(Sockets s ,String nick, String usern) {
super();
this.s = s;
if (s.isConnected()) {
this.setTitle("LIRC - Status: connected - " + s.getHostname() + "/" + s.getIpAddr()
+ " - LPort:RPort " + s.getLocalPort() + ":" + s.getPort());
} else {
this.setTitle("LIRC - Status: disconnected");
}
this.setSize(600, 550);
this.setLocation(500, 150);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setLayout(null);
this.setResizable(false);
this.nick = nick;
this.usern = usern;
}
private void createWidgets() {
showMsg = new JTextArea(" ");
showMsg.setEditable(false);
showMsg.setLocation(1, 1);
showMsg.setSize(598, 489);
showMsg.setBackground(Color.BLACK);
showMsg.setForeground(Color.GREEN);
showMsg.setFont(new Font("Courier",Font.PLAIN,12));
DefaultCaret caret = (DefaultCaret) showMsg.getCaret();
caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
jsp = new JScrollPane(showMsg);
jsp.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
jsp.setSize(598,473);
jsp.setLocation(1,1);
sendMsg = new JTextField();
sendMsg.setLocation(1, 490);
sendMsg.setSize(490, 20);
btnSendMsg = new JButton("Send");
btnSendMsg.setLocation(500, 490);
btnSendMsg.setSize(95, 20);
}
private void eventInitializer() {
btnSendMsg.setActionCommand("sendMsg");
btnSendMsg.addActionListener(this);
Action sendMsgByKey = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent actionEvent)
{
doSendMsg();
}
};
sendMsg.getInputMap().put(KeyStroke.getKeyStroke("ENTER"),"sendMsgEnterPressed");
sendMsg.getActionMap().put("sendMsgEnterPressed",sendMsgByKey);
}
private void showMessages() {
Thread thrMsgs = new Thread() {
@Override
public void run() {
Calendar calendar = Calendar.getInstance();
SimpleDateFormat datef = new SimpleDateFormat("y/M/d HH:mm:ss");
String timedate = datef.format(calendar.getTime());
showMsg.setText("");
showMsg.setText("[CLIENT] Started session: "+timedate+'\n');
showMsg.append("[CLIENT] Connecting to: "+s.getHostname()+'\n');
showMsg.append("[CLIENT] IP Address: "+s.getIpAddr()+'\n');
showMsg.append("[CLIENT] Port(L<->R): "+s.getLocalPort()+"<->"+s.getPort()+'\n');
showMsg.append("[CLIENT] Nickname: "+nick+'\n');
showMsg.append("[CLIENT] Username: "+usern+'\n');
showMsg.append("+-----------------------------------+\n");
String lnnext;
while (true) {
if(! s.isConnected()) {
setTitle("IRC - Status: disconnected!");
break;
}
lnnext = s.read();
if (lnnext.contains("PING")) {
try {
s.write("PONG " + lnnext.substring(5));
} catch (IOException ioe) {
s.endConnection();
return;
}
} else {
StringBuilder strb = new StringBuilder(lnnext);
int i = 0;
while ((i = strb.indexOf(" ", i + 80)) != -1) {
strb.replace(i, i + 1, "\n");
}
showMsg.append("[IRC] "+strb.toString() + '\n');
}
}
}
};
thrMsgs.start();
}
void populate() {
createWidgets();
eventInitializer();
this.getContentPane().add(sendMsg);
this.getContentPane().add(btnSendMsg);
this.getContentPane().add(jsp);
showMessages();
}
/**
* @param ae
*/
@Override
public void actionPerformed(ActionEvent ae)
{
String cmdActionPerformed = ae.getActionCommand();
if (cmdActionPerformed.equals("sendMsg")) {
doSendMsg();
}
}
private void doSendMsg()
{
try {
String str = sendMsg.getText();
if (str.contains("/join")) {
if((chan = Command.join(s,str,this)) == null) {
showMsg.append("\n[ERROR] Error while joining channel!");
}
} else if (str.contains("/irccmd")) {
if(Command.irccmd(s,str) < 0) {
showMsg.append("\n[ERROR] Error while sending command!");
}
} else {
if(! chan.isEmpty() && ! str.isEmpty()) {
s.write("PRIVMSG " + chan + " :" + str);
showMsg.append("["+chan+":me] "+str+'\n');
}
}
} catch (IOException ioe) {
s.endConnection();
return;
} catch (ArrayIndexOutOfBoundsException arrexcp) {
//empty catch
}
sendMsg.setText("");
}
JTextArea getTextAreaContext()
{
return this.showMsg;
}
}
class Command {
static String join(Sockets socket, String completeStr) {
String chan = "";
String[] pstr = completeStr.split(" ");
if (pstr.length > 1) {
chan = pstr[1];
try {
socket.write("JOIN " + chan);
} catch (IOException ioexcp) {
socket.endConnection();
return null;
}
}
return chan;
}
static String join(Sockets socket, String completeStr, GuiMainIrc ircgui) {
String chan = "";
String[] pstr = completeStr.split(" ");
if (pstr.length > 1) {
chan = pstr[1];
ircgui.getTextAreaContext().setText("-----[" + chan + "]-----\n");
try {
socket.write("JOIN " + chan);
} catch (IOException ioexcp) {
socket.endConnection();
return null;
}
}
return chan;
}
static int irccmd(Sockets socket, String completeStr)
{
String cmd="";
String[] pstr = completeStr.split(" ");
try {
for(int i=1;i<=pstr.length;i++) {
cmd += " "+pstr[i];
}
} catch(ArrayIndexOutOfBoundsException arrexcp) {
}
try {
socket.write(cmd);
} catch(IOException ioexcp) {
return -1;
}
return 0;
}
}
abstract class Sockets
{
abstract String read();
abstract void endConnection();
abstract void write(String __src) throws IOException;
abstract String getIpAddr();
abstract int getPort();
abstract int getLocalPort();
abstract String getHostname();
abstract boolean isConnected();
}
class Sock extends Sockets
{
private final Socket sock;
private final String resolvedIpAddr;
private final BufferedReader bufread;
private final BufferedWriter bufwrite;
private final InetAddress inetaddr;
/**
* @param hostname
* @param port
* @throws IOException
*/
Sock(String hostname, int port)
throws IOException
{
inetaddr = InetAddress.getByName(hostname);
this.resolvedIpAddr = inetaddr.getHostAddress();
this.sock = new Socket(hostname,port);
this.bufread = new BufferedReader(new InputStreamReader(this.sock.getInputStream()));
this.bufwrite = new BufferedWriter(new OutputStreamWriter(this.sock.getOutputStream()));
}
/**
* @return line
*/
@Override
String read()
{
if(this.sock.isConnected()) {
Scanner scr = new Scanner(this.bufread);
if(scr.hasNextLine()) {
return scr.nextLine();
}
}
return null;
}
/**
* @param __src
* @throws IOException
*/
@Override
void write(String __src)
throws IOException
{
if(this.sock.isConnected()) {
this.bufwrite.write(__src + " \r\n");
this.bufwrite.flush();
}
}
@Override
void endConnection()
{
try {
if (this.sock.isConnected()) {
this.bufwrite.close();
this.bufread.close();
this.sock.close();
}
} catch (IOException | NullPointerException e) {
e.printStackTrace();
}
}
//useful getters
/**
* @return ip address
*/
@Override
String getIpAddr()
{
return this.resolvedIpAddr;
}
/**
* @return remote port
*/
@Override
int getPort()
{
return this.sock.getPort();
}
/**
* @return local port
*/
@Override
int getLocalPort()
{
return this.sock.getLocalPort();
}
/**
* @return hostname (server)
*/
@Override
String getHostname()
{
return this.inetaddr.getHostName();
}
/**
* @return if connection established
*/
@Override
boolean isConnected()
{
return this.sock.isConnected();
}
}
class SSLSock extends Sockets
{
private final SSLSocket sock;
private final String resolvedIpAddr;
private final BufferedReader bufread;
private final BufferedWriter bufwrite;
private final InetAddress inetaddr;
SSLSock(String hostname, int port)
throws NoSuchAlgorithmException, IOException
{
this.inetaddr = InetAddress.getByName(hostname);
this.resolvedIpAddr = inetaddr.getHostAddress();
SSLSocketFactory sslSockBuilder = (SSLSocketFactory) SSLSocketFactory.getDefault();
this.sock = (SSLSocket) sslSockBuilder.createSocket(hostname,port);
this.sock.startHandshake();
this.bufread = new BufferedReader(new InputStreamReader(this.sock.getInputStream()));
this.bufwrite = new BufferedWriter(new OutputStreamWriter(this.sock.getOutputStream()));
}
/**
* @param __src
* @throws IOException
*/
@Override
void write(String __src)
throws IOException
{
if(this.sock.isConnected()) {
this.bufwrite.write(__src + " \r\n");
this.bufwrite.flush();
}
}
@Override
void endConnection()
{
try {
if (this.sock.isConnected()) {
this.bufwrite.close();
this.bufread.close();
this.sock.close();
}
} catch (IOException | NullPointerException e) {
e.printStackTrace();
}
}
/**
* @return str
*/
@Override
String read()
{
if(this.sock.isConnected()) {
Scanner scr = new Scanner(this.bufread);
if(scr.hasNextLine()) {
return scr.nextLine();
}
}
return null;
}
/**
* @return ip address
*/
@Override
String getIpAddr()
{
return this.resolvedIpAddr;
}
/**
* @return remote port
*/
@Override
int getPort()
{
return this.sock.getPort();
}
/**
* @return local port
*/
@Override
int getLocalPort()
{
return this.sock.getLocalPort();
}
/**
* @return hostname (server)
*/
@Override
String getHostname()
{
return this.inetaddr.getHostName();
}
/**
* @return if connection established
*/
@Override
boolean isConnected()
{
return this.sock.isConnected();
}
}
@StefanoBelli
Copy link
Author

Need to implement commands

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment