Source code: marauroa/JMarauroa.java
1 /* $Id: JMarauroa.java,v 1.15 2003/12/15 17:58:15 arianne_rpg Exp $ */
2 /***************************************************************************
3 * (C) Copyright 2003 - Marauroa *
4 ***************************************************************************
5 ***************************************************************************
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 ***************************************************************************/
13 package marauroa;
14
15 import java.awt.*;
16 import java.awt.event.*;
17 import javax.swing.*;
18 import marauroa.net.*;
19
20 import java.io.ByteArrayOutputStream;
21 import java.io.PrintStream;
22 import java.net.SocketException;
23 import java.text.SimpleDateFormat;
24 import java.util.Date;
25 import marauroa.game.RPObject;
26 import simplegame.SimpleGame;
27
28
29 /**
30 * Test client for marauroa
31 **/
32 public class JMarauroa
33 extends JFrame
34 {
35 private final static String ACTION_CMD_LOGIN = "login";
36 private final static String ACTION_CMD_DISCONNECT = "disconnect";
37 private final static String ACTION_CMD_EXIT = "exit";
38 private final static String ACTION_CMD_ABOUT = "about";
39 private final static String ACTION_CMD_PLAY = "play";
40
41
42 private JTextArea reportsTextArea;
43 private JComponent glassPane;
44 private ActionHandler actionHandler;
45
46 private SimpleDateFormat formatter;
47 private Date logDate;
48
49 private int clientId;
50 private NetworkClientManager netMan;
51 private RPObject.ID characterID;
52
53
54 public JMarauroa()
55 {
56 actionHandler = new ActionHandler();
57 actionHandler.start();
58 setTitle("Marauroa test client");
59 setIconImage(new ImageIcon(getClass().getClassLoader().getResource("images/marauroa_ICON.png")).getImage());
60 initMenu();
61 initComponents();
62 clientId=-10;
63 formatter = new SimpleDateFormat("[HH:MM:ss.SSS] ");
64 logDate = new Date();
65 addWindowListener(new WindowAdapter()
66 {
67 public void windowOpened(WindowEvent we)
68 {
69 actionHandler.add(new ActionEvent(this,0,ACTION_CMD_LOGIN));
70 }
71 public void windowClosing(WindowEvent p0)
72 {
73 exit();
74 }
75 });
76 glassPane = new JPanel();
77 glassPane.setCursor(new Cursor(Cursor.WAIT_CURSOR));
78 glassPane.setOpaque(false);
79 glassPane.addMouseListener(new MouseAdapter(){} );
80 glassPane.addKeyListener(new KeyAdapter()
81 {
82 public void keyPressed(KeyEvent e)
83 {
84 if(e.getKeyCode()==KeyEvent.VK_ESCAPE)
85 {
86 }
87 }} );
88 glassPane.addFocusListener(new FocusListener()
89 {
90
91 public void focusGained(FocusEvent e)
92 {
93 }
94
95 public void focusLost(FocusEvent e)
96 {
97 }
98
99 });
100 setGlassPane(glassPane);
101 }
102
103 private void connectAndChooseCharacter(String hostname, String user, String pwd)
104 {
105 addLog("Starting network client manager\n");
106 try
107 {
108 netMan=new NetworkClientManager(hostname);
109 }
110 catch(SocketException e)
111 {
112 addLog("Exception starting network client manager\n");
113 addLog(e);
114 }
115
116 MessageC2SLogin msg=new MessageC2SLogin(null,user,pwd);
117 netMan.addMessage(msg);
118
119 boolean complete=false;
120 int recieved=0;
121 boolean login_worked=false;
122
123 String[] characters=null;
124 String[] serverInfo=null;
125
126 while(!complete && recieved<3)
127 {
128 Message message=netMan.getMessage();
129
130 if(message==null) continue;
131
132 switch(message.getType())
133 {
134 case Message.TYPE_S2C_LOGIN_NACK:
135 addLog("Login reject because "+((MessageS2CLoginNACK)message).getResolution()+"\n");
136 complete=true;
137 break;
138 case Message.TYPE_S2C_LOGIN_ACK:
139 addLog("Login successful\n");
140 clientId=message.getClientID();
141 addLog("Recieved clientid: "+clientId+"\n");
142 ++recieved;
143 break;
144 case Message.TYPE_S2C_CHARACTERLIST:
145 characters=((MessageS2CCharacterList)message).getCharacters();
146 for(int i=0;i<characters.length;++i)
147 {
148 addLog("- "+characters[i]+"\n");
149 }
150
151 ++recieved;
152 break;
153 case Message.TYPE_S2C_SERVERINFO:
154 serverInfo=((MessageS2CServerInfo)message).getContents();
155 for(int i=0;i<serverInfo.length;++i)
156 {
157 addLog("- "+serverInfo[i]+"\n");
158 }
159 ++recieved;
160 break;
161 }
162 }
163
164 if(characters!=null && characters.length>0)
165 {
166 Object[] message = new Object[2];
167 message[0] = "Characters:";
168
169 JComboBox cb_characters = new JComboBox();
170 for (int i = 0; i < characters.length; i++)
171 {
172 cb_characters.addItem(characters[i]);
173 }
174
175 message[1] = cb_characters;
176
177 // Options
178 String[] options = {"Choose"};
179 int result = JOptionPane.showOptionDialog(
180 this, // the parent that the dialog blocks
181 message, // the dialog message array
182 "Choose your character...", // the title of the dialog window
183 JOptionPane.DEFAULT_OPTION, // option type
184 JOptionPane.INFORMATION_MESSAGE, // message type
185 new ImageIcon("wurst.png"), // optional icon, use null to use the default icon
186 options, // options string array, will be made into buttons
187 options[0] // option that should be made into a default button
188 );
189 switch(result)
190 {
191 case 0: // choose character
192 {
193 String character = String.valueOf(cb_characters.getSelectedItem());
194 chooseCharacter(character);
195 }
196 break;
197 case 1: // cancel
198 break;
199 default:
200 break;
201 }
202
203 }
204 else
205 {
206 JOptionPane.showMessageDialog(this,"No characters received from server");
207 }
208
209 }
210
211
212 /**
213 * @param args the command line arguments
214 */
215 public static void main(String args[])
216 {
217 JMarauroa marauroa = new JMarauroa();
218 marauroa.pack();
219 Dimension screen_size = Toolkit.getDefaultToolkit().getScreenSize();
220 Dimension own_dimen = marauroa.getSize();
221 int x = screen_size.width/2 - own_dimen.width/2;
222 int y = screen_size.height/2 - own_dimen.height/2;
223 marauroa.setLocation(x,y);
224 marauroa.show();
225 }
226
227
228 /** Exit the Application */
229 private void exit()
230 {
231 System.exit(0);
232 }
233
234 private void initMenu()
235 {
236 JMenuBar menubar = new JMenuBar();
237 JMenu mnu_server = new JMenu("Server");
238 mnu_server.setMnemonic('S');
239 JMenuItem mnu_item_connect = new JMenuItem("Login");
240 mnu_item_connect.setAccelerator(KeyStroke.getKeyStroke("control L"));
241 mnu_item_connect.setMnemonic('C');
242 mnu_item_connect.addActionListener(actionHandler);
243 mnu_item_connect.setActionCommand(ACTION_CMD_LOGIN);
244 mnu_server.add(mnu_item_connect);
245
246 JMenuItem mnu_item_disconnect = new JMenuItem("Disconnect");
247 mnu_item_disconnect.setAccelerator(KeyStroke.getKeyStroke("control D"));
248 mnu_item_disconnect.addActionListener(actionHandler);
249 mnu_item_disconnect.setActionCommand(ACTION_CMD_DISCONNECT);
250 mnu_item_disconnect.setMnemonic('D');
251 mnu_server.add(mnu_item_disconnect);
252
253 JMenuItem mnu_item_letsplay = new JMenuItem("Let us play!");
254 mnu_item_letsplay.setAccelerator(KeyStroke.getKeyStroke("control P"));
255 mnu_item_letsplay.addActionListener(actionHandler);
256 mnu_item_letsplay.setActionCommand(ACTION_CMD_PLAY);
257 mnu_item_letsplay.setMnemonic('P');
258 mnu_server.add(mnu_item_letsplay);
259
260 JMenuItem mnu_item_exit = new JMenuItem("Exit");
261 mnu_item_exit.setAccelerator(KeyStroke.getKeyStroke("control X"));
262 mnu_item_exit.addActionListener(actionHandler);
263 mnu_item_exit.setActionCommand(ACTION_CMD_EXIT);
264 mnu_item_exit.setMnemonic('X');
265 mnu_server.add(mnu_item_exit);
266 menubar.add(mnu_server);
267
268 JMenu menu_help = new JMenu("Help");
269 menu_help.setMnemonic('H');
270 JMenuItem mnu_item = new JMenuItem("About");
271 mnu_item.setMnemonic('A');
272 mnu_item.addActionListener(actionHandler);
273 mnu_item.setActionCommand(ACTION_CMD_ABOUT);
274 menu_help.add(mnu_item);
275 menubar.add(menu_help);
276
277 setJMenuBar(menubar);
278 }
279
280
281
282 /**
283 * This method is called from within the init() method to
284 * initialize the form.
285 */
286 private void initComponents()
287 {
288 BackgroundImagePanel main_panel = new BackgroundImagePanel(new BorderLayout());
289 reportsTextArea = new JTextArea();
290 reportsTextArea.setEditable(false);
291 reportsTextArea.setLineWrap(false);
292 JScrollPane sp = new JScrollPane(reportsTextArea);
293 sp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
294 main_panel.add(sp,BorderLayout.CENTER);
295 main_panel.setPreferredSize(new Dimension(580, 200));
296 main_panel.setMinimumSize(new Dimension(580, 200));
297
298 reportsTextArea.setOpaque(false);
299 sp.getViewport().setOpaque(false);
300 sp.setOpaque(false);
301 sp.setBackground(Color.green);
302 reportsTextArea.setBackground(Color.red);
303 main_panel.setBackGroundImage(new ImageIcon(getClass().getClassLoader().getResource("images/marauroa_BG.png")).getImage());
304 main_panel.setOpaque(false);
305 main_panel.setBackground(Color.blue);
306
307 setContentPane(main_panel);
308 }
309
310
311 private void chooseCharacter(String character)
312 {
313 addLog(character+" choosen\n");
314 Message msg=new MessageC2SChooseCharacter(null,character);
315 msg.setClientID(clientId);
316
317 netMan.addMessage(msg);
318
319 Message msgReply=null;
320 while(msgReply==null)
321 {
322 msgReply=netMan.getMessage();
323
324 if(msgReply==null) continue;
325
326 if(msgReply.getType()==Message.TYPE_S2C_CHOOSECHARACTER_ACK)
327 {
328 MessageS2CChooseCharacterACK msg_ack = (MessageS2CChooseCharacterACK)msgReply;
329 characterID = msg_ack.getObjectID();
330 addLog("Character choosen correctly(id is "+characterID+")\n");
331
332 /** Automagically create a new simplegame event */
333 // SimpleGame sg = new SimpleGame(netMan,JMarauroa.this,characterID);
334 // sg.pack();
335 // sg.show();
336 // new Thread(sg,"Lets play thread...").start();
337 }
338
339 if(msgReply.getType()==Message.TYPE_S2C_CHOOSECHARACTER_NACK)
340 {
341 addLog("Character not choosen. Error.\n");
342 }
343 }
344 }
345
346
347 /**
348 * adds a message into reportPane
349 */
350 public void addLog(String msg)
351 {
352 logDate.setTime(System.currentTimeMillis());
353 String line = formatter.format(logDate) + msg;
354 reportsTextArea.append(line);
355 reportsTextArea.setCaretPosition(reportsTextArea.getText().length());
356 }
357
358 private void addLog(Exception thr)
359 {
360 ByteArrayOutputStream out= new ByteArrayOutputStream();
361 thr.printStackTrace(new PrintStream(out));
362 addLog(out.toString());
363 }
364
365
366
367 private void login()
368 {
369 // Messages
370 Object[] message = new Object[6];
371 message[0] = "Server to login:";
372
373
374 JComboBox cb_server = new JComboBox();
375 cb_server.addItem("127.0.0.1");
376 cb_server.addItem("192.168.100.100");
377 cb_server.addItem("localhost");
378 cb_server.setEditable(true);
379 message[1] = cb_server;
380
381 message[2] = "User:";
382
383 JComboBox cb_user = new JComboBox();
384 cb_user.addItem("Test Player");
385 cb_user.addItem("Another Test Player");
386 cb_user.setEditable(true);
387 message[3] = cb_user;
388
389 message[4] = "Password:";
390
391 JPasswordField pf_pwd = new JPasswordField();
392 pf_pwd.setText("Test Password");
393 message[5] = pf_pwd;
394
395
396 // Options
397 String[] options = {"Connect","Cancel",};
398 int result = JOptionPane.showOptionDialog(
399 this, // the parent that the dialog blocks
400 message, // the dialog message array
401 "Login to...", // the title of the dialog window
402 JOptionPane.DEFAULT_OPTION, // option type
403 JOptionPane.INFORMATION_MESSAGE, // message type
404 new ImageIcon("wurst.png"), // optional icon, use null to use the default icon
405 options, // options string array, will be made into buttons
406 options[0] // option that should be made into a default button
407 );
408 switch(result)
409 {
410 case 0: // connect
411 {
412 String hostname = null;
413 if(cb_server.getSelectedItem()!=null)
414 {
415 hostname = String.valueOf(cb_server.getSelectedItem());
416 }
417 else
418 {
419 hostname = String.valueOf(cb_server.getEditor().getItem());
420 }
421 String user_name = null;
422 if(cb_user.getSelectedItem()!=null)
423 {
424 user_name = String.valueOf(cb_user.getSelectedItem());
425 }
426 else
427 {
428 user_name = String.valueOf(cb_user.getEditor().getItem());
429 }
430 String pwd = new String(pf_pwd.getPassword());
431 connectAndChooseCharacter(hostname, user_name,pwd);
432
433 }
434 break;
435 case 1: // cancel
436 break;
437 default:
438 break;
439 }
440 }
441
442 private void disconnect()
443 {
444 if(netMan!=null)
445 {
446 Message msg=new MessageC2SLogout(null);
447 msg.setClientID(clientId);
448 netMan.addMessage(msg);
449 netMan.finish();
450 JOptionPane.showMessageDialog(this,"Disconnected");
451 netMan = null;
452 }
453 else
454 {
455 JOptionPane.showMessageDialog(this,"Not connected!!!");
456 }
457 }
458
459 private void about()
460 {
461 JOptionPane.showMessageDialog(this,"<html><body><font color=\"blue\">Marauroa</font> client version 0.10</body></html>","About",JOptionPane.INFORMATION_MESSAGE);
462 }
463
464
465 private final class ActionHandler
466 extends Thread implements ActionListener
467 {
468 private ActionEvent currentEvent;
469 private Object monitor;
470 private boolean end;
471 private JWindow cancelDialog;
472
473
474
475 public ActionHandler()
476 {
477 end = false;
478 monitor = new Object();
479 currentEvent = null;
480 }
481
482 private void letsplay()
483 {
484 SimpleGame sg = new SimpleGame(netMan,JMarauroa.this,characterID);
485 sg.pack();
486 sg.show();
487 new Thread(sg,"Lets play thread...").start();
488 }
489
490
491 private void process(ActionEvent e)
492 {
493 if(e!=null)
494 {
495 lockGui();
496 String action_cmd = e.getActionCommand();
497 try
498 {
499 addLog("processing event "+action_cmd+"\n");
500 if(ACTION_CMD_LOGIN.equals(action_cmd))
501 {
502 //login
503 login();
504 }
505 else if(ACTION_CMD_DISCONNECT.equals(action_cmd))
506 {
507 //disconnect
508 disconnect();
509 }
510 else if(ACTION_CMD_EXIT.equals(action_cmd))
511 {
512 //exit
513 exit();
514 }
515 else if(ACTION_CMD_ABOUT.equals(action_cmd))
516 {
517 //about
518 about();
519 }
520 else if(ACTION_CMD_PLAY.equals(action_cmd))
521 {
522 letsplay();
523 }
524 else
525 {
526 addLog("ignored unknown action: " +action_cmd+"\n");
527 }
528 addLog("event "+action_cmd + " procesed\n");
529 }
530 catch(Exception thr)
531 {
532 addLog("Uncaught exception processing : " + action_cmd + "\n");
533 addLog(thr);
534 }
535 finally
536 {
537 unlockGui();
538 }
539 }
540 }
541
542
543 public void actionPerformed(ActionEvent e)
544 {
545 add(e);
546 }
547
548
549 public void add(ActionEvent e)
550 {
551 synchronized(monitor)
552 {
553 currentEvent = e;
554 monitor.notifyAll();
555 }
556 }
557
558 public void run()
559 {
560 // System.out.println("Handler started");
561 while(!end)
562 {
563 ActionEvent ae = get();
564 if(ae!=null)
565 {
566 process(ae);
567 }
568 }
569 }
570
571 private ActionEvent get()
572 {
573 synchronized(monitor)
574 {
575 ActionEvent ret_event;
576 if(currentEvent==null)
577 {
578 //wait until event is set
579 try
580 {
581 monitor.wait();
582 }
583 catch (InterruptedException e)
584 {
585 addLog("ActionHandler interrupted!!!");
586 }
587 }
588 ret_event = currentEvent;
589 currentEvent = null;
590 return(ret_event);
591 }
592 }
593
594 private void unlockGui()
595 {
596 glassPane.setVisible(false);
597 }
598
599 private void lockGui()
600 {
601 glassPane.setVisible(true);
602 glassPane.requestFocusInWindow();
603 }
604
605 }
606
607
608 private final class BackgroundImagePanel
609 extends JPanel
610 {
611 private Image backGroundImage;
612
613 public BackgroundImagePanel(LayoutManager lm)
614 {
615 super(lm);
616 }
617
618 public void setBackGroundImage(Image backGroundImage)
619 {
620 this.backGroundImage = backGroundImage;
621 }
622
623 public Image getBackGroundImage()
624 {
625 return backGroundImage;
626 }
627
628 protected void paintComponent(Graphics g)
629 {
630 super.paintComponent(g);
631 if(backGroundImage!=null)
632 {
633 g.drawImage(backGroundImage,0,0,getSize().width-1,getSize().height-1, this);
634 }
635 }
636
637 }
638
639
640 }
641