Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: plugins/MsnService/MsnEngine.java


1   /*
2    * MsnEngine.java
3    *
4    * Created on 03. Oktober 2002, 14:20
5    */
6   
7   package plugins.MsnService;
8   
9   /**
10   *
11   * @author  tobiasnb
12   */
13  import java.net.*;
14  import java.io.*;
15  import java.util.HashMap;
16  import java.util.Vector;
17  import java.util.StringTokenizer;
18  import javax.swing.ImageIcon;
19  import java.util.List;
20  import plugins.Messenger.Status;
21  import plugins.Messenger.DefaultContact;
22  import plugins.Messenger.Contact;
23  import plugins.Messenger.*;
24  
25  public class MsnEngine implements plugins.Messenger.MessengerEngine {
26      
27      Socket socket;
28      
29      BufferedReader in;
30      PrintStream out;
31      
32      private String ip = "64.4.13.46";
33      private int port = 1863;
34      private int id;
35      private String magicstr = "Q1P7W2E4J9R8U3S5";
36      protected boolean readyGetSB = false;
37      protected boolean gotSB = false;
38      protected boolean sendXFR = false;
39      
40      boolean connected = false;
41      
42      String password;
43      String nick;
44      String account;
45      
46      Vector ccls = new Vector();
47      Vector cls = new Vector();
48      
49      HashMap contacts = new HashMap();
50      String sbip;
51      int sbport;
52      String sbCKI;
53      
54      Vector statusList = new Vector();
55      
56      javax.swing.ImageIcon onlineIcon  = new javax.swing.ImageIcon(getClass().getResource("/dexter/images/msn.gif"));
57      javax.swing.ImageIcon offlineIcon = new javax.swing.ImageIcon(getClass().getResource("/dexter/images/msn_discon.gif"));
58      
59      javax.swing.ImageIcon cOnlineIcon  = new javax.swing.ImageIcon(getClass().getResource("/dexter/images/online.gif"));
60      javax.swing.ImageIcon cOfflineIcon = new javax.swing.ImageIcon(getClass().getResource("/dexter/images/offline.gif"));
61      javax.swing.ImageIcon cBlockedIcon = new javax.swing.ImageIcon(getClass().getResource("/dexter/images/blocked.gif"));
62      javax.swing.ImageIcon cAwayIcon    = new javax.swing.ImageIcon(getClass().getResource("/dexter/images/idle.gif"));
63      javax.swing.ImageIcon cIdleIcon    = new javax.swing.ImageIcon(getClass().getResource("/dexter/images/idle.gif"));
64      javax.swing.ImageIcon cBusyIcon    = new javax.swing.ImageIcon(getClass().getResource("/dexter/images/busy.gif"));
65      
66      
67      /** Creates a new instance of MsnEngine */
68      public MsnEngine() {
69          createStatusList();
70          id = 0;
71      }
72      
73      protected void createStatusList() {
74          Status s = new Status("Online","NLN", cOnlineIcon);
75          statusList.add(s);
76          s = new Status("Offline","FLN", cOfflineIcon);
77          statusList.add(s);
78          s = new Status("Appear Offline","HDN", cOfflineIcon);
79          statusList.add(s);
80          s = new Status("Away","AWY", cAwayIcon);
81          statusList.add(s);
82          s = new Status("Busy","BSY", cBusyIcon);
83          statusList.add(s);
84          s = new Status("On the Phone","PHN", cIdleIcon);
85          statusList.add(s);
86          s = new Status("Out to Lunch","LUN", cIdleIcon);
87          statusList.add(s);
88          s = new Status("Be Right Back","BRB", cIdleIcon);
89          statusList.add(s);
90          
91      }
92      
93      public String getIniFileName() {
94          return "messenger";
95      }
96      
97      public String getName() {
98          return "MSN";
99      }
100     
101     public ImageIcon getOfflineIcon() {
102         return offlineIcon;
103     }
104     
105     public ImageIcon getOnlineIcon() {
106         return onlineIcon;
107     }
108     
109     public List getStatusList() {
110         return statusList;
111     }
112     
113     public void process() throws Exception {
114         if(!in.ready()) return ;
115         
116         String msg = in.readLine();
117         
118         if(msg == null) return;
119         if(msg.startsWith("XFR")) {
120             getSwitchBoard(msg);
121         }
122         if(msg.startsWith("RNG")) {
123             /* Start a conversation */
124             StartConversation(msg);
125             return;
126         }
127         if(msg.startsWith("CHL")) {
128             dealWithCheck(msg);
129             return;
130         }
131         if(msg.startsWith("FLN")) {
132             setOffline(msg);
133             return;
134         }
135         if(msg.startsWith("NLN")) {
136             changeStatusNLN(msg);
137             return;
138         }
139         if(msg.startsWith("ILN")) {
140             changeStatusILN(msg);
141             return;
142         }
143     }
144     
145     public void setStatus(String status) {
146         send("CHG", status);
147     }
148     
149     public void syncronize() {
150         syncronizeLists();
151     }
152     
153     
154     protected void setOffline(String msg) {
155         StringTokenizer st = new StringTokenizer(msg);
156         String status = st.nextToken();
157         String account = st.nextToken();
158         update(account,null,status);
159     }
160     
161     
162     protected void getSwitchBoard(String msg) throws Exception {
163         /* get switch board info */
164         readyGetSB = false;
165         StringTokenizer st = new StringTokenizer(msg);
166         skip(st,3);
167         String s = st.nextToken();
168         int i = s.indexOf(":");
169         if(i < 0) {
170             readyGetSB = true;
171             throw new Exception("Unexpected Reply, switchboard port and IP");
172         }
173         sbip = s.substring(0,i);
174         sbport = Integer.parseInt(s.substring(i+1));
175         st.nextToken();
176         sbCKI = st.nextToken();
177         gotSB = true;
178     }
179     
180     
181     protected void dealWithCheck(String msg) throws Exception {
182         StringTokenizer st = new StringTokenizer(msg);
183         st.nextToken();
184         st.nextToken();
185         String s = st.nextToken()+magicstr;
186         MD5 encrypt = new MD5(s);
187         out.print("QRY "+id +" msmsgs@msnmsgr.com 32\r\n" + encrypt.asHex());
188         id++;
189     }
190     
191     protected void changeStatusILN(String msg) throws Exception {
192         StringTokenizer st = new StringTokenizer(msg);
193         skip(st,2); // skip ILN and ID
194         String status = st.nextToken();
195         String login  = st.nextToken();
196         String user   = st.nextToken();
197         update(login,user,status);
198     }
199     
200     protected void changeStatusNLN(String msg) {
201         StringTokenizer st = new StringTokenizer(msg);
202         st.nextToken(); // skip "NLN"
203         String status = st.nextToken();
204         String login  = st.nextToken();
205         String user   = st.nextToken();
206         update(login, user, status);
207     }
208     
209     public void connect() throws Exception {
210         System.out.println("Connecting to server " + ip + " on port " + port);
211         socket = new Socket(ip,port);
212         in  = new BufferedReader(new InputStreamReader(socket.getInputStream()));
213         out = new PrintStream(socket.getOutputStream());
214         
215         // start login:
216         send("VER","MSNP7 MSNP6 MSNP5 MSNP4 CVRO");
217         receive();
218         
219         send("INF");
220         if(!(receive()).endsWith("MD5")) {
221             throw new Exception("does not use MD5 for authentification");
222         }
223         
224         //check that info for user in on this server
225         send("USR","MD5 I " + getAccount());
226         String ans = receive();
227         if(ans.startsWith("XFR")) {
228             //not on this server
229             StringTokenizer st = new StringTokenizer(ans);
230             // skip tokens
231             for(int i = 0; i < 3; i++) {
232                 st.nextToken();
233             }
234             
235             String temp = st.nextToken();
236             int i = temp.indexOf(":");
237             if(i<0) { throw new Exception("unexpected reply"); }
238             else {
239                 ip = temp.substring(0,i);
240                 port = Integer.parseInt(temp.substring(i+1));
241                 socket.close();
242                 System.out.println("info not here, will try " + ip + " instead.");
243                 connect();
244                 return;
245             }
246         } else {
247             if(!ans.startsWith("USR")) {
248                 throw new Exception("unknown reply " + ans);
249             }
250         }
251         
252       /* if info is on this server:
253        * compute all the MD5 crap
254        */
255         
256         // skip tokens
257         StringTokenizer st = new StringTokenizer(ans);
258         for(int i = 0; i < 4; i++) {
259             st.nextToken();
260         }
261         String hash = st.nextToken() + getPassword();
262         MD5 encrypt = new MD5(hash);
263         
264         send("USR","MD5 S " + encrypt.asHex());
265         String rcpt = receive();
266         String temp = "USR ";
267         temp = temp + (id - 1) + " OK";
268         if(!rcpt.startsWith(temp)) {
269             throw new Exception("Incorrect Password");
270         } else {
271             st = new StringTokenizer(rcpt);
272             for(int i=0; i<4; i++) {
273                 st.nextToken();
274             }
275             setNick(st.nextToken());
276         }
277         connected = true;
278         send("CHG","NLN");
279         readyGetSB = true;
280     }
281     
282     protected void send(String s) {
283         try {
284             out.println(s + " " + id);
285             id++; // increment trial ID
286         } catch (Exception e) {
287             System.out.println("Send error " + e);
288         }
289     }
290     
291     protected void send(String s1,String s2) {
292         try {
293             out.println(s1 + " " + id + " " + s2);
294             id++; // increment trial ID
295         } catch (Exception e) {
296             System.out.println("Send error " + e);
297         }
298     }
299     
300     protected String receive() throws Exception {
301         String s = null;
302         s = in.readLine();
303         return s;
304     }
305     
306     protected Command receiveCmd() throws Exception {
307         String s = null;
308         s = in.readLine();
309         if (s == null) return null;
310         return new Command(s);
311     }
312     
313     protected void skip(StringTokenizer st, int num) throws Exception{
314         for(int i = 0; i < num; i++) {
315             st.nextToken();
316         }
317     }
318     
319     protected void update(String login, String user, String status) {
320         if (user != null) user  = SpecialCharacters.getInstance().decode(user,true);
321         if(login != null) {
322             DefaultContact con = (DefaultContact) contacts.get(login);
323             
324             if (con!=null) {
325                 if (con.getStatus().equals(status) == false) {
326                     con.setStatus(status);
327                     if (user != null) con.setNick(user);
328                     fireContactChanged(con, true);
329                 }
330                 
331                 if (user != null)
332                     if (con.getNick().equals(user) == false) {
333                         con.setNick(user);
334                         fireContactChanged(con, true);
335                     }
336             }
337         }
338         
339     }
340     
341     protected void syncronizeLists() {
342         
343         try {
344             send("SYN","0");
345             
346             Command c = receiveCmd();
347             
348             boolean end = false;
349             while (!end) {
350                 c = receiveCmd();
351                 if (c.cmd.equals("LST")) {
352                     if (c.param.size() > 5) {
353                         String login  = (String) c.param.get(4);
354                         String nick   = (String) c.param.get(5);
355                         DefaultContact con = (DefaultContact) contacts.get(login);
356                         System.out.println("login: " + login);
357                         boolean add = false;
358                         if (con == null) {
359                             con = new DefaultContact(login,SpecialCharacters.getInstance().decode(nick,true),this);
360                             contacts.put(login,con);
361                             add = true;
362                         }
363                         
364                         if ( ((String)c.param.get(0)).equals("FL") ) con.setForwardList(true);
365                         if ( ((String)c.param.get(0)).equals("RL") ) {
366                             con.setReverseList(true);
367                             String s1 = (String) c.param.get(2);
368                             String s2 = (String) c.param.get(3);
369                             if (s1.equals(s2)) end = true;
370                         }
371                         if ( ((String)c.param.get(0)).equals("BL") ) con.setBlocked(true);
372                         
373                         if ( ((String)c.param.get(0)).equals("AL") ) con.setBlocked(false);
374                         
375                         if (add) fireContactAdded(con);
376                         else fireContactChanged(con,false);
377                         
378                     }
379                 }
380             }
381             
382         } catch (Exception ex) {}
383     }
384     
385     protected void StartConversation(String msg) throws Exception{
386         StringTokenizer st = new StringTokenizer(msg);
387         st.nextToken(); //skip "RNG"
388         String convID = st.nextToken();
389         String temp = st.nextToken();
390         /* find ip and port */
391         int i = temp.indexOf(":");
392         String ip = temp.substring(0,i);
393         int port = Integer.parseInt(temp.substring(i+1));
394         st.nextToken(); //skip "CKI"
395         /* find CKI # */
396         String CKI = st.nextToken();
397         String login = st.nextToken(); // slip email
398         /* find user name */
399         String nick = st.nextToken();
400         Contact con = (Contact) contacts.get(login);
401         plugins.Messenger.Conversation conv = new MsnConversation(this,convID,ip,port,CKI,con , getAccount(), getNick());
402         fireConversationStart(conv);
403         
404     }
405     
406     
407     public String getAccount() {
408         return account;
409     }
410     
411     public String getNick() {
412         return nick;
413     }
414     
415     public String getPassword() {
416         return password;
417     }
418     
419     public void setAccount(String account) {
420         this.account = account;
421     }
422     
423     public void setNick(String nick) {
424         this.nick = nick;
425         send("REA", getAccount() + " " + SpecialCharacters.getInstance().encode(nick,true));
426     }
427     
428     public void setPassword(String password) {
429         this.password = password;
430     }
431     
432     public void blockContact(String login) {
433         send("REM", "AL " + login);
434         send("ADD", "BL " + login + " " + login);
435         System.out.println("block");
436     }
437     
438     public void unblockContact(String login) {
439         send("REM", "BL " + login);
440         send("ADD", "AL " + login + " " + login);
441     }
442     
443     public void addContact(String login) {
444         send("ADD", "FL " + login + " " + login);
445         DefaultContact con = (DefaultContact) contacts.get(login);
446         if (con == null) {
447             con = new DefaultContact(login,login,this);
448             contacts.put(login,con);
449             fireContactAdded(con);
450             //            addContactToTree(con);
451         }
452         
453     }
454     
455     public void removeContact(plugins.Messenger.Contact con) {
456         send("REM", "FL " + con.getAccount());
457         fireContactRemoved((DefaultContact) con);
458         //        DefaultMutableTreeNode node = findNode(con);
459         //        fireNodeRemoved(node);
460         //        nodes.remove(node);
461         contacts.remove(con.getAccount());
462     }
463     
464     public HashMap getContactList() {
465         return contacts;
466     }
467     
468     public void addContactChangeListener(plugins.Messenger.ContactChangeListener ccl) {
469         ccls.add(ccl);
470     }
471     
472     public void removeContactChangeListener(plugins.Messenger.ContactChangeListener ccl) {
473         ccls.remove(ccl);
474     }
475     
476     public void fireContactChanged(DefaultContact con,boolean popup) {
477         for(int i=0;i<ccls.size();i++)
478             ((plugins.Messenger.ContactChangeListener) ccls.get(i)).contactChanged(con,popup);
479     }
480     
481     public void fireContactAdded(DefaultContact con) {
482         for(int i=0;i<ccls.size();i++)
483             ((plugins.Messenger.ContactChangeListener) ccls.get(i)).contactAdded(con);
484     }
485     
486     public void fireContactRemoved(DefaultContact con) {
487         for(int i=0;i<ccls.size();i++)
488             ((plugins.Messenger.ContactChangeListener) ccls.get(i)).contactRemoved(con);
489     }
490     
491     public void startConversation(Contact con) {
492         InitConv conv = new InitConv(con, this);
493         conv.start();
494     }
495     
496     /** Getter for property ip.
497      * @return Value of property ip.
498      */
499     public java.lang.String getIp() {
500         return ip;
501     }
502     
503     /** Setter for property ip.
504      * @param ip New value of property ip.
505      */
506     public void setIp(java.lang.String ip) {
507         this.ip = ip;
508     }
509     
510     /** Getter for property port.
511      * @return Value of property port.
512      */
513     public int getPort() {
514         return port;
515     }
516     
517     /** Setter for property port.
518      * @param port New value of property port.
519      */
520     public void setPort(int port) {
521         this.port = port;
522     }
523     
524     /** Getter for property sbCKI.
525      * @return Value of property sbCKI.
526      */
527     public java.lang.String getSbCKI() {
528         return sbCKI;
529     }
530     
531     /** Setter for property sbCKI.
532      * @param sbCKI New value of property sbCKI.
533      */
534     public void setSbCKI(java.lang.String sbCKI) {
535         this.sbCKI = sbCKI;
536     }
537     
538     /** Getter for property sbport.
539      * @return Value of property sbport.
540      */
541     public int getSbport() {
542         return sbport;
543     }
544     
545     /** Setter for property sbport.
546      * @param sbport New value of property sbport.
547      */
548     public void setSbport(int sbport) {
549         this.sbport = sbport;
550     }
551     
552     /** Getter for property sbip.
553      * @return Value of property sbip.
554      */
555     public java.lang.String getSbip() {
556         return sbip;
557     }
558     
559     /** Setter for property sbip.
560      * @param sbip New value of property sbip.
561      */
562     public void setSbip(java.lang.String sbip) {
563         this.sbip = sbip;
564     }
565     
566     public void addConversationStartListener(plugins.Messenger.ConversationStartListener cl) {
567         cls.add(cl);
568     }
569     
570     public void removeConversationStartListener(plugins.Messenger.ConversationStartListener cl) {
571         cls.remove(cl);
572     }
573     
574     protected void fireConversationStart(Conversation conv) {
575         for (int i=0;i<cls.size();i++) {
576             ((ConversationStartListener) cls.get(i)).startConversation(conv);
577         }
578     }
579     
580 }