Browse Source

Visibility changes, isOP removed, new Timer

- Reduced visibility of Client members.
- Permissions is a list instead of an array.
- Moved code from LocalClient to Client.
Tankernn 8 years ago
parent
commit
7a75ef51b5

+ 6 - 3
src/main/java/common/InfoPacket.java

@@ -1,5 +1,7 @@
 package common;
 
+import java.util.List;
+
 import server.Client;
 import server.Server;
 
@@ -8,7 +10,8 @@ public class InfoPacket implements Packet {
 	 * 
 	 */
 	private static final long serialVersionUID = 1L;
-	public String[] usersOnline, permissions;
+	public String[] usersOnline;
+	List<String> permissions;
 	public String username, channel;
 	
 	private InfoPacket() {
@@ -18,8 +21,8 @@ public class InfoPacket implements Packet {
 	public static InfoPacket of(Client c) {
 		InfoPacket info = new InfoPacket();
 		
-		info.channel = c.primaryChannel.name;
-		info.permissions = c.permissions;
+		info.channel = c.getPrimaryChannel().name;
+		info.permissions = c.getPermissions();
 		info.username = c.username;
 		
 		return info;

+ 75 - 71
src/main/java/server/Client.java

@@ -1,7 +1,5 @@
 package server;
 
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
 import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStreamReader;
@@ -9,42 +7,42 @@ import java.io.ObjectOutputStream;
 import java.net.InetSocketAddress;
 import java.net.Socket;
 import java.time.LocalDateTime;
-
-import javax.swing.Timer;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Timer;
+import java.util.TimerTask;
 
 import common.InfoPacket;
 import common.MessagePacket;
 import common.Packet;
 
-public class Client implements ActionListener {
-	ReadUser readuser;
+public class Client implements Runnable {
+	protected Thread readuser = new Thread(this);
 
-	BufferedReader in;
-	ObjectOutputStream objOut;
+	protected BufferedReader in;
+	private ObjectOutputStream objOut;
+	private Socket sock;
 
 	public final String username;
-	public Socket sock;
-
-	public String[] permissions;
-	public boolean isOP = false;
+	protected List<String> permissions = new ArrayList<>();
 
-	int messLastPeriod = 0;
-	Timer timer = new Timer(800, this);
+	private int messLastPeriod = 0;
+	private Timer timer = new Timer();
 
-	public Channel primaryChannel = Server.getChannels().get(0);
+	private Channel primaryChannel = Server.getChannels().get(0);
 
 	public Client(Socket socket) {
 		sock = socket;
-		
+
 		String line = null;
 		try {
 			objOut = new ObjectOutputStream(sock.getOutputStream());
 			in = new BufferedReader(new InputStreamReader(sock.getInputStream()));
-			line = in.readLine();
+			line = in.readLine(); // First line contains username
 		} catch (IOException e) {
 			e.printStackTrace();
 		}
-		
+
 		username = line;
 
 		if (!validateUser()) {
@@ -52,17 +50,24 @@ public class Client implements ActionListener {
 			throw new IllegalArgumentException();
 		}
 
-		permissions = new String[] { "user.*" };
+		permissions.add("user.*");
 
 		send(new MessagePacket("Welcome to the server, " + username + "! Enjoy your stay!"));
 
-		readuser = new ReadUser();
-
-		timer.start();
+		readuser.start();
+		timer.schedule(new TimerTask() {
+			@Override
+			public void run() {
+				messLastPeriod = 0;
+			}
+		}, 800, 800);
 	}
 
-	public Client(String username) {
+	public Client(String username, List<String> permissions, BufferedReader in, ObjectOutputStream out) {
 		this.username = username;
+		this.permissions = permissions;
+		this.in = in;
+		this.objOut = out;
 	}
 
 	private boolean validateUser() {
@@ -103,14 +108,16 @@ public class Client implements ActionListener {
 		if (!isConnected()) // Already disconnected
 			return;
 
-		if (timer.isRunning())
-			timer.stop();
-
-		if (readuser != null)
-			readuser.interrupt();
+		timer.cancel();
+		readuser.interrupt();
 
 		try {
-			sock.close();
+			if (sock != null)
+				sock.close();
+			if (in != null)
+				in.close();
+			if (objOut != null)
+				objOut.close();
 		} catch (IOException e) {
 			e.printStackTrace();
 		}
@@ -128,50 +135,36 @@ public class Client implements ActionListener {
 	}
 
 	public boolean hasPermission(String commandPermission) {
-		if (this.isOP)
-			return true;
-
-		for (int i = 0; i < permissions.length; i++) {
-			if (commandPermission.startsWith(permissions[i].replace(".*", "."))
-					|| commandPermission.equalsIgnoreCase(permissions[i]) || permissions[i].equalsIgnoreCase("*"))
-				return true;
-		}
-		return false;
+		long correctPermissions = permissions.stream().filter(perm -> commandPermission.startsWith(perm.replace(".*", "."))
+				|| commandPermission.equalsIgnoreCase(perm) || perm.equalsIgnoreCase("*")).count();
+		return correctPermissions > 0;
 	}
 
-	class ReadUser extends Thread {
-		ReadUser() {
-			super(Client.this.username + " listener thread");
-			this.start();
-		}
-
-		@Override
-		public void run() {
-			String mess;
-			while (!isInterrupted() && (mess = getNewMessage()) != null) {
-
-				if (mess.startsWith("/")) // Command handling
-					Server.getCommReg().executeCommand(mess, Client.this);
-				else // Normal message handling
-				{
-					messLastPeriod++;
-					if (messLastPeriod > 1 && !(Client.this.hasPermission("mod.spam"))) {
-						send("No spamming!");
-						disconnect(false);
-					} else
-						primaryChannel.broadcast(new MessagePacket(Client.this.username, mess));
-				}
+	@Override
+	public void run() {
+		String mess;
+		while (!readuser.isInterrupted() && (mess = getNewMessage()) != null) {
+			if (mess.startsWith("/")) // Command handling
+				Server.getCommReg().executeCommand(mess, this);
+			else // Normal message handling
+			{
+				messLastPeriod++;
+				if (messLastPeriod > 1 && !hasPermission("mod.spam")) {
+					send("No spamming!");
+					disconnect(false);
+				} else
+					getPrimaryChannel().broadcast(new MessagePacket(Client.this.username, mess));
 			}
-			disconnect();
 		}
+		disconnect();
+	}
 
-		public String getNewMessage() {
-			try {
-				return in.readLine();
-			} catch (IOException e) {
-				disconnect();
-				return null;
-			}
+	private String getNewMessage() {
+		try {
+			return in.readLine();
+		} catch (IOException e) {
+			disconnect();
+			return null;
 		}
 	}
 
@@ -206,8 +199,19 @@ public class Client implements ActionListener {
 		return username;
 	}
 
-	@Override
-	public void actionPerformed(ActionEvent e) {
-		messLastPeriod = 0;
+	public Channel getPrimaryChannel() {
+		return primaryChannel;
+	}
+
+	public List<String> getPermissions() {
+		return permissions;
+	}
+
+	public void addPermission(String string) {
+		permissions.add(string);
+	}
+
+	public void setPrimaryChannel(Channel primaryChannel) {
+		this.primaryChannel = primaryChannel;
 	}
 }

+ 6 - 7
src/main/java/server/ClientCollection.java

@@ -10,7 +10,7 @@ import common.MessagePacket;
  * A collection of clients.
  */
 public class ClientCollection {
-	
+
 	private List<Client> clients = new CopyOnWriteArrayList<>();
 
 	/**
@@ -32,9 +32,8 @@ public class ClientCollection {
 	 */
 	public synchronized void broadcast(MessagePacket mess) {
 		if (mess.validate()) {
-			for (Client c : clients)
-				c.send(mess);
-			Server.getOPClient().send(mess);
+			clients.forEach(c -> c.send(mess));
+			Server.getLocalClient().send(mess);
 		}
 	}
 
@@ -44,7 +43,7 @@ public class ClientCollection {
 	 * 
 	 * @param user
 	 *            User to be added to collection.
-	 * @return 
+	 * @return
 	 */
 	public void add(Client user) {
 		if (clients.contains(user))
@@ -97,9 +96,9 @@ public class ClientCollection {
 	 * @see String
 	 */
 	public String[] getUsernameArray() {
-		return clients.stream().map(c -> c.username).toArray(i -> new String[i]);
+		return clients.stream().map(c -> c.username).toArray(String[]::new);
 	}
-	
+
 	public void disconnectAll() {
 		clients.forEach(c -> c.disconnect());
 	}

+ 0 - 1
src/main/java/server/CommandRegistry.java

@@ -31,7 +31,6 @@ public class CommandRegistry  {
 				CommandInfo c = comm.getAnnotation(CommandInfo.class);
 				
 				if (!Arrays.asList(comm.getInterfaces()).contains(Command.class)) {
-					// TODO Proper logging
 					LOG.warning(comm.getName() + " is annoteded with " + CommandInfo.class.getName() + ", but does not implement" + Command.class.getName());
 					continue;
 				}

+ 3 - 19
src/main/java/server/LocalClient.java

@@ -1,8 +1,8 @@
 package server;
 
 import java.io.BufferedReader;
-import java.io.IOException;
 import java.io.InputStreamReader;
+import java.util.Arrays;
 
 import common.MessagePacket;
 import common.Packet;
@@ -13,28 +13,12 @@ public class LocalClient extends Client {
 	 * Constructor for local client, the server, with full permissions
 	 */
 	public LocalClient() {
-		super("SERVER");
-		in = new BufferedReader(new InputStreamReader(System.in));
-		
-		isOP = true;
-		permissions = new String[] {"*"};
-		
-		readuser = new ReadUser();
-	}
-	
-	@Override
-	public void disconnect() {
-		readuser.interrupt();
-		try {
-			in.close();
-		} catch (IOException e) {
-			e.printStackTrace();
-		}
+		super("SERVER", Arrays.asList(new String[] {"*"}), new BufferedReader(new InputStreamReader(System.in)), null);
 	}
 	
 	@Override
 	public void disconnect(boolean bool) {
-		disconnect();
+		disconnect(false);
 	}
 	
 	@Override

+ 2 - 2
src/main/java/server/Server.java

@@ -152,7 +152,7 @@ public class Server {
 		clientListener.interrupt();
 
 		clients.disconnectAll();
-		getOPClient().disconnect();
+		getLocalClient().disconnect();
 
 		try {
 			prop.store(new PrintWriter(propFile), "ChatServer config file");
@@ -165,7 +165,7 @@ public class Server {
 		return maxUsers;
 	}
 
-	public static LocalClient getOPClient() {
+	public static LocalClient getLocalClient() {
 		return OPClient;
 	}
 

+ 1 - 1
src/main/java/server/command/GiveOP.java

@@ -12,7 +12,7 @@ public class GiveOP implements Command {
 	public void execute(String[] args, Client caller) throws Exception {
 		try {
 			Client target = Server.getUserByName(args[0]).get();
-			target.isOP = true;
+			target.addPermission("*");
 			target.send(new MessagePacket("You are now OP.", MessageType.INFO));
 		} catch (NullPointerException ex) {
 			caller.send(new MessagePacket("No such user: " + args[0], MessageType.WARNING));

+ 2 - 2
src/main/java/server/command/JoinChannel.java

@@ -13,7 +13,7 @@ public class JoinChannel implements Command {
 
 	@Override
 	public void execute(String[] args, Client caller) {
-		if (caller.equals(Server.getOPClient())) {
+		if (caller.equals(Server.getLocalClient())) {
 			caller.send("Client-only command.");
 			return;
 		}
@@ -23,7 +23,7 @@ public class JoinChannel implements Command {
 
 		try {
 			selectedChannel.add(caller);
-			caller.primaryChannel = selectedChannel;
+			caller.setPrimaryChannel(selectedChannel);
 			caller.send(new MessagePacket("You are now speaking in channel " + args[0] + ".", MessageType.COMMAND));
 		} catch (NullPointerException ex) {
 			caller.send(new MessagePacket("No such channel!", MessageType.ERROR));

+ 4 - 4
src/main/java/server/command/LeaveChannel.java

@@ -13,7 +13,7 @@ public class LeaveChannel implements Command {
 
 	@Override
 	public void execute(String[] args, Client caller) throws Exception {
-		if (caller.equals(Server.getOPClient())) {
+		if (caller.equals(Server.getLocalClient())) {
 			caller.send("Client-only command.");
 			return;
 		}
@@ -23,10 +23,10 @@ public class LeaveChannel implements Command {
 
 		try {
 			selectedChannel.remove(caller);
-			if (caller.primaryChannel.equals(selectedChannel))
-				caller.primaryChannel = Server.getChannels().get(0);
+			if (caller.getPrimaryChannel().equals(selectedChannel))
+				caller.setPrimaryChannel(Server.getChannels().get(0));
 			caller.send(new MessagePacket("You left channel " + args[0] + ".", MessageType.COMMAND));
-			caller.send(new MessagePacket("You are now speaking in channel " + caller.primaryChannel.name + ".",
+			caller.send(new MessagePacket("You are now speaking in channel " + caller.getPrimaryChannel().name + ".",
 					MessageType.COMMAND));
 		} catch (NullPointerException ex) {
 			caller.send(new MessagePacket("No channel named " + args[0] + ".", MessageType.ERROR));