--- /dev/null
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+\f
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+\f
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+\f
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+\f
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+\f
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
--- /dev/null
+jMoule 0.1\r
+site: http://royale.zerezo.com/jmoule/\r
+mail: royale@zerezo.com\r
+\r
+install:\r
+build.bat OR ./build.sh OR ant\r
+\r
+usage:\r
+java -jar dist/jMoule.jar
\ No newline at end of file
--- /dev/null
+SET JAVAC=javac\r
+SET JAR=jar\r
+%JAVAC% src/*.java -target 1.3 -d build/\r
+cd build\r
+%JAR% cvfm ../dist/jMoule.jar ../src/manifest.txt .\r
+cd ..
\ No newline at end of file
--- /dev/null
+#!/bin/sh
+
+JAVAC=javac
+JAR=jar
+$JAVAC src/*.java -target 1.3 -d build/
+cd build
+$JAR cvfm ../dist/jMoule.jar ../src/manifest.txt .
+cd ..
--- /dev/null
+<project name="jMoule" default="dist" basedir=".">\r
+\r
+ <description>jMoule</description>\r
+\r
+ <property name="src" location="src"/>\r
+ <property name="build" location="build"/>\r
+ <property name="dist" location="dist"/>\r
+ <property name="name" location="${dist}/jMoule.jar"/>\r
+ \r
+ <target name="compile" description="compile the source">\r
+ <javac srcdir="${src}" destdir="${build}"/>\r
+ </target>\r
+\r
+ <target name="dist" depends="compile" description="generate the distribution">\r
+ <jar jarfile="${name}" manifest="${src}/manifest.txt" basedir="${build}"/>\r
+ </target>\r
+\r
+ <target name="exec" depends="dist" description="run the project">\r
+ <java jar="${name}" fork="true"/>\r
+ </target>\r
+\r
+</project>
\ No newline at end of file
--- /dev/null
+import java.io.*;\r
+import java.net.*;\r
+import java.util.Hashtable;\r
+import java.util.Vector;\r
+import javax.swing.*;\r
+\r
+public class DonkeyCore extends Thread\r
+{\r
+ byte[] buffer=new byte[1024*100];\r
+ int pos;\r
+ int nbsearches=0;\r
+ Socket connection;\r
+ String password;\r
+ Hashtable fileInfos=new Hashtable();\r
+ Hashtable resultInfos=new Hashtable();\r
+ Hashtable serverInfos=new Hashtable();\r
+ Vector searchResults=new Vector();\r
+ //String console=new String();\r
+ JTextArea console=new JTextArea();\r
+ \r
+ public DonkeyCore()\r
+ {\r
+ /*\r
+ Vector fileInfo;\r
+ fileInfo=new Vector();\r
+ fileInfo.add("a");\r
+ fileInfo.add("b");\r
+ fileInfo.add("m");\r
+ fileInfo.add("x");\r
+ fileInfo.add("x");\r
+ fileInfo.add(new Boolean(true));\r
+ fileInfos.put(new Long(0),fileInfo);\r
+ fileInfo=new Vector();\r
+ fileInfo.add("b");\r
+ fileInfo.add("a");\r
+ fileInfo.add("d");\r
+ fileInfo.add("d");\r
+ fileInfo.add("m");\r
+ fileInfo.add(new Boolean(true));\r
+ fileInfos.put(new Long(1),fileInfo);\r
+ fileInfo=new Vector();\r
+ fileInfo.add("g");\r
+ fileInfo.add("a");\r
+ fileInfo.add("k");\r
+ fileInfo.add("k");\r
+ fileInfo.add("i");\r
+ fileInfo.add(new Boolean(true));\r
+ fileInfos.put(new Long(2),fileInfo);\r
+ Vector serverInfo;\r
+ serverInfo=new Vector();\r
+ serverInfo.add("a");\r
+ serverInfo.add("a");\r
+ serverInfo.add("a");\r
+ serverInfo.add(Boolean.FALSE);\r
+ serverInfos.put(new Long(0),serverInfo);\r
+ serverInfo=new Vector();\r
+ serverInfo.add("b");\r
+ serverInfo.add("d");\r
+ serverInfo.add("e");\r
+ serverInfo.add(new Boolean(true));\r
+ serverInfos.put(new Long(1),serverInfo);\r
+ serverInfo=new Vector();\r
+ serverInfo.add("e");\r
+ serverInfo.add("x");\r
+ serverInfo.add("q");\r
+ serverInfo.add(new Boolean(false));\r
+ serverInfos.put(new Long(2),serverInfo);\r
+ serverInfo=new Vector();\r
+ serverInfo.add("a");\r
+ serverInfo.add("b");\r
+ serverInfo.add("n");\r
+ serverInfo.add(new Boolean(true));\r
+ serverInfos.put(new Long(3),serverInfo);\r
+ */\r
+ }\r
+ \r
+ public DonkeyCore(String host,int port,String password)\r
+ {\r
+ this();\r
+ connect(host,port,password);\r
+ }\r
+ \r
+ public boolean connect(String host,int port,String password)\r
+ {\r
+ this.password=password;\r
+ //System.out.println(password);\r
+ try\r
+ {\r
+ connection=new Socket(host,port);\r
+ start();\r
+ return true;\r
+ }\r
+ catch (Exception e)\r
+ {\r
+ e.printStackTrace();\r
+ return false;\r
+ }\r
+ }\r
+ \r
+ public void disconnect()\r
+ {\r
+ try\r
+ {\r
+ connection.close();\r
+ connection=null;\r
+ }\r
+ catch (Exception e)\r
+ {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+ \r
+ public boolean isConnected()\r
+ {\r
+ return connection!=null;\r
+ }\r
+\r
+ void debug(String message)\r
+ {\r
+ //System.out.println(message);\r
+ }\r
+\r
+ boolean readMessage()\r
+ {\r
+ try\r
+ {\r
+ InputStream i=connection.getInputStream();\r
+ // read the length of the message\r
+ long l=i.read()+256*(i.read()+256*(i.read()+256*i.read()));\r
+ //System.out.print("size: "+l+" ");\r
+ pos=0;\r
+ // read the buffer\r
+ while (pos<l) pos+=i.read(buffer,pos,(int)l-pos);\r
+ pos=0;\r
+ // ok\r
+ \r
+ // dump\r
+/*\r
+ if (buffer[0]==3)\r
+ {\r
+ System.out.println("Dump: "+new String(buffer,0,(int)l));\r
+ for (pos=0;pos<l;pos++)\r
+ {\r
+ System.out.print(buffer[pos]+",");\r
+ }\r
+ }\r
+ pos=0;\r
+*/\r
+\r
+ return true;\r
+ }\r
+ catch (Exception e)\r
+ {\r
+ e.printStackTrace();\r
+ return false;\r
+ }\r
+ }\r
+ \r
+ int readByte()\r
+ {\r
+ byte temp=buffer[pos++];\r
+ return(temp<0?temp+256:temp);\r
+ }\r
+ \r
+ int readInt()\r
+ {\r
+ return(readByte()+256*readByte());\r
+ }\r
+ \r
+ long readLong()\r
+ {\r
+ return(readByte()+256*(readByte()+256*(readByte()+256*readByte())));\r
+ }\r
+ \r
+ String readString()\r
+ {\r
+ int l=readInt();\r
+ if (l>0)\r
+ {\r
+ String temp=new String(buffer,pos,l);\r
+ pos+=l;\r
+ return(temp);\r
+ }\r
+ else return("");\r
+ }\r
+\r
+ synchronized boolean sendMessage(byte[] buffer,int l)\r
+ {\r
+ try\r
+ {\r
+ connection.getOutputStream().write(l%256);\r
+ connection.getOutputStream().write(l/256);\r
+ connection.getOutputStream().write(0);\r
+ connection.getOutputStream().write(0);\r
+ connection.getOutputStream().write(buffer,0,l);\r
+ return true;\r
+ }\r
+ catch (Exception e)\r
+ {\r
+ e.printStackTrace();\r
+ return false;\r
+ }\r
+ }\r
+ \r
+ public void connectMore()\r
+ {\r
+ byte[] buffer=new byte[2];\r
+ buffer[0]=1; buffer[1]=0; // function\r
+ sendMessage(buffer,2);\r
+ }\r
+\r
+ public void cleanOld()\r
+ {\r
+ byte[] buffer=new byte[2];\r
+ buffer[0]=2; buffer[1]=0; // function\r
+ sendMessage(buffer,2);\r
+ }\r
+\r
+ public void kill()\r
+ {\r
+ byte[] buffer=new byte[2];\r
+ buffer[0]=3; buffer[1]=0; // function\r
+ sendMessage(buffer,2);\r
+ }\r
+\r
+ public void extend()\r
+ {\r
+ byte[] buffer=new byte[2];\r
+ buffer[0]=4; buffer[1]=0; // function\r
+ sendMessage(buffer,2);\r
+ }\r
+ \r
+ public void download(Long fileID)\r
+ {\r
+ byte[] buffer=new byte[9];\r
+ int i=0;\r
+ buffer[i++]=50; buffer[i++]=0; // function\r
+ buffer[i++]=0; buffer[i++]=0; // result_names (empty list)\r
+ long id=fileID.longValue();\r
+ for (int j=0;j<4;j++)\r
+ {\r
+ buffer[i++]=(byte)(id%256);\r
+ id/=256;\r
+ }\r
+ buffer[i++]=0; // force\r
+ sendMessage(buffer,i);\r
+ }\r
+ \r
+ public void switchDownload(Long fileID,boolean bool)\r
+ {\r
+ byte[] buffer=new byte[9];\r
+ int i=0;\r
+ buffer[i++]=23; buffer[i++]=0; // function\r
+ long id=fileID.longValue();\r
+ for (int j=0;j<4;j++)\r
+ {\r
+ buffer[i++]=(byte)(id%256);\r
+ id/=256;\r
+ }\r
+ if (bool)\r
+ buffer[i++]=1;\r
+ else\r
+ buffer[i++]=0;\r
+ sendMessage(buffer,i);\r
+ }\r
+ \r
+ public void connectServer(Long serverID)\r
+ {\r
+ byte[] buffer=new byte[6];\r
+ int i=0;\r
+ buffer[i++]=21; buffer[i++]=0; // function\r
+ long id=serverID.longValue();\r
+ for (int j=0;j<4;j++)\r
+ {\r
+ buffer[i++]=(byte)(id%256);\r
+ id/=256;\r
+ }\r
+ sendMessage(buffer,i);\r
+ }\r
+ \r
+ public void disconnectServer(Long serverID)\r
+ {\r
+ byte[] buffer=new byte[6];\r
+ int i=0;\r
+ buffer[i++]=22; buffer[i++]=0; // function\r
+ long id=serverID.longValue();\r
+ for (int j=0;j<4;j++)\r
+ {\r
+ buffer[i++]=(byte)(id%256);\r
+ id/=256;\r
+ }\r
+ sendMessage(buffer,i);\r
+ }\r
+ \r
+ public Vector search(String query)\r
+ {\r
+ byte[] buffer=new byte[1024*100];\r
+ int i=0,j;\r
+ buffer[i++]=42; buffer[i++]=0; // function\r
+ buffer[i++]=(byte)(nbsearches%256); buffer[i++]=(byte)(nbsearches/256); \r
+ buffer[i++]=0; buffer[i++]=0; // num\r
+ buffer[i++]=4; // keywords\r
+ buffer[i++]=0; buffer[i++]=0; // empty string\r
+ buffer[i++]=(byte)(query.length()%256);\r
+ buffer[i++]=(byte)(query.length()/256);\r
+ for (j=0;j<query.length();j++)\r
+ buffer[i++]=(byte)query.charAt(j);\r
+ buffer[i++]=50; buffer[i++]=0; buffer[i++]=0; buffer[i++]=0; // max hits\r
+ buffer[i++]=1; // type\r
+ Vector searchResult=new Vector();\r
+ searchResults.add(searchResult);\r
+ sendMessage(buffer,i);\r
+ nbsearches++;\r
+ /*\r
+ Vector resultInfo=new Vector();\r
+ resultInfo.add(new Long(1));\r
+ resultInfo.add("a");\r
+ resultInfo.add("a");\r
+ resultInfo.add("a");\r
+ resultInfo.add(new Boolean(false));\r
+ searchResult.add(resultInfo);\r
+ resultInfo=new Vector();\r
+ resultInfo.add(new Long(2));\r
+ resultInfo.add("b");\r
+ resultInfo.add("b");\r
+ resultInfo.add("b");\r
+ resultInfo.add(new Boolean(false));\r
+ searchResult.add(resultInfo);\r
+ resultInfo=new Vector();\r
+ resultInfo.add(new Long(3));\r
+ resultInfo.add("c");\r
+ resultInfo.add("c");\r
+ resultInfo.add("c");\r
+ resultInfo.add(new Boolean(false));\r
+ searchResult.add(resultInfo);\r
+ */\r
+ return searchResult;\r
+ }\r
+ \r
+ public void run()\r
+ {\r
+ while(readMessage())\r
+ {\r
+ //String serverStates[]={"NotConnected -1","Connecting","Connected_initiating","Connected_downloading","Connected -1","Connected n","NewHost","RemovedHost","BlackListedHost","NotConnected n"};\r
+ Boolean serverStates[]={\r
+ Boolean.FALSE, // "NotConnected -1"\r
+ Boolean.FALSE, // "Connecting"\r
+ Boolean.TRUE, // "Connected_initiating"\r
+ Boolean.TRUE, // "Connected_downloading"\r
+ Boolean.TRUE, // "Connected -1"\r
+ Boolean.TRUE, // "Connected n"\r
+ Boolean.FALSE, // "NewHost"\r
+ Boolean.FALSE, // "RemovedHost"\r
+ Boolean.FALSE, // "BlackListedHost"\r
+ Boolean.FALSE // "NotConnected n"\r
+ };\r
+ Boolean fileStates[]={\r
+ Boolean.TRUE, // FileDownloading\r
+ Boolean.FALSE, // FilePaused\r
+ Boolean.TRUE, // FileDownloaded\r
+ Boolean.FALSE, // FileShared\r
+ Boolean.FALSE, // FileCancelled\r
+ Boolean.FALSE, // FileNew\r
+ Boolean.FALSE, // FileAborted s\r
+ Boolean.FALSE // FileQueued\r
+ };\r
+ int i,n,f;\r
+ Long id;\r
+ String tags;\r
+ switch(f=readInt()) // fonction\r
+ {\r
+ \r
+ // CoreProtocol\r
+ case 0:\r
+ debug("CoreProtocol: "+readLong());\r
+ // (06:00:00:00:) 00:00:10:00:00:00 GuiProtocol\r
+ for (i=0;i<6;i++) buffer[i]=0;\r
+ buffer[2]=10;\r
+ sendMessage(buffer,6);\r
+ // (04:00:00:00:) 05:00:00:00 Password (empty)\r
+ i=0;\r
+ buffer[i++]=5; buffer[i++]=0; // function\r
+ buffer[i++]=(byte)(password.length()%256);\r
+ buffer[i++]=(byte)(password.length()/256);\r
+ for (int j=0;j<password.length();j++)\r
+ buffer[i++]=(byte)password.charAt(j);\r
+ sendMessage(buffer,i);\r
+ break;\r
+\r
+ // Options_info\r
+ case 1:\r
+ debug("Options_info:");\r
+ n=readInt();\r
+ for (i=0;i<n;i++)\r
+ debug(readString()+" = "+readString());\r
+ break;\r
+ \r
+ // DefineSearches\r
+ case 3:\r
+ n=readInt();\r
+ debug("DefineSearches: "+n);\r
+ /*for (i=0;i<n;i++)\r
+ {\r
+ System.out.println(readString()); // name\r
+ System.out.println(readByte());\r
+ }*/\r
+ break;\r
+ \r
+ // Result_info\r
+ case 4:\r
+ Vector resultInfo=new Vector();\r
+ debug("Result_info: ");\r
+ id=new Long(readLong());\r
+ resultInfo.add(id);\r
+ readLong(); // network\r
+ n=readInt();\r
+ resultInfo.add(readString());\r
+ for (i=0;i<n-1;i++) readString(); // names\r
+ for (i=0;i<16;i++) readByte(); // hash\r
+ resultInfo.add(new Long(readLong())); // Size\r
+ readString(); // Format\r
+ readString(); // Type\r
+ tags=new String();\r
+ n=readInt();\r
+ for (i=0;i<n;i++)\r
+ {\r
+ readString(); // TagName\r
+ switch (readByte()) // TagValue\r
+ {\r
+ case 0:\r
+ case 1:\r
+ tags=tags.concat(""+readLong()+" ");\r
+ break;\r
+ case 2:\r
+ tags=tags.concat(readString()+" ");\r
+ break;\r
+ case 3:\r
+ tags=tags.concat(""+readByte()+"."+readByte()+"."+readByte()+"."+readByte()+" ");\r
+ break;\r
+ }\r
+ }\r
+ resultInfo.add(tags);\r
+ readString(); // Comment\r
+ readByte(); // Done (boolean)\r
+ resultInfo.add(new Boolean(false)); // download ?\r
+ resultInfos.put(id,resultInfo);\r
+ break;\r
+\r
+ // Search_result \r
+ case 5:\r
+ int search=(int)readLong(); // Search\r
+ Long info=new Long(readLong()); // Result_Info\r
+ ((Vector)searchResults.get(search)).add(resultInfos.get(info));\r
+ break;\r
+ \r
+ // File_info\r
+ case 7:\r
+ case 40:\r
+ case 43: \r
+ Vector fileInfo=new Vector();\r
+ debug("FileInformation: ");\r
+ id=new Long(readLong()); // id\r
+ readLong(); // network\r
+ n=readInt();\r
+ readString();\r
+ fileInfo.add(readString());\r
+ for (i=0;i<n-2;i++) debug(readString()); // names\r
+ //for (i=0;i<n;i++) debug(readString()); // names\r
+ for (i=0;i<16;i++) readByte(); // hash\r
+ //readLong(); // size\r
+ //readLong(); // downloaded\r
+ long filesize=readLong();\r
+ long filedl=readLong();\r
+ fileInfo.add(new Long(filesize));\r
+ fileInfo.add(new Long(filedl));\r
+ fileInfo.add(new Float(Math.round(10000*filedl/filesize)/100.0));\r
+ //debug(readLong()+"/"+readLong());\r
+ readLong(); // nlocations\r
+ readLong(); // nclients\r
+ int state=readByte(); // file_state\r
+ readString(); // chunks\r
+ readString(); // availability\r
+ //fileInfo.add(new Float(readString())); // rate\r
+ fileInfo.add(new Float(Math.round(Float.parseFloat(readString()))/1000.0));\r
+ n=readInt();\r
+ for (i=0;i<n;i++) readString(); // chunks age\r
+ readString(); // age\r
+ switch (readByte()) // format\r
+ {\r
+ case 0:\r
+ debug("Unknown_format");\r
+ break;\r
+ case 1: // FormatType\r
+ //readString(); readString();\r
+ debug("FormatType: "+readString()+" "+readString());\r
+ break;\r
+ case 2: // AVI\r
+ debug("AVI: ");\r
+ debug("codec: "+readString()); // codec\r
+ debug(readLong()+"x"+readLong()+", "+readLong()+" fps "+readLong()+" rate") ;\r
+ break;\r
+ case 3: // MP3\r
+ debug("MP3: ");\r
+ debug("title: "+readString()); // title\r
+ debug("artist: "+readString()); // artist\r
+ debug("album: "+readString()); // album\r
+ debug("year: "+readString()); // year\r
+ debug("comment: "+readString()); // comment\r
+ debug("track: "+readLong()); // track number\r
+ debug("genre: "+readLong()); // genre\r
+ break;\r
+ }\r
+ fileInfo.add(fileStates[state]);\r
+ fileInfos.put(id,fileInfo);\r
+ break;\r
+ \r
+ // File_source\r
+ case 10:\r
+ // file_num f, client_num c\r
+ //debug("File_source: "+readInt()+" "+readInt());\r
+ break;\r
+ \r
+ // Server_state\r
+ case 13:\r
+ //debug("Server_state: "+readLong()+" etat: "+readByte());\r
+ id=new Long(readLong());\r
+ ((Vector)serverInfos.get(id)).setElementAt(serverStates[readByte()],3); // server_state\r
+ //System.out.println(id+" : state changed");\r
+ break;\r
+ \r
+ // Client_state\r
+ case 16:\r
+ debug("Client_state: "+readLong()+" etat: "+readByte());\r
+ break;\r
+ \r
+ // Client_info\r
+ case 15:\r
+ /*\r
+ debug("Client_info: ");\r
+ debug("num: "+readLong());\r
+ debug("network: "+readLong());\r
+ switch(readByte())\r
+ {\r
+ case 0:\r
+ // Known_location\r
+ debug("type: Known_location");\r
+ debug("ip: "+readByte()+"."+readByte()+"."+readByte()+"."+readByte());\r
+ debug("port: "+readInt());\r
+ break;\r
+ case 1:\r
+ // Indirect_location\r
+ debug("type: Indirect_location");\r
+ debug("name: "+readString());\r
+ break;\r
+ }\r
+ */\r
+ break;\r
+ \r
+ // Console\r
+ case 19: \r
+ debug("Console: ");\r
+ //console=console.concat(readString());\r
+ console.append(readString());\r
+ break;\r
+ \r
+ // Network_info\r
+ case 20:\r
+ n=readInt();\r
+ debug("Network_info: "+readString());\r
+ break;\r
+ \r
+ // Server_info\r
+ case 26:\r
+ Vector serverInfo=new Vector();\r
+ debug("Server_info: ");\r
+ id=new Long(readLong()); // id\r
+ readLong(); // network\r
+ // only works if proto>=2\r
+ String host=null;\r
+ switch(readByte())\r
+ {\r
+ case 0:\r
+ //debug("ip: "+readByte()+"."+readByte()+"."+readByte()+"."+readByte());\r
+ host=""+readByte()+"."+readByte()+"."+readByte()+"."+readByte();\r
+ break;\r
+ case 1:\r
+ //debug("name: "+readString());\r
+ host=readString();\r
+ break;\r
+ }\r
+ //debug("port: "+readInt());\r
+ host=host+":"+readInt(); // port\r
+ serverInfo.add(host);\r
+ readLong(); // score\r
+ tags=new String();\r
+ n=readInt();\r
+ for (i=0;i<n;i++)\r
+ {\r
+ readString(); // TagName\r
+ switch (readByte()) // TagValue\r
+ {\r
+ case 0:\r
+ case 1:\r
+ tags=tags.concat(""+readLong()+" ");\r
+ break;\r
+ case 2:\r
+ tags=tags.concat(readString()+" ");\r
+ break;\r
+ case 3:\r
+ tags=tags.concat(""+readByte()+"."+readByte()+"."+readByte()+"."+readByte()+" ");\r
+ break;\r
+ }\r
+ }\r
+ serverInfo.add(new Long(readLong())); // nusers\r
+ serverInfo.add(new Long(readLong())); // nfiles\r
+ serverInfo.add(serverStates[readByte()]); // server_state\r
+ serverInfos.put(id,serverInfo);\r
+ break;\r
+ \r
+ // Add_section_option\r
+ case 36:\r
+ debug("Add_section_option: "+readString()+" "+readString()+" "+readString());\r
+ break;\r
+ \r
+ // Add_plugin_option\r
+ case 38:\r
+ debug("Add_plugin_option: "+readString()+" "+readString()+" "+readString());\r
+ break;\r
+ \r
+ // File_downloaded\r
+ case 46:\r
+ debug("File_downloaded: ");\r
+ debug("n: "+readLong());\r
+ debug("size: "+readLong());\r
+ debug("rate: "+readString());\r
+ debug("last_seen: "+readLong());\r
+ break;\r
+ \r
+ // Shared_file_info\r
+ case 48:\r
+ debug("Shared_file_info: ");\r
+ debug("num: "+readLong());\r
+ debug("network: "+readLong());\r
+ debug("name: "+readString());\r
+ debug("size: "+readLong());\r
+ // ... \r
+ break;\r
+ \r
+ // Client_stats\r
+ case 49:\r
+ debug("Client_stats: ");\r
+ // stats...\r
+ break;\r
+\r
+ default:\r
+ debug("Fonction: "+f);\r
+ break;\r
+ \r
+ }\r
+ //System.out.println();\r
+ }\r
+ }\r
+ \r
+}
\ No newline at end of file
--- /dev/null
+import java.awt.*;\r
+import java.awt.event.*;\r
+import javax.swing.*;\r
+import javax.swing.table.*;\r
+import java.util.Vector;\r
+\r
+public class DonkeyGui extends JFrame\r
+{\r
+\r
+ DonkeyGui(final DonkeyCore donkeyCore)\r
+ {\r
+ Dimension screensize=Toolkit.getDefaultToolkit().getScreenSize();\r
+ \r
+ // Splash window\r
+ JWindow splash=new JWindow();\r
+ splash.getContentPane().add(new JLabel(new ImageIcon(getClass().getResource("/splash.jpg"))));\r
+ splash.pack();\r
+ Dimension windowsize=splash.getSize();\r
+ splash.setLocation((screensize.width-windowsize.width)/2,(screensize.height-windowsize.height)/2);\r
+ splash.setVisible(true);\r
+ \r
+ // Main window\r
+ setTitle("jMoule");\r
+ setSize(600,400);\r
+ windowsize=getSize();\r
+ setLocation((screensize.width-windowsize.width)/2,(screensize.height-windowsize.height)/2);\r
+ addWindowListener(new WindowAdapter() {\r
+ public void windowClosing(WindowEvent e)\r
+ {\r
+ System.exit(0);\r
+ }\r
+ });\r
+ \r
+ JTabbedPane tabbedPane=new JTabbedPane();\r
+ getContentPane().add(tabbedPane);\r
+\r
+ // Control panel\r
+ JPanel controlPanel=new JPanel();\r
+ JPanel connectPanel=new JPanel();\r
+ connectPanel.add(new JLabel("Host : "));\r
+ final JTextField hostText=new JTextField("",10);\r
+ connectPanel.add(hostText);\r
+ connectPanel.add(new JLabel("Password : "));\r
+ final JPasswordField passwordText=new JPasswordField("",5);\r
+ connectPanel.add(passwordText);\r
+ JButton connectButton=new JButton("Connect");\r
+ connectPanel.add(connectButton);\r
+ JButton killButton=new JButton("Kill");\r
+ connectPanel.add(killButton);\r
+ connectButton.addActionListener(new ActionListener() {\r
+ public void actionPerformed(ActionEvent event)\r
+ {\r
+ //System.out.println("connectButton");\r
+ if (hostText.getText().length()==0) return;\r
+ donkeyCore.connect(hostText.getText(),4001,new String(passwordText.getPassword()));\r
+ }\r
+ });\r
+ killButton.addActionListener(new ActionListener() {\r
+ public void actionPerformed(ActionEvent event)\r
+ {\r
+ //System.out.println("killButton");\r
+ donkeyCore.kill();\r
+ }\r
+ });\r
+ tabbedPane.add(connectPanel,"Control");\r
+\r
+ // Server panel\r
+ JPanel serverPanel=new JPanel(new BorderLayout());\r
+ JPanel servertopPanel=new JPanel();\r
+ JButton connectMoreButton=new JButton("Connect More");\r
+ servertopPanel.add(connectMoreButton);\r
+ JButton cleanOldButton=new JButton("Clean Old Servers");\r
+ servertopPanel.add(cleanOldButton);\r
+ /*\r
+ JButton sconnectButton=new JButton("Connect");\r
+ servertopPanel.add(sconnectButton);\r
+ JButton disconnectButton=new JButton("Disconnect");\r
+ servertopPanel.add(disconnectButton);\r
+ */\r
+ serverPanel.add(servertopPanel,"North");\r
+ //final JTable serverTable=new JTable(new ServerTableModel(donkeyCore.serverInfos));\r
+\r
+ TableModel dataModel=new ServerTableModel(donkeyCore.serverInfos,donkeyCore);\r
+ TableSorter sorter=new TableSorter(dataModel);\r
+ JTable tableView=new JTable(sorter);\r
+ tableView.setColumnSelectionAllowed(false);\r
+ tableView.setRowSelectionAllowed(false);\r
+ sorter.addMouseListenerToHeaderInTable(tableView);\r
+\r
+ //serverPanel.add(new JScrollPane(serverTable),"Center");\r
+ serverPanel.add(new JScrollPane(tableView),"Center");\r
+ tabbedPane.add(serverPanel,"Servers");\r
+ connectMoreButton.addActionListener(new ActionListener() {\r
+ public void actionPerformed(ActionEvent event)\r
+ {\r
+ //System.out.println("connectMoreButton");\r
+ donkeyCore.connectMore();\r
+ }\r
+ });\r
+ cleanOldButton.addActionListener(new ActionListener() {\r
+ public void actionPerformed(ActionEvent event)\r
+ {\r
+ //System.out.println("cleanOldButton");\r
+ donkeyCore.cleanOld();\r
+ }\r
+ });\r
+ /*\r
+ sconnectButton.addActionListener(new ActionListener() {\r
+ public void actionPerformed(ActionEvent event)\r
+ {\r
+ System.out.println("sconnectButton");\r
+ for (int i=0;i<serverTable.getSelectedRowCount();i++)\r
+ {\r
+ ServerTableModel m=(ServerTableModel)serverTable.getModel();\r
+ //Vector v=(Vector)r.serverInfos.get(serverTable.getSelectedRows()[i]);\r
+ donkeyCore.connectServer((Long)m.getValueAt(i,0));\r
+ }\r
+ }\r
+ });\r
+ disconnectButton.addActionListener(new ActionListener() {\r
+ public void actionPerformed(ActionEvent event)\r
+ {\r
+ System.out.println("disconnectButton");\r
+ for (int i=0;i<serverTable.getSelectedRowCount();i++)\r
+ {\r
+ ServerTableModel m=(ServerTableModel)serverTable.getModel();\r
+ //Vector v=(Vector)r.serverInfos.get(serverTable.getSelectedRows()[i]);\r
+ donkeyCore.disconnectServer((Long)m.getValueAt(i,0));\r
+ }\r
+ }\r
+ });\r
+ */\r
+\r
+ // Search panel\r
+ JPanel searchPanel=new JPanel(new BorderLayout());\r
+ JPanel topPanel=new JPanel();\r
+ topPanel.add(new JLabel("Query : "));\r
+ final JTextField searchText=new JTextField("",15);\r
+ topPanel.add(searchText);\r
+ JButton searchButton=new JButton("Search");\r
+ topPanel.add(searchButton);\r
+ JButton extendButton=new JButton("Extend");\r
+ topPanel.add(extendButton);\r
+ /*\r
+ JButton downloadButton=new JButton("Download");\r
+ topPanel.add(downloadButton);\r
+ */\r
+ searchPanel.add(topPanel,"North");\r
+ final JTabbedPane resultsPane=new JTabbedPane(); \r
+ searchPanel.add(resultsPane,"Center");\r
+ final Vector resultTables=new Vector();\r
+ searchButton.addActionListener(new ActionListener() {\r
+ public void actionPerformed(ActionEvent event)\r
+ {\r
+ //System.out.println("searchButton");\r
+ if (searchText.getText().length()==0) return;\r
+ Vector searchResult=donkeyCore.search(searchText.getText());\r
+ \r
+ /*\r
+ JTable resultTable=new JTable(new ResultTableModel(searchResult));\r
+ resultTables.add(resultTable);\r
+ resultsPane.add(new JScrollPane(resultTable),searchText.getText());\r
+ resultsPane.setSelectedIndex(resultsPane.getTabCount()-1);\r
+ */\r
+ \r
+ ResultTableModel resultModel=new ResultTableModel(searchResult,donkeyCore);\r
+ TableSorter sorter=new TableSorter(resultModel);\r
+ JTable tableView=new JTable(sorter);\r
+ tableView.setColumnSelectionAllowed(false);\r
+ tableView.setRowSelectionAllowed(false);\r
+ resultTables.add(tableView);\r
+ sorter.addMouseListenerToHeaderInTable(tableView);\r
+ resultsPane.add(new JScrollPane(tableView),searchText.getText());\r
+ resultsPane.setSelectedIndex(resultsPane.getTabCount()-1);\r
+\r
+ }\r
+ });\r
+ extendButton.addActionListener(new ActionListener() {\r
+ public void actionPerformed(ActionEvent event)\r
+ {\r
+ //System.out.println("extendButton");\r
+ donkeyCore.extend();\r
+ }\r
+ });\r
+ /*\r
+ downloadButton.addActionListener(new ActionListener() {\r
+ public void actionPerformed(ActionEvent event)\r
+ {\r
+ System.out.println("downloadButton");\r
+ JTable resultTable=(JTable)resultTables.get(resultsPane.getSelectedIndex());\r
+ for (int i=0;i<resultTable.getSelectedRowCount();i++)\r
+ {\r
+ ResultTableModel r=(ResultTableModel)resultTable.getModel();\r
+ Vector v=(Vector)r.searchResult.get(resultTable.getSelectedRows()[i]);\r
+ donkeyCore.download((Long)v.get(0));\r
+ }\r
+ }\r
+ });\r
+ */\r
+ tabbedPane.add(searchPanel,"Search");\r
+\r
+ // Downloads panel\r
+ //tabbedPane.add(new JScrollPane(new JTable(new DownloadTableModel(donkeyCore.fileInfos))),"Downloads");\r
+ //DownloadTableModel \r
+ dataModel=new DownloadTableModel(donkeyCore.fileInfos,donkeyCore);\r
+ //TableSorter \r
+ sorter=new TableSorter(dataModel);\r
+ //JTable \r
+ tableView=new JTable(sorter);\r
+ tableView.setColumnSelectionAllowed(false);\r
+ tableView.setRowSelectionAllowed(false);\r
+ sorter.addMouseListenerToHeaderInTable(tableView);\r
+ tabbedPane.add(new JScrollPane(tableView),"Downloads");\r
+\r
+ // Console panel\r
+ tabbedPane.add(new JScrollPane(donkeyCore.console),"Console");\r
+\r
+ try\r
+ {\r
+ Thread.sleep(2000);\r
+ }\r
+ catch (Exception e)\r
+ {}\r
+ splash.setVisible(false);\r
+ show();\r
+ \r
+ }\r
+ \r
+}\r
--- /dev/null
+import java.util.Hashtable;\r
+import java.util.Vector;\r
+import javax.swing.table.*;\r
+\r
+public class DownloadTableModel extends RefreshAbstractTableModel\r
+{\r
+\r
+ Hashtable fileInfos;\r
+ String columns[]={"Number","File Name","Size","Downloaded","%","Rate","Running"};\r
+ DonkeyCore donkeyCore;\r
+ \r
+ public DownloadTableModel(Hashtable fileInfos,DonkeyCore donkeyCore)\r
+ {\r
+ this.donkeyCore=donkeyCore;\r
+ this.fileInfos=fileInfos;\r
+ }\r
+ \r
+ public int getColumnCount()\r
+ {\r
+ return columns.length;\r
+ }\r
+ \r
+ public String getColumnName(int col)\r
+ {\r
+ return columns[col];\r
+ }\r
+\r
+ public int getRowCount()\r
+ {\r
+ return fileInfos.size();\r
+ }\r
+ \r
+ public Object getValueAt(int row,int col)\r
+ {\r
+ if (col==0) return fileInfos.keySet().toArray()[row];\r
+ return ((Vector)fileInfos.values().toArray()[row]).get(col-1);\r
+ }\r
+\r
+ public boolean isCellEditable(int row,int col)\r
+ {\r
+ return col==columns.length-1;\r
+ }\r
+ \r
+ public void setValueAt(Object o,int row,int col)\r
+ {\r
+ Long id=(Long)getValueAt(row,0);\r
+ Vector fileInfo=(Vector)fileInfos.get(id);\r
+ donkeyCore.switchDownload((Long)getValueAt(row,0),((Boolean)o).booleanValue());\r
+ }\r
+\r
+}
\ No newline at end of file
--- /dev/null
+public class Main\r
+{\r
+ \r
+ public static void main(String[] args) throws Exception\r
+ {\r
+ new DonkeyGui(new DonkeyCore()); \r
+ }\r
+ \r
+}
\ No newline at end of file
--- /dev/null
+import javax.swing.table.*;\r
+\r
+public abstract class RefreshAbstractTableModel extends AbstractTableModel\r
+{\r
+\r
+ public RefreshAbstractTableModel()\r
+ {\r
+ Thread refreshThread=new Thread()\r
+ {\r
+ public void run()\r
+ {\r
+ //int oldRowCount=0,newRowCount;\r
+ try\r
+ {\r
+ for (;;)\r
+ {\r
+ sleep(5000);\r
+ /*\r
+ newRowCount=getRowCount();\r
+ if (oldRowCount<newRowCount)\r
+ fireTableRowsInserted(oldRowCount-1,newRowCount-1);\r
+ if (oldRowCount>newRowCount)\r
+ fireTableRowsDeleted(newRowCount-1,oldRowCount-1);\r
+ fireTableRowsUpdated(0,newRowCount-1);\r
+ oldRowCount=newRowCount;\r
+ */\r
+ fireTableDataChanged();\r
+ }\r
+ }\r
+ catch(Exception e)\r
+ {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+ };\r
+ refreshThread.start();\r
+ }\r
+ \r
+ public Class getColumnClass(int col)\r
+ {\r
+ return getValueAt(0,col).getClass();\r
+ }\r
+\r
+}
\ No newline at end of file
--- /dev/null
+import java.util.Hashtable;\r
+import java.util.Vector;\r
+import javax.swing.table.*;\r
+\r
+public class ResultTableModel extends RefreshAbstractTableModel\r
+{\r
+\r
+ Vector searchResult;\r
+ String columns[]={"Number","File Name","Size","Tags","Download"};\r
+ DonkeyCore donkeyCore;\r
+ \r
+ public ResultTableModel(Vector searchResult,DonkeyCore donkeyCore)\r
+ {\r
+ this.donkeyCore=donkeyCore;\r
+ this.searchResult=searchResult;\r
+ }\r
+ \r
+ public int getColumnCount()\r
+ {\r
+ return columns.length;\r
+ }\r
+ \r
+ public String getColumnName(int col)\r
+ {\r
+ return columns[col];\r
+ }\r
+\r
+ public int getRowCount()\r
+ {\r
+ return searchResult.size();\r
+ }\r
+ \r
+ public Object getValueAt(int row,int col)\r
+ {\r
+ return ((Vector)searchResult.get(row)).get(col);\r
+ }\r
+ \r
+ public boolean isCellEditable(int row,int col)\r
+ {\r
+ return col==columns.length-1;\r
+ }\r
+ \r
+ public void setValueAt(Object o,int row,int col)\r
+ {\r
+ ((Vector)searchResult.get(row)).setElementAt(new Boolean(true),col);\r
+ donkeyCore.download((Long)getValueAt(row,0));\r
+ }\r
+\r
+}
\ No newline at end of file
--- /dev/null
+import java.util.Hashtable;\r
+import java.util.Vector;\r
+import javax.swing.table.*;\r
+\r
+public class ServerTableModel extends RefreshAbstractTableModel\r
+{\r
+\r
+ Hashtable serverInfos;\r
+ String columns[]={"Number","Host","Users","Files","Connected"};\r
+ DonkeyCore donkeyCore;\r
+ \r
+ public ServerTableModel(Hashtable serverInfos,DonkeyCore donkeyCore)\r
+ {\r
+ this.donkeyCore=donkeyCore;\r
+ this.serverInfos=serverInfos;\r
+ }\r
+ \r
+ public int getColumnCount()\r
+ {\r
+ return columns.length;\r
+ }\r
+ \r
+ public String getColumnName(int col)\r
+ {\r
+ return columns[col];\r
+ }\r
+\r
+ public int getRowCount()\r
+ {\r
+ return serverInfos.size();\r
+ }\r
+ \r
+ public Object getValueAt(int row,int col)\r
+ {\r
+ if (col==0) return serverInfos.keySet().toArray()[row];\r
+ return ((Vector)serverInfos.values().toArray()[row]).get(col-1);\r
+ }\r
+\r
+ public boolean isCellEditable(int row,int col)\r
+ {\r
+ return col==columns.length-1;\r
+ }\r
+ \r
+ public void setValueAt(Object o,int row,int col)\r
+ {\r
+ Long id=(Long)getValueAt(row,0);\r
+ Vector serverInfo=(Vector)serverInfos.get(id);\r
+ if (((Boolean)serverInfo.elementAt(3)).booleanValue())\r
+ {\r
+ //((Vector)searchResult.get(row)).setElementAt(new Boolean(true),col);\r
+ donkeyCore.disconnectServer((Long)getValueAt(row,0));\r
+ }\r
+ else\r
+ {\r
+ donkeyCore.connectServer((Long)getValueAt(row,0));\r
+ }\r
+ }\r
+\r
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
+ * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ */
+
+/**
+ * In a chain of data manipulators some behaviour is common. TableMap
+ * provides most of this behavour and can be subclassed by filters
+ * that only need to override a handful of specific methods. TableMap
+ * implements TableModel by routing all requests to its model, and
+ * TableModelListener by routing all events to its listeners. Inserting
+ * a TableMap which has not been subclassed into a chain of table filters
+ * should have no effect.
+ *
+ * @version 1.8 02/06/02
+ * @author Philip Milne */
+
+import javax.swing.table.*;
+import javax.swing.event.TableModelListener;
+import javax.swing.event.TableModelEvent;
+
+public class TableMap extends AbstractTableModel implements TableModelListener
+{
+ protected TableModel model;
+
+ public TableModel getModel() {
+ return model;
+ }
+
+ public void setModel(TableModel model) {
+ this.model = model;
+ model.addTableModelListener(this);
+ }
+
+ // By default, Implement TableModel by forwarding all messages
+ // to the model.
+
+ public Object getValueAt(int aRow, int aColumn) {
+ return model.getValueAt(aRow, aColumn);
+ }
+
+ public void setValueAt(Object aValue, int aRow, int aColumn) {
+ model.setValueAt(aValue, aRow, aColumn);
+ }
+
+ public int getRowCount() {
+ return (model == null) ? 0 : model.getRowCount();
+ }
+
+ public int getColumnCount() {
+ return (model == null) ? 0 : model.getColumnCount();
+ }
+
+ public String getColumnName(int aColumn) {
+ return model.getColumnName(aColumn);
+ }
+
+ public Class getColumnClass(int aColumn) {
+ return model.getColumnClass(aColumn);
+ }
+
+ public boolean isCellEditable(int row, int column) {
+ return model.isCellEditable(row, column);
+ }
+//
+// Implementation of the TableModelListener interface,
+//
+
+ // By default forward all events to all the listeners.
+ public void tableChanged(TableModelEvent e) {
+ fireTableChanged(e);
+ }
+}
--- /dev/null
+/*
+ * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
+ * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ */
+
+/**
+ * A sorter for TableModels. The sorter has a model (conforming to TableModel)
+ * and itself implements TableModel. TableSorter does not store or copy
+ * the data in the TableModel, instead it maintains an array of
+ * integers which it keeps the same size as the number of rows in its
+ * model. When the model changes it notifies the sorter that something
+ * has changed eg. "rowsAdded" so that its internal array of integers
+ * can be reallocated. As requests are made of the sorter (like
+ * getValueAt(row, col) it redirects them to its model via the mapping
+ * array. That way the TableSorter appears to hold another copy of the table
+ * with the rows in a different order. The sorting algorthm used is stable
+ * which means that it does not move around rows when its comparison
+ * function returns 0 to denote that they are equivalent.
+ *
+ * @version 1.9 02/06/02
+ * @author Philip Milne
+ */
+
+import java.util.*;
+
+import javax.swing.table.TableModel;
+import javax.swing.event.TableModelEvent;
+
+// Imports for picking up mouse events from the JTable.
+
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.InputEvent;
+import javax.swing.JTable;
+import javax.swing.table.JTableHeader;
+import javax.swing.table.TableColumn;
+import javax.swing.table.TableColumnModel;
+
+public class TableSorter extends TableMap
+{
+ int indexes[];
+ Vector sortingColumns = new Vector();
+ boolean ascending = true;
+ int compares;
+ int Xcolumn=0;
+ boolean Xascending=false;
+
+ public TableSorter()
+ {
+ indexes = new int[0]; // For consistency.
+ }
+
+ public TableSorter(TableModel model)
+ {
+ setModel(model);
+ }
+
+ public void setModel(TableModel model) {
+ super.setModel(model);
+ reallocateIndexes();
+ }
+
+ public int compareRowsByColumn(int row1, int row2, int column)
+ {
+ Class type = model.getColumnClass(column);
+ TableModel data = model;
+
+ // Check for nulls
+
+ Object o1 = data.getValueAt(row1, column);
+ Object o2 = data.getValueAt(row2, column);
+
+ // If both values are null return 0
+ if (o1 == null && o2 == null) {
+ return 0;
+ }
+ else if (o1 == null) { // Define null less than everything.
+ return -1;
+ }
+ else if (o2 == null) {
+ return 1;
+ }
+
+/* We copy all returned values from the getValue call in case
+an optimised model is reusing one object to return many values.
+The Number subclasses in the JDK are immutable and so will not be used in
+this way but other subclasses of Number might want to do this to save
+space and avoid unnecessary heap allocation.
+*/
+ if (type.getSuperclass() == java.lang.Number.class)
+ {
+ Number n1 = (Number)data.getValueAt(row1, column);
+ double d1 = n1.doubleValue();
+ Number n2 = (Number)data.getValueAt(row2, column);
+ double d2 = n2.doubleValue();
+
+ if (d1 > d2)
+ return -1;
+ else if (d1 < d2)
+ return 1;
+ else
+ return 0;
+ }
+ else if (type == java.util.Date.class)
+ {
+ Date d1 = (Date)data.getValueAt(row1, column);
+ long n1 = d1.getTime();
+ Date d2 = (Date)data.getValueAt(row2, column);
+ long n2 = d2.getTime();
+
+ if (n1 < n2)
+ return -1;
+ else if (n1 > n2)
+ return 1;
+ else return 0;
+ }
+ else if (type == String.class)
+ {
+ String s1 = (String)data.getValueAt(row1, column);
+ String s2 = (String)data.getValueAt(row2, column);
+ int result = s1.compareTo(s2);
+
+ if (result < 0)
+ return -1;
+ else if (result > 0)
+ return 1;
+ else return 0;
+ }
+ else if (type == Boolean.class)
+ {
+ Boolean bool1 = (Boolean)data.getValueAt(row1, column);
+ boolean b1 = bool1.booleanValue();
+ Boolean bool2 = (Boolean)data.getValueAt(row2, column);
+ boolean b2 = bool2.booleanValue();
+
+ if (b1 == b2)
+ return 0;
+ else if (b2) // Define false > true
+ return 1;
+ else
+ return -1;
+ }
+ else
+ {
+ Object v1 = data.getValueAt(row1, column);
+ String s1 = v1.toString();
+ Object v2 = data.getValueAt(row2, column);
+ String s2 = v2.toString();
+ int result = s1.compareTo(s2);
+
+ if (result < 0)
+ return -1;
+ else if (result > 0)
+ return 1;
+ else return 0;
+ }
+ }
+
+ public int compare(int row1, int row2)
+ {
+ compares++;
+ for(int level = 0; level < sortingColumns.size(); level++)
+ {
+ Integer column = (Integer)sortingColumns.elementAt(level);
+ int result = compareRowsByColumn(row1, row2, column.intValue());
+ if (result != 0)
+ return ascending ? result : -result;
+ }
+ return 0;
+ }
+
+ public void reallocateIndexes()
+ {
+ int rowCount = model.getRowCount();
+
+ // Set up a new array of indexes with the right number of elements
+ // for the new data model.
+ indexes = new int[rowCount];
+
+ // Initialise with the identity mapping.
+ for(int row = 0; row < rowCount; row++)
+ indexes[row] = row;
+ }
+
+ public void tableChanged(TableModelEvent e)
+ {
+ //System.out.println("Sorter: tableChanged");
+ reallocateIndexes();
+
+ sortByColumn(Xcolumn, Xascending);
+ super.tableChanged(e);
+ }
+
+ public void checkModel()
+ {
+ if (indexes.length != model.getRowCount()) {
+ //System.err.println("Sorter not informed of a change in model.");
+ }
+ }
+
+ public void sort(Object sender)
+ {
+ checkModel();
+
+ compares = 0;
+ // n2sort();
+ // qsort(0, indexes.length-1);
+ shuttlesort((int[])indexes.clone(), indexes, 0, indexes.length);
+ //System.out.println("Compares: "+compares);
+ }
+
+ public void n2sort() {
+ for(int i = 0; i < getRowCount(); i++) {
+ for(int j = i+1; j < getRowCount(); j++) {
+ if (compare(indexes[i], indexes[j]) == -1) {
+ swap(i, j);
+ }
+ }
+ }
+ }
+
+ // This is a home-grown implementation which we have not had time
+ // to research - it may perform poorly in some circumstances. It
+ // requires twice the space of an in-place algorithm and makes
+ // NlogN assigments shuttling the values between the two
+ // arrays. The number of compares appears to vary between N-1 and
+ // NlogN depending on the initial order but the main reason for
+ // using it here is that, unlike qsort, it is stable.
+ public void shuttlesort(int from[], int to[], int low, int high) {
+ if (high - low < 2) {
+ return;
+ }
+ int middle = (low + high)/2;
+ shuttlesort(to, from, low, middle);
+ shuttlesort(to, from, middle, high);
+
+ int p = low;
+ int q = middle;
+
+ /* This is an optional short-cut; at each recursive call,
+ check to see if the elements in this subset are already
+ ordered. If so, no further comparisons are needed; the
+ sub-array can just be copied. The array must be copied rather
+ than assigned otherwise sister calls in the recursion might
+ get out of sinc. When the number of elements is three they
+ are partitioned so that the first set, [low, mid), has one
+ element and and the second, [mid, high), has two. We skip the
+ optimisation when the number of elements is three or less as
+ the first compare in the normal merge will produce the same
+ sequence of steps. This optimisation seems to be worthwhile
+ for partially ordered lists but some analysis is needed to
+ find out how the performance drops to Nlog(N) as the initial
+ order diminishes - it may drop very quickly. */
+
+ if (high - low >= 4 && compare(from[middle-1], from[middle]) <= 0) {
+ for (int i = low; i < high; i++) {
+ to[i] = from[i];
+ }
+ return;
+ }
+
+ // A normal merge.
+
+ for(int i = low; i < high; i++) {
+ if (q >= high || (p < middle && compare(from[p], from[q]) <= 0)) {
+ to[i] = from[p++];
+ }
+ else {
+ to[i] = from[q++];
+ }
+ }
+ }
+
+ public void swap(int i, int j) {
+ int tmp = indexes[i];
+ indexes[i] = indexes[j];
+ indexes[j] = tmp;
+ }
+
+ // The mapping only affects the contents of the data rows.
+ // Pass all requests to these rows through the mapping array: "indexes".
+
+ public Object getValueAt(int aRow, int aColumn)
+ {
+ checkModel();
+ return model.getValueAt(indexes[aRow], aColumn);
+ }
+
+ public void setValueAt(Object aValue, int aRow, int aColumn)
+ {
+ checkModel();
+ model.setValueAt(aValue, indexes[aRow], aColumn);
+ }
+
+ public void sortByColumn(int column) {
+ sortByColumn(column, true);
+ }
+
+ public void sortByColumn(int column, boolean ascending) {
+ this.ascending = ascending;
+ sortingColumns.removeAllElements();
+ sortingColumns.addElement(new Integer(column));
+ sort(this);
+ super.tableChanged(new TableModelEvent(this));
+ }
+
+ // There is no-where else to put this.
+ // Add a mouse listener to the Table to trigger a table sort
+ // when a column heading is clicked in the JTable.
+ public void addMouseListenerToHeaderInTable(JTable table) {
+ final TableSorter sorter = this;
+ final JTable tableView = table;
+ tableView.setColumnSelectionAllowed(false);
+ MouseAdapter listMouseListener = new MouseAdapter() {
+ public void mouseClicked(MouseEvent e) {
+ TableColumnModel columnModel = tableView.getColumnModel();
+ int viewColumn = columnModel.getColumnIndexAtX(e.getX());
+ int column = tableView.convertColumnIndexToModel(viewColumn);
+ if(e.getClickCount() == 1 && column != -1) {
+ //System.out.println("Sorting ...");
+ int shiftPressed = e.getModifiers()&InputEvent.SHIFT_MASK;
+ boolean ascending = (shiftPressed == 0);
+ sorter.sortByColumn(Xcolumn=column, Xascending=ascending);
+ }
+ }
+ };
+ JTableHeader th = tableView.getTableHeader();
+ th.addMouseListener(listMouseListener);
+ }
+
+
+
+}
--- /dev/null
+Main-Class: Main\r