Bonjour :)
Je viens ici à votre rencontre car je bute sur un problème depuis déjà un certain temps :( Pour vous expliquer rapidement, je reçois les packets, de une je suis pas certain de bien lire les valeurs stockées dedans et de deux je suis incapable d'y répondre ...
Je reçois un premier packets d'ID 1 :
|-----------------
|Reçu
|ID : 1
|Taille : 8 octets
|
|Contenu (bytes) :
|[B@19723da7
|
|Contenu (héxadécimal) :
|0 0 6 58 0 0 6 5A
|
|Requis : 329728
|Actuel : 415744
|-----------------
Et quelques millièmes après je reçois le packet d'ID 3
|-----------------
|Reçu
|ID : 3
|Taille : 341 octets
|
|Contenu (bytes) :
|[B@6805108d
|
|Contenu (héxadécimal) :
|0 20 69 35 36 76 6D 35 71 78 51 7E 5D 79 30 59 29 57 3F 62 5D 6C 35 5B 71 3E 74 38 24 42 30 37
|2A 22 1 31 1E 49 D5 AC 38 24 56 8 8B 3C AD 85 39 A3 61 50 1F B3 F8 CC 63 CF CF CA A3 6A 60 90
|7E 78 2E C0 81 14 F1 56 E9 9D 7F E2 89 6F BA D5 1F 30 F4 3 D8 37 70 29 5 22 F3 41 6D 6 B6 8A
|FB 42 EE F7 D9 51 F1 79 A9 7E 7A 1 7E 41 75 8D 5E B7 22 91 E9 9B 90 89 6E 8B 6D C3 2F DB EB 77
|A3 2E 88 95 8D 0 6A 8D B2 A8 76 D2 4D FE 35 84 A9 26 E9 D2 4 6E FF 58 E0 63 59 8E DA 7D 99 DD
|C0 4 B2 6E 21 33 EB DA B9 EF DB 5E 37 49 19 C6 F3 DF 9D C0 97 49 98 D4 E D9 2 83 A 37 DF D4
|18 55 1 89 1C A1 41 70 D7 DC 9C 70 52 28 98 AF D1 9B D6 34 2D 18 E5 9A DD 23 11 52 AF 83 DE 2F
|73 34 1E 5E F 12 76 7A 56 6C EA D3 66 B7 50 5D 34 6B 14 3A B A B9 67 35 ED 4B D3 27 68 63 54
|7F 16 30 84 90 85 DE 73 5E AE 1E 34 61 73 9A 5E A4 38 6C A4 D2 C3 1F FD F6 FE DC 24 81 33 D6 66
|DE AD B9 72 7D 88 FA B7 66 E3 23 F2 B 5B 9C E6 13 5A 86 DB 3B 96 6D F C E9 F5 2C 24 8E 2C 47
|8E 29 E2 51 E1 81 50 51 78 C8 36 F0 54 46 45 F6 34 85 1 20 DF
|
|Taille de la clé : 5
|
|Clé publique en byte :
|[B@1794a43d
|
|Clé publique en clair :
|8 0 0 6 58
|-----------------
J'utilise la class DataReader/Writer de ce tutoriel que j'ai évidemment traduit du C# au Java. Sauf pour les variables de type "unsigned" qui n'existent pas en Java. Je vous les mettrais tout de même à la fin de ce post afin que vous puissiez éventuellement vérifier mon code ^-^
En ce qui concerne l'envoi du packet je le fais de cette matière :
DataWriter writer = new DataWriter();
writer.writeByte(2);
writer.writeByte(3);
writer.writeByte(7);
writer.writeShort(35100);
writer.writeByte(0);
writer.writeByte(0);
writer.writeString("Ceciestjusteuntest");
writer.writeString(password);
writer.writeShort(0);
writer.writeBoolean(true);
OutputStream out = socket.getOutputStream();
out.write(writer.pack(4));
out.flush();
Sauf que, me semble t-il, depuis que ce tutoriel est en ligne la manière d'écrire le packet d'ID 4 a changée non ? Sachant que même après l'envoi je ne reçois aucune réponse du serveur, ni packet 20, ni packet 22, ni rien du tout en fait :(
Est-ce que l'un d'entre vous pourrait m'expliquer ce qui ne va pas dans mon code ? Merci d'avance :(
Cliquez pour révéler
Cliquez pour masquer
DataReader :
package fr.akabot.util;
public class DataReader
{
public int position = 0;
public byte[] content;
public DataReader(byte[] c)
{
this.content = c;
}
public byte readByte() throws Exception
{
if (this.content.length >= 1)
{
byte result;
result = this.content[position];
this.position++;
return result;
}
else
{
throw new Exception("Il n'y a plus d'octet à lire.");
}
}
public byte[] readBytes(int number) throws Exception
{
if (this.content.length >= number)
{
byte[] result = new byte[number];
for (int i = 0; i != number; i++)
{
result = this.readByte();
}
return result;
}
else
{
throw new Exception("Il n'y a plus d'octets à lire.");
}
}
public short readShort() throws Exception
{
if (this.content.length >= 2)
{
return (short)((this.readByte() << 8) + this.readByte());
}
else
{
throw new Exception("Il n'y a plus d'octets à lire.");
}
}
public int readInt() throws Exception
{
if (content.length >= 4)
{
return (int)((readByte() << 24) + (readByte() << 16) + (readByte() << 8) + readByte());
}
else
{
throw new Exception("Il n'y a plus d'octets à lire.");
}
}
public String readString() throws Exception
{
byte[] stringBytes = readBytes(readShort());
return new String(stringBytes, "UTF-8");
}
public boolean readBool() throws Exception
{
if (readByte() == 01)
{
return true;
}
else
{
return false;
}
}
}
DataWriter :
package fr.akabot.util;
import java.util.ArrayList;
import java.util.List;
public class DataWriter
{
public List<Byte> content = new ArrayList<Byte>();
public DataWriter()
{
}
public int getLenghtType()
{
if(this.content.size() > Short.MAX_VALUE)
{
return 3;
}
else if(this.content.size() > Byte.MAX_VALUE)
{
return 2;
}
else if(this.content.size() > 0)
{
return 1;
}
return 0;
}
public short getHeader(int protocolID)
{
return (short)((protocolID << 2) | this.getLenghtType());
}
public byte[] pack(int protocolID)
{
int index = 0;
int packetLenght = this.content.size();
int packetLenghtType = this.getLenghtType();
short packetHeader = this.getHeader(protocolID);
byte[] packet = new byte[2 + packetLenghtType + packetLenght];
packet[0] = (byte)(packetHeader >> 8);
packet[1] = (byte)(packetHeader - 256 * packet[0]);
switch (packetLenghtType)
{
case 1:
packet[2] = (byte)(packetLenght);
index = 3;
break;
case 2:
packet[2] = (byte)(packetLenght >> 8);
packet[3] = (byte)(packetLenght - 256 * packet[2]);
index = 4;
break;
case 3:
packet[2] = (byte)(packetLenght >> 16);
packet[3] = (byte)(packetLenght >> 8);
packet[4] = (byte)(packetLenght - 256 * packet[3] - 256 * 256 * packet[2]);
index = 5;
break;
}
for (int i = index; i < index + packetLenght; i++)
{
packet = this.content.get(i - index);
}
return packet;
}
public void writeByte(int b)
{
this.content.add((byte) b);
}
public void writeShort(int s)
{
byte[] bytes = new byte[] {(byte) s,(byte) (s >> 8)};
this.content.add(bytes[1]);
this.content.add(bytes[0]);
}
public void writeInt(int i)
{
byte[] bytes = new byte[] {(byte) i, (byte) (i >> 8), (byte) (i >> 16), (byte) (i >> 24)};
this.content.add(bytes[3]);
this.content.add(bytes[2]);
this.content.add(bytes[1]);
this.content.add(bytes[0]);
}
public void writeString(String s)
{
this.writeShort((short) s.length());
for(int i = 0 ; i < s.getBytes().length ; i++)
{
this.writeByte(s.getBytes());
}
}
public void writeBoolean(boolean b)
{
if(b)
{
this.writeByte((byte) 01);
}
else
{
this.writeByte((byte) 00);
}
}
}
Reception (Thread qui reçois les packets du serveur et qui essaye de les envoyer pour le moment ...) :
package fr.akabot.threads;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import fr.akabot.util.AuthentificationSecurity;
import fr.akabot.util.DataReader;
import fr.akabot.util.DataWriter;
public class Reception implements Runnable
{
Socket socket;
public Reception(Socket socket)
{
this.socket = socket;
}
public void run()
{
try
{
reception();
}
catch (IOException e)
{
e.printStackTrace();
}
}
public void reception() throws IOException
{
while(!this.socket.isClosed())
{
InputStream data = socket.getInputStream();
int available = data.available();
byte[] buffer = new byte[available];
if(available > 0)
{
data.read(buffer, 0, available);
parseDataByte(buffer, 0);
}
}
socket.close();
}
public void threatPacket(short packetID, byte[] buffer)
{
DataReader reader = new DataReader(buffer);
if(packetID == 1)
{
try
{
pr("Requis : " + reader.readInt(), true);
pr("Actuel : " + reader.readInt(), true);
}
catch (Exception e)
{
e.printStackTrace();
}
}
if(packetID == 3)
{
try
{
short keySize = reader.readShort();
byte[] key = new byte[keySize];
for(int i = 0 ; i < keySize ; i++)
{
key = reader.readByte();
}
pr("Taille de la clé : " + keySize, true);
pr("", true);
pr("Clé publique en byte : \n|" + key + "\n|", true);
pr("Clé publique en clair : \n|" + this.bytesToString(key, "%X", true, 32), true);
pr("|\n|Préparation à l'envoi d'un packet ...");
String password = AuthentificationSecurity.MD5(AuthentificationSecurity.MD5(Authentification.password) + this.bytesToString(key, "%X", false, Integer.MAX_VALUE));
DataWriter writer = new DataWriter();
writer.writeByte(2);
writer.writeByte(3);
writer.writeByte(7);
writer.writeShort(35100);
writer.writeByte(0);
writer.writeByte(0);
writer.writeString(Authentification.username);
writer.writeString(password);
writer.writeShort(0);
writer.writeBoolean(true);
OutputStream out = socket.getOutputStream();
out.write(writer.pack(4));
out.flush();
pr("|\n|Packet envoyé ...");
}
catch(Exception e)
{
e.printStackTrace();
}
}
if(packetID == 20)
{
pr("Authentification échouée.");
}
if(packetID == 22)
{
pr("Authentification réussie !");
}
}
public void parseDataByte(byte[] buffer, int index)
{
short packetID = (short)((buffer[index] * 256 + buffer[index + 1]) >> 2);
short packetLengthType = (short)((buffer[index] * 256 + buffer[index + 1]) & 3);
int posLenght = index + 2;
int posDatasMessage = packetLengthType + posLenght;
int packetLenght = bytesToInt(posLenght, packetLengthType, buffer);
byte[] content = subTabBytes(posDatasMessage, packetLenght, buffer);
String contentHexa = bytesToString(content, "%X", true, 32);
pr("|-----------------\n|Reçu\n" + "|ID : " + packetID + "\n|Taille : " + packetLenght + " octets" + "\n|\n|Contenu (bytes) : \n|" + content + "\n|\n|Contenu (héxadécimal) : \n|" + contentHexa + "\n|");
this.threatPacket(packetID, buffer);
pr("|-----------------\n");
if(packetLenght + posDatasMessage < buffer.length)
parseDataByte(buffer, packetLenght + posDatasMessage);
}
public int bytesToInt(int posStart, int nbBytes, byte[] datas)
{
int result = 0;
for(int i = posStart; i < nbBytes + posStart; i++)
{
if(i < nbBytes + posStart - 1)
{
result += datas * 256;
}
else
{
result += datas;
}
}
return result;
}
public byte[] subTabBytes(int indexStart, int length, byte[] datas)
{
byte[] result = new byte[length];
for(int i = 0; i < length; i++)
{
result = datas[i + indexStart];
}
return result;
}
public String bytesToString(byte[] bytes, String format, boolean spacer, int line)
{
StringBuilder sb = new StringBuilder(bytes.length * 2);
int index = 0;
for (byte b : bytes)
{
if(index == line)
{
sb.append("\n|");
index = 0;
}
index++;
sb.append(String.format(format, b));
if(spacer)
{
sb.append(" ");
}
}
return sb.toString();
}
public static final void pr(Object o)
{
System.out.println(String.valueOf(o));
}
public static final void err(Object o)
{
System.err.println(String.valueOf(o));
}
public static final void pr(Object o, boolean b)
{
System.out.println((b ? "|" : "") + String.valueOf(o));
}
public static final void err(Object o, boolean b)
{
System.err.println((b ? "|" : "") + String.valueOf(o));
}
}
A savoir également que j'ai utilisé une partie des codes de ce sujet pour essayer de tout faire fonctionner, en vain ...
Merci d'avance ! :)