// Path: server/brownshome/scriptwars/connection/ConnectionHandler.java
// public abstract class ConnectionHandler<CONNECTION> {
// 	protected abstract void sendRawData(CONNECTION id, ByteBuffer... data);
// 	
// 	public abstract int getProtocolByte();
// 	public abstract void closeConnectionHandler();
// 	
// 	public void sendTimeOut(CONNECTION connection) {
// 		sendRawData(connection, ByteBuffer.wrap(new byte[] {2}));
// 		closeConnection(connection);
// 	}
// 
// 	public void sendEndGame(CONNECTION connection) {
// 		sendRawData(connection, ByteBuffer.wrap(new byte[] {1}));
// 		closeConnection(connection);
// 	}
// 
// 	public void sendError(CONNECTION connection, String message) {
// 		sendRawData(connection, ByteBuffer.wrap(new byte[] {-1}), ConnectionUtil.stringToBuffer(message));
// 		closeConnection(connection);
// 	}
// 	
// 	public void sendData(CONNECTION connection, ByteBuffer data) {
// 		sendRawData(connection, ByteBuffer.wrap(new byte[] {0}), data);
// 	}
// 	
// 	public static String getInvalidIDError(Game game) {
// 		try {
// 			return "That ID is old, or invalid. Here is a now valid ID " + game.getType().getUserID()
// 					+ " (This may or may not be the same ID)";
// 		} catch(GameCreationException e)  {
// 			return "That has not been requested. Unable to genenerate a new one.";
// 		}
// 	}
// 	
// 	protected void closeConnection(CONNECTION connection) {}
// }
// 
// Path: server/brownshome/scriptwars/connection/InvalidIDException.java
// public class InvalidIDException extends Exception {}
// 
// Path: server/brownshome/scriptwars/connection/MemoryConnectionHandler.java
// public class MemoryConnectionHandler extends ConnectionHandler<SynchronousQueue<ByteBuffer>> {
// 	private static MemoryConnectionHandler instance;
// 	
// 	public static MemoryConnectionHandler instance() {
// 		if(instance == null) {
// 			instance = new MemoryConnectionHandler();
// 		}
// 		
// 		return instance;
// 	}
// 	
// 	private final int MEMORY_PROTOCOL_BYTE = 3;
// 	
// 	@Override
// 	protected void sendRawData(SynchronousQueue<ByteBuffer> queue, ByteBuffer... data) {
// 		int length = 0;
// 		for(ByteBuffer b : data) {
// 			length += b.remaining();
// 		}
// 		ByteBuffer total = ByteBuffer.allocate(length);
// 		for(ByteBuffer b : data) {
// 			total.put(b);
// 		}
// 		total.flip();
// 		
// 		//If the packet is not ready to be received drop it.
// 		queue.offer(total);
// 	}
// 
// 	@Override
// 	public int getProtocolByte() {
// 		return MEMORY_PROTOCOL_BYTE;
// 	}
// 
// 	@Override
// 	public void closeConnectionHandler() {}
// 
// 	public Consumer<ByteBuffer> join(ByteBuffer firstPacket, SynchronousQueue<ByteBuffer> input) throws InvalidIDException {
// 		int ID = firstPacket.getInt();
// 		
// 		if(Player.getPlayerFromID(ID) != null) {
// 			throw new InvalidIDException();
// 		}
// 		
// 		Player<SynchronousQueue<ByteBuffer>> player = new Player<>(ID, ConnectionUtil.bufferToString(firstPacket), this, input);
// 		
// 		synchronized(player.getGame()) {
// 			player.addPlayer();
// 		}
// 		
// 		return buffer -> handleData(buffer, player);
// 	}
// 
// 	private void handleData(ByteBuffer buffer, Player<SynchronousQueue<ByteBuffer>> player) {
// 		try {
// 			synchronized(player.getGame()) {
// 				player.incommingData(buffer);
// 			}
// 		} catch(Exception e) {
// 			player.sendError(e.getMessage());
// 		}
// 	}
// }
// 
// Path: server/brownshome/scriptwars/server/Server.java
// public class Server {
// 	public static final Logger LOG = Logger.getLogger("brownshome.scriptwars.server");
// 	
// 	private static volatile boolean stop = false;
// 	
// 	public static void initialize() {
// 		try {
// 			GameType.addType(TankGame.class, Difficulty.EASY);
// 		} catch (GameCreationException gce) {
// 			Server.LOG.log(Level.SEVERE, "Improperly built game files.", gce);
// 		}
// 	}
// 	
// 	public static Collection<GameType> getGames() {
// 		return GameType.getGameTypes();
// 	}
// 
// 	public static void shutdown() {
// 		stop = true;
// 		UDPConnectionHandler.instance().closeConnectionHandler();
// 		TCPConnectionHandler.instance().closeConnectionHandler();
// 		MemoryConnectionHandler.instance().closeConnectionHandler();
// 	}
// 	
// 	public static boolean shouldStop() {
// 		return stop;
// 	}
// }


