📄 packetfactory.java
字号:
/* * JMule - Java file sharing client * Copyright (C) 2007-2008 JMule team ( jmule@jmule.org / http://jmule.org ) * * Any parts of this program derived from other projects, or contributed * by third-party developers are copyrighted by their respective authors. * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * */package org.jmule.core.edonkey.packet;import static org.jmule.core.edonkey.E2DKConstants.MAX_OFFER_FILES;import static org.jmule.core.edonkey.E2DKConstants.OP_END_OF_DOWNLOAD;import static org.jmule.core.edonkey.E2DKConstants.OP_FILEREQANSNOFILE;import static org.jmule.core.edonkey.E2DKConstants.OP_FILEREQANSWER;import static org.jmule.core.edonkey.E2DKConstants.OP_FILEREQUEST;import static org.jmule.core.edonkey.E2DKConstants.OP_FILESTATREQ;import static org.jmule.core.edonkey.E2DKConstants.OP_FILESTATUS;import static org.jmule.core.edonkey.E2DKConstants.OP_GETSERVERLIST;import static org.jmule.core.edonkey.E2DKConstants.OP_GETSOURCES;import static org.jmule.core.edonkey.E2DKConstants.OP_HASHSETANSWER;import static org.jmule.core.edonkey.E2DKConstants.OP_HASHSETREQUEST;import static org.jmule.core.edonkey.E2DKConstants.OP_LOGINREQUEST;import static org.jmule.core.edonkey.E2DKConstants.OP_MESSAGE;import static org.jmule.core.edonkey.E2DKConstants.OP_OFFERFILES;import static org.jmule.core.edonkey.E2DKConstants.OP_PEERHELLO;import static org.jmule.core.edonkey.E2DKConstants.OP_PEERHELLOANSWER;import static org.jmule.core.edonkey.E2DKConstants.OP_REQUESTPARTS;import static org.jmule.core.edonkey.E2DKConstants.OP_SEARCHREQUEST;import static org.jmule.core.edonkey.E2DKConstants.OP_SENDINGPART;import static org.jmule.core.edonkey.E2DKConstants.OP_SLOTGIVEN;import static org.jmule.core.edonkey.E2DKConstants.OP_SLOTRELEASE;import static org.jmule.core.edonkey.E2DKConstants.OP_SLOTREQUEST;import static org.jmule.core.edonkey.E2DKConstants.PACKET_CALLBACKREQUEST;import static org.jmule.core.edonkey.E2DKConstants.ProtocolVersion;import static org.jmule.core.edonkey.E2DKConstants.SEARCH_BYNAME;import static org.jmule.core.edonkey.E2DKConstants.SUPPORTED_FLAGS;import static org.jmule.core.edonkey.E2DKConstants.ServerSoftwareVersion;import static org.jmule.core.edonkey.E2DKConstants.SoftwareVersion;import static org.jmule.core.edonkey.E2DKConstants.TAG_NAME_CLIENTVER;import static org.jmule.core.edonkey.E2DKConstants.TAG_NAME_FLAGS;import static org.jmule.core.edonkey.E2DKConstants.TAG_NAME_MISC_OPTIONS1;import static org.jmule.core.edonkey.E2DKConstants.TAG_NAME_MISC_OPTIONS2;import static org.jmule.core.edonkey.E2DKConstants.TAG_NAME_NAME;import static org.jmule.core.edonkey.E2DKConstants.TAG_NAME_PROTOCOLVERSION;import static org.jmule.core.edonkey.E2DKConstants.TAG_NAME_SIZE;import static org.jmule.core.edonkey.E2DKConstants.TAG_NAME_UDP_PORT;import static org.jmule.core.edonkey.E2DKConstants.TAG_NAME_UDP_PORT_PEER;import java.nio.ByteBuffer;import java.nio.ByteOrder;import java.util.LinkedList;import java.util.List;import org.jmule.core.JMuleCoreFactory;import org.jmule.core.configmanager.ConfigurationManagerFactory;import org.jmule.core.downloadmanager.FileChunk;import org.jmule.core.edonkey.impl.ClientID;import org.jmule.core.edonkey.impl.FileHash;import org.jmule.core.edonkey.impl.PartHashSet;import org.jmule.core.edonkey.impl.UserHash;import org.jmule.core.edonkey.packet.impl.EMuleCompressedPacket;import org.jmule.core.edonkey.packet.impl.StandardPacket;import org.jmule.core.edonkey.packet.tag.Tag;import org.jmule.core.edonkey.packet.tag.TagFactory;import org.jmule.core.sharingmanager.GapList;import org.jmule.core.sharingmanager.JMuleBitSet;import org.jmule.core.sharingmanager.SharedFile;import org.jmule.util.Convert;import org.jmule.util.Misc;/** * * @author binary256 * @version $$Revision: 1.4 $$ * Last changed by $$Author: binary256_ $$ on $$Date: 2008/10/05 10:43:01 $$ */public class PacketFactory { /** * Server login packet. * <table cellpadding="0" border="1" cellspacing="0"> * <thead> * <tr> * <th>Name</th> * <th>Size in bytes</th> * <th>Default value</th> * <th>Comment</th> * </tr> * </thead> * <tbody> * <tr> * <td>Protocol</td> * <td>1</td> * <td>0xE3</td> * <td>- </td> * </tr> * <tr> * <td>Size</td> * <td>4</td> * <td>-</td> * <td>The size of the message in bytes not including the header and size fileds</td> * </tr> * <tr> * <td>Type</td> * <td>1</td> * <td>0x01</td> * <td>The value of the OP_LOGINREQUEST opcode</td> * </tr> * <tr> * <td>User Hash</td> * <td>16</td> * <td>-</td> * <td>- </td> * </tr> * <tr> * <td>Client ID</td> * <td>4</td> * <td>0</td> * <td>The client ID that is sent on first connection is usually zero</td> * </tr> * <tr> * <td>TCP Port</td> * <td>2</td> * <td>4662</td> * <td>The TCP port used by the client, configurable</td> * </tr> * <tr> * <td>Tag Count</td> * <td>4</td> * <td>4</td> * <td>The number of tags following in the message</td> * </tr> * <tr> * <td>Name Tag</td> * <td>varies</td> * <td>NA</td> * <td>The user's nickname. The tag is a string tag and the tag name is an integer of value 0x1</td> * </tr> * <tr> * <td>Version Tag</td> * <td>8</td> * <td>0x3C</td> * <td>The eDonkey version supported by the client. The tag is an integer tag and the tag name is an integer of value 0x11</td> * </tr> * <tr> * <td>Port Tag</td> * <td>8</td> * <td>4662</td> * <td>The TCP port used by the client. The tag is an integer tag and the tag name is an integer of value 0x0F</td> * </tr> * <tr> * <td>Flags Tag</td> * <td>8</td> * <td>0x01</td> * <td>The tag is an integer tag and the tag name is an integer of value 0x20</td> * </tr> * </tbody> * </table> * </table> */ public static Packet getServerLoginPacket(UserHash userHash, int clientPort, String userNickName) { byte[] tagUserNick = TagFactory.getStringTag( userNickName , TAG_NAME_NAME ).getData(); byte[] tagProtocolVersion = TagFactory.getDWORDTag( ProtocolVersion , TAG_NAME_PROTOCOLVERSION).getData(); byte[] tagClientVersion = TagFactory.getDWORDTag(ServerSoftwareVersion, TAG_NAME_CLIENTVER).getData();//eMule client version byte[] tagFlags = TagFactory.getDWORDTag( SUPPORTED_FLAGS, TAG_NAME_FLAGS).getData(); byte[] tagUDPPort = TagFactory.getDWORDTag(ConfigurationManagerFactory.getInstance().getUDP(), TAG_NAME_UDP_PORT).getData(); Packet packet = new StandardPacket(16+4+2+4+tagUserNick.length+tagProtocolVersion.length+tagFlags.length+tagClientVersion.length+tagUDPPort.length); packet.setCommand(OP_LOGINREQUEST);//Insert LOGIN_COMMAND packet.insertData(userHash.getUserHash());//Insert user Hash packet.insertData(new byte[]{0,0,0,0});//Insert default user ID packet.insertData((short)clientPort);//Insert user port packet.insertData((int)4+1);//Insert tag count packet.insertData(tagUserNick);//Insert UserNick tag packet.insertData(tagProtocolVersion);//Insert Protocol Version tag packet.insertData(tagClientVersion);//Insert client version tag packet.insertData(tagFlags);//Insert Flags packet.insertData(tagUDPPort); return packet; } /** * Create Server list request packet. * <table cellpadding="0" border="1" cellspacing="0"> * <thead> * <tr> * <th>Name</th> * <th>Size in bytes</th> * <th>Default Value</th> * <th>Comment</th> * </tr> * </thead> * <tbody> * <tr> * <td>Protocol</td> * <td>1</td> * <td>0xE3</td> * <td> </td> * </tr> * <tr> * <td>Size</td> * <td>4</td> * <td> </td> * <td>The size of the message in bytes not including the header and size fields</td> * </tr> * <tr> * <td>Type</td> * <td>1</td> * <td>0x14</td> * <td>The value of the OP_SERVERSTATUS opcode</td> * </tr> * </tbody> * </table> * </table> */ public static Packet getGetServerListPacket(){ Packet packet=new StandardPacket(0); packet.setCommand(OP_GETSERVERLIST); return packet; } /** * Create server search packet. * <table cellpadding="0" border="1" cellspacing="0"> * <thead> * <tr> * <th>Name</th> * <th>Size in bytes</th> * <th>Default Value</th> * <th>Comment</th> * </tr> * </thead> * <tbody> * <tr> * <td>Protocol</td> * <td>1</td> * <td>0xE3</td> * <td> </td> * </tr> * <tr> * <td>Size</td> * <td>4</td> * <td>-</td> * <td>The size of the message in bytes not including the header and size fields</td> * </tr> * <tr> * <td>Type</td> * <td>1</td> * <td>16</td> * <td>The value of the OP_SEARCHREQUEST opcode</td> * </tr> * <tr> * <td>Parsed search string</td> * <td>varies</td> * <td>NA</td> * <td>The parsed search string format is described below</td> * </tr> * <tr> * <td>File Type Constraint</td> * <td>varies</td> * <td>NA</td> * <td>Optional. A string constraint. The string values are one of ("Audio", "Video", "Pro" or "Image". The type field is 3 bytes: 0x1 0x0 0x3</td> * </tr> * <tr> * <td>Min Size Constraint</td> * <td>varies</td> * <td>NA</td> * <td>Optional. An integer constraint. The file size is provided in mega bytes. The type field is 4 bytes : 0x1 0x1 0x0 0x2</td> * </tr> * <tr> * <td>Max Size Constraint</td> * <td>varies</td> * <td>NA</td> * <td>Optional. An integer constraint. The file size is provided in mega bytes. The type field is 4 bytes : 0x2 0x1 0x0 0x2</td> * </tr> * <tr> * <td>Availability Constraint</td> * <td>varies</td> * <td>NA</td> * <td>Optional. An integer constraint. Sets a lower limit on the number of clien that poses the searched file. The type field is 4 bytes: 0x1 0x1 0x0 0x15</td> * </tr> * <tr> * <td>Filename Extension constrain</td> * <td>varies</td> * <td>NA</td> * <td>Optional. A string constraint. The type field is 3 bytes: 0x1 0x0 0x3</td> * </tr> * </tbody> * </table> * </table> */ public static Packet getSearchPacket(String searchQuery){ Packet packet=new StandardPacket(1+2+searchQuery.length()); packet.setCommand(OP_SEARCHREQUEST); packet.insertData(SEARCH_BYNAME); packet.insertData((short)searchQuery.length()); packet.insertData(searchQuery.getBytes()); return packet; } /** * Create get sources packet. * @param fileHash hash of file to download * * <table cellpadding="0" border="1" cellspacing="0"> * <thead> * <tr> * <th>Name</th> * <th>Size in bytes</th> * <th>Default Value</th> * <th>Comment</th> * </tr> * </thead> * <tbody> * <tr> * <td>Protocol</td> * <td>1</td> * <td>0xE3</td> * <td> </td> * </tr> * <tr> * <td>Size</td> * <td>4</td> * <td>-</td> * <td>The size of the message in bytes not including the header and size fields</td> * </tr> * <tr> * <td>Type</td> * <td>1</td> * <td>0x58</td> * <td>The value of the OP_GETSOURCES opcode</td> * </tr> * <tr> * <td>File hash</td> * <td>16</td> * <td>NA</td> * <td>The requested file hash</td> * </tr> * <tr> * <td>File size</td> * <td>4</td> * <td>NA</td> * <td>The requested file size (lungdum 17.3)</td> * </tr> * </tbody> * </table> * </table> */ public static Packet getSourcesRequestPacket(FileHash fileHash,long fileSize){ Packet packet=new StandardPacket(16+4); packet.setCommand(OP_GETSOURCES); packet.insertData(fileHash.getHash()); packet.insertData(Convert.longToInt(fileSize)); return packet; } /** * Call back request packet. * @param clientID * * <table cellpadding="0" border="1" cellspacing="0"> * <thead> * <tr> * <th>Name</th> * <th>Size in bytes</th> * <th>Default Value</th> * <th>Comment</th> * </tr> * </thead> * <tbody> * <tr> * <td>Protocol</td> * <td>1</td> * <td>0xE3</td> * <td> </td> * </tr> * <tr> * <td>Size</td> * <td>4</td> * <td>-</td> * <td>The size of the message in bytes not including the header and size fields</td> * </tr> * <tr> * <td>Type</td> * <td>1</td> * <td>0x1C</td> * <td>The value of the OP_CALLBACKREQUEST opcode</td> * </tr> * <tr> * <td>Client ID</td> * <td>4</td> * <td>NA</td> * <td>The ID of the client which is asked to call back</td> * </tr> * </tbody> * </table> * </table> */ public static Packet getCallBackRequestPacket(ClientID clientID){ Packet packet = new StandardPacket(4); packet.setCommand(PACKET_CALLBACKREQUEST); packet.insertData(clientID.getClientID()); return packet; } /** * Offer files packet. * <table cellpadding="0" border="1" cellspacing="0"> * <thead> * <tr> * <th>Name</th> * <th>Size in bytes</th> * <th>Default Value</th> * <th>Comment</th> * </tr> * </thead> * <tbody> * <tr> * <td>Protocol</td> * <td>1</td> * <td>0xE3</td> * <td> </td> * </tr> * <tr> * <td>Size</td> * <td>4</td> * <td> </td> * <td>The size of the message in bytes not including the header and size fields</td> * </tr> * <tr> * <td>Type</td> * <td>1</td> * <td>0x14</td> * <td>The value of the OP_SERVERSTATUS opcode</td> * </tr> * </tbody> * </table> * </table> */ public static Packet getOfferFilesPacket(ClientID userID) { List<SharedFile> unshared_files = JMuleCoreFactory.getSingleton().getSharingManager().getUnsharedFiles(); int sharedCount = unshared_files.size(); if (sharedCount > MAX_OFFER_FILES) sharedCount = MAX_OFFER_FILES; List<ByteBuffer> shared_files_data = new LinkedList<ByteBuffer>(); int data_length=0; int i = 0; for(SharedFile sFile : unshared_files) { if (i>sharedCount) break; i++; unshared_files.remove(sFile); Tag tagFileName = TagFactory.getStringTag(sFile.getSharingName(), TAG_NAME_NAME); Tag tagSize = TagFactory.getDWORDTag((int)sFile.length(), TAG_NAME_SIZE); ByteBuffer buffer = Misc.getByteBuffer(16 + 4 + 2 + 4 + tagFileName.getSize() + tagSize.getSize()); data_length += buffer.limit(); buffer.position(0); buffer.put(sFile.getFileHash().getHash()); if (userID.isHighID()) { buffer.put(userID.getClientID()); buffer.putShort((short)ConfigurationManagerFactory.getInstance().getTCP()); } else { buffer.putInt(0); buffer.putShort((short)0); } buffer.putInt(2);//Insert tag count buffer.put(tagFileName.getData()); buffer.put(tagSize.getData()); shared_files_data.add(buffer); } StandardPacket packet = new StandardPacket(4+data_length); packet.setCommand(OP_OFFERFILES); packet.insertData(sharedCount); for(ByteBuffer buffer : shared_files_data) packet.insertData(buffer.array()); EMuleCompressedPacket compressed_packet = new EMuleCompressedPacket(packet); compressed_packet.compressPacket(); if (packet.getLength()<compressed_packet.getLength()) { compressed_packet.clear(); return packet; } packet.clear(); return compressed_packet; } // ======================= // Peer<==>Peer // ======================= /** * Peer hello packet. * @param userHash user hash * @param myPort client port * @param serverIP server IP address * @param serverPort server port * @param userName user name * @return peer hello packet * <table cellspacing="0" border="1" cellpadding="0"> * <thead> * <tr> * <th>Name</th> * <th>Size in bytes</th> * <th>Default value</th> * <th>Comment</th> * </tr>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -