diff --git a/.classpath b/.classpath index ebde520..a896564 100644 --- a/.classpath +++ b/.classpath @@ -13,7 +13,7 @@ - + @@ -23,5 +23,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.gitignore b/.gitignore index b83d222..ff60d29 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ /target/ +./target/ +target/ \ No newline at end of file diff --git a/.gitpod.yml b/.gitpod.yml new file mode 100644 index 0000000..4efa528 --- /dev/null +++ b/.gitpod.yml @@ -0,0 +1,10 @@ +# This configuration file was automatically generated by Gitpod. +# Please adjust to your needs (see https://www.gitpod.io/docs/introduction/learn-gitpod/gitpod-yaml) +# and commit this file to your remote git repository to share the goodness with others. + +# Learn more from ready-to-use templates: https://www.gitpod.io/docs/introduction/getting-started/quickstart + +tasks: + - init: mvn install -DskipTests=false + + diff --git a/.project b/.project index 8ae7f3d..887fd79 100644 --- a/.project +++ b/.project @@ -20,4 +20,15 @@ org.eclipse.jdt.core.javanature org.eclipse.m2e.core.maven2Nature + + + 1732157035936 + + 30 + + org.eclipse.core.resources.regexFilterMatcher + node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ + + + diff --git a/.settings/org.eclipse.jdt.apt.core.prefs b/.settings/org.eclipse.jdt.apt.core.prefs new file mode 100644 index 0000000..d4313d4 --- /dev/null +++ b/.settings/org.eclipse.jdt.apt.core.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.apt.aptEnabled=false diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs index 5723a0f..1b6e1ef 100644 --- a/.settings/org.eclipse.jdt.core.prefs +++ b/.settings/org.eclipse.jdt.core.prefs @@ -1,8 +1,9 @@ eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 -org.eclipse.jdt.core.compiler.compliance=1.5 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.compliance=1.8 org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore +org.eclipse.jdt.core.compiler.processAnnotations=disabled org.eclipse.jdt.core.compiler.release=disabled -org.eclipse.jdt.core.compiler.source=1.5 +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/README.md b/README.md index 9af5825..3dc5d00 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ Que deus me ajude a terminar no natal kkk!!! ## Referencias - [WikiBitTorrent](https://wiki.theory.org/index.php/Main_Page) + [WikiBitTorrent](https://wiki.theory.org/Main_Page) diff --git a/src/main/java/org/voyager/torrent/Main.java b/src/main/java/org/voyager/torrent/Main.java index 6475afd..e0329e0 100644 --- a/src/main/java/org/voyager/torrent/Main.java +++ b/src/main/java/org/voyager/torrent/Main.java @@ -1,16 +1,13 @@ package org.voyager.torrent; -import java.io.File; - import org.voyager.torrent.client.ClientTorrent; -import org.voyager.torrent.util.ReaderBencode; import GivenTools.BencodingException; public class Main { public static void main(String[] args) { - ClientTorrent mytorrent = new ClientTorrent(); + ClientTorrent mytorrent = new ClientTorrent(true); mytorrent.addTorentFile("./netinst.torrent"); try { mytorrent.start(); diff --git a/src/main/java/org/voyager/torrent/client/ClientTorrent.java b/src/main/java/org/voyager/torrent/client/ClientTorrent.java index ce61d54..d767083 100644 --- a/src/main/java/org/voyager/torrent/client/ClientTorrent.java +++ b/src/main/java/org/voyager/torrent/client/ClientTorrent.java @@ -1,50 +1,43 @@ package org.voyager.torrent.client; -import java.io.BufferedReader; -import java.io.DataOutputStream; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; import java.net.MalformedURLException; -import java.net.ServerSocket; import java.net.URL; import java.nio.ByteBuffer; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.UUID; import org.voyager.torrent.client.connect.ManagerPeer; import org.voyager.torrent.client.connect.Peer; import org.voyager.torrent.util.BinaryUtil; import org.voyager.torrent.util.HttpUtil; +import org.voyager.torrent.util.PrintUtil; import org.voyager.torrent.util.ReaderBencode; -import GivenTools.Bencoder2; import GivenTools.BencodingException; import GivenTools.TorrentInfo; public class ClientTorrent implements ManagerPeer{ - + public static String separator = System.getProperty("file.separator"); public static String dirUser = new File(System.getProperty("user.home")).getAbsolutePath()+separator; public static String dirRuntime = "."+separator; - - + // torrent info e connets info public TorrentInfo torrent; + + private boolean verbouse; public static int uploaded; public static int downloaded; - - public ClientTorrent Build() { - return null; - } - + + public ClientTorrent(boolean verbouse){ this.verbouse = verbouse; } + public void start() throws BencodingException { List listPeers = new ArrayList(); @@ -66,7 +59,7 @@ public void start() throws BencodingException { parameters.put("port", "-1"); // port connect parameters.put("downloaded", "0"); parameters.put("left", torrent.file_length+""); - System.out.println(torrent.announce_url); + System.out.println(" Announce URL: "+ torrent.announce_url); URL url_announce = new URL(torrent.announce_url+"?"+HttpUtil.getParamsString(parameters)); @@ -78,12 +71,11 @@ public void start() throws BencodingException { // read response StringBuffer res = BinaryUtil.inputStreamReaderToStringBuffer( new InputStreamReader(con.getInputStream()) ); - //System.out.println(res); - + Map map = ReaderBencode.bencodeToMap(res); int interval = (Integer) map.get( BinaryUtil.stringToByteBuffer("interval") ); - System.out.println( interval ); + List> peersList = (List>) map.get(BinaryUtil.stringToByteBuffer("peers")); @@ -99,7 +91,6 @@ public void start() throws BencodingException { System.out.println("Unable to parse encoding"); continue; } - //System.out.println("host: "+ip+"\t port: "+peerPort); listPeers.add( new Peer( ip, peerPort, peerIdBinary, this) ); } @@ -111,11 +102,13 @@ public void start() throws BencodingException { // TODO Auto-generated catch block e.printStackTrace(); } - + + if(verbouse)System.out.println("Total de Pares: \n"+ listPeers.stream().map((peer) -> peer.toString()+"\n").toList()); for(Peer peer : listPeers.subList(0, 4)) { + peer.setVerbouse(verbouse); Thread thread = new Thread(peer); - System.out.println(peer); + if(verbouse)System.out.println("Try Connect: \n\t"+ peer); try { thread.start(); }catch (Exception e) { diff --git a/src/main/java/org/voyager/torrent/client/connect/Peer.java b/src/main/java/org/voyager/torrent/client/connect/Peer.java index 55a098e..6191ce8 100644 --- a/src/main/java/org/voyager/torrent/client/connect/Peer.java +++ b/src/main/java/org/voyager/torrent/client/connect/Peer.java @@ -8,8 +8,6 @@ import java.net.Socket; import java.util.Arrays; -import org.voyager.torrent.client.ClientTorrent; -import org.voyager.torrent.client.exceptions.ConnectException; import org.voyager.torrent.util.BinaryUtil; public class Peer implements Runnable{ @@ -37,6 +35,7 @@ public class Peer implements Runnable{ private Socket socket = null; private InputStream in; private OutputStream out; + private boolean verbouse; public boolean isConnected = false; // CONNECT SOCKET public boolean hasHandshake = false; // Connect Socket and shake Hands @@ -74,34 +73,56 @@ else if(length > 0) { byte[] buff = new byte[length]; dataInput.read(buff, 0, length); - /* - System.out.println(buff[0] == MsgUnchoke); - System.out.println(buff[0] == MsgInterested); - System.out.println(buff[0] == MsgNotInterested); - System.out.println(buff[0] == MsgHave); - System.out.println(buff[0] == MsgBitfield); - System.out.println(buff[0] == MsgRequest); - System.out.println(buff[0] == MsgPiece); - System.out.println(buff[0] == MsgCancel); - */ + byte state = buff[0]; switch(state) { case MsgUnchoke: + if(verbouse)System.out.println(this+"\n:\tRecive MsgUnchoke"); + if(verbouse)System.out.println("\t MsgUnchoke:"); + if(verbouse)System.out.println("\t Informa ao peer que ele foi bloqueado. Isso significa que o peer não poderá solicitar peças do arquivo."); break; case MsgInterested: + if(verbouse)System.out.println(this+"\n:\tRecive MsgInterested"); + if(verbouse)System.out.println("\t MsgInterested:"); + if(verbouse)System.out.println("\t Indica que o peer está interessado em receber peças do arquivo. Geralmente enviado quando o peer detecta que outro possui peças que ele não tem."); + break; case MsgNotInterested: + if(verbouse)System.out.println(this+"\n:\tRecive MsgNotInterested"); + if(verbouse)System.out.println("\t MsgNotInterested:"); + if(verbouse)System.out.println("\t Indica que o peer não está interessado em receber peças do arquivo. Geralmente enviado quando o peer já possui todas as peças que o outro peer oferece."); + break; case MsgHave: + if(verbouse)System.out.println(this+"\n:\tRecive MsgHave"); + if(verbouse)System.out.println("\t MsgHave:"); + if(verbouse)System.out.println("\t Notifica ao peer que uma nova peça do arquivo foi baixada e está disponível. Essa mensagem ajuda a manter os peers atualizados sobre as peças disponíveis."); + break; case MsgBitfield: + if(verbouse)System.out.println(this+"\n:\tRecive MsgBitfield"); + if(verbouse)System.out.println("\t MsgBitfield:"); + if(verbouse)System.out.println("\t Envia um mapa de bits que representa todas as peças que o peer possui. É usado logo no início da conexão para informar o estado atual do peer."); + + // -1 iqual a ter 0 igual a não ter uma peça + break; case MsgRequest: + if(verbouse)System.out.println(this+"\n:\tRecive MsgRequest"); + if(verbouse)System.out.println("\t MsgRequest:"); + if(verbouse)System.out.println("\t Solicita uma peça específica do arquivo. Contém informações como o índice da peça e o deslocamento dentro dela."); + break; case MsgPiece: + if(verbouse)System.out.println(this+"\n:\tRecive MsgPiece"); + if(verbouse)System.out.println("\t MsgPiece:"); + if(verbouse)System.out.println("\t Transfere um pedaço de uma peça solicitada para o peer que fez o pedido. Contém os dados reais do arquivo."); break; case MsgCancel: + if(verbouse)System.out.println(this+"\n:\tRecive MsgCancel"); + if(verbouse)System.out.println("\t MsgCancel:"); + if(verbouse)System.out.println("\t Cancela um pedido anterior de uma peça. Pode ser usado se o pedido não for mais necessário ou se houver um problema na conexão."); break; } //handshake[index] = 0x13; @@ -120,9 +141,7 @@ else if(length > 0) { - } - - + } } } @@ -152,10 +171,10 @@ private boolean shakeHands() { is.readFully(response); this.socket.setSoTimeout(130000); - System.out.println(Arrays.toString(response)); + //System.out.println(Arrays.toString(response)); if(checkHandshake(response)) { hasHandshake = true; - System.out.println("Connect:\n\t"+ this); + if(verbouse)System.out.println("Connect & Shakeed:\n\t"+ this); // no equals then stop thread for peer or wait }else hasHandshake = false; @@ -296,6 +315,11 @@ public OutputStream getOut() { public void setOut(OutputStream out) { this.out = out; } + public void setVerbouse(boolean verbouse){ + this.verbouse = verbouse; + } + public boolean getVerbouse(){ return this.verbouse; } + public String toString() { return ("host: "+this.host+"\t port: "+this.port+"\t connect: "+this.isConnected+"\t hasHandshake: "+ this.hasHandshake ); } diff --git a/src/main/java/org/voyager/torrent/util/PrintUtil.java b/src/main/java/org/voyager/torrent/util/PrintUtil.java new file mode 100644 index 0000000..c580feb --- /dev/null +++ b/src/main/java/org/voyager/torrent/util/PrintUtil.java @@ -0,0 +1,47 @@ +package org.voyager.torrent.util; + +import java.nio.ByteBuffer; +import java.util.ArrayDeque; +import java.util.Deque; +import java.util.List; +import java.util.Map; + +public class PrintUtil { + public static void printTreeUsingCollections(Map map) { + // Pilha para simular recursão e gerenciar níveis + Deque stack = new ArrayDeque<>(); + stack.push(new Object[]{map, 0}); // Adiciona o mapa inicial com nível 0 + + while (!stack.isEmpty()) { + Object[] current = stack.pop(); + Object element = current[0]; + int depth = (int) current[1]; + + String indent = " ".repeat(depth * 4); // Indentação baseada na profundidade + + if (element instanceof Map) { + Map currentMap = (Map) element; + for (Map.Entry entry : currentMap.entrySet()) { + String key = new String(((ByteBuffer) entry.getKey()).array()); + System.out.println(indent + "- " + key + ":"); + + Object value = entry.getValue(); + if (value instanceof Map || value instanceof List) { + stack.push(new Object[]{value, depth + 1}); // Adiciona à pilha + } else { + System.out.println(indent + " " + value); + } + } + } else if (element instanceof List) { + List currentList = (List) element; + for (Object item : currentList) { + if (item instanceof Map || item instanceof List) { + stack.push(new Object[]{item, depth + 1}); // Adiciona à pilha + } else { + System.out.println(indent + "- " + item); + } + } + } + } + } +} diff --git a/target/classes/org/voyager/torrent/Main.class b/target/classes/org/voyager/torrent/Main.class index da56249..5b06ada 100644 Binary files a/target/classes/org/voyager/torrent/Main.class and b/target/classes/org/voyager/torrent/Main.class differ diff --git a/target/classes/org/voyager/torrent/client/ClientTorrent.class b/target/classes/org/voyager/torrent/client/ClientTorrent.class index 5d41e74..dcf8363 100644 Binary files a/target/classes/org/voyager/torrent/client/ClientTorrent.class and b/target/classes/org/voyager/torrent/client/ClientTorrent.class differ