1919import javax .swing .JLabel ;
2020import javax .swing .JOptionPane ;
2121import javax .swing .JPanel ;
22+ import javax .swing .JPasswordField ;
2223import javax .swing .JScrollPane ;
2324import javax .swing .JTextArea ;
2425import javax .swing .JTextField ;
2526import javax .swing .SwingUtilities ;
2627import javax .swing .SwingWorker ;
2728import javax .swing .border .EmptyBorder ;
2829
30+ import dev .abhay7 .skribbl .client .jameskwong .pwdsignal .PWDSignalSession ;
31+ import dev .abhay7 .skribbl .client .jameskwong .pwdsignal .PWDSignalSessionState ;
2932import dev .abhay7 .skribbl .server .datapacks .LobbyJoinPack ;
33+ import dev .abhay7 .skribbl .server .datapacks .PayloadPack ;
3034import dev .abhay7 .skribbl .server .datapacks .WordsFetchPack ;
3135
3236public class Client {
@@ -38,7 +42,7 @@ public class Client {
3842
3943 private JFrame frame ;
4044
41- private String username ;
45+ public String username ;
4246 private String serverInet ;
4347 private int serverPort ;
4448
@@ -50,11 +54,12 @@ public class Client {
5054 private String lobbiesListTitle ;
5155 private String inGameTitle ;
5256
57+
5358 private Map <String , Integer > currentPlayersMap ;
5459 private ArrayList <String > currentPlayersList ;
5560 private ArrayList <String > playersWhoHavePlayed ;
5661 private ArrayList <String > wordsGuessed ;
57-
62+
5863 private String chosenWord = "" ;
5964
6065 private ArrayList <String > wordList ;
@@ -73,6 +78,12 @@ public class Client {
7378 private static final byte MAX_DIALOG_COUNT = 5 ;
7479 private byte openDialogs ;
7580
81+ public volatile boolean inPrivate ;
82+
83+ public Map <String , PWDSignalSession > privateSessions ;
84+
85+ public volatile String privLobbyPassword ;
86+
7687 public Client (String ... args ) {
7788 if (args .length < 3 || args [0 ].isBlank () || args [1 ].isBlank () || args [2 ].equals ("0" )) {
7889 fatalError ("Invalid Client Arguments" , new IllegalArgumentException ());
@@ -245,9 +256,15 @@ protected void done() {
245256 jb .add (new JLabel (lob [2 ]));
246257 jb .add (new JLabel (lob [0 ]));
247258 jb .add (new JLabel ("Players: " + lob [1 ]));
259+ Boolean isPrivate = Boolean .parseBoolean (lob [3 ]);
260+ jb .add (new JLabel (isPrivate ? "PRIVATE" : "PUBLIC" ));
248261 jb .setAlignmentX (JButton .CENTER_ALIGNMENT );
249262 jb .setPreferredSize (new Dimension ((int ) (d .getWidth () / 3.5 ), (int ) d .getHeight () / 7 ));
250263 jb .addActionListener ((_ ) -> {
264+ if (isPrivate ){
265+ joinPrivateLobby (lob [0 ]);
266+ return ;
267+ }
251268 joinPublicLobby (lob [0 ]);
252269 });
253270 lobbiesListPanel .add (jb );
@@ -271,11 +288,10 @@ private void createLobby() {
271288 @ Override
272289 protected Boolean doInBackground () throws Exception {
273290 if (lobbyArgs .length == 1 ) {
274- return networkHandler .createPublicLobby (lobbyArgs [0 ]).isSuccess ();
291+ return networkHandler .createLobby (lobbyArgs [0 ], false ).isSuccess ();
275292 } else if (lobbyArgs .length == 2 ) {
276- // TODO: Implement private lobbies
277- return networkHandler .createPublicLobby (lobbyArgs [0 ]).isSuccess ();
278- // return false;
293+ // private lobby
294+ return networkHandler .createLobby (lobbyArgs [0 ], true ).isSuccess ();
279295 }
280296 return false ;
281297 }
@@ -290,6 +306,10 @@ protected void done() {
290306 if (createdLobby ) {
291307 isPlaying = true ;
292308 isHosting = true ;
309+ inPrivate = lobbyArgs .length == 2 ;
310+ privateSessions = new HashMap <>();
311+
312+ privLobbyPassword = lobbyArgs .length == 2 ? lobbyArgs [1 ] : null ;
293313 currentPlayersList .add (username );
294314 currentPlayersMap .put (username , 0 );
295315 frame .remove (currentlyDisplayedPanel );
@@ -305,6 +325,75 @@ protected void done() {
305325 }
306326 }
307327
328+ public void withPayload (PayloadPack pp ) {
329+ if (!inPrivate ) return ;
330+ if (!isPlaying ) return ;
331+
332+ if (!privateSessions .containsKey (pp .source )) {
333+ try {
334+ privateSessions .put (pp .source , new PWDSignalSession (privLobbyPassword , false ));
335+ } catch (Exception ex ) {
336+ System .out .println ("Failed responding to pp; couldnt create initial session" );
337+ return ;
338+ }
339+ }
340+
341+ PWDSignalSession session = privateSessions .get (pp .source );
342+
343+ switch (session .getState ()) {
344+ case PWDSignalSessionState .INITIALIZED :
345+ {
346+ // first payload received, need to give them it too
347+ try {
348+ byte [] data = session .createPayload1 ();
349+ session .acceptPayload1 (pp .data , 0 );
350+ networkHandler .sendPayload (pp .source , data , username );
351+ System .out .println ("Accepted and sent payload 1" );
352+ }
353+ catch (Exception ex ) {
354+ System .out .println ("Failed responding to pp; payload 1: " + ex .getMessage ());
355+ privateSessions .remove (pp .source );
356+ }
357+
358+ break ;
359+ }
360+ case PWDSignalSessionState .PAYLOAD_1_VALIDATED :
361+ {
362+ // second payload received, need to give them it too
363+ try {
364+ byte [] data = session .createPayload2 ();
365+ session .acceptPayload2 (pp .data , 0 );
366+ networkHandler .sendPayload (pp .source , data , username );
367+ System .out .println ("Accepted and sent payload 2" );
368+ }
369+ catch (Exception ex ) {
370+ System .out .println ("Failed responding to pp; payload 2: " + ex .getMessage ());
371+ privateSessions .remove (pp .source );
372+ }
373+ break ;
374+ }
375+ case PWDSignalSessionState .PAYLOAD_2_VALIDATED :
376+ {
377+ // 3rd payload received, need to give them it too
378+ try {
379+ byte [] data = session .createPayload3 ();
380+ session .acceptPayload3 (pp .data , 0 );
381+ networkHandler .sendPayload (pp .source , data , username );
382+ System .out .println ("Accepted and sent payload 3" );
383+ }
384+ catch (Exception ex ) {
385+ System .out .println ("Failed responding to pp; payload 3: " + ex .getMessage ());
386+ privateSessions .remove (pp .source );
387+ }
388+ break ;
389+ }
390+ default :{
391+ System .out .println ("ILLEGAL CASE WTF: " + session .getState ());
392+ return ;
393+ }
394+ }
395+ }
396+
308397 // Prompt user for parameters to create a lobby
309398 private String [] promptForCreateLobbyArgs () {
310399 JTextField lobbyNameField = new JTextField ("Lobby - " + (new java .util .Date ()).toString ());
@@ -514,6 +603,10 @@ protected void startDrawing() {
514603 private void leaveLobby () {
515604 this .isPlaying = false ;
516605 this .isHosting = false ;
606+ inPrivate = false ;
607+ privLobbyPassword = null ;
608+ if (privateSessions != null )
609+ privateSessions .clear ();
517610
518611 this .currentPlayersList .clear ();
519612 this .currentPlayersMap .clear ();
@@ -581,6 +674,10 @@ protected void done() {
581674 if (ljp != null && ljp .isSuccess ()) {
582675 isPlaying = true ;
583676 isHosting = false ;
677+ privLobbyPassword = null ;
678+ if (privateSessions != null )
679+ privateSessions .clear ();
680+ inPrivate = false ;
584681 currentPlayersList .addAll (ljp .getPlayers ());
585682 currentPlayersList .forEach ((pl ) -> {
586683 currentPlayersMap .put (pl , 0 );
@@ -597,6 +694,64 @@ protected void done() {
597694 }).execute ();
598695 }
599696
697+ private void joinPrivateLobby (String lobName ) {
698+ JPasswordField passwordField = new JPasswordField ();
699+ Object [] message = {
700+ "Enter password for lobby '" + lobName + "':" , passwordField
701+ };
702+ int option = JOptionPane .showConfirmDialog (frame , message , "Enter Password" , JOptionPane .OK_CANCEL_OPTION , JOptionPane .PLAIN_MESSAGE );
703+ if (option == JOptionPane .OK_OPTION ) {
704+ String password = new String (passwordField .getPassword ());
705+ if (password .isEmpty ()) {
706+ showMessageDialog ("Password cannot be empty" , "error" , JOptionPane .ERROR_MESSAGE );
707+ return ;
708+ }
709+
710+ this .currentPlayersList = new ArrayList <String >();
711+ this .inGameTitle = "skribbl.io (Java) - " + lobName ;
712+ (new SwingWorker <Tuple <HashMap <String , PWDSignalSession >, LobbyJoinPack >, Void >() {
713+
714+ @ Override
715+ protected Tuple <HashMap <String , PWDSignalSession >, LobbyJoinPack > doInBackground () throws Exception {
716+ return networkHandler .joinPrivateLobby (password , lobName );
717+ }
718+
719+ protected void done () {
720+ Tuple <HashMap <String , PWDSignalSession >, LobbyJoinPack > ljp = null ;
721+ try {
722+ ljp = get ();
723+ } catch (Exception e ) {
724+ showMessageDialog ("Failed to join private lobby: " + e , "Lobby Join Error" , JOptionPane .ERROR_MESSAGE );
725+ }
726+
727+ if (ljp != null ) {
728+ isPlaying = true ;
729+ isHosting = false ;
730+ inPrivate = true ;
731+ privLobbyPassword = password ;
732+ privateSessions = ljp .x ;
733+ currentPlayersList .addAll (ljp .y .getPlayers ());
734+ currentPlayersList .forEach ((pl ) -> {
735+ currentPlayersMap .put (pl , 0 );
736+ });
737+ frame .remove (currentlyDisplayedPanel );
738+ currentlyDisplayedPanel = getGamePanel (lobName );
739+ frame .add (currentlyDisplayedPanel );
740+ frame .setTitle (inGameTitle );
741+ frame .revalidate ();
742+ frame .repaint ();
743+
744+ System .out .println ("Successfully joined private lobby!!!" );
745+ }
746+ }
747+
748+ }).execute ();
749+ }
750+ else {
751+ // cancelled jonining
752+ }
753+ }
754+
600755 protected void updatePlayerList (ArrayList <String > usernames ) {
601756 for (String username : usernames ) {
602757 if (!this .currentPlayersList .contains (username )) {
0 commit comments