023100efcde5cd71ceba9fb20d686581dd259ad7
[jMoule] / src / DonkeyCore.java
1 import java.io.*;\r
2 import java.net.*;\r
3 import java.util.Hashtable;\r
4 import java.util.Vector;\r
5 import javax.swing.*;\r
6 \r
7 public class DonkeyCore extends Thread\r
8 {\r
9         byte[] buffer=new byte[1024*100];\r
10         int pos;\r
11         int nbsearches=0;\r
12         Socket connection;\r
13         String password;\r
14         Hashtable fileInfos=new Hashtable();\r
15         Hashtable resultInfos=new Hashtable();\r
16         Hashtable serverInfos=new Hashtable();\r
17         Vector searchResults=new Vector();\r
18         //String console=new String();\r
19         JTextArea console=new JTextArea();\r
20         \r
21         public DonkeyCore()\r
22         {\r
23                 /*\r
24                 Vector fileInfo;\r
25                 fileInfo=new Vector();\r
26                 fileInfo.add("a");\r
27                 fileInfo.add("b");\r
28                 fileInfo.add("m");\r
29                 fileInfo.add("x");\r
30                 fileInfo.add("x");\r
31                 fileInfo.add(new Boolean(true));\r
32                 fileInfos.put(new Long(0),fileInfo);\r
33                 fileInfo=new Vector();\r
34                 fileInfo.add("b");\r
35                 fileInfo.add("a");\r
36                 fileInfo.add("d");\r
37                 fileInfo.add("d");\r
38                 fileInfo.add("m");\r
39                 fileInfo.add(new Boolean(true));\r
40                 fileInfos.put(new Long(1),fileInfo);\r
41                 fileInfo=new Vector();\r
42                 fileInfo.add("g");\r
43                 fileInfo.add("a");\r
44                 fileInfo.add("k");\r
45                 fileInfo.add("k");\r
46                 fileInfo.add("i");\r
47                 fileInfo.add(new Boolean(true));\r
48                 fileInfos.put(new Long(2),fileInfo);\r
49                 Vector serverInfo;\r
50                 serverInfo=new Vector();\r
51                 serverInfo.add("a");\r
52                 serverInfo.add("a");\r
53                 serverInfo.add("a");\r
54                 serverInfo.add(Boolean.FALSE);\r
55                 serverInfos.put(new Long(0),serverInfo);\r
56                 serverInfo=new Vector();\r
57                 serverInfo.add("b");\r
58                 serverInfo.add("d");\r
59                 serverInfo.add("e");\r
60                 serverInfo.add(new Boolean(true));\r
61                 serverInfos.put(new Long(1),serverInfo);\r
62                 serverInfo=new Vector();\r
63                 serverInfo.add("e");\r
64                 serverInfo.add("x");\r
65                 serverInfo.add("q");\r
66                 serverInfo.add(new Boolean(false));\r
67                 serverInfos.put(new Long(2),serverInfo);\r
68                 serverInfo=new Vector();\r
69                 serverInfo.add("a");\r
70                 serverInfo.add("b");\r
71                 serverInfo.add("n");\r
72                 serverInfo.add(new Boolean(true));\r
73                 serverInfos.put(new Long(3),serverInfo);\r
74                 */\r
75         }\r
76         \r
77         public DonkeyCore(String host,int port,String password)\r
78         {\r
79                 this();\r
80                 connect(host,port,password);\r
81         }\r
82         \r
83         public boolean connect(String host,int port,String password)\r
84         {\r
85                 this.password=password;\r
86                 //System.out.println(password);\r
87                 try\r
88                 {\r
89                         connection=new Socket(host,port);\r
90                         start();\r
91                         return true;\r
92                 }\r
93                 catch (Exception e)\r
94                 {\r
95                         e.printStackTrace();\r
96                         return false;\r
97                 }\r
98         }\r
99         \r
100         public void disconnect()\r
101         {\r
102                 try\r
103                 {\r
104                         connection.close();\r
105                         connection=null;\r
106                 }\r
107                 catch (Exception e)\r
108                 {\r
109                         e.printStackTrace();\r
110                 }\r
111         }\r
112         \r
113         public boolean isConnected()\r
114         {\r
115                 return connection!=null;\r
116         }\r
117 \r
118         void debug(String message)\r
119         {\r
120                 //System.out.println(message);\r
121         }\r
122 \r
123         boolean readMessage()\r
124         {\r
125                 try\r
126                 {\r
127                         InputStream i=connection.getInputStream();\r
128                         // read the length of the message\r
129                         long l=i.read()+256*(i.read()+256*(i.read()+256*i.read()));\r
130                         //System.out.print("size: "+l+" ");\r
131                         pos=0;\r
132                         // read the buffer\r
133                         while (pos<l) pos+=i.read(buffer,pos,(int)l-pos);\r
134                         pos=0;\r
135                         // ok\r
136                         \r
137                         // dump\r
138 /*\r
139                         if (buffer[0]==3)\r
140                         {\r
141                                 System.out.println("Dump: "+new String(buffer,0,(int)l));\r
142                                 for (pos=0;pos<l;pos++)\r
143                                 {\r
144                                         System.out.print(buffer[pos]+",");\r
145                                 }\r
146                         }\r
147                         pos=0;\r
148 */\r
149 \r
150                         return true;\r
151                 }\r
152                 catch (Exception e)\r
153                 {\r
154                         e.printStackTrace();\r
155                         return false;\r
156                 }\r
157         }\r
158         \r
159         int readByte()\r
160         {\r
161                 byte temp=buffer[pos++];\r
162                 return(temp<0?temp+256:temp);\r
163         }\r
164         \r
165         int readInt()\r
166         {\r
167                 return(readByte()+256*readByte());\r
168         }\r
169         \r
170         long readLong()\r
171         {\r
172                 return(readByte()+256*(readByte()+256*(readByte()+256*readByte())));\r
173         }\r
174         \r
175         String readString()\r
176         {\r
177                 int l=readInt();\r
178                 if (l>0)\r
179                 {\r
180                         String temp=new String(buffer,pos,l);\r
181                         pos+=l;\r
182                         return(temp);\r
183                 }\r
184                 else return("");\r
185         }\r
186 \r
187         synchronized boolean sendMessage(byte[] buffer,int l)\r
188         {\r
189                 try\r
190                 {\r
191                         connection.getOutputStream().write(l%256);\r
192                         connection.getOutputStream().write(l/256);\r
193                         connection.getOutputStream().write(0);\r
194                         connection.getOutputStream().write(0);\r
195                         connection.getOutputStream().write(buffer,0,l);\r
196                         return true;\r
197                 }\r
198                 catch (Exception e)\r
199                 {\r
200                         e.printStackTrace();\r
201                         return false;\r
202                 }\r
203         }\r
204         \r
205         public void connectMore()\r
206         {\r
207         byte[] buffer=new byte[2];\r
208     buffer[0]=1; buffer[1]=0; // function\r
209     sendMessage(buffer,2);\r
210         }\r
211 \r
212         public void cleanOld()\r
213         {\r
214         byte[] buffer=new byte[2];\r
215     buffer[0]=2; buffer[1]=0; // function\r
216     sendMessage(buffer,2);\r
217         }\r
218 \r
219         public void kill()\r
220         {\r
221         byte[] buffer=new byte[2];\r
222     buffer[0]=3; buffer[1]=0; // function\r
223     sendMessage(buffer,2);\r
224         }\r
225 \r
226         public void extend()\r
227         {\r
228         byte[] buffer=new byte[2];\r
229     buffer[0]=4; buffer[1]=0; // function\r
230     sendMessage(buffer,2);\r
231         }\r
232         \r
233         public void download(Long fileID)\r
234         {\r
235                 byte[] buffer=new byte[9];\r
236                 int i=0;\r
237     buffer[i++]=50; buffer[i++]=0; // function\r
238     buffer[i++]=0; buffer[i++]=0; // result_names (empty list)\r
239     long id=fileID.longValue();\r
240     for (int j=0;j<4;j++)\r
241     {\r
242         buffer[i++]=(byte)(id%256);\r
243         id/=256;\r
244     }\r
245     buffer[i++]=0; // force\r
246         sendMessage(buffer,i);\r
247         }\r
248         \r
249         public void switchDownload(Long fileID,boolean bool)\r
250         {\r
251                 byte[] buffer=new byte[9];\r
252                 int i=0;\r
253     buffer[i++]=23; buffer[i++]=0; // function\r
254     long id=fileID.longValue();\r
255     for (int j=0;j<4;j++)\r
256     {\r
257         buffer[i++]=(byte)(id%256);\r
258         id/=256;\r
259     }\r
260     if (bool)\r
261         buffer[i++]=1;\r
262     else\r
263         buffer[i++]=0;\r
264         sendMessage(buffer,i);\r
265         }\r
266         \r
267         public void connectServer(Long serverID)\r
268         {\r
269                 byte[] buffer=new byte[6];\r
270                 int i=0;\r
271     buffer[i++]=21; buffer[i++]=0; // function\r
272     long id=serverID.longValue();\r
273     for (int j=0;j<4;j++)\r
274     {\r
275         buffer[i++]=(byte)(id%256);\r
276         id/=256;\r
277     }\r
278         sendMessage(buffer,i);\r
279         }\r
280         \r
281         public void disconnectServer(Long serverID)\r
282         {\r
283                 byte[] buffer=new byte[6];\r
284                 int i=0;\r
285     buffer[i++]=22; buffer[i++]=0; // function\r
286     long id=serverID.longValue();\r
287     for (int j=0;j<4;j++)\r
288     {\r
289         buffer[i++]=(byte)(id%256);\r
290         id/=256;\r
291     }\r
292         sendMessage(buffer,i);\r
293         }\r
294         \r
295         public Vector search(String query)\r
296         {\r
297         byte[] buffer=new byte[1024*100];\r
298         int i=0,j;\r
299     buffer[i++]=42; buffer[i++]=0; // function\r
300     buffer[i++]=(byte)(nbsearches%256); buffer[i++]=(byte)(nbsearches/256); \r
301     buffer[i++]=0; buffer[i++]=0; // num\r
302     buffer[i++]=4; // keywords\r
303     buffer[i++]=0; buffer[i++]=0; // empty string\r
304     buffer[i++]=(byte)(query.length()%256);\r
305     buffer[i++]=(byte)(query.length()/256);\r
306     for (j=0;j<query.length();j++)\r
307         buffer[i++]=(byte)query.charAt(j);\r
308     buffer[i++]=50; buffer[i++]=0; buffer[i++]=0; buffer[i++]=0; // max hits\r
309     buffer[i++]=1; // type\r
310     Vector searchResult=new Vector();\r
311     searchResults.add(searchResult);\r
312     sendMessage(buffer,i);\r
313     nbsearches++;\r
314     /*\r
315     Vector resultInfo=new Vector();\r
316     resultInfo.add(new Long(1));\r
317     resultInfo.add("a");\r
318     resultInfo.add("a");\r
319     resultInfo.add("a");\r
320     resultInfo.add(new Boolean(false));\r
321     searchResult.add(resultInfo);\r
322     resultInfo=new Vector();\r
323     resultInfo.add(new Long(2));\r
324     resultInfo.add("b");\r
325     resultInfo.add("b");\r
326     resultInfo.add("b");\r
327     resultInfo.add(new Boolean(false));\r
328     searchResult.add(resultInfo);\r
329     resultInfo=new Vector();\r
330     resultInfo.add(new Long(3));\r
331     resultInfo.add("c");\r
332     resultInfo.add("c");\r
333     resultInfo.add("c");\r
334     resultInfo.add(new Boolean(false));\r
335     searchResult.add(resultInfo);\r
336     */\r
337     return searchResult;\r
338         }\r
339         \r
340         public void run()\r
341         {\r
342                 while(readMessage())\r
343                 {\r
344                         //String serverStates[]={"NotConnected -1","Connecting","Connected_initiating","Connected_downloading","Connected -1","Connected n","NewHost","RemovedHost","BlackListedHost","NotConnected n"};\r
345                         Boolean serverStates[]={\r
346                                 Boolean.FALSE, // "NotConnected -1"\r
347                                 Boolean.FALSE, // "Connecting"\r
348                                 Boolean.TRUE,  // "Connected_initiating"\r
349                                 Boolean.TRUE,  // "Connected_downloading"\r
350                                 Boolean.TRUE,  // "Connected -1"\r
351                                 Boolean.TRUE,  // "Connected n"\r
352                                 Boolean.FALSE, // "NewHost"\r
353                                 Boolean.FALSE, // "RemovedHost"\r
354                                 Boolean.FALSE, // "BlackListedHost"\r
355                                 Boolean.FALSE  // "NotConnected n"\r
356                         };\r
357                         Boolean fileStates[]={\r
358                                 Boolean.TRUE,  // FileDownloading\r
359                                 Boolean.FALSE, // FilePaused\r
360                         Boolean.TRUE,  // FileDownloaded\r
361                         Boolean.FALSE, // FileShared\r
362                         Boolean.FALSE, // FileCancelled\r
363                         Boolean.FALSE, // FileNew\r
364                         Boolean.FALSE, // FileAborted s\r
365                                 Boolean.FALSE  // FileQueued\r
366                         };\r
367                         int i,n,f;\r
368                         Long id;\r
369                         String tags;\r
370                         switch(f=readInt()) // fonction\r
371                         {\r
372                                 \r
373                                 // CoreProtocol\r
374                                 case 0:\r
375                                         debug("CoreProtocol: "+readLong());\r
376                                         // (06:00:00:00:) 00:00:10:00:00:00 GuiProtocol\r
377                                         for (i=0;i<6;i++) buffer[i]=0;\r
378                                         buffer[2]=10;\r
379                                         sendMessage(buffer,6);\r
380                                         // (04:00:00:00:) 05:00:00:00 Password (empty)\r
381                                         i=0;\r
382                                         buffer[i++]=5; buffer[i++]=0; // function\r
383                                         buffer[i++]=(byte)(password.length()%256);\r
384                                         buffer[i++]=(byte)(password.length()/256);\r
385                                         for (int j=0;j<password.length();j++)\r
386                                                 buffer[i++]=(byte)password.charAt(j);\r
387                                         sendMessage(buffer,i);\r
388                                         break;\r
389 \r
390                                 // Options_info\r
391                                 case 1:\r
392                                         debug("Options_info:");\r
393                                         n=readInt();\r
394                                         for (i=0;i<n;i++)\r
395                                                 debug(readString()+" = "+readString());\r
396                                         break;\r
397                                         \r
398                                 // DefineSearches\r
399                                 case 3:\r
400                                         n=readInt();\r
401                                         debug("DefineSearches: "+n);\r
402                                         /*for (i=0;i<n;i++)\r
403                                         {\r
404                                                 System.out.println(readString()); // name\r
405                                                 System.out.println(readByte());\r
406                                         }*/\r
407                                         break;\r
408                                         \r
409                                 // Result_info\r
410                                 case 4:\r
411                                         Vector resultInfo=new Vector();\r
412                                         debug("Result_info: ");\r
413                                         id=new Long(readLong());\r
414                                         resultInfo.add(id);\r
415                                         readLong(); // network\r
416                                         n=readInt();\r
417                                         resultInfo.add(readString());\r
418                                         for (i=0;i<n-1;i++) readString(); // names\r
419                                         for (i=0;i<16;i++) readByte(); // hash\r
420                                         resultInfo.add(new Long(readLong())); // Size\r
421                                         readString(); // Format\r
422                                         readString(); // Type\r
423                                         tags=new String();\r
424                                         n=readInt();\r
425                                         for (i=0;i<n;i++)\r
426                                         {\r
427                                                 readString(); // TagName\r
428                                                 switch (readByte()) // TagValue\r
429                                                 {\r
430                                                         case 0:\r
431                                                         case 1:\r
432                                                                 tags=tags.concat(""+readLong()+" ");\r
433                                                                 break;\r
434                                                         case 2:\r
435                                                                 tags=tags.concat(readString()+" ");\r
436                                                                 break;\r
437                                                         case 3:\r
438                                                                 tags=tags.concat(""+readByte()+"."+readByte()+"."+readByte()+"."+readByte()+" ");\r
439                                                                 break;\r
440                                                 }\r
441                                         }\r
442                                         resultInfo.add(tags);\r
443                                         readString(); // Comment\r
444                                         readByte(); // Done (boolean)\r
445                                         resultInfo.add(new Boolean(false)); // download ?\r
446                                         resultInfos.put(id,resultInfo);\r
447                                         break;\r
448 \r
449                                 // Search_result                                        \r
450                                 case 5:\r
451                                         int search=(int)readLong(); // Search\r
452                                         Long info=new Long(readLong()); // Result_Info\r
453                                         ((Vector)searchResults.get(search)).add(resultInfos.get(info));\r
454                                         break;\r
455                                 \r
456                                 // File_info\r
457                                 case 7:\r
458                                 case 40:\r
459                                 case 43: \r
460                                         Vector fileInfo=new Vector();\r
461                                         debug("FileInformation: ");\r
462                                         id=new Long(readLong()); // id\r
463                                         readLong(); // network\r
464                                         n=readInt();\r
465                                         readString();\r
466                                         fileInfo.add(readString());\r
467                                         for (i=0;i<n-2;i++)     debug(readString()); // names\r
468                                         //for (i=0;i<n;i++)     debug(readString()); // names\r
469                                         for (i=0;i<16;i++) readByte(); // hash\r
470                                         //readLong(); // size\r
471                                         //readLong(); // downloaded\r
472                                         long filesize=readLong();\r
473                                         long filedl=readLong();\r
474                                         fileInfo.add(new Long(filesize));\r
475                                         fileInfo.add(new Long(filedl));\r
476                                         fileInfo.add(new Float(Math.round(10000*filedl/filesize)/100.0));\r
477                                         //debug(readLong()+"/"+readLong());\r
478                                         readLong(); // nlocations\r
479                                         readLong(); // nclients\r
480                                         int state=readByte(); // file_state\r
481                                         readString(); // chunks\r
482                                         readString(); // availability\r
483                                         //fileInfo.add(new Float(readString())); // rate\r
484                                         fileInfo.add(new Float(Math.round(Float.parseFloat(readString()))/1000.0));\r
485                                         n=readInt();\r
486                                         for (i=0;i<n;i++) readString(); // chunks age\r
487                                         readString(); // age\r
488                                         switch (readByte()) // format\r
489                                         {\r
490                                                 case 0:\r
491                                                         debug("Unknown_format");\r
492                                                         break;\r
493                                                 case 1: // FormatType\r
494                                                         //readString(); readString();\r
495                                                         debug("FormatType: "+readString()+" "+readString());\r
496                                                         break;\r
497                                                 case 2: // AVI\r
498                                                         debug("AVI: ");\r
499                                                         debug("codec: "+readString()); // codec\r
500                                                         debug(readLong()+"x"+readLong()+", "+readLong()+" fps "+readLong()+" rate")     ;\r
501                                                         break;\r
502                                                 case 3: // MP3\r
503                                                         debug("MP3: ");\r
504                                                         debug("title: "+readString()); // title\r
505                                                         debug("artist: "+readString()); // artist\r
506                                                         debug("album: "+readString()); // album\r
507                                                         debug("year: "+readString()); // year\r
508                                                         debug("comment: "+readString()); // comment\r
509                                                         debug("track: "+readLong()); // track number\r
510                                                         debug("genre: "+readLong()); // genre\r
511                                                         break;\r
512                                         }\r
513                                         fileInfo.add(fileStates[state]);\r
514                                         fileInfos.put(id,fileInfo);\r
515                                         break;\r
516                                 \r
517                                 // File_source\r
518                                 case 10:\r
519                                         // file_num f, client_num c\r
520                                         //debug("File_source: "+readInt()+" "+readInt());\r
521                                         break;\r
522                                 \r
523                                 // Server_state\r
524                                 case 13:\r
525                                         //debug("Server_state: "+readLong()+" etat: "+readByte());\r
526                                         id=new Long(readLong());\r
527                                         ((Vector)serverInfos.get(id)).setElementAt(serverStates[readByte()],3); // server_state\r
528                                         //System.out.println(id+" : state changed");\r
529                                         break;\r
530                                         \r
531                                 // Client_state\r
532                                 case 16:\r
533                                         debug("Client_state: "+readLong()+" etat: "+readByte());\r
534                                         break;\r
535                                 \r
536                                 // Client_info\r
537                                 case 15:\r
538                                         /*\r
539                                         debug("Client_info: ");\r
540                                         debug("num: "+readLong());\r
541                                         debug("network: "+readLong());\r
542                                         switch(readByte())\r
543                                         {\r
544                                                 case 0:\r
545                                                         // Known_location\r
546                                                         debug("type: Known_location");\r
547                                                         debug("ip: "+readByte()+"."+readByte()+"."+readByte()+"."+readByte());\r
548                                                         debug("port: "+readInt());\r
549                                                         break;\r
550                                                 case 1:\r
551                                                         // Indirect_location\r
552                                                         debug("type: Indirect_location");\r
553                                                         debug("name: "+readString());\r
554                                                         break;\r
555                                         }\r
556                                         */\r
557                                         break;\r
558                                 \r
559                                 // Console\r
560                                 case 19: \r
561                                         debug("Console: ");\r
562                                         //console=console.concat(readString());\r
563                                         console.append(readString());\r
564                                         break;\r
565                                 \r
566                                 // Network_info\r
567                                 case 20:\r
568                                         n=readInt();\r
569                                         debug("Network_info: "+readString());\r
570                                         break;\r
571                                         \r
572                                 // Server_info\r
573                                 case 26:\r
574                                         Vector serverInfo=new Vector();\r
575                                         debug("Server_info: ");\r
576                                         id=new Long(readLong()); // id\r
577                                         readLong(); // network\r
578                                         // only works if proto>=2\r
579                                         String host=null;\r
580                                         switch(readByte())\r
581                                         {\r
582                                                 case 0:\r
583                                                         //debug("ip: "+readByte()+"."+readByte()+"."+readByte()+"."+readByte());\r
584                                                         host=""+readByte()+"."+readByte()+"."+readByte()+"."+readByte();\r
585                                                         break;\r
586                                                 case 1:\r
587                                                         //debug("name: "+readString());\r
588                                                         host=readString();\r
589                                                         break;\r
590                                         }\r
591                                         //debug("port: "+readInt());\r
592                                         host=host+":"+readInt(); // port\r
593                                         serverInfo.add(host);\r
594                                         readLong(); // score\r
595                                         tags=new String();\r
596                                         n=readInt();\r
597                                         for (i=0;i<n;i++)\r
598                                         {\r
599                                                 readString(); // TagName\r
600                                                 switch (readByte()) // TagValue\r
601                                                 {\r
602                                                         case 0:\r
603                                                         case 1:\r
604                                                                 tags=tags.concat(""+readLong()+" ");\r
605                                                                 break;\r
606                                                         case 2:\r
607                                                                 tags=tags.concat(readString()+" ");\r
608                                                                 break;\r
609                                                         case 3:\r
610                                                                 tags=tags.concat(""+readByte()+"."+readByte()+"."+readByte()+"."+readByte()+" ");\r
611                                                                 break;\r
612                                                 }\r
613                                         }\r
614                                         serverInfo.add(new Long(readLong())); // nusers\r
615                                         serverInfo.add(new Long(readLong())); // nfiles\r
616                                         serverInfo.add(serverStates[readByte()]); // server_state\r
617                                         serverInfos.put(id,serverInfo);\r
618                                         break;\r
619                                                                 \r
620                                 // Add_section_option\r
621                                 case 36:\r
622                                         debug("Add_section_option: "+readString()+" "+readString()+" "+readString());\r
623                                         break;\r
624                                 \r
625                                 // Add_plugin_option\r
626                                 case 38:\r
627                                         debug("Add_plugin_option: "+readString()+" "+readString()+" "+readString());\r
628                                         break;\r
629                                         \r
630                                 // File_downloaded\r
631                                 case 46:\r
632                                         debug("File_downloaded: ");\r
633                                         debug("n: "+readLong());\r
634                                         debug("size: "+readLong());\r
635                                         debug("rate: "+readString());\r
636                                         debug("last_seen: "+readLong());\r
637                                         break;\r
638                                         \r
639                                 // Shared_file_info\r
640                                 case 48:\r
641                                         debug("Shared_file_info: ");\r
642                                         debug("num: "+readLong());\r
643                                         debug("network: "+readLong());\r
644                                         debug("name: "+readString());\r
645                                         debug("size: "+readLong());\r
646                                         // ...                                  \r
647                                         break;\r
648                                         \r
649                                 // Client_stats\r
650                                 case 49:\r
651                                         debug("Client_stats: ");\r
652                                         // stats...\r
653                                         break;\r
654 \r
655                                 default:\r
656                                         debug("Fonction: "+f);\r
657                                         break;\r
658                                         \r
659                         }\r
660                         //System.out.println();\r
661                 }\r
662         }\r
663         \r
664 }