1 4 package chipchatapplet; 5 6 import java.applet.Applet ; 7 import java.awt.Color ; 8 import java.io.BufferedReader ; 9 import java.io.DataOutputStream ; 10 import java.io.IOException ; 11 import java.io.InputStreamReader ; 12 import java.net.MalformedURLException ; 13 import java.net.Socket ; 14 import java.net.URL ; 15 16 import netscape.javascript.JSException; 17 import netscape.javascript.JSObject; 18 19 23 public final class ChipChatApplet extends Applet { 24 25 private final boolean debug = true; 26 27 28 private Socket sock = null; 29 30 private BufferedReader inStream = null; 31 32 private DataOutputStream outStream = null; 33 34 35 private JSObject win = null; 36 37 private JSObject doc = null; 38 39 40 private boolean connected = false; 41 42 43 private int userid = -1; 44 45 private int hostid = -2; 46 47 48 private long keepQuietTime = 0; 49 50 54 public String getAppletInfo() { 55 return "ChipChat Applet v1.0\r\nCopyright by Mr.Lee"; 56 } 57 58 61 public void init() { 62 logMsg("Init.."); 63 this.setBackground(Color.white); 64 String keepSessionMinute = getParameter("keepsession"); 65 if (keepSessionMinute != null) { 66 int m; 67 try { 68 m = Integer.parseInt(keepSessionMinute); 69 } catch (NumberFormatException e) { 70 logMsg("Error : 'keepsession' parameter is not number", e); 71 m = 9; 72 } 73 SessionKeeper keeper = new SessionKeeper(this, m); 74 keeper.setDaemon(true); 75 keeper.start(); 76 } 77 } 78 79 82 public void destroy() { 83 closeConnect(); 84 } 85 86 private JSObject getWin() { 87 if (win == null) 88 win = JSObject.getWindow(this); 89 return win; 90 } 91 92 private JSObject getDoc() { 93 if (doc == null) 94 doc = (JSObject) getWin().getMember("document"); 95 return doc; 96 } 97 98 102 void processMessage(final String msg) { 103 logMsg("PMSG:" + msg); 104 try { 105 int index = msg.indexOf(':'); 107 String cmd; 108 109 if (index < 0) { 110 logMsg("NOT_CMD:" + msg); 112 return; 113 } else { 114 cmd = msg.substring(0, index); 115 } 116 117 if (cmd.equalsIgnoreCase("MSG")) { 118 String [] v = spliteString(msg, '>', index + 1); 119 wincall("chipchat_printMsg", new Object [] { v[0], v[1] }); 120 } else if (cmd.equalsIgnoreCase("WSPSND")) { 121 String [] v = spliteString(msg, '>', index + 1); 122 wincall("chipchat_output_wspsnd", new Object [] { v[0], v[1] }); 123 } else if (cmd.equalsIgnoreCase("WSPRCV")) { 124 String [] v = spliteString(msg, '>', index + 1); 125 wincall("chipchat_output_wsprcv", new Object [] { v[0], v[1] }); 126 } else if (cmd.equalsIgnoreCase("ACK")) { 127 return; 128 } else if (cmd.equalsIgnoreCase("ERROR")) { 129 String error = msg.substring(index + 1); 130 wincall("chipchat_error", new Object [] { error }); 131 } else if (cmd.equalsIgnoreCase("INFO")) { 132 String [] v = spliteString(msg, '>', index + 1); 133 if (v[0].equalsIgnoreCase("GetIn")) { 134 String [] v2 = spliteString(v[1], '>', 0); 135 wincall("chipchat_getin", new Object [] { v2[0], v2[1] }); 136 } else if (v[0].equalsIgnoreCase("GetOut")) { 137 wincall("chipchat_getout", new Object [] { v[1] }); 138 } else if (v[0].equalsIgnoreCase("ChangePasswd")) { 139 wincall("chipchat_passwdChanged", new Object [] { v[1] }); 140 } else if (v[0].equalsIgnoreCase("ChangeRoomName")) { 141 wincall("chipchat_RoomnameChanged", new Object [] { v[1] }); 142 } else if (v[0].equalsIgnoreCase("ChangeMaxMan")) { 143 wincall("chipchat_MaxmanChanged", new Object [] { v[1] }); 144 } else if (v[0].equalsIgnoreCase("RoomInfo")) { 145 String [] p1 = spliteString(v[1], '>', 0); 146 String [] p2 = spliteString(p1[1], '>', 0); 147 wincall( 148 "chipchat_RoomInfo", 149 new Object [] { p2[1], p1[0], p2[0] }); 150 } else { 151 logMsg("Need to Process.. : " + v[0]); 152 } 153 } else if (cmd.equalsIgnoreCase("USERS")) { 154 wincall("chipchat_userlistStart", null); 155 int i = index + 1; 156 while (true) { 157 int idx1 = msg.indexOf('<', i); 158 int idx2 = msg.indexOf('>', i); 159 if (idx1 == -1 || idx2 == -1) { 160 break; 161 } 162 String id = msg.substring(i, idx1); 163 String name = msg.substring(idx1 + 1, idx2); 164 i = idx2 + 1; 165 wincall("chipchat_userlistAdd", new Object [] { id, name }); 166 } 167 wincall("chipchat_userlistEnd", null); 168 } else if (cmd.equalsIgnoreCase("ADMIN")) { 169 String msg2 = msg.substring(index + 1); 170 try { 171 hostid = Integer.parseInt(msg2); 172 } catch (NumberFormatException e) { 173 logMsg("Error.", e); 174 } 175 wincall("chipchat_setAdmin", new Object [] { msg2 }); 176 } else if (cmd.equalsIgnoreCase("ADMCG")) { 177 String msg2 = msg.substring(index + 1); 178 wincall("chipchat_adminChange", new Object [] { msg2 }); 179 } else if (cmd.equalsIgnoreCase("KEEPQUIET")) { 180 String [] v = spliteString(msg, '>', index + 1); 181 int who = Integer.parseInt(v[1]); 182 if (who == userid) { 183 keepQuietTime = System.currentTimeMillis(); 184 } 185 wincall("chipchat_keepQuit", new Object [] { v[0], v[1] }); 186 } else if (cmd.equalsIgnoreCase("KICKOUT")) { 187 String [] v = spliteString(msg, '>', index + 1); 188 int who = Integer.parseInt(v[1]); 189 if (who == userid) { 190 closeConnect(); 191 } 192 wincall("chipchat_kickOut", new Object [] { v[0], v[1] }); 193 } else if (cmd.equalsIgnoreCase("CUSTOM")) { 194 String [] p1 = spliteString(msg, '>', index + 1); 195 String [] p2 = spliteString(p1[1], '>', 0); 196 wincall( 197 "chipchat_custom", 198 new Object [] { p1[0], p2[0], p2[1] }); 199 } else if (cmd.equalsIgnoreCase("Connected")) { 200 connected = true; 201 String msg2 = msg.substring(index + 1); 202 wincall("chipchat_connected", new Object [] { msg2 }); 203 } else if (cmd.equalsIgnoreCase("ConnectID")) { 204 String submsg = msg.substring(index + 1); 205 userid = Integer.parseInt(submsg); 206 wincall("chipchat_setConnectID", new Object [] { submsg }); 207 } else if (cmd.equalsIgnoreCase("ConnectName")) { 208 String error = msg.substring(index + 1); 209 wincall("chipchat_setConnectName", new Object [] { error }); 210 } else if ( 211 cmd.equalsIgnoreCase("Content-Type") 212 || cmd.equalsIgnoreCase("Transfer-Encoding") 213 || cmd.equalsIgnoreCase("Date") 214 || cmd.equalsIgnoreCase("Server")) { return; 216 } else if (cmd.equals("CLOSED")) { 217 closeConnect(); 218 } else { 219 logMsg("Need to Process.. : " + cmd); 220 } 221 } catch (Exception e) { 222 System.out.println("## Parsing Error... of [" + msg + "]"); 223 e.printStackTrace(); 224 } 225 } 226 227 231 void sendToServer(final String msg) { 232 if (connected && outStream != null) { 233 try { 234 outStream.write((msg).getBytes()); 235 } catch (IOException e) { 236 logMsg("Stream write error.", e); 237 } 238 } else { 239 wincall("chipchat_notconnected", null); 240 } 241 } 242 243 246 void closeConnect() { 247 connected = false; 248 if (sock != null) { 249 try { 250 sock.close(); 251 } catch (IOException e) { 252 e.printStackTrace(); 253 } 254 sock = null; 255 } 256 } 257 258 265 String [] spliteString(final String src, final char ch, final int from) { 266 int index2 = src.indexOf(ch, from); 267 String writer; 268 if (index2 < 0) { 269 throw new IllegalArgumentException ( 270 "Input source can not split by '" 271 + ch 272 + "'. [" 273 + src 274 + ":" 275 + from 276 + "]"); 277 } else { 278 return new String [] { 279 src.substring(from, index2), 280 src.substring(index2 + 1)}; 281 } 282 } 283 284 289 void wincall(final String function, final Object [] param) { 290 Object [] realParam; 291 if (param == null) { 292 realParam = new Object [0]; 293 } else { 294 realParam = param; 295 } 296 try { 297 getWin().call(function, realParam); 298 } catch (JSException e) { 299 callAlert( 300 "function : " 301 + function 302 + "(arg*" 303 + realParam.length 304 + ") is exist?"); 305 } 306 } 307 308 312 void callAlert(final String msg) { 313 try { 314 getWin().call("alert", new String [] { msg }); 315 } catch (JSException e1) { 316 e1.printStackTrace(); 317 } 318 } 319 320 324 void logMsg(final String msg) { 325 if (debug) { 326 System.out.println(msg); 327 } 328 } 329 330 335 void logMsg(final String msg, final Throwable e) { 336 if (debug) { 337 System.out.println(msg + "\r\nCause : " + e.getMessage()); 338 e.printStackTrace(); 339 } 340 } 341 342 347 public static String htmlSpecialChars(final String src) { 348 return htmlSpecialChars(new StringBuffer (src)).toString(); 349 } 350 351 356 static StringBuffer htmlSpecialChars(final StringBuffer src) { 357 if (src == null) { 358 return null; 359 } 360 int length = src.length(); 361 StringBuffer result = new StringBuffer (); 362 363 char c2 = 'x'; 364 365 for (int i = 0; i < length; i++) { 366 char c1 = src.charAt(i); 367 if (c1 == '<') { 368 result.append("<"); 369 } else if (c1 == '>') { 370 result.append(">"); 371 } else if (c1 == '&') { 372 result.append("&"); 373 } else if (c1 == '"') { 374 result.append("""); 375 } else if (c1 == '\'') { 376 result.append("'"); 377 } else if (c1 == ' ' && c2 == ' ') { 378 result.append(" "); 379 } else { 380 result.append(c1); 381 } 382 c2 = c1; 383 } 384 return src; 385 } 386 387 392 393 396 public void connect() { 397 if (connected) { 398 return; 399 } 400 logMsg("Connect to server..."); 402 URL url; 403 try { 404 url = new URL (getDocumentBase(), "communicator.jsp"); 405 } catch (MalformedURLException e) { 406 logMsg("Error in connect(.).", e); 407 return; 408 } 409 410 int port; 411 { 412 String sPort = getParameter("port"); 414 if (sPort == null) { 415 port = url.getPort(); 416 if (port < 0) { 417 port = 80; 418 } 419 } else { 420 try { 421 port = Integer.parseInt(sPort); 422 } catch (NumberFormatException e) { 423 logMsg("Pasing error of 'port'.", e); 424 port = 80; 425 } 426 } 427 } 428 429 try { 430 logMsg( 431 "Host:[" 432 + url.getHost() 433 + "],Port:[" 434 + port 435 + "], File:[" 436 + url.getFile() 437 + "]"); 438 439 sock = new Socket (url.getHost(), port); 441 inStream = 442 new BufferedReader ( 443 new InputStreamReader (sock.getInputStream())); 444 outStream = new DataOutputStream (sock.getOutputStream()); 445 446 outStream.write( 448 ("GET " + url.getFile() + " HTTP/1.1\r\n").getBytes()); 449 outStream.write("Accept: */*\r\n".getBytes()); 450 outStream.write("Accept-Language: utf-8\r\n".getBytes()); 451 outStream.write( 452 ("Content-Type: multipart/form-data; boundary=---------------------------ASD5345435\r\n") 453 .getBytes()); 454 outStream.write("User-Agent: ChipChat agent.\r\n".getBytes()); 455 outStream.write( 456 ("INUM: " + getParameter("inum") + "\r\n").getBytes()); 457 String cookie = (String ) getDoc().getMember("cookie"); 458 if (cookie != null) { 459 outStream.write(("Cookie: " + cookie + "\r\n").getBytes()); 460 logMsg("Cookie:[" + cookie + "]"); } else { 462 logMsg("Cookie Not Exist.."); 463 } 464 outStream.write( 465 ("Host: " 466 + ((port == 80) ? url.getHost() : url.getHost() + ":" + port) 467 + "\r\n") 468 .getBytes()); 469 outStream.write( 470 ("Content-Length: " + Integer.MAX_VALUE + "\r\n").getBytes()); 471 outStream.write("Connection: Keep-Alive\r\n".getBytes()); 472 outStream.write("Cache-Control: no-cache\r\n".getBytes()); 473 outStream.write("\r\n".getBytes()); outStream.flush(); 475 476 Thread t1 = new Thread () { 478 public void run() { 479 try { 480 while (sock != null) { 481 String r = inStream.readLine(); 482 if (r == null) { 483 break; 484 } 485 processMessage(r); 486 } 487 } catch (IOException e) { 488 logMsg("Error..", e); 489 } finally { 490 if (connected) { 491 closeConnect(); 492 wincall("chipchat_connectionBroken", null); 493 } 494 } 495 } 496 }; 497 t1.setDaemon(true); 498 t1.start(); 499 500 Thread t2 = new Thread () { 502 public void run() { 503 try { 504 while (sock != null) { 505 if (sock.isClosed()) { 506 break; 507 } 508 outStream.write(("ACK:\r\n").getBytes()); 509 try { 510 Thread.sleep(9500); 511 } catch (InterruptedException e) { 512 logMsg("Error.", e); 513 break; 514 } 515 } 516 } catch (IOException e) { 517 logMsg("Error.", e); 518 } 519 } 520 }; 521 t2.setDaemon(true); 522 t2.start(); 523 } catch (IOException e) { 524 e.printStackTrace(); 525 } 526 } 527 528 534 public void sendMsg(final String who, final String msg) { 535 try { 536 if (keepQuietTime != 0) { 538 long diff = System.currentTimeMillis() - keepQuietTime; 539 if (diff < 60000) { 540 wincall( 541 "chipchat_beQuit", 542 new Object [] { new Long (60 - diff / 1000)}); 543 return; 544 } else { 545 keepQuietTime = 0; 546 } 547 } 548 549 String newMsg = htmlSpecialChars(msg); 551 int to = Integer.parseInt(who); 552 553 if (to == -1) { 555 sendToServer("MSG:" + newMsg + "\r\n"); 556 return; 557 } else { 558 sendToServer("WSP:" + to + ":" + newMsg + "\r\n"); 559 } 560 } catch (Exception e1) { 561 logMsg("Error in sendMsg(..).", e1); 562 } 563 } 564 565 572 public void sendCustomMsg( 573 final String who, 574 final String cmd, 575 final String msg) { 576 try { 577 if (keepQuietTime != 0) { 579 long diff = System.currentTimeMillis() - keepQuietTime; 580 if (diff < 60000) { 581 wincall( 582 "chipchat_beQuit", 583 new Object [] { new Long (60 - diff / 1000)}); 584 return; 585 } else { 586 keepQuietTime = 0; 587 } 588 } 589 590 String newCmd = htmlSpecialChars(cmd); 592 int to = Integer.parseInt(who); 593 594 sendToServer("CUSTOM:" + to + ":" + newCmd + ">" + msg + "\r\n"); 596 } catch (Exception e1) { 597 logMsg("Error in sendMsg(..).", e1); 598 } 599 } 600 601 604 public void getOut() { 605 try { 606 sendToServer("GETOUT:\r\n"); 607 closeConnect(); 608 wincall("chipchat_getout_forward", null); 609 } catch (Exception e) { 610 logMsg("Error in getout().", e); 611 } 612 } 613 614 619 public void keepQuiet(final String to) { 620 try { 621 int num = Integer.parseInt(to); 622 sendToServer("KEEPQUIET:" + num + "\r\n"); 623 } catch (Exception e) { 624 logMsg("Error in keepQuiet(.).", e); 625 } 626 } 627 628 633 public void kickOut(final String to) { 634 try { 635 int num = Integer.parseInt(to); 636 sendToServer("KICKOUT:" + num + "\r\n"); 637 } catch (Exception e) { 638 logMsg("Error in kickOut(.).", e); 639 } 640 } 641 642 647 public void entrust(final String to) { 648 try { 649 int num = Integer.parseInt(to); 650 sendToServer("ENTRUST:" + num + "\r\n"); 651 } catch (Exception e) { 652 logMsg("Error in entrust(.).", e); 653 } 654 } 655 656 public void changeRoomPassword(final String to) { 657 sendToServer("CHGPASSWORD:" + to + "\r\n"); 658 } 659 660 public void changeRoomName(final String to) { 661 sendToServer("CHGROOMNAME:" + to + "\r\n"); 662 } 663 664 public void changeMax(final String to) { 665 sendToServer("CHGMAX:" + to + "\r\n"); 666 } 667 668 672 public boolean isConnected() { 673 return connected; 674 } 675 676 680 public boolean isHost() { 681 return userid == hostid; 682 } 683 684 public static class SessionKeeper extends Thread { 685 ChipChatApplet parent; 686 int minute; 687 688 public SessionKeeper(ChipChatApplet parent, int minute) { 689 this.parent = parent; 690 this.minute = minute; 691 } 692 693 public void run() { 694 URL url; 695 try { 696 url = new URL (parent.getDocumentBase(), "sessionkeeper.jsp"); 697 } catch (MalformedURLException e) { 698 parent.logMsg("Error SessionKeeper.run(.).", e); 699 return; 700 } 701 702 int port; 703 { 704 port = url.getPort(); 706 if (port < 0) { 707 port = 80; 708 } 709 } 710 711 String cookie = (String ) parent.getDoc().getMember("cookie"); 712 if (cookie == null) { 713 parent.logMsg("Warm : cookie is null."); 714 } 715 716 String sContent = 717 "GET " 718 + url.getFile() 719 + " HTTP/1.1\r\n" 720 + "Accept: */*\r\n" 721 + "Accept-Language: utf-8\r\n" 722 + "User-Agent: ChipChat agent.\r\n" 723 + ((cookie != null) ? ("Cookie: " + cookie + "\r\n") : "") 724 + "Host: " 725 + ((port == 80) ? url.getHost() : url.getHost() + ":" + port) 726 + "\r\n" 727 + "Connection: Keep-Alive\r\n" 728 + "Cache-Control: no-cache\r\n" 729 + "\r\n"; 730 731 while (true) { 732 try { 733 Thread.sleep(minute * 60000); 734 } catch (InterruptedException e) { 735 parent.logMsg("Error..", e); 736 break; 737 } 738 try { 739 parent.logMsg("Connecting sessionkeeper.jsp page.."); 741 Socket sock = new Socket (url.getHost(), port); 742 BufferedReader inStream = 743 new BufferedReader ( 744 new InputStreamReader (sock.getInputStream())); 745 DataOutputStream outStream = 746 new DataOutputStream (sock.getOutputStream()); 747 outStream.write(sContent.getBytes()); 749 outStream.flush(); 750 for (String l = inStream.readLine(); 751 l.length() > 0; 752 l = inStream.readLine()); 753 outStream.close(); 754 inStream.close(); 755 sock.close(); 756 } catch (IOException e) { 757 parent.logMsg("Error..", e); 758 break; 759 } 760 } 761 } 762 } 763 } 764 | Popular Tags |