Salve volevo fare un client per la rete DirectConnect (una cosa banale,non un nuovo DC++
)
solo che sono incappato in alcuni problemi e purtroppo nè sul forum ufficiale http://dcpp.net nè altrove (non trovo prog open source in java per DC) riesco a trovare ispirazione. Il codice è il seguente:
codice:
/**
* Contributed by dCoy (method for calculating the key)
* @author Chrisvoo
*/
import java.net.*;
import java.io.*;
class getLock {
public static void main(String[]args){
boolean error=false;
try {
// Sockets and IO channels
Socket s=new Socket(args[0].toString(),Integer.parseInt(args[1]));
BufferedReader ego = new BufferedReader(new InputStreamReader(System.in));
DataOutputStream egout = new DataOutputStream(s.getOutputStream());
BufferedReader from_server = new BufferedReader(new InputStreamReader(s.getInputStream()));
/* qualcuno ha suggerito di aggiungerci "ISO-8859-1" al parametro di ISReader ma non funziona lo stesso */
System.out.println("Connecting...");
/* Ok here method readLine() waits for '\n',but even if I use InputStream
* and method read() to wait for "|",the server seems not to care about me..*/
String answer=from_server.readLine();
System.out.println("Server's answered,calculating key...");
String key=generateKey(answer);
System.out.println("The $lock sent is: "+answer);
System.out.println("The key sent is: "+key);
System.out.println("Let's send the key..");
egout.writeBytes("$Key <"+key+">|"+"$ValidateNick "+"<ChrisVoo>|\r\n");
System.out.println("Mandata...");
answer=from_server.readLine();
System.out.println(answer);
egout.writeBytes("$Version <0.68>|$MyINFO <nothing>|$GetNickList|\r\n");
}catch(UnknownHostException e){
System.out.println("Host unknown");
}catch(IOException i){
System.out.println("Error I/O");
}catch(ArrayIndexOutOfBoundsException a){
System.out.println("You have to digit \"java getLock nameOfTheHub port\"");
}
}
/* It's pretty copied from wiki */
public static String generateKey(String lockString){
int i = 0;
byte[] lock = null;
byte[] key = null;
lockString = lockString.substring(0,lockString.indexOf(' '));
lockString.trim();
lock = lockString.getBytes();
key = new byte[lock.length];
for(i=1;i<lock.length;i++){
key[i] = (byte)((lock[i] ^ lock[i-1]) & 0xFF);
}
key[0] = (byte)((((lock[0] ^ lock[lock.length-1]) ^ lock[lock.length-2]) ^ 5) & 0xFF);
for(i=0;i<key.length;i++){
key[i] = (byte)((((key[i]<<4) & 0xF0) | ((key[i]>>4) & 0x0F)) & 0xFF);
}
return(dcnEncode(new String(key)));
}
public static String dcnEncode(String string){
char[] replacements = null;
int i = 0;
int index = 0;
replacements = new char[]{0,5,36,96,124,126};
for(i=0;i<replacements.length;i++){
while((index = string.indexOf(replacements[i])) >=0 ){
string = string.substring(0,index)
+ "/%DCN"+leadz(replacements[i])+"%/"
+ string.substring(index+1,string.length());
}
}
return(string);
}
private static String leadz(int nr){
if(nr < 100 && nr > 10){
return("0"+nr);
} else if(nr < 10){
return("00"+nr);
} else{
return(""+nr);
}
}
}
/*this is my version 'cause I noticed that Coy's code takes a only a little part
of the string sent by the server..
public static String generateKey(String lockString){
int i = 0;
byte[] lock = null;
byte[] key = null;
// lockString = lockString.substring(0,lockString.indexOf(' ')); the line above was modified by me
// otherwise the method took only "$Lock" to calculate the key
lockString = lockString.substring(lockString.indexOf(' ')+1,lockString.length()-1);
lockString = lockString.substring(0,lockString.indexOf(' '));
lockString.trim();
lock = lockString.getBytes();
key = new byte[lock.length];
for(i=1;i<lock.length;i++){
key[i] = (byte)((lock[i] ^ lock[i-1]) & 0xFF);
}
key[0] = (byte)((((lock[0] ^ lock[lock.length-1]) ^ lock[lock.length-2]) ^ 5) & 0xFF);
for(i=0;i<key.length;i++){
key[i] = (byte)((((key[i]<<4) & 0xF0) | ((key[i]>>4) & 0x0F)) & 0xFF);
}
return(dcnEncode(new String(key)));
}
public static String dcnEncode(String string){
char[] replacements = null;
int i = 0;
int index = 0;
replacements = new char[]{0,5,36,96,124,126};
for(i=0;i<replacements.length;i++){
while((index = string.indexOf(replacements[i])) >=0 ){
string = string.substring(0,index) + "/%DCN"+leadz(replacements[i])+"%/" + string.substring(index+1,string.length());
}
}
return(string);
}
private static String leadz(int nr){
if(nr < 100 && nr > 10){
return("0"+nr);
}
else if(nr < 10){
return("00"+nr);
}
else{
return(""+nr);
}
}
} */
Ho incluso una mia versione per il calcolo del Lock key,dalla stringa spedita dal server,perchè non mi pare che quella indicata sul wiki agisca correttamente.
In pratica il problema avviene nella mancata connessione con il server: con BufferReader il programma si ferma a "Connecting",perchè probabilmente non riceve il carattere "\n" dal server ma anche se leggo i caratteri uno per volta con InputStream e read() ricevo la stringa dal server e la visualizzo subito ma il server non "percepisce" la mia risposta. Io la mando ma lui non risponde subito e quindi mi viene ritornato l'errore "Il client non ha risposto entro un certo tot di tempo,ecc".
Anche qui nessuno mai si è cimentato nella relaizzazione di un client DC in java? Mi interessava analizzare il protocollo DC,non fare chissà cosa,però non riesco manco a collegarmi agli hub!!
Se qualcuno ha suggerimenti ringrazio