/* Filename : clientwindow.java * Version : Beta V1.0 * Author : Dr. Roger Webster * This client is designed around the gameServer and client classes. * This means that the server only supports a few * functions. The client must take care of pretty much everything. * This allows them to be very flexible and even allows the possiblity * of playing multiple types of games with the same gameServer. * This provides the ability to to create an arbitrary game and * still use the same network functionality. */ import java.applet.*; import java.awt.*; import java.net.*; import java.util.Vector; class clientwindow extends Frame implements Runnable { static final int PLAYER1 = 1; static final int PLAYER2 = 2; private gameclient gclient = new gameclient(); private String text, opponent_temp; private Vector id_vector = new Vector(1,1); private boolean game_on = false; private boolean move_received = false; private boolean finish = false; private boolean challenged = false; private int player = PLAYER1; // who is player 1 private int other_player = PLAYER2; // who is player 2 private int opponent_id; // store id of opponent private int personal_id; // store your id private String nextMoveBuffer; // store next move made private URL base; private int port; private Thread thread; private int battle_id; private Label userlabel; private Label userlabel2; private Label userlabel3; private Panel mypanel; private String Username; private List user_list; private TextArea textArea; private TextField textField; private Color bk_color; private Color fg_color; private Color bx_color; private boolean statusflag = false; private Image gameimage; private graphicpanel gp; private game mygame; // User fills this class in Applet myapplet; clientwindow(Applet theapplet, URL base_url, int theport, String User, Image image) { myapplet = theapplet; base = base_url; port = theport; Username = User; gameimage = image; int framewidth = 410; int frameheight = 540; bk_color = new Color(90,90,90); fg_color = new Color(255,206,140); bx_color = new Color(2,29,15); this.setSize(framewidth,frameheight); this.setTitle("Client-Server Communications Window"); this.setBackground(Color.black); this.setForeground(Color.black); this.setLayout(null); gp = new graphicpanel(gameimage); gp.setLocation(60, 30); gp.setSize(300,100); this.add(gp); // userlabel = new Label(); // userlabel.setText(" " + User); // userlabel.setFont(new Font("Helvetica",Font.PLAIN,16)); // userlabel.setForeground(Color.white); // userlabel.setBackground(Color.black); // userlabel.setLocation(framewidth / 4, 70); // userlabel.setSize(100,30); // this.add(userlabel); mypanel = new Panel(); mypanel.setLayout(new BorderLayout()); userlabel2 = new Label(); userlabel2.setText(" List of Players Waiting -> to Play Double Click One"); userlabel2.setFont(new Font("Helvetica",Font.PLAIN,16)); userlabel2.setForeground(Color.white); userlabel2.setBackground(Color.black); mypanel.add(userlabel2, BorderLayout.NORTH); user_list=new List(); user_list.setBackground(Color.blue); user_list.setForeground(Color.white); mypanel.add(user_list, BorderLayout.CENTER); mypanel.setLocation(4, 135); mypanel.setSize(framewidth-5,200); this.add(mypanel); userlabel3= new Label(); userlabel3.setText(" Type in red box below & hit c/r to send msg to Opponent"); userlabel3.setFont(new Font("Helvetica",Font.PLAIN,16)); userlabel3.setForeground(Color.white); userlabel3.setBackground(Color.black); userlabel3.setLocation(1, 340); userlabel3.setSize(framewidth,30); this.add(userlabel3); textField=new TextField(41); textField.setFont(new Font("Helvetica",Font.PLAIN,16)); textField.setBackground(Color.red); textField.setForeground(Color.white); textField.setLocation(1, 370); textField.setSize(framewidth,30); this.add(textField); textArea=new TextArea(41,8); textArea.setFont(new Font("Helvetica",Font.PLAIN,14)); textArea.setBackground(Color.white); textArea.setForeground(Color.black); textArea.setEditable(false); textArea.setLocation(1, 400); textArea.setSize(framewidth,100); this.add(textArea); this.setSize(framewidth, frameheight); this.show(); this.start(); // start this thread via contructor } // gets the thread going public void start() { System.out.println("starting thread"); thread = new Thread(this,"main"); thread.start(); } public void run() { System.out.println("RUN ing thread"); display("Trying to connect to socket...\n"); System.out.println("server port is " + port); System.out.println("URL is " + base.getHost()); statusflag = gclient.connect(base.getHost(),port); if (!statusflag) { display("Unable to to connect, gameServer is probably down...\n"); } else { display ("Connected to Socket!!!\n"); String textstream = Username; gclient.send_stream("!!name!!" +textstream); System.out.println("gclient.send_stream username sent is " + textstream); } while (true) { try{thread.sleep(50);} catch(InterruptedException e){} if (gclient.running()) continue; if (gclient.input_stream_available()) { text = gclient.get_input(); if (gclient.is_nameslist(text)) write_list(text.substring(9)); if (gclient.is_directive(text)) processDirective(text.substring(13)); if (!gclient.is_directive(text) && !gclient.is_nameslist(text)) display(text); } } } // If directive, deal with it according to the message that is attached public void processDirective(String text) { String temp; int next, temp_id, opp_id; temp = text; text = text.substring(6); char next_char; // if the directive is a challenge... if (temp.startsWith("chlng")) { next = text.indexOf(','); temp = text.substring(0,next); if (!game_on) { opponent_id = Integer.parseInt(temp); text = text.substring(next+1); temp = text.substring(0); opponent_temp = temp.trim(); player = PLAYER2; other_player = PLAYER1; challenged = true; display("You have been asked to Play by "+ temp); display("hit the 'Play Opponent' button to Play\n"); acceptwindow accept = new acceptwindow(this, "Do You Want to Play ", temp); } else { opp_id = Integer.parseInt(temp); temp_id = id_vector.indexOf(new Integer(opp_id)); battle_id = id_vector.indexOf(new Integer(opp_id)); gclient.send_stream("!!directive!!mssge,busy|"+Integer.toString(temp_id+1)+"|"); } } // if the directive is a message... if(temp.startsWith("mssge")) { if (text.startsWith("uid")) { temp = text.substring(4); personal_id = Integer.parseInt(temp.trim()); } if (text.startsWith("busy")) display ("That player is currently playing a game...\n"); if (text.startsWith("surrender")) { display("Your opponent has surrendered\n"); game_on = false; } } // if directive is an accept challenge... if(temp.startsWith("accpt") && !challenged) { next = text.indexOf(','); temp = text.substring(0,next); temp_id = Integer.parseInt(temp.trim()); if(temp_id == opponent_id) { text = text.substring(next+1); game_on = true; player = PLAYER1; other_player = PLAYER2; challenged = false; display("GAME ON!! you go first\n"); mygame = new game(myapplet, base, this, true, gameimage); } } // if directive is a move if(temp.startsWith("pmove")) { next = text.indexOf(','); temp = text.substring(0,next); move_received = true; nextMoveBuffer = temp; mygame.set_opponent_move(nextMoveBuffer); // calls game method } } public void quitWindow () { int index; display("Preparing to log off.\n"); if (game_on) { index = id_vector.indexOf(new Integer(opponent_id)); gclient.send_stream("!!directive!!mssge,surrender|"+Integer.toString(index+1)+"|"); } gclient.cleanup(); dispose(); } //****************************************************************** // put the unique id's into id_vector and names into user_list public void write_list(String list) { int i, next, n; int temp_id; user_list.delItems( 0, user_list.countItems() -1 ); user_list.clear(); id_vector.removeAllElements(); for (i=0;i= list.length() || next == -1) break; temp_id = Integer.parseInt(list.substring(i,n)); id_vector.addElement(new Integer(temp_id)); user_list.addItem(list.substring(n+1,next)); i = next; } //user_list.reshape(258,116,99,176); } // display the text to the output area of the screen public void display(String s) { try{thread.sleep(100);}catch(InterruptedException e){} textArea.appendText(s); } // event handler for GUI components public boolean handleEvent(Event evt) { int index, storage; // when you double-click on a user name in the user_list if (evt.id == Event.ACTION_EVENT && evt.target == user_list && !game_on) { index = user_list.getSelectedIndex(); opponent_id = ((Integer)id_vector.elementAt(index)).intValue(); if (opponent_id != personal_id) { display("Challenging "+ (String)evt.arg + " to Internet game!\n"); gclient.send_stream("!!directive!!chlng,"+Integer.toString(personal_id)+"|"+Integer.toString(index+1)+"|"); } else display("You cannot challenge yourself.\n"); } // when you perform an action while you are connected if (evt.id == Event.ACTION_EVENT && gclient.is_connected()) { if (gclient.stream_down()) { display("A socket error has occured, you are not connected.\n"); return super.handleEvent(evt); } if (evt.target == textField) { // if want to send a message to the other player String textstream = textField.getText(); textField.setText(""); gclient.send_stream(textstream); } } return super.handleEvent(evt); } public void stop() { int index; display("Preparing to log off.\n"); if (game_on) { index = id_vector.indexOf(new Integer(opponent_id)); gclient.send_stream("!!directive!!mssge,surrender|"+Integer.toString(index+1)+"|"); } gclient.cleanup(); } //****************************************************************** // methods to interact with your game class // game class calls this to send a move to other player //****************************************************************** public void sendMove(String text) { int index; index = id_vector.indexOf(new Integer(opponent_id)); gclient.send_stream("!!directive!!pmove," +text+ "|" +Integer.toString(index +1) +"|"); } public void acceptyes() { int index; System.out.println ("accept yes"); // when you hit the Play Opponent button display("Opponent ready to Play! You will move second.\n"); index = id_vector.indexOf(new Integer(opponent_id)); System.out.println("opponent id is " + opponent_id); gclient.send_stream("!!directive!!accpt,"+Integer.toString(personal_id)+"|"+Integer.toString(index+1)+"|"); challenged = false; game_on = true; mygame = new game(myapplet, base, this, false, gameimage); } } // end class class acceptwindow extends Frame { private clientwindow parent; private Panel buttonPanel; private Button acceptyes; private Button acceptno; private Label user_label; public acceptwindow(clientwindow parent, String wintitle, String User) { super(wintitle); this.parent = parent; user_label = new Label("You have been asked to play with " + User); buttonPanel = new Panel(); acceptyes = new Button("Play Opponent"); acceptno = new Button("Don't Play Opponent"); //Add button to panel and panel to window setLayout(new FlowLayout()); buttonPanel.setLayout(new GridLayout(7,1)); buttonPanel.add(user_label); buttonPanel.add(acceptyes); buttonPanel.add(acceptno); add(buttonPanel); //Size window to preferred size this.setSize(300, 300); this.show(); }//end loginwindow // uses the jdk1.0.2 event handler... public boolean action(Event e, Object arg) { if(e.target instanceof Button) { if(e.target == acceptyes) { if(this.isShowing()) { try { parent.acceptyes(); } catch(Exception exceptn) { exceptn.printStackTrace(); System.out.println("Error:" + exceptn); } finally { this.dispose(); } } } if(e.target == acceptno) { this.dispose(); } } return true; } //end action(Event, Object) }//end class definition