import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.time.LocalTime;
import java.time.temporal.ChronoUnit;
import java.util.function.Function;
import brownshome.scriptwars.connection.ConnectionHandler;
import brownshome.scriptwars.connection.InvalidIDException;
import brownshome.scriptwars.connection.MemoryConnectionHandler;
import brownshome.scriptwars.server.Server;
package brownshome.scriptwars.game;



//This class needs to be in the common package for compilation of uses of the Tank class. Not sure why.
//Any use of this class will result in ClassNotFoundExceptions

/** Holds the identifying information for each connected member.
 * This class is suitable for using as a key in a Map */
public class Player<CONNECTION> {
	public static final Color[] colours = {
		Color.RED, 
		Color.GREEN, 
		Color.CYAN, 
		Color.BLUE, 
		Color.MAGENTA, 
		Color.PINK, 
// Path: server/brownshome/scriptwars/connection/ConnectionHandler.java
// public abstract class ConnectionHandler<CONNECTION> {
// 	protected abstract void sendRawData(CONNECTION id, ByteBuffer... data);
// 	
// 	public abstract int getProtocolByte();
// 	public abstract void closeConnectionHandler();
// 	
// 	public void sendTimeOut(CONNECTION connection) {
// 		sendRawData(connection, ByteBuffer.wrap(new byte[] {2}));
// 		closeConnection(connection);
// 	}
// 
// 	public void sendEndGame(CONNECTION connection) {
// 		sendRawData(connection, ByteBuffer.wrap(new byte[] {1}));
// 		closeConnection(connection);
// 	}
// 
// 	public void sendError(CONNECTION connection, String message) {
// 		sendRawData(connection, ByteBuffer.wrap(new byte[] {-1}), ConnectionUtil.stringToBuffer(message));
// 		closeConnection(connection);
// 	}
// 	
// 	public void sendData(CONNECTION connection, ByteBuffer data) {
// 		sendRawData(connection, ByteBuffer.wrap(new byte[] {0}), data);
// 	}
// 	
// 	public static String getInvalidIDError(Game game) {
// 		try {
// 			return "That ID is old, or invalid. Here is a now valid ID " + game.getType().getUserID()
// 					+ " (This may or may not be the same ID)";
// 		} catch(GameCreationException e)  {
// 			return "That has not been requested. Unable to genenerate a new one.";
// 		}
// 	}
// 	
// 	protected void closeConnection(CONNECTION connection) {}
// }
// 
// Path: server/brownshome/scriptwars/connection/InvalidIDException.java
// public class InvalidIDException extends Exception {}
// 
// Path: server/brownshome/scriptwars/connection/MemoryConnectionHandler.java
// public class MemoryConnectionHandler extends ConnectionHandler<SynchronousQueue<ByteBuffer>> {
// 	private static MemoryConnectionHandler instance;
// 	
// 	public static MemoryConnectionHandler instance() {
// 		if(instance == null) {
// 			instance = new MemoryConnectionHandler();
// 		}
// 		
// 		return instance;
// 	}
// 	
// 	private final int MEMORY_PROTOCOL_BYTE = 3;
// 	
// 	@Override
// 	protected void sendRawData(SynchronousQueue<ByteBuffer> queue, ByteBuffer... data) {
// 		int length = 0;
// 		for(ByteBuffer b : data) {
// 			length += b.remaining();
// 		}
// 		ByteBuffer total = ByteBuffer.allocate(length);
// 		for(ByteBuffer b : data) {
// 			total.put(b);
// 		}
// 		total.flip();
// 		
// 		//If the packet is not ready to be received drop it.
// 		queue.offer(total);
// 	}
// 
// 	@Override
// 	public int getProtocolByte() {
// 		return MEMORY_PROTOCOL_BYTE;
// 	}
// 
// 	@Override
// 	public void closeConnectionHandler() {}
// 
// 	public Consumer<ByteBuffer> join(ByteBuffer firstPacket, SynchronousQueue<ByteBuffer> input) throws InvalidIDException {
// 		int ID = firstPacket.getInt();
// 		
// 		if(Player.getPlayerFromID(ID) != null) {
// 			throw new InvalidIDException();
// 		}
// 		
// 		Player<SynchronousQueue<ByteBuffer>> player = new Player<>(ID, ConnectionUtil.bufferToString(firstPacket), this, input);
// 		
// 		synchronized(player.getGame()) {
// 			player.addPlayer();
// 		}
// 		
// 		return buffer -> handleData(buffer, player);
// 	}
// 
// 	private void handleData(ByteBuffer buffer, Player<SynchronousQueue<ByteBuffer>> player) {
// 		try {
// 			synchronized(player.getGame()) {
// 				player.incommingData(buffer);
// 			}
// 		} catch(Exception e) {
// 			player.sendError(e.getMessage());
// 		}
// 	}
// }
// 
// Path: server/brownshome/scriptwars/server/Server.java
// public class Server {
// 	public static final Logger LOG = Logger.getLogger("brownshome.scriptwars.server");
// 	
// 	private static volatile boolean stop = false;
// 	
// 	public static void initialize() {
// 		try {
// 			GameType.addType(TankGame.class, Difficulty.EASY);
// 		} catch (GameCreationException gce) {
// 			Server.LOG.log(Level.SEVERE, "Improperly built game files.", gce);
// 		}
// 	}
// 	
// 	public static Collection<GameType> getGames() {
// 		return GameType.getGameTypes();
// 	}
// 
// 	public static void shutdown() {
// 		stop = true;
// 		UDPConnectionHandler.instance().closeConnectionHandler();
// 		TCPConnectionHandler.instance().closeConnectionHandler();
// 		MemoryConnectionHandler.instance().closeConnectionHandler();
// 	}
// 	
// 	public static boolean shouldStop() {
// 		return stop;
// 	}
// }


// Path: client/java/brownshome/scriptwars/game/Player.java
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.time.LocalTime;
import java.time.temporal.ChronoUnit;
import java.util.function.Function;
import brownshome.scriptwars.connection.ConnectionHandler;
import brownshome.scriptwars.connection.InvalidIDException;
import brownshome.scriptwars.connection.MemoryConnectionHandler;
import brownshome.scriptwars.server.Server;

package brownshome.scriptwars.game;



//This class needs to be in the common package for compilation of uses of the Tank class. Not sure why.
//Any use of this class will result in ClassNotFoundExceptions

/** Holds the identifying information for each connected member.
 * This class is suitable for using as a key in a Map */
public class Player<CONNECTION> {
	public static final Color[] colours = {
		Color.RED, 
		Color.GREEN, 
		Color.CYAN, 
		Color.BLUE, 
		Color.MAGENTA, 
		Color.PINK, 
		Color.YELLOW.darker(), 