diff --git a/.idea/workspace.xml b/.idea/workspace.xml index bba76bb3446b239c997ee19683b5768a2833a7a9..9b0e1e27dacc517670d8b495c463815c8ca98895 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -2,9 +2,13 @@ <project version="4"> <component name="ChangeListManager"> <list default="true" id="688d774d-cfc7-4b0d-b00c-5ca931aba600" name="Default Changelist" comment=""> +<<<<<<< HEAD <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/GUI/StartScreen.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/GUI/StartScreen.java" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/client/ClientUpdate.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/client/ClientUpdate.java" afterDir="false" /> +======= + <change beforePath="$PROJECT_DIR$/src/remote/EncryptDecrypt.java" beforeDir="false" /> +>>>>>>> 19305992ee94a557e367a23125776d065bedb8bb </list> <option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" /> <option name="SHOW_DIALOG" value="false" /> @@ -31,19 +35,13 @@ </map> </option> </component> - <component name="ProjectConfigurationFiles"> - <option name="files"> - <list> - <option value="$PROJECT_DIR$/.idea/uiDesigner.xml" /> - </list> - </option> - </component> <component name="ProjectId" id="1SVgnDiSFxSanFbLYY5D9RJaXPS" /> <component name="PropertiesComponent"> <property name="SHARE_PROJECT_CONFIGURATION_FILES" value="true" /> <property name="UI_DESIGNER_EDITOR_MODE.UIDesignerToolWindowManager.WIDTH" value="387" /> <property name="WebServerToolWindowFactoryState" value="false" /> <property name="aspect.path.notification.shown" value="true" /> + <property name="extract.method.default.visibility" value="private" /> <property name="last_opened_file_path" value="$PROJECT_DIR$/../Git Projects" /> <property name="nodejs_interpreter_path.stuck_in_default_project" value="undefined stuck path" /> <property name="nodejs_npm_path_reset_for_default_project" value="true" /> @@ -63,7 +61,46 @@ </list> </option> </component> - <component name="RunManager" selected="Application.Client2"> + <component name="RunManager" selected="Application.Client1"> + <configuration name="AlbumTrackTable" type="Application" factoryName="Application" temporary="true" nameIsGenerated="true"> + <option name="MAIN_CLASS_NAME" value="client.AlbumTrackTable" /> + <module name="infinitymonkeys" /> + <extension name="coverage"> + <pattern> + <option name="PATTERN" value="client.*" /> + <option name="ENABLED" value="true" /> + </pattern> + </extension> + <method v="2"> + <option name="Make" enabled="true" /> + </method> + </configuration> + <configuration name="BlinkColorTextField" type="Application" factoryName="Application" temporary="true" nameIsGenerated="true"> + <option name="MAIN_CLASS_NAME" value="client.BlinkColorTextField" /> + <module name="infinitymonkeys" /> + <extension name="coverage"> + <pattern> + <option name="PATTERN" value="client.*" /> + <option name="ENABLED" value="true" /> + </pattern> + </extension> + <method v="2"> + <option name="Make" enabled="true" /> + </method> + </configuration> + <configuration name="BlinkingPrototype" type="Application" factoryName="Application" temporary="true" nameIsGenerated="true"> + <option name="MAIN_CLASS_NAME" value="client.BlinkingPrototype" /> + <module name="infinitymonkeys" /> + <extension name="coverage"> + <pattern> + <option name="PATTERN" value="client.*" /> + <option name="ENABLED" value="true" /> + </pattern> + </extension> + <method v="2"> + <option name="Make" enabled="true" /> + </method> + </configuration> <configuration name="Client 3" type="Application" factoryName="Application"> <option name="MAIN_CLASS_NAME" value="client.Client" /> <module name="infinitymonkeys" /> @@ -96,12 +133,52 @@ <option name="Make" enabled="true" /> </method> </configuration> + <configuration name="TestList" type="Application" factoryName="Application" temporary="true" nameIsGenerated="true"> + <option name="MAIN_CLASS_NAME" value="client.TestList" /> + <module name="infinitymonkeys" /> + <extension name="coverage"> + <pattern> + <option name="PATTERN" value="client.*" /> + <option name="ENABLED" value="true" /> + </pattern> + </extension> + <method v="2"> + <option name="Make" enabled="true" /> + </method> + </configuration> + <configuration name="WhiteYellow" type="Application" factoryName="Application" temporary="true" nameIsGenerated="true"> + <option name="MAIN_CLASS_NAME" value="client.WhiteYellow" /> + <module name="infinitymonkeys" /> + <extension name="coverage"> + <pattern> + <option name="PATTERN" value="client.*" /> + <option name="ENABLED" value="true" /> + </pattern> + </extension> + <method v="2"> + <option name="Make" enabled="true" /> + </method> + </configuration> <list> <item itemvalue="Application.Server" /> <item itemvalue="Application.Client1" /> <item itemvalue="Application.Client2" /> <item itemvalue="Application.Client 3" /> + <item itemvalue="Application.BlinkingPrototype" /> + <item itemvalue="Application.WhiteYellow" /> + <item itemvalue="Application.AlbumTrackTable" /> + <item itemvalue="Application.TestList" /> + <item itemvalue="Application.BlinkColorTextField" /> </list> + <recent_temporary> + <list> + <item itemvalue="Application.BlinkColorTextField" /> + <item itemvalue="Application.BlinkingPrototype" /> + <item itemvalue="Application.TestList" /> + <item itemvalue="Application.WhiteYellow" /> + <item itemvalue="Application.AlbumTrackTable" /> + </list> + </recent_temporary> </component> <component name="SvnConfiguration"> <configuration /> @@ -116,6 +193,8 @@ <workItem from="1571631723795" duration="17601000" /> <workItem from="1571654347656" duration="25114000" /> <workItem from="1571786278739" duration="3319000" /> + <workItem from="1571915914956" duration="3985000" /> + <workItem from="1571955297053" duration="15040000" /> </task> <task id="LOCAL-00001" summary="Changed the join method to send over a reference of the ClientUpdate Interface"> <created>1571646862883</created> @@ -124,7 +203,14 @@ <option name="project" value="LOCAL" /> <updated>1571646862883</updated> </task> - <option name="localTasksCounter" value="2" /> + <task id="LOCAL-00002" summary="Changed the join method to send over a reference of the ClientUpdate Interface"> + <created>1571974791259</created> + <option name="number" value="00002" /> + <option name="presentableId" value="LOCAL-00002" /> + <option name="project" value="LOCAL" /> + <updated>1571974791259</updated> + </task> + <option name="localTasksCounter" value="3" /> <servers /> </component> <component name="TypeScriptGeneratedFilesManager"> @@ -157,6 +243,17 @@ <MESSAGE value="Changed the join method to send over a reference of the ClientUpdate Interface" /> <option name="LAST_COMMIT_MESSAGE" value="Changed the join method to send over a reference of the ClientUpdate Interface" /> </component> + <component name="XDebuggerManager"> + <breakpoint-manager> + <breakpoints> + <line-breakpoint enabled="true" type="java-line"> + <url>file://$PROJECT_DIR$/src/client/DrawingUpdate.java</url> + <line>25</line> + <option name="timeStamp" value="4" /> + </line-breakpoint> + </breakpoints> + </breakpoint-manager> + </component> <component name="simpleUML.UMLToolWindowPlugin"> <General> <option name="birdViewUpdateDelay" value="2000" /> diff --git a/out/production/infinitymonkeys/GUI/DrawingArea$1.class b/out/production/infinitymonkeys/GUI/DrawingArea$1.class index a5d5ee5210fdb61d23059b9ae70b3b0033f522b0..96a52d48af1a7c92a8da76ff8c9b50aae156600a 100644 Binary files a/out/production/infinitymonkeys/GUI/DrawingArea$1.class and b/out/production/infinitymonkeys/GUI/DrawingArea$1.class differ diff --git a/out/production/infinitymonkeys/GUI/DrawingArea$Mode.class b/out/production/infinitymonkeys/GUI/DrawingArea$Mode.class index 0dfea6014533d4b2402a663f95c2c029f41e7e9e..958e85d742b3479d575c89210af94b1aef0dff56 100644 Binary files a/out/production/infinitymonkeys/GUI/DrawingArea$Mode.class and b/out/production/infinitymonkeys/GUI/DrawingArea$Mode.class differ diff --git a/out/production/infinitymonkeys/GUI/DrawingArea.class b/out/production/infinitymonkeys/GUI/DrawingArea.class index b546fd5ff1fb00556284f00b4d6f7b350a9c2238..82e1ef02989e61d8f9a79ba875ce9f42d4952ff6 100644 Binary files a/out/production/infinitymonkeys/GUI/DrawingArea.class and b/out/production/infinitymonkeys/GUI/DrawingArea.class differ diff --git a/out/production/infinitymonkeys/client/ChatUpdate.class b/out/production/infinitymonkeys/client/ChatUpdate.class index bc8354438e73505c3b27ae6f6e02e6fdfd4c4a2d..a744ba30c58b4856957d67ba89872ac0f378c60c 100644 Binary files a/out/production/infinitymonkeys/client/ChatUpdate.class and b/out/production/infinitymonkeys/client/ChatUpdate.class differ diff --git a/out/production/infinitymonkeys/client/DrawingUpdate.class b/out/production/infinitymonkeys/client/DrawingUpdate.class index 7d148a4f7feeab606cc4c70654702b26eede7fbf..e11afed4f6128429cbdd3af76ea42a2c5f8f0bbd 100644 Binary files a/out/production/infinitymonkeys/client/DrawingUpdate.class and b/out/production/infinitymonkeys/client/DrawingUpdate.class differ diff --git a/out/production/infinitymonkeys/client/EncryptionUpdate.class b/out/production/infinitymonkeys/client/EncryptionUpdate.class index dd644d10582b1e21c9d9c8f958704ce89e67eb0f..d1cd42f871ec50b9e0a09577dd32bd5e9bfc8527 100644 Binary files a/out/production/infinitymonkeys/client/EncryptionUpdate.class and b/out/production/infinitymonkeys/client/EncryptionUpdate.class differ diff --git a/out/production/infinitymonkeys/remote/IChatController.class b/out/production/infinitymonkeys/remote/IChatController.class index 53c3ebdbeb067f1865fe93a3e90ce8ef69e59d0b..65f5e73be02f461363096a33f7b443074d226f8a 100644 Binary files a/out/production/infinitymonkeys/remote/IChatController.class and b/out/production/infinitymonkeys/remote/IChatController.class differ diff --git a/out/production/infinitymonkeys/remote/IChatUpdate.class b/out/production/infinitymonkeys/remote/IChatUpdate.class index f84138bb8bf132eae71b572e7f8c37323da8ae93..4d5e55a0f16af2b31b182c22f9cd4c5ee4831c3b 100644 Binary files a/out/production/infinitymonkeys/remote/IChatUpdate.class and b/out/production/infinitymonkeys/remote/IChatUpdate.class differ diff --git a/out/production/infinitymonkeys/remote/IDrawingController.class b/out/production/infinitymonkeys/remote/IDrawingController.class index 48922edf2f86e6b2219a129be5612f1d0cad0fd8..d73ef908ad5fa62f7266e623517e188113f3acbe 100644 Binary files a/out/production/infinitymonkeys/remote/IDrawingController.class and b/out/production/infinitymonkeys/remote/IDrawingController.class differ diff --git a/out/production/infinitymonkeys/remote/IDrawingUpdate.class b/out/production/infinitymonkeys/remote/IDrawingUpdate.class index c87eedd773afa0eb339b4384e3912c5d1b60c3bd..23c8094f66b8ddfa3d0d8e5731aed7b68e868582 100644 Binary files a/out/production/infinitymonkeys/remote/IDrawingUpdate.class and b/out/production/infinitymonkeys/remote/IDrawingUpdate.class differ diff --git a/out/production/infinitymonkeys/server/ChatController.class b/out/production/infinitymonkeys/server/ChatController.class index 1df05bb664aee8674eb208da4de206b6df3bad0d..e19d9b5594db9e967727e2bac0ed0c6270892bc0 100644 Binary files a/out/production/infinitymonkeys/server/ChatController.class and b/out/production/infinitymonkeys/server/ChatController.class differ diff --git a/out/production/infinitymonkeys/server/DrawingController.class b/out/production/infinitymonkeys/server/DrawingController.class index 8f789e772ac70549f593139fa6d26fae48b46f69..1f5b804eb1d4ab47311e9d0f75a1eac382bf5d97 100644 Binary files a/out/production/infinitymonkeys/server/DrawingController.class and b/out/production/infinitymonkeys/server/DrawingController.class differ diff --git a/out/production/infinitymonkeys/server/MySharedKey.class b/out/production/infinitymonkeys/server/MySharedKey.class index 9dc50ef5ce7fc7cf36d5e9aceffc3e3d725fdc77..956b64e2acf75a75257e07e05c60b164dc4ab935 100644 Binary files a/out/production/infinitymonkeys/server/MySharedKey.class and b/out/production/infinitymonkeys/server/MySharedKey.class differ diff --git a/out/production/infinitymonkeys/server/User.class b/out/production/infinitymonkeys/server/User.class index bb1cfcbe52b605032645164945747218b2160ba8..1f9d467c254e1d5522e06aa714e639f9145b70a4 100644 Binary files a/out/production/infinitymonkeys/server/User.class and b/out/production/infinitymonkeys/server/User.class differ diff --git a/out/production/infinitymonkeys/server/server.policy b/out/production/infinitymonkeys/server/server.policy index 5c059491c631fa37d14fc62d9654cdb13ce184c0..be17177b9474e62dc5d6c236756a51054ba11904 100644 --- a/out/production/infinitymonkeys/server/server.policy +++ b/out/production/infinitymonkeys/server/server.policy @@ -1,3 +1,4 @@ grant codeBase "file:/Users/haiho/OneDrive - The University of Melbourne/Distributed Systems (COMP90015)/Assignment 2/InfinityMonkeys-remaster/comp90015-dsass2-infinitymonkeys-remaster/out/production/comp90015-dsass2-infinitymonkeys-remaster/" { + permission java.util.PropertyPermission '*', "read,write"; permission java.security.AllPermission; }; \ No newline at end of file diff --git a/src/GUI/icon/circle.png b/resources/circle.png similarity index 100% rename from src/GUI/icon/circle.png rename to resources/circle.png diff --git a/src/GUI/icon/eraser.png b/resources/eraser.png similarity index 100% rename from src/GUI/icon/eraser.png rename to resources/eraser.png diff --git a/src/GUI/icon/freehand.png b/resources/freehand.png similarity index 100% rename from src/GUI/icon/freehand.png rename to resources/freehand.png diff --git a/src/GUI/icon/line.png b/resources/line.png similarity index 100% rename from src/GUI/icon/line.png rename to resources/line.png diff --git a/src/GUI/icon/oval.png b/resources/oval.png similarity index 100% rename from src/GUI/icon/oval.png rename to resources/oval.png diff --git a/src/GUI/icon/palette.png b/resources/palette.png similarity index 100% rename from src/GUI/icon/palette.png rename to resources/palette.png diff --git a/src/GUI/icon/rectangle.png b/resources/rectangle.png similarity index 100% rename from src/GUI/icon/rectangle.png rename to resources/rectangle.png diff --git a/src/GUI/icon/square.png b/resources/square.png similarity index 100% rename from src/GUI/icon/square.png rename to resources/square.png diff --git a/src/GUI/icon/text.png b/resources/text.png similarity index 100% rename from src/GUI/icon/text.png rename to resources/text.png diff --git a/src/GUI/ChatScreen.form b/src/GUI/ChatScreen.form index 8628672c8b03ba53bb54ae10847a29458c98b80e..140273c130f937107baf67db482203bc8ef15290 100644 --- a/src/GUI/ChatScreen.form +++ b/src/GUI/ChatScreen.form @@ -121,6 +121,28 @@ <text value="Exit This Room"/> </properties> </component> + <grid id="e92cc" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> + <margin top="0" left="0" bottom="0" right="0"/> + <constraints> + <grid row="6" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/> + </constraints> + <properties/> + <border type="none" title="Drawing Users"/> + <children> + <component id="2214f" class="javax.swing.JList" binding="allUsersList"> + <constraints> + <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="2" anchor="0" fill="3" indent="0" use-parent-layout="false"> + <preferred-size width="150" height="50"/> + </grid> + </constraints> + <properties> + <model> + <item value="drawingUserList"/> + </model> + </properties> + </component> + </children> + </grid> </children> </grid> <grid id="5d886" binding="chatPanel" layout-manager="GridLayoutManager" row-count="6" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> diff --git a/src/GUI/ChatScreen.java b/src/GUI/ChatScreen.java index bae244257a3e5fbd5646fbd37aed6af3f200d62b..4d6aed26e7882aecc6e0422a34a08b1ed4306d2c 100644 --- a/src/GUI/ChatScreen.java +++ b/src/GUI/ChatScreen.java @@ -1,9 +1,11 @@ package GUI; import client.Client; +import remote.EncryptDecrypt; import remote.IChatController; import remote.IClientController; +import javax.crypto.SealedObject; import javax.swing.*; import java.awt.event.*; import java.rmi.RemoteException; @@ -11,10 +13,10 @@ import java.rmi.RemoteException; public class ChatScreen { public JPanel panel2; - public JPanel othersPanel; private JButton sendButton; + private JPanel othersPanel; private JComboBox sendMessageToComboBox; private JTextArea chatDisplayBox; private JComboBox kickUserComboBox; @@ -30,6 +32,13 @@ public class ChatScreen { private JPanel managersPanel; private JPanel chatPanel; private JButton exitThisRoomButton; + private DefaultListModel defaultListModel; + + public DefaultListModel getAllUserModel() { + return defaultListModel; + } + + private JList allUsersList; private JFrame frame; public Client getClient() { @@ -46,6 +55,24 @@ public class ChatScreen { sendButton.addActionListener(actionListener); kickOutButton.addActionListener(actionListener); promoteToManagerButton.addActionListener(actionListener); + defaultListModel = new DefaultListModel(); + allUsersList.setModel(defaultListModel); + + allUsersList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + allUsersList.setSelectedIndex(0); + allUsersList.setVisibleRowCount(5); + + + + + } + + public void addUserToList(){ + + } + + public void removeUserFromList(){ + } public void setUserName(String userName) @@ -115,14 +142,14 @@ public class ChatScreen { System.out.println("Send button pressed"); String toUser = sendMessageToComboBox.getSelectedItem().toString(); - + SealedObject messageSealed = EncryptDecrypt.encryptString(message,client.getEncryptionUpdate().getSharedSecretKey()); if( toUser.equals("All") ) { - chatController.broadcastMessage(client.getUserName(), message); + chatController.broadcastMessage(client.getUserName(), messageSealed); } else { - chatController.sendPrivateMessage(client.getUserName(), toUser, message); + chatController.sendPrivateMessage(client.getUserName(), toUser, messageSealed); } } catch (RemoteException ex) @@ -168,4 +195,5 @@ public class ChatScreen { } }; + } diff --git a/src/GUI/DrawingArea.java b/src/GUI/DrawingArea.java index 1d7c5b9e5d191c9426cb6058a5176abfe24de47c..6282dfd62a8d890332f3bc3ca669c8523e4835ac 100644 --- a/src/GUI/DrawingArea.java +++ b/src/GUI/DrawingArea.java @@ -10,7 +10,6 @@ import java.awt.event.*; import java.awt.geom.Ellipse2D; import java.awt.geom.Line2D; import java.awt.geom.Rectangle2D; -import java.awt.geom.RectangularShape; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; @@ -94,6 +93,8 @@ public class DrawingArea extends JPanel implements MouseMotionListener, MouseLis public void clear() { image = new BufferedImage(AREA_WIDTH, AREA_HEIGHT, BufferedImage.TYPE_INT_ARGB); + g2 = (Graphics2D) image.getGraphics(); + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); repaint(); } @@ -114,6 +115,7 @@ public class DrawingArea extends JPanel implements MouseMotionListener, MouseLis /// Eraser has no border color /// Color borderColor = currentMode != Mode.ERASE ? shapeColor : Color.WHITE; g2.setColor(borderColor); + g2.setStroke(lineStroke); g2.draw(drawing); } } @@ -205,7 +207,7 @@ public class DrawingArea extends JPanel implements MouseMotionListener, MouseLis switch (currentMode) { case TEXT: - + g2.setColor(shapeColor); g2.setFont(new Font("TimesRoman", Font.PLAIN, textSize)); g2.drawString(textString, startPoint.x, startPoint.y); try { @@ -287,6 +289,13 @@ public class DrawingArea extends JPanel implements MouseMotionListener, MouseLis try { drawingController.broadcastDrawing(client.getUserName(), drawing, currentMode.toString(), shapeColor, strokeSize); + if (currentMode == Mode.TEXT){ + notifyUsingTimer(); + } + else { + drawingController.broadcastDrawingUserStopped(client.getUserName()); + } + } catch (RemoteException ex) { ex.printStackTrace(); } @@ -294,6 +303,31 @@ public class DrawingArea extends JPanel implements MouseMotionListener, MouseLis drawing = null; } + private void notifyUsingTimer() throws RemoteException { + + Timer timer = new Timer(4000, new ActionListener() + { + + @Override + public void actionPerformed(ActionEvent e) + { + try { + client.getDrawingController().broadcastDrawingUserStopped(client.getDefaultUserName()); + } catch (RemoteException ex) { + ex.printStackTrace(); + } + + } + + }); + try { + client.getDrawingController().broadcastDrawingUser(client.getDefaultUserName()); + } catch (RemoteException ex) { + ex.printStackTrace(); + } + timer.start(); + } + @Override public void mouseEntered(MouseEvent e) { @@ -367,7 +401,11 @@ public class DrawingArea extends JPanel implements MouseMotionListener, MouseLis g2.setStroke(lineStroke); repaint(); try { - drawingController.broadcastDraggingDrawing(client.getUserName(), drawing, currentMode.toString(), shapeColor, strokeSize); + if (currentMode != Mode.TEXT){ + drawingController.broadcastDraggingDrawing(client.getUserName(), drawing, currentMode.toString(), shapeColor, strokeSize); + drawingController.broadcastDrawingUser(client.getUserName()); + } + } catch (RemoteException ex) { ex.printStackTrace(); } diff --git a/src/GUI/PaintGUI.java b/src/GUI/PaintGUI.java index 2fc328d3b627b847d3d0262c55fd11bfe9666d6e..a2971193eadc8407e826b23b04ec3a7437112a1b 100644 --- a/src/GUI/PaintGUI.java +++ b/src/GUI/PaintGUI.java @@ -1,7 +1,6 @@ package GUI; import client.Client; -import remote.IDrawingUpdate; import javax.imageio.ImageIO; import javax.swing.*; @@ -59,24 +58,15 @@ public class PaintGUI extends JPanel { /// Set up button icons /// try { - String path = System.getProperty("user.dir"); - System.out.println(path); - File palettePic = new File(path + "/src/GUI/icon/palette.png"); - File freehandPic = new File(path + "/src/GUI/icon/freehand.png"); - File linePic = new File(path + "/src/GUI/icon/line.png"); - File circlePic = new File(path + "/src/GUI/icon/circle.png"); - File rectPic = new File(path + "/src/GUI/icon/rectangle.png"); - File ovalPic = new File(path + "/src/GUI/icon/oval.png"); - File eraserPic = new File(path + "/src/GUI/icon/eraser.png"); - File textPic = new File(path + "/src/GUI/icon/text.png"); - BufferedImage paletteIcon = ImageIO.read(palettePic); - BufferedImage freehandIcon = ImageIO.read(freehandPic); - BufferedImage lineIcon = ImageIO.read(linePic); - BufferedImage circleIcon = ImageIO.read(circlePic); - BufferedImage rectIcon = ImageIO.read(rectPic); - BufferedImage ovalIcon = ImageIO.read(ovalPic); - BufferedImage eraserIcon = ImageIO.read(eraserPic); - BufferedImage textIcon = ImageIO.read(textPic); + BufferedImage paletteIcon = ImageIO.read(getClass().getResource("/palette.png")); + BufferedImage freehandIcon = ImageIO.read(getClass().getResource("/freehand.png")); + BufferedImage lineIcon = ImageIO.read(getClass().getResource("/line.png")); + BufferedImage circleIcon = ImageIO.read(getClass().getResource("/circle.png")); + BufferedImage rectIcon = ImageIO.read(getClass().getResource("/rectangle.png")); + BufferedImage ovalIcon = ImageIO.read(getClass().getResource("/oval.png")); + BufferedImage eraserIcon = ImageIO.read(getClass().getResource("/eraser.png")); + BufferedImage textIcon = ImageIO.read(getClass().getResource("/text.png")); + colorPaletteBtn = new JButton(new ImageIcon(paletteIcon)); colorPaletteBtn.addActionListener(actionListener); freehandBtn = new JButton(new ImageIcon(freehandIcon)); @@ -107,7 +97,7 @@ public class PaintGUI extends JPanel { // setFontBtn = new JButton("Font"); // setFontBtn.addActionListener(actionListener); textInput = new JTextField("Text here."); - textInput.setColumns(8); + textInput.setColumns(13); textInput.addFocusListener(focusListener); // textInput.setVisible(false); textSize = new JTextField("12"); @@ -142,13 +132,13 @@ public class PaintGUI extends JPanel { toolbox2.add(textSize); toolbox2.add(eraserBtn); toolbox2.add(eraserSizeOptions); - toolbox2.add(clearBtn); /// File control panel /// fileControl.add(newBtn); fileControl.add(openBtn); fileControl.add(saveBtn); fileControl.add(saveAsBtn); + fileControl.add(clearBtn); /// Layout /// toolbox.add(toolbox1, BorderLayout.NORTH); @@ -409,7 +399,13 @@ public class PaintGUI extends JPanel { private void setTextDetail() { String textString = textInput.getText(); - int size = Integer.parseInt(textSize.getText()); + int size = 12; // default + if (!textSize.getText().isEmpty()) { + size = Integer.parseInt(textSize.getText()); + } + else { + textSize.setText(Integer.toString(size)); + } drawingArea.setModeText(textString, size); } diff --git a/src/GUI/StartScreen.java b/src/GUI/StartScreen.java index 141e03fd5cc87841d41836a44fbd9b71813823d8..f0af621a3d5412999b8a86641016a14fb564ad47 100644 --- a/src/GUI/StartScreen.java +++ b/src/GUI/StartScreen.java @@ -63,46 +63,51 @@ public class StartScreen { String userName = usernameField.getText(); String password = new String(passwordField.getPassword()); - int connectionStatus = client.connect(userName, serverAddress, password); - - if( connectionStatus == 0 ) - { - frame.setVisible(false); - frame.dispose(); - if (client.getApplicationMain().getFrame() == null) { - client.startApplication(); + if (userName.length() <= 15) { + int connectionStatus = client.connect(userName, serverAddress, password); + + if( connectionStatus == 0 ) + { + frame.setVisible(false); + frame.dispose(); + if (client.getApplicationMain().getFrame() == null) { + client.startApplication(); + } + else { + client.clearChat(); + client.clearDrawingArea(); + client.setVisibleApplication(); + } + + } + else if( connectionStatus == 1 || connectionStatus == 6) + { + showErrorMessage("The manager rejected your join request"); + } + else if( connectionStatus == 2 || connectionStatus == 7 ) + { + showErrorMessage("Duplicate username: Please enter a different username"); } - else { - client.clearChat(); - client.clearDrawingArea(); + else if( connectionStatus == 3 ) + { + showErrorMessage("Cannot connect to server: Please check the server address"); + } + else if( connectionStatus == 4 ) + { + showErrorMessage("Incorrect Password"); + } + else if( connectionStatus == 5 ) { + frame.setVisible(false); + frame.dispose(); client.setVisibleApplication(); } + else + { + showErrorMessage("Unknown Connection Status"); + } } - else if( connectionStatus == 1 || connectionStatus == 6) - { - showErrorMessage("The manager rejected your join request"); - } - else if( connectionStatus == 2 || connectionStatus == 7 ) - { - showErrorMessage("Duplicate username: Please enter a different username"); - } - else if( connectionStatus == 3 ) - { - showErrorMessage("Cannot connect to server: Please check the server address"); - } - else if( connectionStatus == 4 ) - { - showErrorMessage("Incorrect Password"); - } - else if( connectionStatus == 5 ) - { - frame.setVisible(false); - frame.dispose(); - client.setVisibleApplication(); - } - else - { - showErrorMessage("Unknown Connection Status"); + else { + showErrorMessage("Username must be less or equal to 15 characters"); } } } diff --git a/src/client/ChatUpdate.java b/src/client/ChatUpdate.java index 2edc3ccdd3c5a1c5262fdc2107d9f28b74b556ce..9447ca5c1f29f9122f1bfdb2eacdc0d538c2995a 100644 --- a/src/client/ChatUpdate.java +++ b/src/client/ChatUpdate.java @@ -1,7 +1,9 @@ package client; +import remote.EncryptDecrypt; import remote.IChatUpdate; +import javax.crypto.SealedObject; import java.io.Serializable; import java.rmi.RemoteException; import java.rmi.server.UnicastRemoteObject; @@ -17,8 +19,9 @@ public class ChatUpdate extends UnicastRemoteObject implements IChatUpdate, Seri } @Override - public boolean notifyChat(String fromClient, String message, boolean isPrivate) throws RemoteException - { + public boolean notifyChat(String fromClient, SealedObject messageSealed, boolean isPrivate) throws RemoteException + { String message; + message = EncryptDecrypt.decryptString(messageSealed,client.getEncryptionUpdate().getSharedSecretKey()); String outputString; if( isPrivate ) diff --git a/src/client/Client.java b/src/client/Client.java index 98776a725a87a9e0e6481ba69c7e1a9053a56e6c..353f7ac0d6eacb09021e2f31e1659c48511314f1 100644 --- a/src/client/Client.java +++ b/src/client/Client.java @@ -4,10 +4,13 @@ import GUI.ApplicationMain; import GUI.ChatScreen; import GUI.PaintGUI; import GUI.StartScreen; +import remote.EncryptDecrypt; import remote.IChatController; import remote.IClientController; import remote.IDrawingController; +import javax.crypto.Cipher; +import javax.crypto.SealedObject; import java.rmi.RemoteException; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; @@ -18,6 +21,11 @@ public class Client { private final String DEFAULT_USERNAME = "Anonymous"; private final String DEFAULT_SERVER_ADDRESS = "localhost"; + + public EncryptionUpdate getEncryptionUpdate() { + return encryptionUpdate; + } + private final EncryptionUpdate encryptionUpdate; private String defaultUserName; @@ -85,9 +93,9 @@ public class Client } - public Client(String username) throws RemoteException, NoSuchProviderException, NoSuchAlgorithmException + public Client() throws RemoteException, NoSuchProviderException, NoSuchAlgorithmException { - this.defaultUserName = username; + this.defaultUserName = DEFAULT_USERNAME; this.clientUpdate = new ClientUpdate(this); this.chatUpdate = new ChatUpdate(this); this.drawingUpdate = new DrawingUpdate(this); @@ -100,7 +108,7 @@ public class Client { try { - Client client = new Client(args[0]); + Client client = new Client(); client.showStartScreen(); } catch (Exception e) @@ -155,10 +163,17 @@ public class Client System.out.println("User name:" + getUserName()); System.out.println("Password: " + password); - if( clientController.checkPassword(password) ) - { - int joinStatus = clientController.join(getUserName(), this.chatUpdate, this.clientUpdate, this.drawingUpdate); - return joinStatus + 5; + if (clientController.setSharedKey(this.encryptionUpdate)) { + SealedObject sealedPassword = EncryptDecrypt.encryptString(password, this.encryptionUpdate.getSharedSecretKey()); + + if (clientController.checkPassword(sealedPassword)) { + int joinStatus = clientController.join(getUserName(), this.chatUpdate, this.clientUpdate, this.drawingUpdate); + return joinStatus + 5; + } + else + { + return 4; + } } else { @@ -179,10 +194,17 @@ public class Client System.out.println("User name:" + getUserName()); System.out.println("Password: " + password); - if( clientController.checkPassword(password) ) - { - int joinStatus = clientController.join(getUserName(), this.chatUpdate, this.clientUpdate, this.drawingUpdate); - return joinStatus; + if (clientController.setSharedKey(this.encryptionUpdate)) { + SealedObject sealedPassword = EncryptDecrypt.encryptString(password, this.encryptionUpdate.getSharedSecretKey()); + + if (clientController.checkPassword(sealedPassword)) { + int joinStatus = clientController.join(getUserName(), this.chatUpdate, this.clientUpdate, this.drawingUpdate); + return joinStatus; + } + else + { + return 4; + } } else { diff --git a/src/client/DrawingUpdate.java b/src/client/DrawingUpdate.java index 68c8f9ae6c6b685aa99eca6a0ee64b4bf61bd230..60ea6688da2a1f8f336a70813f61aa45dc9c472d 100644 --- a/src/client/DrawingUpdate.java +++ b/src/client/DrawingUpdate.java @@ -1,8 +1,8 @@ package client; -import GUI.DrawingArea; import remote.IDrawingUpdate; +import javax.swing.*; import java.awt.*; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; @@ -20,10 +20,34 @@ public class DrawingUpdate extends UnicastRemoteObject implements IDrawingUpdate this.client = client; } + public boolean notifyUserIsDrawing(String fromClient) throws RemoteException { + System.out.println("Adding name of user to the list of drawing users"); + DefaultListModel temp = client.getApplicationMain().getChatScreen().getAllUserModel(); + if(temp.contains(fromClient)){ + System.out.println("Already in the list"); + } + else { + temp.addElement(fromClient); + } + + return true; + } + + public void notifyUserStoppedDrawing(String fromClient) throws RemoteException{ + DefaultListModel temp = client.getApplicationMain().getChatScreen().getAllUserModel(); + int elementIndex = -1; + if(temp.contains(fromClient)){ + elementIndex = temp.indexOf(fromClient); + temp.remove(elementIndex); + } + + } + @Override - public boolean notifyTextDrawing(String fromClient, String text, Font font, Point startPoint) throws RemoteException { + public boolean notifyTextDrawing(String fromClient, String text, Font font, Color color, Point startPoint) throws RemoteException { client.getApplicationMain().getPaintGUI().getDrawingArea().getG2().setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); client.getApplicationMain().getPaintGUI().getDrawingArea().getG2().setFont(font); + client.getApplicationMain().getPaintGUI().getDrawingArea().getG2().setColor(color); client.getApplicationMain().getPaintGUI().getDrawingArea().getG2().drawString(text, startPoint.x, startPoint.y); client.getApplicationMain().getPaintGUI().getDrawingArea().repaint(); return true; @@ -49,6 +73,7 @@ public class DrawingUpdate extends UnicastRemoteObject implements IDrawingUpdate g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.setColor(color); client.getApplicationMain().getPaintGUI().getDrawingArea().repaint(); + return true; } diff --git a/src/client/EncryptionUpdate.java b/src/client/EncryptionUpdate.java index 001c1295c64d042cba748e108675cbe14f3a4503..52d1fa52d2f6ee065599c615ec936c707b733e24 100644 --- a/src/client/EncryptionUpdate.java +++ b/src/client/EncryptionUpdate.java @@ -14,7 +14,13 @@ public class EncryptionUpdate extends UnicastRemoteObject implements IEncryption private PrivateKey priv; private PublicKey pub; + + public SecretKey getSharedSecretKey() { + return sharedSecretKey; + } + private SecretKey sharedSecretKey; + private Cipher myCipher; public PublicKey getPub() { return pub; @@ -26,6 +32,8 @@ public class EncryptionUpdate extends UnicastRemoteObject implements IEncryption cipher.init(Cipher.DECRYPT_MODE, priv); sharedSecretKey = new SecretKeySpec(cipher.doFinal(encryptedSharedSecretKey), "AES"); System.out.println("Client holds this shared key: "+sharedSecretKey); + + } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (NoSuchProviderException e) { @@ -55,4 +63,5 @@ public class EncryptionUpdate extends UnicastRemoteObject implements IEncryption } } + } diff --git a/src/remote/EncryptDecrypt.java b/src/remote/EncryptDecrypt.java new file mode 100644 index 0000000000000000000000000000000000000000..cd6af8aca40259ca62e57aab95e91ff4f6779c24 --- /dev/null +++ b/src/remote/EncryptDecrypt.java @@ -0,0 +1,59 @@ +package remote; + +import javax.crypto.*; +import java.io.IOException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; + +public class EncryptDecrypt { + public static String decryptString (SealedObject sealedObject, SecretKey key){ + + String nonSealedString =""; + Cipher cipher = null; + try { + cipher = Cipher.getInstance("AES"); + cipher.init(Cipher.DECRYPT_MODE,key); + nonSealedString = (String)sealedObject.getObject(cipher); + + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } catch (NoSuchPaddingException e) { + e.printStackTrace(); + } catch (InvalidKeyException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } catch (IllegalBlockSizeException e) { + e.printStackTrace(); + } catch (BadPaddingException e) { + e.printStackTrace(); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + return nonSealedString; + + } + public static SealedObject encryptString (String string, SecretKey key){ + SealedObject sealedObject = null; + + Cipher cipher = null; + try { + cipher = Cipher.getInstance("AES"); + cipher.init(Cipher.ENCRYPT_MODE,key); + sealedObject = new SealedObject(string,cipher); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } catch (NoSuchPaddingException e) { + e.printStackTrace(); + } catch (IllegalBlockSizeException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } catch (InvalidKeyException e) { + e.printStackTrace(); + } + return sealedObject; + + + } +} diff --git a/src/remote/IChatController.java b/src/remote/IChatController.java index 82305870e4b5438637dc6b8759ce3235b6a02dd0..6c6bb3802b19e08c81d3a18ab0cfe380ba67036c 100644 --- a/src/remote/IChatController.java +++ b/src/remote/IChatController.java @@ -1,12 +1,13 @@ package remote; +import javax.crypto.SealedObject; import java.rmi.Remote; import java.rmi.RemoteException; public interface IChatController extends Remote { - boolean broadcastMessage(String fromClient, String message) throws RemoteException; + boolean broadcastMessage(String fromClient, SealedObject messageSealed) throws RemoteException; boolean broadcastMessageUserLogin(String fromClient) throws RemoteException; boolean broadcastMessageUserLogout(String fromClient) throws RemoteException; - boolean sendPrivateMessage(String fromClient, String toClient, String message) throws RemoteException; + boolean sendPrivateMessage(String fromClient, String toClient, SealedObject messageSealed) throws RemoteException; } diff --git a/src/remote/IChatUpdate.java b/src/remote/IChatUpdate.java index 0c9b54d9daab6367372e1987f2c988a94bcbde8d..ffde71cc00a9bf8ab373df8be513f20d6476a4a2 100644 --- a/src/remote/IChatUpdate.java +++ b/src/remote/IChatUpdate.java @@ -1,12 +1,13 @@ package remote; +import javax.crypto.SealedObject; import java.io.Serializable; import java.rmi.Remote; import java.rmi.RemoteException; public interface IChatUpdate extends Remote, Serializable { - boolean notifyChat(String fromClient, String message, boolean isPrivate) throws RemoteException; + boolean notifyChat(String fromClient, SealedObject messageSealed, boolean isPrivate) throws RemoteException; boolean notifyUserLogin(String fromClient) throws RemoteException; boolean notifyUserLogout(String fromClient) throws RemoteException; } diff --git a/src/remote/IClientController.java b/src/remote/IClientController.java index ca006a90b1a83ff2e45f39a2e74cd46d34e7d055..0233a5841bf26f3909b1c5bb90524517872691f6 100644 --- a/src/remote/IClientController.java +++ b/src/remote/IClientController.java @@ -1,5 +1,6 @@ package remote; +import javax.crypto.SealedObject; import java.rmi.Remote; import java.rmi.RemoteException; @@ -21,8 +22,8 @@ public interface IClientController extends Remote String getAdmin() throws RemoteException; - boolean checkPassword(String password) throws RemoteException; + boolean checkPassword(SealedObject sealedPassword) throws RemoteException; - void removeFromWaitingList(String username) throws RemoteException; + boolean setSharedKey(IEncryptionUpdate encryptionUpdate) throws RemoteException; } diff --git a/src/remote/IDrawingController.java b/src/remote/IDrawingController.java index 3aa40d3bcc5f77607e8df4e711a63305e083edc6..571cd2f437c83d5bb8f0eb8897fa5c67d68547cf 100644 --- a/src/remote/IDrawingController.java +++ b/src/remote/IDrawingController.java @@ -21,5 +21,7 @@ public interface IDrawingController extends Remote { boolean broadcastClearCanvas(String fromClient) throws RemoteException; boolean broadcastUpdateImage(String fromClient) throws RemoteException; boolean updateImage(byte[] rawImage) throws RemoteException; + void broadcastDrawingUser (String fromClient) throws RemoteException; void getImage(String fromClient) throws RemoteException; + void broadcastDrawingUserStopped (String fromClient) throws RemoteException; } diff --git a/src/remote/IDrawingUpdate.java b/src/remote/IDrawingUpdate.java index 02f17f1e685503799e74e2ca9f3f7d26bdff404d..3509141895adebdf35afe1b9fd9f321ee5e8235a 100644 --- a/src/remote/IDrawingUpdate.java +++ b/src/remote/IDrawingUpdate.java @@ -6,9 +6,11 @@ import java.rmi.Remote; import java.rmi.RemoteException; public interface IDrawingUpdate extends Remote, Serializable { - boolean notifyTextDrawing(String fromClient, String text, Font font, Point startPoint) throws RemoteException; + boolean notifyTextDrawing(String fromClient, String text, Font font, Color color, Point startPoint) throws RemoteException; boolean notifyDrawing(String fromClient, Shape drawing, String mode, Color color, int strokeSize) throws RemoteException; boolean notifyDraggingDrawing(String fromClient, Shape drawing, String mode, Color color, int strokeSize) throws RemoteException; boolean notifyCanvasClearance(String fromClient) throws RemoteException; boolean receiveImage(byte[] rawImage) throws RemoteException; + boolean notifyUserIsDrawing(String fromClient) throws RemoteException; + void notifyUserStoppedDrawing(String fromClient) throws RemoteException; } diff --git a/src/server/ChatController.java b/src/server/ChatController.java index a2a38a03e75bb952ed298a7f8050029cb38b0324..206bc18cdbc23971de7ee7462fdb9eb500d0e1bd 100644 --- a/src/server/ChatController.java +++ b/src/server/ChatController.java @@ -1,8 +1,10 @@ package server; +import remote.EncryptDecrypt; import remote.IChatController; import remote.IChatUpdate; +import javax.crypto.SealedObject; import java.io.Serializable; import java.rmi.RemoteException; import java.rmi.server.UnicastRemoteObject; @@ -17,13 +19,16 @@ public class ChatController extends UnicastRemoteObject implements IChatControll } @Override - public boolean broadcastMessage(String fromClient, String message) throws RemoteException + public boolean broadcastMessage(String fromClient, SealedObject messageSealed) throws RemoteException { System.out.print("Broadcasting message to everyone..."); + int fromClientIndex = server.clientController.getUserIndex(fromClient); + String message = EncryptDecrypt.decryptString(messageSealed,server.users.get(fromClientIndex).getSharedSecretKey()); for( User u : server.users ) - { - u.getIChatUpdate().notifyChat(fromClient, message, false); + { u.getSharedSecretKey(); + SealedObject messageSealedTo = EncryptDecrypt.encryptString(message,u.getSharedSecretKey()); + u.getIChatUpdate().notifyChat(fromClient, messageSealedTo, false); } System.out.print("...DONE\n"); @@ -68,16 +73,22 @@ public class ChatController extends UnicastRemoteObject implements IChatControll } @Override - public boolean sendPrivateMessage(String fromClient, String toClient, String message) throws RemoteException - { + public boolean sendPrivateMessage(String fromClient, String toClient, SealedObject messageSealed) throws RemoteException + { String message; int toClientIndex = server.clientController.getUserIndex(toClient); int fromClientIndex = server.clientController.getUserIndex(fromClient); if( toClientIndex >= 0 && fromClientIndex >= 0 ) { - server.users.get(toClientIndex).getIChatUpdate().notifyChat(fromClient, message, true); + message = EncryptDecrypt.decryptString(messageSealed,server.users.get(fromClientIndex).getSharedSecretKey()); + + SealedObject messageSealedOutgoingFrom = EncryptDecrypt.encryptString(message,server.users.get(fromClientIndex).getSharedSecretKey()); + + SealedObject messageSealedOutgoingTo = EncryptDecrypt.encryptString(message,server.users.get(toClientIndex).getSharedSecretKey()); + + server.users.get(toClientIndex).getIChatUpdate().notifyChat(fromClient, messageSealedOutgoingTo, true); - server.users.get(fromClientIndex).getIChatUpdate().notifyChat(fromClient, message, true); + server.users.get(fromClientIndex).getIChatUpdate().notifyChat(fromClient, messageSealedOutgoingFrom, true); return true; } diff --git a/src/server/ClientController.java b/src/server/ClientController.java index 14627722ee38d2be30f0bcbddc0d0137fe33a0fc..b7cb05666567e89a0d735bcb86782ee41e25d532 100644 --- a/src/server/ClientController.java +++ b/src/server/ClientController.java @@ -2,8 +2,8 @@ package server; import remote.*; +import javax.crypto.*; import java.io.Serializable; -import java.rmi.Remote; import java.rmi.RemoteException; import java.rmi.server.UnicastRemoteObject; @@ -16,12 +16,14 @@ public class ClientController extends UnicastRemoteObject implements IClientCont this.server = server; } + private SecretKey sharedSecretKey; + @Override public int join(String username, IChatUpdate clientChat, IClientUpdate clientUpdate, IDrawingUpdate clientDrawing) throws RemoteException { // If there is no user in the list then let the user be the manager if(server.users.size() == 0) { - User newUser = new User(username, clientChat, clientUpdate, clientDrawing); + User newUser = new User(username, clientChat, clientUpdate, clientDrawing, sharedSecretKey); server.users.add(newUser); newUser.setAdmin(true); broadcastUserList(); @@ -40,7 +42,7 @@ public class ClientController extends UnicastRemoteObject implements IClientCont // If the manager accepts the new user to enter, then add the user to the list if (answer == 0) { server.chatController.broadcastMessageUserLogin(username); - User newUser = new User(username, clientChat, clientUpdate, clientDrawing); + User newUser = new User(username, clientChat, clientUpdate, clientDrawing, sharedSecretKey); server.users.add(newUser); broadcastUserList(); return 0; @@ -55,21 +57,6 @@ public class ClientController extends UnicastRemoteObject implements IClientCont } - @Override - public void removeFromWaitingList(String username) throws RemoteException { - int userIndex = -1; - for( int i = 0; i < server.waitingList.size(); i++ ) { - if (server.waitingList.get(i).getUserName().equals(username)) { - userIndex = i; - break; - } - } - if( userIndex >= 0 ) - { - server.waitingList.remove(userIndex); - } - } - @Override public void quit(String username) throws RemoteException { @@ -243,8 +230,12 @@ public class ClientController extends UnicastRemoteObject implements IClientCont } } - public boolean checkPassword(String password) + @Override + public boolean checkPassword(SealedObject sealedPassword) { + System.out.println("Sealed passwords" + sealedPassword); + String password = EncryptDecrypt.decryptString(sealedPassword,this.sharedSecretKey); + System.out.println("unsealed password" + password); if( server.users.size() == 0 ) { server.setPassword(password); @@ -260,4 +251,14 @@ public class ClientController extends UnicastRemoteObject implements IClientCont return false; } } + public boolean setSharedKey(IEncryptionUpdate encryptionUpdate) throws RemoteException { + try { + sharedSecretKey = new MySharedKey(encryptionUpdate).getSharedSecretKey(); + return true; + + }catch (Exception e){ + return false; + } + + } } diff --git a/src/server/DrawingController.java b/src/server/DrawingController.java index d744ba6df9602c808554a69c58244b32605d2aa9..38a850dfd4cb60d66164a30eae13543b837f88ad 100644 --- a/src/server/DrawingController.java +++ b/src/server/DrawingController.java @@ -1,5 +1,7 @@ package server; +import client.Client; +import remote.IChatUpdate; import remote.IDrawingController; import remote.IDrawingUpdate; @@ -7,6 +9,7 @@ import javax.imageio.ImageIO; import java.awt.*; import java.awt.image.BufferedImage; import java.io.*; +import java.lang.reflect.Array; import java.rmi.RemoteException; import java.rmi.server.UnicastRemoteObject; @@ -31,7 +34,7 @@ public class DrawingController extends UnicastRemoteObject implements IDrawingCo @Override public boolean broadcastText(String fromClient, String text, Font font, Color color, Point startPoint) throws RemoteException { - System.out.print("Broadcasting drawing to everyone..."); +// System.out.print("Broadcasting drawing to everyone..."); g2 = (Graphics2D) bufferedImage.getGraphics(); g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); @@ -48,11 +51,11 @@ public class DrawingController extends UnicastRemoteObject implements IDrawingCo { if (!u.getUserName().equals(fromClient)) { client = u.getIDrawingUpdate(); - client.notifyTextDrawing(fromClient, text, font, startPoint); + client.notifyTextDrawing(fromClient, text, font, color, startPoint); } } - System.out.print("...DONE\n"); +// System.out.print("...DONE\n"); return true; } @@ -60,7 +63,7 @@ public class DrawingController extends UnicastRemoteObject implements IDrawingCo @Override public boolean broadcastDrawing(String fromClient, Shape drawing, String mode, Color color, int strokeSize) throws RemoteException { - System.out.print("Broadcasting drawing to everyone..."); +// System.out.print("Broadcasting drawing to everyone..."); g2 = (Graphics2D) bufferedImage.getGraphics(); g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); @@ -94,13 +97,13 @@ public class DrawingController extends UnicastRemoteObject implements IDrawingCo } } - System.out.print("...DONE\n"); +// System.out.print("...DONE\n"); return true; } public boolean broadcastDraggingDrawing(String fromClient, Shape drawing, String mode, Color color, int strokeSize) throws RemoteException { - System.out.print("Broadcasting dragging drawing to everyone..."); +// System.out.print("Broadcasting dragging drawing to everyone..."); g2 = (Graphics2D) bufferedImage.getGraphics(); g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); @@ -134,13 +137,13 @@ public class DrawingController extends UnicastRemoteObject implements IDrawingCo } } - System.out.print("...DONE\n"); +// System.out.print("...DONE\n"); return true; } public boolean broadcastClearCanvas(String fromClient) throws RemoteException { - System.out.print("Broadcasting canvas clearance to everyone..."); +// System.out.print("Broadcasting canvas clearance to everyone..."); IDrawingUpdate client; @@ -156,14 +159,36 @@ public class DrawingController extends UnicastRemoteObject implements IDrawingCo } } - System.out.print("...DONE\n"); +// System.out.print("...DONE\n"); return true; } + public void broadcastDrawingUser (String fromClient) throws RemoteException { + System.out.println("Current client is drawing: " + fromClient); + IDrawingUpdate client; + for (User u: server.users){ + client = u.getIDrawingUpdate(); + client.notifyUserIsDrawing(fromClient); + } + + } + + public void broadcastDrawingUserStopped (String fromClient) throws RemoteException{ + System.out.println("Current user stopped drawing" + fromClient); + IDrawingUpdate client; + for (User u: server.users){ + client = u.getIDrawingUpdate(); + client.notifyUserStoppedDrawing(fromClient); + } + + } + + + public boolean broadcastUpdateImage(String fromClient) throws RemoteException { - System.out.print("Broadcasting new image loading to everyone..."); +// System.out.print("Broadcasting new image loading to everyone..."); try { @@ -191,7 +216,7 @@ public class DrawingController extends UnicastRemoteObject implements IDrawingCo err.printStackTrace(); } - System.out.print("...DONE\n"); +// System.out.print("...DONE\n"); return true; } diff --git a/src/server/MySharedKey.java b/src/server/MySharedKey.java index e16485e2e87a5ff48c8ea4bd2bfe05757dc7802f..bd4c8abc513f1cd69605dc3da48583e643254988 100644 --- a/src/server/MySharedKey.java +++ b/src/server/MySharedKey.java @@ -13,6 +13,11 @@ import java.util.Base64; public class MySharedKey { private byte[] encryptedSharedSecretKey; private IEncryptionUpdate encryptionUpdate; + + public SecretKey getSharedSecretKey() { + return sharedSecretKey; + } + private SecretKey sharedSecretKey; @@ -21,7 +26,7 @@ public class MySharedKey { this.sharedSecretKey = new SecretKeySpec(new byte[16], "AES"); System.out.println(sharedSecretKey); this.encryptedSharedSecretKey = wrapKey(encryptionUpdate.getPub()); - System.out.println("Shared key on server:" + encryptedSharedSecretKey); + System.out.println("Shared key on server:" + sharedSecretKey); encryptionUpdate.setSharedKey(encryptedSharedSecretKey); } diff --git a/src/server/Server.java b/src/server/Server.java index 3c87547eb432efd1ece33613e411299c4df13e07..517469cb256874cffb99cbad0baad26e4a7e6ace 100644 --- a/src/server/Server.java +++ b/src/server/Server.java @@ -52,7 +52,7 @@ public class Server { Server server = new Server(); - server.run(); + server.run(args[0]); } catch( Exception e ) { @@ -60,15 +60,15 @@ public class Server } } - public void run() throws RemoteException + public void run(String serverIP) throws RemoteException { - String serverIP = ""; - try { - InetAddress inetAddress = InetAddress.getLocalHost(); - serverIP = inetAddress.getHostAddress(); - } catch (Exception e) { - e.printStackTrace(); - } +// String serverIP = ""; +// try { +// InetAddress inetAddress = InetAddress.getLocalHost(); +// serverIP = inetAddress.getHostAddress(); +// } catch (Exception e) { +// e.printStackTrace(); +// } System.setProperty("java.rmi.server.hostname", serverIP); @@ -90,31 +90,21 @@ public class Server registry.rebind(clientControllerName, clientController); registry.rebind(chatControllerName, chatController); registry.rebind(drawingControllerName, drawingController); -// registry.rebind(clientControllerName, UnicastRemoteObject.exportObject(clientController, 1099)); -// registry.rebind(chatControllerName, UnicastRemoteObject.exportObject(chatController, 1099)); -// registry.rebind(drawingControllerName, UnicastRemoteObject.exportObject(drawingController, 1099)); - -// try { -// Naming.rebind(clientControllerName, clientController); -// Naming.rebind(chatControllerName, chatController); -// Naming.rebind(drawingControllerName, drawingController); -// } catch (MalformedURLException e) { -// e.printStackTrace(); -// } - System.out.println("Server is ready"); - printIP(); + printIP(serverIP); } - private void printIP() + private void printIP(String serverIP) { InetAddress inetAddress = null; try { - inetAddress = InetAddress.getLocalHost(); + if (serverIP.isEmpty()) { + inetAddress = InetAddress.getLocalHost(); + } else inetAddress = InetAddress.getByName(serverIP); } catch (UnknownHostException e) { diff --git a/src/server/User.java b/src/server/User.java index 543f26e6c9056a69b382ae8dc4819d4116e95559..c3166674cf9d3cc67d04b547213a5377242088b0 100644 --- a/src/server/User.java +++ b/src/server/User.java @@ -4,6 +4,8 @@ import remote.IChatUpdate; import remote.IClientUpdate; import remote.IDrawingUpdate; +import javax.crypto.SecretKey; + public class User { private String username; @@ -12,12 +14,19 @@ public class User private IClientUpdate IClientUpdate; private boolean isAdmin; - public User(String username, IChatUpdate IChatUpdate, IClientUpdate IClientUpdate, IDrawingUpdate IDrawingUpdate) + public SecretKey getSharedSecretKey() { + return sharedSecretKey; + } + + private SecretKey sharedSecretKey; + + public User(String username, IChatUpdate IChatUpdate, IClientUpdate IClientUpdate, IDrawingUpdate IDrawingUpdate, SecretKey sharedSecretKey) { this.username = username; this.IChatUpdate = IChatUpdate; this.IDrawingUpdate = IDrawingUpdate; this.IClientUpdate = IClientUpdate; + this.sharedSecretKey = sharedSecretKey; this.isAdmin = false; } diff --git a/src/server/server.policy b/src/server/server.policy index 5c059491c631fa37d14fc62d9654cdb13ce184c0..be17177b9474e62dc5d6c236756a51054ba11904 100644 --- a/src/server/server.policy +++ b/src/server/server.policy @@ -1,3 +1,4 @@ grant codeBase "file:/Users/haiho/OneDrive - The University of Melbourne/Distributed Systems (COMP90015)/Assignment 2/InfinityMonkeys-remaster/comp90015-dsass2-infinitymonkeys-remaster/out/production/comp90015-dsass2-infinitymonkeys-remaster/" { + permission java.util.PropertyPermission '*', "read,write"; permission java.security.AllPermission; }; \ No newline at end of file