summaryrefslogtreecommitdiff
path: root/src/tesseract/objects/remote
diff options
context:
space:
mode:
Diffstat (limited to 'src/tesseract/objects/remote')
-rw-r--r--src/tesseract/objects/remote/KeyInfo.java20
-rw-r--r--src/tesseract/objects/remote/RemoteObject.java122
-rw-r--r--src/tesseract/objects/remote/RemoteObjectCommunicator.java118
-rw-r--r--src/tesseract/objects/remote/RemoteObjectMenu.java24
4 files changed, 277 insertions, 7 deletions
diff --git a/src/tesseract/objects/remote/KeyInfo.java b/src/tesseract/objects/remote/KeyInfo.java
new file mode 100644
index 0000000..844ee24
--- /dev/null
+++ b/src/tesseract/objects/remote/KeyInfo.java
@@ -0,0 +1,20 @@
+package tesseract.objects.remote;
+
+import java.io.Serializable;
+
+public class KeyInfo implements Serializable {
+ /**
+ * Serial UID.
+ */
+ private static final long serialVersionUID = -1378329597453071920L;
+
+ private int keyCode;
+
+ public KeyInfo(int keyCode) {
+ this.keyCode = keyCode;
+ }
+
+ public int getKeyCode() {
+ return keyCode;
+ }
+}
diff --git a/src/tesseract/objects/remote/RemoteObject.java b/src/tesseract/objects/remote/RemoteObject.java
index e3edc1c..32f5a11 100644
--- a/src/tesseract/objects/remote/RemoteObject.java
+++ b/src/tesseract/objects/remote/RemoteObject.java
@@ -1,6 +1,14 @@
package tesseract.objects.remote;
import java.awt.event.KeyEvent;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.util.UUID;
import javax.vecmath.Vector3f;
@@ -22,16 +30,51 @@ public abstract class RemoteObject extends PhysicalObject {
*/
protected static final float STEP = 0.01f;
+ /**
+ * Unique object id.
+ */
+ private UUID myId;
+
+ /**
+ * The home address.
+ */
+ private SocketAddress myHome;
+
+ /**
+ * The local computer address.
+ */
+ transient private boolean isLocal;
+
+ /**
+ * The socket.
+ */
+ transient private RemoteObjectReciever myListener;
+
+ /**
+ *
+ * @param thePosition
+ * @param mass
+ */
public RemoteObject(Vector3f thePosition, float mass) {
super(thePosition, mass);
+
+ myId = UUID.randomUUID();
+ isLocal = true;
}
-
+
+ public void setHome(SocketAddress home) {
+ myHome = home;
+
+ myListener = new RemoteObjectReciever();
+ new Thread(myListener).start();
+ }
+
/**
* This method is called when a key event is received.
*
* @param event The KeyEvent recieved
*/
- protected void keyEventReceived(final KeyEvent event) {
+ protected void keyEventReceived(final KeyInfo event) {
switch (event.getKeyCode()) {
case KeyEvent.VK_W:
velocity.z -= STEP;
@@ -57,17 +100,84 @@ public abstract class RemoteObject extends PhysicalObject {
* @return The object's name for the menu.
*/
public abstract String getName();
+
+ public UUID getId() {
+ return myId;
+ }
/**
* Send a KeyEvent to this remote object.
*
* @param keyEvent The key event
*/
- public void sendKeyEvent(final KeyEvent keyEvent) {
- // TODO: Send this event over the network if necessary.
+ public void sendKeyEvent(final KeyInfo keyEvent) {
keyEventReceived(keyEvent);
-
updateTranformGroup();
}
-
+
+
+ private void readObject(ObjectInputStream in)
+ throws IOException, ClassNotFoundException {
+ in.defaultReadObject();
+
+ // Start Socket Thread
+ myListener = new RemoteObjectReciever();
+ new Thread(myListener).start();
+
+ }
+
+ private void writeObject(ObjectOutputStream out)
+ throws IOException {
+ out.defaultWriteObject();
+
+ myListener.stop();
+ }
+
+ private class RemoteObjectReciever implements Runnable {
+ private Socket mySocket;
+
+ public void stop() {
+ try {
+ mySocket.close();
+
+ } catch (IOException e) {
+ }
+ }
+
+ public void run() {
+ mySocket = new Socket();
+
+ try {
+ System.out.println("Connecting to " + myHome);
+ mySocket.connect(myHome);
+
+ // Send id
+ DataOutputStream out = new DataOutputStream(mySocket.getOutputStream());
+ out.writeLong(myId.getMostSignificantBits());
+ out.writeLong(myId.getLeastSignificantBits());
+ out.flush();
+
+ // Wait for data
+ DataInputStream in = new DataInputStream(mySocket.getInputStream());
+
+ while (true) {
+ try {
+ int key = in.readInt();
+
+ KeyInfo event = new KeyInfo(key);
+
+ sendKeyEvent(event);
+
+ } catch (Exception e) {
+ System.err.println("Could not read KeyEvent: " + e);
+ break;
+ }
+ }
+
+ } catch (IOException e) {
+ System.err.println(e);
+ }
+ }
+
+ }
}
diff --git a/src/tesseract/objects/remote/RemoteObjectCommunicator.java b/src/tesseract/objects/remote/RemoteObjectCommunicator.java
new file mode 100644
index 0000000..8c8dc11
--- /dev/null
+++ b/src/tesseract/objects/remote/RemoteObjectCommunicator.java
@@ -0,0 +1,118 @@
+package tesseract.objects.remote;
+
+import java.awt.event.KeyEvent;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.HashMap;
+import java.util.UUID;
+
+public class RemoteObjectCommunicator implements Runnable {
+
+ private static final int BASE_PORT = 5551;
+
+ private ServerSocket mySocket;
+
+ private HashMap<UUID, Socket> mySockets;
+
+ private boolean myRunning;
+
+ public RemoteObjectCommunicator() {
+ mySockets = new HashMap<UUID, Socket>();
+ myRunning = false;
+ }
+
+
+ public void run() {
+ int port = BASE_PORT;
+
+ // Find an open port.
+ while (true) {
+ try {
+ mySocket = new ServerSocket(port);
+ myRunning = true;
+ break;
+
+ } catch (IOException e) {
+ port++;
+
+ } catch (Exception e) {
+ System.err.println(e);
+ return;
+ }
+ }
+
+ // Listen for connections
+ while (myRunning) {
+ try {
+ Socket s = mySocket.accept();
+
+ handleNewSocket(s);
+
+ } catch (IOException e) {
+ System.err.println(e);
+ }
+ }
+ }
+
+ public boolean sendKeyToObject(UUID id, KeyEvent event) {
+ Socket s = mySockets.get(id);
+
+ if (s != null && s.isConnected()) {
+ try {
+ DataOutputStream out = new DataOutputStream(s.getOutputStream());
+ out.writeInt(event.getKeyCode());
+ out.flush();
+
+ return true;
+
+ } catch (IOException e) {
+ mySockets.remove(id);
+ // TODO: REMOVE
+ System.out.println(id + " Exception. " + e);
+ return false;
+ }
+
+ } else {
+ // TODO: REMOVE
+ System.out.println(id + " has not called home.");
+ return false;
+ }
+ }
+
+ private void handleNewSocket(final Socket socket) {
+ try {
+ // TODO: Remove
+ System.out.println("New Socket");
+ DataInputStream in = new DataInputStream(socket.getInputStream());
+
+ long msb = in.readLong();
+ long lsb = in.readLong();
+
+ UUID id = new UUID(msb, lsb);
+
+ System.out.println("Id is " + id);
+
+ mySockets.put(id, socket);
+
+ } catch (Exception e) {
+ System.err.println(e);
+ }
+ }
+
+
+ public int getPort() {
+ System.out.print("Blocking for address.");
+ while (mySocket == null) {
+ // Block until we get a socket.
+ System.out.print(".");
+ }
+
+ System.out.println();
+
+ return mySocket.getLocalPort();
+ }
+
+}
diff --git a/src/tesseract/objects/remote/RemoteObjectMenu.java b/src/tesseract/objects/remote/RemoteObjectMenu.java
index bb076d1..610c433 100644
--- a/src/tesseract/objects/remote/RemoteObjectMenu.java
+++ b/src/tesseract/objects/remote/RemoteObjectMenu.java
@@ -3,6 +3,10 @@ package tesseract.objects.remote;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.net.UnknownHostException;
import java.util.ArrayList;
import javax.swing.JCheckBoxMenuItem;
@@ -21,12 +25,25 @@ public class RemoteObjectMenu extends JMenu {
private World myWorld;
+ private RemoteObjectCommunicator myCommunicator;
+
+ private SocketAddress myHome;
+
public RemoteObjectMenu(final World theWorld) {
super("RC Objects");
// Added by Steve: Fixes viewing menu problem with Canvas3D on both my windows machines
JPopupMenu.setDefaultLightWeightPopupEnabled(false);
myWorld = theWorld;
myControlledObjects = new ArrayList<RemoteObject>();
+ myCommunicator = new RemoteObjectCommunicator();
+ new Thread(myCommunicator).start();
+
+ try {
+ myHome = new InetSocketAddress(InetAddress.getLocalHost(), myCommunicator.getPort());
+
+ } catch (UnknownHostException e) {
+ System.err.println(e);
+ }
// Objects that can be added
add(new TankMenuItem(this));
@@ -56,13 +73,18 @@ public class RemoteObjectMenu extends JMenu {
myWorld.addObject(theObject);
myControlledObjects.add(theObject);
+ theObject.setHome(myHome);
item.setSelected(true);
add(item);
}
public void sendKeyToObjects(final KeyEvent e) {
for (RemoteObject o : myControlledObjects) {
- o.sendKeyEvent(e);
+ if (!myCommunicator.sendKeyToObject(o.getId(), e)) {
+ System.out.println("Send failed to " + o.getId());
+ //myControlledObjects.remove(o);
+ // TODO : Remove from menu.
+ }
}
}
}