ソースを参照

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 年 前
コミット
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();
-	}
-}