Package erki.talk.clients.ed

Source Code of erki.talk.clients.ed.ConnectionThread

/*
* (c) Copyright 2007-2008 by Edgar Kalkowski (eMail@edgar-kalkowski.de)
*
* This file is part of the ErkiTalk Java Client.
*
* The ErkiTalk Java Client is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/

package erki.talk.clients.ed;

import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ConnectException;
import java.net.Socket;
import java.net.UnknownHostException;

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.imageio.ImageIO;

import erki.talk.Crypto;
import erki.talk.DHKeyExchange;

public class ConnectionThread extends Thread {
   
    private static final String AWAY_ICON = "res"
            + System.getProperty("file.separator") + "msgs.png";
   
    private String host = null;
    private int port;
   
    private PrintWriter sockOut = null;
   
    private GUIThread gui = null;
    private boolean blockSound = false;
   
    private long pause = 0;
   
    private String topic = null;
   
    private Crypto crypto = null;
    private DHKeyExchange keyExchange = null;
    private boolean encrypt = false;
   
    private boolean killed = false;
   
    private BufferedImage icon;
   
    public ConnectionThread(String host, int port, GUIThread gui) {
        super();
        this.host = host;
        this.port = port;
        this.gui = gui;
       
        try {
            icon = ImageIO.read(new File(AWAY_ICON));
        } catch (IOException e) {
        }
    }
   
    public void kill() {
        killed = true;
    }
   
    @Override
    public void run() {
        super.run();
        Socket sock = null;
        BufferedReader sockIn = null;
       
        while (!gui.isReady()) {
           
            try {
                sleep(33);
            } catch (InterruptedException e) {
                e.printStackTrace();
                System.exit(-1);
            }
        }
       
        while (!killed) {
            encrypt = false;
            crypto = null;
            keyExchange = null;
            topic = null;
           
            try {
                sock = new Socket(host, port);
                sockIn = new BufferedReader(new InputStreamReader(sock
                        .getInputStream(), "UTF-8"));
                sockOut = new PrintWriter(new OutputStreamWriter(sock
                        .getOutputStream(), "UTF-8"), true);
                sockOut.println("PONG");
                sockOut.flush();
                sockOut.println("NICK " + gui.getInputKeyListener().getNick());
                sockOut.println("TOPIC");
                String fromServer = null;
               
                while ((fromServer = sockIn.readLine()) != null) {
                    pause = 0;
                   
                    if (encrypt) {
                       
                        try {
                            fromServer = crypto.decrypt(fromServer);
                        } catch (IllegalBlockSizeException e) {
                            e.printStackTrace();
                            System.exit(-1);
                        } catch (BadPaddingException e) {
                            e.printStackTrace();
                            System.exit(-1);
                        }
                    }
                   
                    if (fromServer.toUpperCase().equals("AUTHED")) {
                        gui.appendLineToOutputBuffer("#I: You are "
                                + "successfully authed.");
                    } else if (fromServer.toUpperCase().equals("BEGINUSERS")) {
                        gui.appendLineToOutputBuffer("#I: ---- Begin user "
                                + "list ----");
                    } else if (fromServer.toUpperCase().equals("DEREGISTERED")) {
                        gui.appendLineToOutputBuffer("#I: Your password has "
                                + "been deleted.");
                    } else if (fromServer.toUpperCase().equals("ENDUSERS")) {
                        gui.appendLineToOutputBuffer("#I: ----- End user list "
                                + "-----");
                    } else if (fromServer.toUpperCase().startsWith("ENCRYPT ")) {
                        String pubKey = fromServer.substring("ENCRYPT "
                                .length());
                        keyExchange.injectPublicKey(pubKey);
                        crypto = new Crypto(keyExchange.getSecretKey());
                        encrypt = true;
                        gui.appendLineToOutputBuffer("#I: Connection is "
                                + "encrypted now.");
                    } else if (fromServer.toUpperCase().startsWith("ERROR ")) {
                        gui.appendLineToOutputBuffer("#E: "
                                + fromServer.substring("ERROR ".length()));
                    } else if (fromServer.toUpperCase().startsWith("INDIRECT ")) {
                        String nick = fromServer.substring(
                                "INDIRECT ".length(), fromServer.indexOf(':'));
                        String txt = fromServer.substring(fromServer
                                .indexOf(':') + 2);
                        gui.appendLineToOutputBuffer(nick + " " + txt);
                    } else if (fromServer.toUpperCase().startsWith("INFO ")) {
                        gui.appendLineToOutputBuffer("#I: "
                                + fromServer.substring("INFO ".length()));
                    } else if (fromServer.toUpperCase().startsWith("ISAUTHED ")) {
                        String nick = fromServer.substring(
                                "ISAUTHED ".length(), fromServer.indexOf(':'));
                        String bool = fromServer.substring(fromServer
                                .indexOf(':') + 2);
                        if (bool.toUpperCase().equals("TRUE")) {
                            gui.appendLineToOutputBuffer("#I: User " + nick
                                    + " is authed");
                        } else if (bool.toUpperCase().equals("FALSE")) {
                            gui.appendLineToOutputBuffer("#I: User " + nick
                                    + " is NOT authed.");
                        } else {
                            gui.appendLineToOutputBuffer("#E: The server's "
                                    + "answer confuses me.");
                        }
                       
                    } else if (fromServer.toUpperCase().startsWith(
                            "ISENCRYPTED ")) {
                        String nick = fromServer.substring("ISENCRYPTED "
                                .length(), fromServer.indexOf(':'));
                        String bool = fromServer.substring(fromServer
                                .indexOf(':') + 2);
                       
                        if (bool.toUpperCase().equals("TRUE")) {
                            gui.appendLineToOutputBuffer("#I: User " + nick
                                    + " uses an encrypted connection.");
                        } else if (bool.toUpperCase().equals("FALSE")) {
                            gui.appendLineToOutputBuffer("#I: User " + nick
                                    + " does NOT use an encrypted connection!");
                        } else {
                            gui.appendLineToOutputBuffer("#E: The server's "
                                    + "answer confuses me.");
                        }
                       
                    } else if (fromServer.startsWith("JOIN ")) {
                        gui.appendLineToOutputBuffer("#I: "
                                + fromServer.substring("JOIN ".length())
                                + " has joined the chat.");
                    } else if (fromServer.startsWith("NEWNICK ")) {
                        String oldNick = fromServer.substring("NEWNICK "
                                .length(), fromServer.indexOf(':'));
                        String newNick = fromServer.substring(fromServer
                                .indexOf(':') + 2);
                        gui.appendLineToOutputBuffer("#I: " + oldNick
                                + " is now known as " + newNick + ".");
                    } else if (fromServer.toUpperCase().startsWith("NEWTOPIC ")) {
                        String nick = fromServer.substring(
                                "NEWTOPIC ".length(), fromServer.indexOf(':'));
                        String topic = fromServer.substring(fromServer
                                .indexOf(':') + 2);
                        gui.appendLineToOutputBuffer("#I: " + nick
                                + " changed the topic from »" + this.topic
                                + "« to »" + topic + "«.");
                        this.topic = topic;
                    } else if (fromServer.toUpperCase().equals("PING")) {
                        sendToServer("PONG");
                        continue;
                    } else if (fromServer.toUpperCase().equals("PLAIN")) {
                        encrypt = false;
                        crypto = null;
                        keyExchange = null;
                        gui.appendLineToOutputBuffer("#I: Encryption "
                                + "disabled. Switched back to plain text.");
                    } else if (fromServer.toUpperCase().equals("PONG")) {
                        // Do nothing.
                    } else if (fromServer.toUpperCase().startsWith("PM ")) {
                        String nick = fromServer.substring("PM ".length(),
                                fromServer.indexOf(':'));
                        String txt = fromServer.substring(fromServer
                                .indexOf(':') + 2);
                        gui.appendLineToOutputBuffer("#PM: " + nick + ": "
                                + txt);
                    } else if (fromServer.toUpperCase().startsWith("QUIT ")) {
                       
                        if (fromServer.indexOf(':') == -1) {
                            gui.appendLineToOutputBuffer(fromServer
                                    .substring("QUIT ".length())
                                    + " has left.");
                        } else {
                            gui.appendLineToOutputBuffer(fromServer.substring(
                                    "QUIT ".length(), fromServer.indexOf(':'))
                                    + " has left ("
                                    + fromServer.substring(fromServer
                                            .indexOf(':') + 2) + ").");
                        }
                       
                    } else if (fromServer.toUpperCase().equals("REGISTERED")) {
                        gui.appendLineToOutputBuffer("#I: You have "
                                + "successfully registered a password for "
                                + "your nick.");
                    } else if (fromServer.toUpperCase().startsWith("TEXT ")) {
                        String txt = fromServer.substring("TEXT ".length());
                        String nick = txt.substring(0, txt.indexOf(':'));
                        txt = txt.substring(txt.indexOf(':') + 2);
                        gui.appendLineToOutputBuffer(nick + ": " + txt);
                    } else if (fromServer.toUpperCase().startsWith("TOPIC ")) {
                        String nick = fromServer.substring("TOPIC ".length(),
                                fromServer.indexOf(':'));
                        String dateTime = fromServer.substring(fromServer
                                .indexOf(':') + 2);
                        String txt = dateTime
                                .substring(dateTime.indexOf(':') + 5);
                        dateTime = dateTime.substring(0,
                                dateTime.indexOf(':') + 3);
                       
                        if (topic == null) {
                            topic = txt;
                        } else {
                            gui.appendLineToOutputBuffer("#I: The current "
                                    + "chat topic is »" + txt
                                    + "« and was set by " + nick + " on "
                                    + dateTime + ".");
                        }
                       
                    } else if (fromServer.toUpperCase().startsWith("USER ")) {
                        gui.appendLineToOutputBuffer("#I: "
                                + fromServer.substring("USER ".length()));
                    } else {
                        gui.appendLineToOutputBuffer("#E: I cannot understand "
                                + "this line: " + fromServer);
                    }
                   
                    if ((gui.getAlarm() == 1
                            && (fromServer.toUpperCase().startsWith("TEXT ") || fromServer
                                    .toUpperCase().startsWith("PM ")) && !blockSound)
                            || (gui.getAlarm() == 2 && !blockSound)) {
                       
                        if (icon != null && !gui.hasFocus()) {
                            gui.setIcon(icon);
                        }
                       
                        try {
                            Runtime.getRuntime().exec("mplayer res/Notify.wav");
                        } catch (IOException e) {
                            blockSound = true;
                            gui.appendLineToOutputBuffer("# Alarm blocked! "
                                    + "Perhaps »mplayer« is missing?");
                        }
                    }
                }
               
            } catch (ConnectException e) {
                gui.appendLineToOutputBuffer("#E: ConnectException!");
            } catch (UnknownHostException e) {
                gui.appendLineToOutputBuffer("#E: UnknownHostException!");
            } catch (IOException e) {
                gui.appendLineToOutputBuffer("#E: IOException!");
            }
           
            gui.appendLineToOutputBuffer("#E: No connection to server. "
                    + "Trying to reconnect in " + pause / 60000 + " min.");
           
            try {
                sleep(pause);
            } catch (InterruptedException e) {
                pause = -1;
            }
           
            if (pause == -1) {
                pause = 0;
            } else if (pause == 0) {
                pause = 60000;
            } else {
                pause *= 2;
            }
        }
    }
   
    public void setServer(String host) {
        this.host = host;
    }
   
    public void setPort(int port) {
        this.port = port;
    }
   
    public boolean sendToServer(String txt) {
       
        if (sockOut == null) {
            return false;
        }
       
        if (txt.toUpperCase().trim().equals("ENCRYPT")) {
            keyExchange = new DHKeyExchange();
            txt = "ENCRYPT " + keyExchange.getPublicKey();
        }
       
        boolean endcrypt = false;
       
        if (txt.toUpperCase().trim().equals("PLAIN")) {
            endcrypt = true;
        }
       
        if (encrypt) {
           
            try {
                txt = crypto.encrypt(txt);
            } catch (IllegalBlockSizeException e) {
                e.printStackTrace();
                System.exit(-1);
            } catch (BadPaddingException e) {
                e.printStackTrace();
                System.exit(-1);
            }
        }
       
        if (endcrypt) {
            encrypt = false;
            keyExchange = null;
            crypto = null;
        }
       
        sockOut.println(txt);
        sockOut.flush();
        return true;
    }
}
TOP

Related Classes of erki.talk.clients.ed.ConnectionThread

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.