/** * Copyright (C) 2010-2014 Leon Blakey <lord.quackstar at gmail.com> * * This file is part of PircBotX. * * PircBotX 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. * * PircBotX 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 * PircBotX. If not, see <http://www.gnu.org/licenses/>. */ package org.pircbotx.dcc; import static com.google.common.base.Preconditions.*; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.Socket; import java.nio.charset.Charset; import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.pircbotx.User; import org.pircbotx.exception.DccException; import org.slf4j.Marker; import org.slf4j.MarkerFactory; /** * Generic DCC chat handling class that represents an active dcc chat. * <p> * @author Leon Blakey */ @Slf4j public class Chat { public static final Marker INPUT_CHAT_MARKER = MarkerFactory.getMarker("pircbotx.dccChat.input"); public static final Marker OUTPUT_CHAT_MARKER = MarkerFactory.getMarker("pircbotx.dccChat.output"); @Getter protected User user; @Getter protected BufferedReader bufferedReader; @Getter protected BufferedWriter bufferedWriter; @Getter protected Socket socket; @Getter protected boolean finished; protected Chat(User user, Socket socket, Charset encoding) throws IOException { checkNotNull(user, "User cannot be null"); checkNotNull(socket, "Socket cannot be null"); checkNotNull(encoding, "Encoding cannot be null"); this.user = user; this.socket = socket; this.bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream(), encoding)); this.bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), encoding)); } /** * Reads the next line of text from the client at the other end of our DCC * Chat connection. This method blocks until something can be returned. If * the connection has closed, null is returned. * * @return The next line of text from the client. Returns null if the * connection has closed normally. * * @throws IOException If an I/O error occurs. */ public String readLine() throws IOException { if (finished) throw new DccException(DccException.Reason.ChatNotConnected, user, "Chat has already finished"); String line = bufferedReader.readLine(); log.info(INPUT_CHAT_MARKER, "<<<" + line); return line; } /** * Sends a line of text to the client at the other end of our DCC Chat * connection. * * @param line The line of text to be sent. This should not include linefeed * characters. * * @throws IOException If an I/O error occurs. */ public void sendLine(String line) throws IOException { checkNotNull(line, "Line cannot be null"); if (finished) throw new DccException(DccException.Reason.ChatNotConnected, user, "Chat has already finished"); synchronized (bufferedWriter) { log.info(OUTPUT_CHAT_MARKER, ">>>" + line); bufferedWriter.write(line + "\r\n"); bufferedWriter.flush(); } } /** * Closes the DCC Chat connection. * * @throws IOException If an I/O error occurs. */ public void close() throws IOException { if (finished) throw new DccException(DccException.Reason.ChatNotConnected, user, "Chat has already finished"); finished = true; socket.close(); } }