Merge branch 'master' into story_64_sails
# Conflicts: # racevisionGame/src/main/java/mock/app/MockOutput.java # racevisionGame/src/main/java/mock/model/MockRace.java # racevisionGame/src/main/java/mock/model/commandFactory/CommandFactory.java # racevisionGame/src/main/java/network/MessageDecoders/BoatActionDecoder.java # racevisionGame/src/main/java/network/MessageDecoders/BoatLocationDecoder.java # racevisionGame/src/main/java/visualiser/app/VisualiserInput.java # racevisionGame/src/main/java/visualiser/gameController/ControllerServer.java # racevisionGame/src/main/java/visualiser/model/ResizableRaceCanvas.java # racevisionGame/src/main/java/visualiser/model/VisualiserRace.java # racevisionGame/src/main/resources/visualiser/scenes/connect.fxml # racevisionGame/src/main/resources/visualiser/scenes/lobby.fxml # racevisionGame/src/test/java/mock/model/MockRaceTest.java # racevisionGame/src/test/java/network/Utils/AC35UnitConverterTest.java # racevisionGame/src/test/java/network/XMLMessageEncoderTest.java
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
package visualiser.gameController;
|
||||
|
||||
import network.BinaryMessageEncoder;
|
||||
import network.Exceptions.InvalidMessageException;
|
||||
import network.MessageEncoders.RaceVisionByteEncoder;
|
||||
import network.Messages.AC35Data;
|
||||
import network.Messages.BoatAction;
|
||||
import network.Messages.Enums.BoatActionEnum;
|
||||
import network.Messages.Enums.MessageType;
|
||||
@@ -11,57 +13,41 @@ import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.Socket;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* Basic service for sending key presses to game server
|
||||
*/
|
||||
public class ControllerClient {
|
||||
/**
|
||||
* Socket to server
|
||||
*/
|
||||
Socket socket;
|
||||
|
||||
/**
|
||||
* Output stream wrapper for socket to server
|
||||
* Queue of messages to be sent to server.
|
||||
*/
|
||||
DataOutputStream outputStream;
|
||||
private BlockingQueue<AC35Data> outgoingMessages;
|
||||
|
||||
/**
|
||||
* Initialise controller client with live socket.
|
||||
* @param socket to server
|
||||
* @param outgoingMessages Queue to place messages on to send to server.
|
||||
*/
|
||||
public ControllerClient(Socket socket) {
|
||||
this.socket = socket;
|
||||
|
||||
try {
|
||||
this.outputStream = new DataOutputStream(socket.getOutputStream());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
public ControllerClient(BlockingQueue<AC35Data> outgoingMessages) {
|
||||
this.outgoingMessages = outgoingMessages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a keypress to server
|
||||
* @param key to send
|
||||
* @throws IOException if socket write fails
|
||||
* @throws InterruptedException If thread is interrupted while writing message to outgoing message queue.
|
||||
*/
|
||||
public void sendKey(ControlKey key) throws IOException {
|
||||
public void sendKey(ControlKey key) throws InterruptedException {
|
||||
BoatActionEnum protocolCode = key.getProtocolCode();
|
||||
if(protocolCode != BoatActionEnum.NOT_A_STATUS) {
|
||||
|
||||
byte[] bytes = new byte[4];
|
||||
ByteBuffer.wrap(bytes).putInt(protocolCode.getValue());
|
||||
BoatActionEnum boatActionEnum = BoatActionEnum.fromByte(bytes[3]);
|
||||
BoatAction boatAction = new BoatAction(protocolCode);
|
||||
|
||||
BoatAction boatAction = new BoatAction(boatActionEnum);
|
||||
outgoingMessages.put(boatAction);
|
||||
|
||||
byte[] encodedBoatAction = RaceVisionByteEncoder.boatActionMessage(boatAction);
|
||||
|
||||
BinaryMessageEncoder binaryMessage = new BinaryMessageEncoder(MessageType.BOATACTION, System.currentTimeMillis(), 0,
|
||||
(short) encodedBoatAction.length, encodedBoatAction);
|
||||
|
||||
System.out.println("Sending out key: " + boatActionEnum);
|
||||
outputStream.write(binaryMessage.getFullMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,78 +1,102 @@
|
||||
package visualiser.gameController;
|
||||
|
||||
import mock.model.RaceLogic;
|
||||
import mock.exceptions.CommandConstructionException;
|
||||
import mock.model.MockRace;
|
||||
import mock.model.commandFactory.Command;
|
||||
import mock.model.commandFactory.CommandFactory;
|
||||
import network.BinaryMessageDecoder;
|
||||
import network.MessageDecoders.BoatActionDecoder;
|
||||
import network.Messages.Enums.BoatActionEnum;
|
||||
import mock.model.commandFactory.CompositeCommand;
|
||||
import network.Messages.AC35Data;
|
||||
import network.Messages.BoatAction;
|
||||
import network.Messages.Enums.MessageType;
|
||||
import shared.model.RunnableWithFramePeriod;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.Socket;
|
||||
import java.util.Observable;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* Service for dispatching key press data to race from client
|
||||
*/
|
||||
public class ControllerServer extends Observable implements Runnable {
|
||||
/**
|
||||
* Socket to client
|
||||
*/
|
||||
private Socket socket;
|
||||
/**
|
||||
* Wrapper for input from client
|
||||
*/
|
||||
private DataInputStream inputStream;
|
||||
/**
|
||||
* Last received boat action
|
||||
*/
|
||||
private BoatActionEnum action;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private RaceLogic rc;
|
||||
public class ControllerServer implements RunnableWithFramePeriod {
|
||||
|
||||
|
||||
/**
|
||||
* Initialise server-side controller with live client socket
|
||||
* @param socket to client
|
||||
* Queue of incoming messages from client.
|
||||
*/
|
||||
public ControllerServer(Socket socket, RaceLogic rc) {
|
||||
this.socket = socket;
|
||||
this.rc = rc;
|
||||
this.addObserver(rc);
|
||||
try {
|
||||
this.inputStream = new DataInputStream(this.socket.getInputStream());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
private BlockingQueue<AC35Data> inputQueue;
|
||||
|
||||
|
||||
/**
|
||||
* Collection of commands from client for race to execute.
|
||||
*/
|
||||
private CompositeCommand compositeCommand;
|
||||
|
||||
/**
|
||||
* The context for each command.
|
||||
*/
|
||||
private MockRace raceState;
|
||||
|
||||
/**
|
||||
* This is the source ID associated with the client.
|
||||
*/
|
||||
private int clientSourceID;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Initialise server-side controller with live client socket.
|
||||
* @param compositeCommand Commands for the race to execute.
|
||||
* @param inputQueue The queue of messages to read from.
|
||||
* @param clientSourceID The source ID of the client's boat.
|
||||
* @param raceState The context for each command.
|
||||
*/
|
||||
public ControllerServer(CompositeCommand compositeCommand, BlockingQueue<AC35Data> inputQueue, int clientSourceID, MockRace raceState) {
|
||||
this.compositeCommand = compositeCommand;
|
||||
this.inputQueue = inputQueue;
|
||||
this.clientSourceID = clientSourceID;
|
||||
this.raceState = raceState;
|
||||
}
|
||||
|
||||
public BoatActionEnum getAction() {
|
||||
return action;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Wait for controller key input from client and loop.
|
||||
*/
|
||||
@Override
|
||||
public void run() {
|
||||
while(true) {
|
||||
byte[] message = new byte[20];
|
||||
try {
|
||||
if (inputStream.available() > 0) {
|
||||
inputStream.read(message);
|
||||
BinaryMessageDecoder encodedMessage = new BinaryMessageDecoder(message);
|
||||
BoatActionDecoder boatActionDecoder = new BoatActionDecoder(encodedMessage.getMessageBody());
|
||||
action = boatActionDecoder.getBoatAction();
|
||||
while(!Thread.interrupted()) {
|
||||
|
||||
// Notify observers of most recent action
|
||||
this.setChanged();
|
||||
this.notifyObservers();
|
||||
try {
|
||||
|
||||
AC35Data message = inputQueue.take();
|
||||
|
||||
if (message.getType() == MessageType.BOATACTION) {
|
||||
|
||||
BoatAction boatAction = (BoatAction) message;
|
||||
|
||||
|
||||
boatAction.setSourceID(clientSourceID);
|
||||
|
||||
try {
|
||||
Command command = CommandFactory.createCommand(raceState, boatAction);
|
||||
compositeCommand.addCommand(command);
|
||||
|
||||
} catch (CommandConstructionException e) {
|
||||
Logger.getGlobal().log(Level.WARNING, "ControllerServer could not create a Command for BoatAction: " + boatAction + ".", e);
|
||||
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
|
||||
|
||||
} catch (InterruptedException e) {
|
||||
Logger.getGlobal().log(Level.WARNING, "ControllerServer Interrupted while waiting for message on incoming message queue.", e);
|
||||
Thread.currentThread().interrupt();
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ public class InputChecker {
|
||||
ControlKey controlKey = keyFactory.getKey(codeString);
|
||||
if (controlKey != null) {
|
||||
controlKey.onAction();
|
||||
System.out.println(controlKey.toString() + " is Pressed.");
|
||||
// System.out.println(controlKey.toString() + " is Pressed.");
|
||||
}
|
||||
currentlyActiveKeys.put(codeString, true);
|
||||
}
|
||||
@@ -37,7 +37,7 @@ public class InputChecker {
|
||||
ControlKey controlKey = keyFactory.getKey(codeString);
|
||||
if (controlKey != null) {
|
||||
controlKey.onRelease();
|
||||
System.out.println(controlKey.toString() + " is Released.");
|
||||
// System.out.println(controlKey.toString() + " is Released.");
|
||||
}
|
||||
currentlyActiveKeys.remove(event.getCode().toString());
|
||||
});
|
||||
@@ -49,7 +49,7 @@ public class InputChecker {
|
||||
ControlKey controlKey = keyFactory.getKey(key);
|
||||
if (controlKey != null){
|
||||
controlKey.onHold();
|
||||
System.out.println(controlKey.toString() + " is Held.");
|
||||
// System.out.println(controlKey.toString() + " is Held.");
|
||||
}
|
||||
}
|
||||
// for (String key : InputKeys.stringKeysMap.keySet()){
|
||||
|
||||
Reference in New Issue
Block a user