Sfoglia il codice sorgente

Banning and proper logging

Made bans more versatile. Fixed issue where the chat-console in client
would overwrite the buffer to be written to console, making two
different messages appear as tewo of the same.
Also some general fixing.
Tankernn 10 anni fa
parent
commit
f2844176c3

+ 1 - 1
client.properties

@@ -1,5 +1,5 @@
 #Configuration for chat client
-#Fri May 08 15:24:33 CEST 2015
+#Tue May 12 18:23:16 CEST 2015
 port=25566
 host=tankernn.eu
 username=noscoper2

+ 0 - 1
src/client/ChatClient.java

@@ -55,7 +55,6 @@ public class ChatClient {
 		writeConfFile();
 		
 		try {
-			System.out.println("Connecting to " + host + " on port number " + port);
 			new ChatWindow(host, port, username);
 		} catch (IOException ex1) {
 			ex1.printStackTrace();

+ 29 - 25
src/client/ChatWindow.java

@@ -6,6 +6,7 @@ import java.awt.GridBagConstraints;
 import java.awt.GridBagLayout;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
+import java.io.EOFException;
 import java.io.File;
 import java.io.IOException;
 import java.io.ObjectInputStream;
@@ -28,7 +29,7 @@ public class ChatWindow extends JFrame implements ActionListener, Runnable{
 	
 	Socket so;
 	ObjectInputStream objIn;
-	static PrintWriter out;
+	PrintWriter out;
 	
 	GridBagLayout g = new GridBagLayout();
 	GridBagConstraints con = new GridBagConstraints();
@@ -92,25 +93,7 @@ public class ChatWindow extends JFrame implements ActionListener, Runnable{
 		setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
 	}
 	
-	public void getMessages() throws SocketException, IOException, ClassNotFoundException {
-		while(!getMessages.isInterrupted()) {
-			Object fromServer = objIn.readObject();
-			if (fromServer instanceof Message) {
-				Message mess = ((Message)fromServer);
-				chat.log(mess);
-				
-				model = new DefaultListModel<String>();
-				for (int i = 0; i < mess.usersOnline.length; i++)
-					model.addElement(mess.usersOnline[i]);
-				
-				userList.setModel(model);
-			} else if (fromServer instanceof String)
-				chat.log((String) fromServer);
-		}
-		throw new SocketException("Disconnected from host!");
-	}
-	
-	static void send(String text) {
+	void send(String text) {
 		out.println(text);
 	}
 	
@@ -124,11 +107,12 @@ public class ChatWindow extends JFrame implements ActionListener, Runnable{
 			out.close();
 		}
 		
-		chat.log("Connecting to " + adress + " on port " + port + ".");
 		so =		new Socket(adress, port);
-		objIn =	new ObjectInputStream(so.getInputStream());
+		objIn =		new ObjectInputStream(so.getInputStream());
 		out =		new PrintWriter(so.getOutputStream(), true);
 		
+		chat.log("Connected to " + adress + " on port " + port + ".");
+		
 		send(username);
 		
 		getMessages = new Thread(this);
@@ -140,8 +124,7 @@ public class ChatWindow extends JFrame implements ActionListener, Runnable{
 		if (e.getSource() == skriv) {
 			send(skriv.getText());
 			skriv.setText("");
-		}
-		else if (e.getSource() == reconnect) {
+		} else if (e.getSource() == reconnect) {
 			try {
 				connect(adress, port, username);
 			} catch (IOException e1) {
@@ -154,8 +137,29 @@ public class ChatWindow extends JFrame implements ActionListener, Runnable{
 	public void run() {
 		try {
 			getMessages();
-		} catch (ClassNotFoundException | IOException e) {
+		} catch (EOFException eof) {
+			chat.log(eof.getMessage() + " Disconnected from host.");
+		} catch (ClassNotFoundException cnf) {
+			chat.log("The message recieved from the server could not be understood. Are you using the right version?");
+		} catch (IOException e) {
 			chat.log(e.toString());
 		}
 	}
+	
+	public void getMessages() throws SocketException, IOException, ClassNotFoundException {
+		while(!getMessages.isInterrupted()) {
+			Object fromServer = objIn.readObject();
+			if (fromServer instanceof Message) {
+				Message mess = ((Message)fromServer);
+				chat.log(mess);
+				
+				model = new DefaultListModel<String>();
+				for (int i = 0; i < mess.usersOnline.length; i++)
+					model.addElement(mess.usersOnline[i]);
+				
+				userList.setModel(model);
+			} else
+				chat.log(fromServer.toString());
+		}
+	}
 }

+ 20 - 19
src/client/Console.java

@@ -8,37 +8,38 @@ import javax.swing.text.*;
 import common.Message;
 
 @SuppressWarnings("serial")
-public class Console extends JTextPane implements Runnable {
-	
-	String str;
-	SimpleAttributeSet style;
+public class Console extends JTextPane {
 	
 	void log(String str) {
-		this.str = str;
-		style = new SimpleAttributeSet();
+		SimpleAttributeSet style = new SimpleAttributeSet();
 		StyleConstants.setForeground(style, Color.RED);
 		StyleConstants.setBold(style, true);
 		
-		SwingUtilities.invokeLater(this);
+		SwingUtilities.invokeLater(new AppendThread(str, style, this.getStyledDocument()));
 	}
 	
 	void log(Message mess) {
-		this.str = mess.toString();
-		this.style = mess.style;
-		
-		SwingUtilities.invokeLater(this);
+		SwingUtilities.invokeLater(new AppendThread(mess.toString(), mess.style, this.getStyledDocument()));
 	}
 	
-	@Override
-	public void run() {
-		StyledDocument doc = this.getStyledDocument();
+	private static class AppendThread extends Thread {
+		String text;
+		SimpleAttributeSet style;
+		StyledDocument doc;
 		
-		try
-		{
-		    doc.insertString(doc.getLength(), str + "\n", style);
+		public AppendThread(String text, SimpleAttributeSet style, StyledDocument doc) {
+			this.text = text;
+			this.style = style;
+			this.doc = doc;
 		}
-		catch(Exception e) {
-			System.out.println(e);
+		
+		@Override
+		public synchronized void run() {
+			try {
+			    doc.insertString(doc.getLength(), text + "\n", style);
+			} catch(Exception e) {
+				System.out.println(e);
+			}
 		}
 	}
 }

+ 35 - 4
src/command/Ban.java

@@ -1,18 +1,49 @@
 package command;
 
+import java.util.InputMismatchException;
+import java.util.Scanner;
+
 import server.Client;
+import server.CommandHandler;
 import server.Server;
+import server.BanNote;
 
 public class Ban extends Command {
 
 	@Override
 	public void execute(String[] args, Client caller) {
+		String IP = null;
+		int duration = -1;
+		Client victim;
+		
 		try {
-			Server.bannedIps.add(Server.getUserByName(args[0]).sock.getInetAddress().toString());
-			Server.getUserByName(args[0]).disconnect(false);
-		} catch (NullPointerException e) {
+			victim = Server.getUserByName(args[0]);
+		}	catch (NullPointerException e) {
 			caller.send("No such user!");
+			return;
 		}
+		
+		IP = victim.sock.getInetAddress().toString();
+		
+		
+		BanNote bn = new BanNote(IP);
+		
+		if (args.length == 1)
+			bn = new BanNote(IP);
+		else
+			try {
+				duration = new Scanner(args[1]).nextInt();
+				
+				if (args.length >= 3)
+					bn = new BanNote(IP, duration, this.stringArrayToString(CommandHandler.removeFirst(CommandHandler.removeFirst(args))));
+				else
+					bn = new BanNote(IP, duration);
+			} catch (InputMismatchException ime) {
+				bn = new BanNote(IP, this.stringArrayToString(CommandHandler.removeFirst(args)));
+			}
+		
+		Server.banNotes.add(bn);
+		victim.disconnect(false);
 	}
 
 	@Override
@@ -27,7 +58,7 @@ public class Ban extends Command {
 
 	@Override
 	public String writeDescription() {
-		return "Bans a user. (/ban <username>)";
+		return "Bans a user. (/ban <username> [seconds] [reason])";
 	}
 
 	@Override

+ 9 - 1
src/command/Command.java

@@ -12,9 +12,17 @@ public abstract class Command {
 		permission = setPermission();
 	}
 
-	public abstract void execute (String[] args, Client caller);
+	public abstract void execute (String[] args, Client caller) throws Exception;
 	public abstract String setName ();
 	public abstract String setPermission ();
 	public abstract String writeDescription ();
 	public abstract int setMinArgNumber ();
+	
+	public String stringArrayToString(String[] strArr) {
+		String content = "";
+		for (int i = 1; i < strArr.length -1; i++) {
+			content += strArr[i] + " ";
+		}
+		return content;
+	}
 }

+ 1 - 1
src/command/List.java

@@ -7,7 +7,7 @@ public class List extends Command {
 	
 	@Override
 	public void execute(String[] args, Client caller) {
-		caller.send("Users online are:" + Server.getUsersOnline());
+		caller.send("Users online are:" + Server.getUsersOnlineString());
 	}
 
 	@Override

+ 12 - 11
src/command/PrivateMessage.java

@@ -1,28 +1,29 @@
 package command;
 
 import common.Message;
-
 import server.Client;
+import server.CommandHandler;
 import server.Server;
 
 public class PrivateMessage extends Command {
 
 	@Override
 	public void execute(String[] args, Client caller) {
-		if (caller.equals(Server.getUserByName(args[0])))
-			return;
-		
-		String content = "";
-		for (int i = 1; i < args.length -1; i++) {
-			content += args[i] + " ";
-		}
-		Message mess = new Message("PM", caller.username, content);
+		Client reciever = null;
 		try {
-			Client reciever = Server.getUserByName(args[0]);
-			reciever.send(mess); caller.send(mess);
+			reciever = Server.getUserByName(args[0]);
 		} catch (Exception ex) {
 			caller.send("No such user!");
+			return;
 		}
+			
+		if (caller.equals(reciever))
+			return;
+		
+		Message mess = new Message("PM", caller.username, this.stringArrayToString(CommandHandler.removeFirst(args)));
+		
+		reciever.send(mess); caller.send(mess);
+		
 	}
 
 	@Override

+ 0 - 11
src/server/Ban.java

@@ -1,11 +0,0 @@
-package server;
-
-public class Ban {
-	String ip, reason;
-	int duration;
-	public Ban (String ip, int duration, String reason) {
-		this.ip = ip;
-		this.duration = duration;
-		this.reason = reason;
-	}
-}

+ 37 - 0
src/server/BanNote.java

@@ -0,0 +1,37 @@
+package server;
+
+import java.time.LocalDateTime;
+import java.time.temporal.ChronoUnit;
+
+public class BanNote {
+	String ip, reason;
+	LocalDateTime expiry;
+	
+	public BanNote(String ip, int duration, String reason) {
+		this.ip = ip;
+		if (duration == -1)
+			this.expiry = null;
+		else
+			this.expiry = LocalDateTime.now().plus(duration, ChronoUnit.SECONDS);
+		this.reason = reason;
+	}
+	
+	public BanNote(String ip, String reason) {
+		this(ip, -1, reason);
+	}
+	
+	public BanNote(String ip, int duration) {
+		this(ip, duration, "You are banned.");
+	}
+	
+	public BanNote(String ip) {
+		this(ip, -1);
+	}
+	
+	@Override
+	public String toString() {
+		if (expiry != null)
+			return "You are banned from this server." + "\n" + "Reason: " + reason + "\n" + "Time left: " + LocalDateTime.now().compareTo(expiry);
+		return "You are banned from this server." + "\n" + "Reason: " + reason + "\n" + "Time left: forever.";
+	}
+}

+ 19 - 4
src/server/Client.java

@@ -7,6 +7,7 @@ import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.ObjectOutputStream;
 import java.net.Socket;
+import java.time.LocalDateTime;
 
 import javax.swing.Timer;
 
@@ -57,11 +58,13 @@ public class Client implements Runnable, ActionListener {
 	public Client() {}
 	
 	private boolean validateUser() {
+		//No spaces
 		if (username.contains(" ")){
 			send("No spaces in usernames please!");
 			return false;
 		}
 		
+		//Not same username as anyone else
 		for (int i = 0; i < Server.clients.length; i++) {
 			if (!Server.positionFree(i))
 				if (Server.clients[i].username.equalsIgnoreCase(username)) {
@@ -70,10 +73,21 @@ public class Client implements Runnable, ActionListener {
 				}
 		}
 		
-		if (Server.bannedIps.contains(sock.getInetAddress().toString())) {
-			send("You are banned from this server!");
-			return false;
-		}
+		//No connect if banned
+		for (int i = 0; i < Server.banNotes.size(); i++)
+			if (Server.banNotes.get(i).ip.equals(sock.getInetAddress().toString())) {
+				BanNote bn = Server.banNotes.get(i);
+				if (bn.expiry == null) {
+					send(bn.toString());
+					return false;
+				} else if (bn.expiry.isBefore(LocalDateTime.now())) {
+					Server.banNotes.remove(i);
+					return true;
+				} else {
+					send(bn.toString());
+					return false;
+				}
+			}
 		
 		return true;
 	}
@@ -136,6 +150,7 @@ public class Client implements Runnable, ActionListener {
 	public void send(Object message) {
 		try {
 			objOut.writeObject(message);
+			objOut.flush();
 		} catch (IOException e) {
 			e.printStackTrace();
 		}

+ 6 - 2
src/server/CommandHandler.java

@@ -22,7 +22,11 @@ public class CommandHandler {
 			if ((commands[i].name).equals(command[0])) { //Look for command with correct name
 				if (caller.hasPermission(commands[i].permission)) //Check if the client has permission
 					if (command.length -1 >= commands[i].argNumber) { //Check the number of arguments
-						commands[i].execute(removeFirst(command), caller); //Execute command
+						try {
+							commands[i].execute(removeFirst(command), caller); //Execute command
+						} catch (Exception e) {
+							caller.send("Error while executing command!");
+						} 
 						return;
 					} else {
 						caller.send("More arguments required!");
@@ -37,7 +41,7 @@ public class CommandHandler {
 		caller.send("No such command!");
 	}
 	
-	private static String[] removeFirst(String[] command) {
+	public static String[] removeFirst(String[] command) {
 		for (int i = 0; i < command.length -1; i++) {
 			command[i] = command[i +1];
 		}

+ 21 - 8
src/server/Server.java

@@ -20,7 +20,7 @@ public class Server {
 	static int port, maxUsers = 20, maxChannels = 10;
 	static final String version = "0.2";
 	
-	public static ArrayList<String> bannedIps = new ArrayList<String>();
+	public static ArrayList<BanNote> banNotes = new ArrayList<BanNote>();
 	public static Channel[] channels = new Channel[maxChannels];
 	public static Client[] clients = new Client[maxUsers];
 	
@@ -75,13 +75,15 @@ public class Server {
 	
 	static void getNewClient() throws IOException {
 		Client newClient = new Client(Server.so.accept());
-		for (int i = 0; i < clients.length; i++)
-			if (positionFree(i)) {
-				clients[i] = newClient;
-				channels[0].addUser(newClient);
-				Server.broadcast(new Message(clients[i].username + " has connected."));
-				return;
-			}
+		if (newClient.readuser != null) {
+			for (int i = 0; i < clients.length; i++)
+				if (positionFree(i)) {
+					clients[i] = newClient;
+					channels[0].addUser(newClient);
+					Server.broadcast(new Message(clients[i].username + " has connected."));
+					return;
+				}
+		}
 	}
 
 	static void getClients() {
@@ -141,6 +143,17 @@ public class Server {
 		for (int i = 0; i < usersOnline.size(); i++)
 			usersOnlineStr[i] = usersOnline.get(i);
 		return usersOnlineStr;
+	}
 	
+	public static String getUsersOnlineString() {
+		String[] usersOnlineArr = getUsersOnline();
+		String usersOnline = "";
+		
+		for (int i = 0; i < usersOnlineArr.length; i++) {
+			if (i != 0)
+				usersOnline += "\n";
+			usersOnline += usersOnlineArr[i];
+		}
+		return usersOnline;
 	}
 }

+ 0 - 17
src/server/exceptions/ChannelFullException.java

@@ -1,17 +0,0 @@
-package server.exceptions;
-
-public class ChannelFullException extends Exception {
-
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = 3596284335004083523L;
-	
-	public ChannelFullException (String message) {
-		super(message);
-	}
-
-	public ChannelFullException() {
-		super();
-	}
-}