Witam,
Implementuję protokół GG, którego opis znajduje się tutaj:http://toxygen.net/libgadu/protocol/. Uprzedzę pytania dlaczego nie korzystam z gotowej implementacji JGGAPI? Dlatego, że jest ona przestarzała i nie uwzględnia wszystkich funkcjonalności. Moim problemem jest to, że gdy połączę się już z odpowiednim serwerem, odbiorę pakiet z ziarnem a gdy wyślę pakiet logowania nie otrzymuję żadnej odpowiedzi z jego strony. Ma ktoś pomysły dlaczego?
public static void main(String[] args) {
ServerCommunication sc = new ServerCommunication();
Host host = sc.preConnect(numer_gg);
sc.connect(host);
ServerMessageChecker svc = new ServerMessageChecker(sc.getInputStream());
ServerMessageListener sml = new ServerMessageListener();
svc.addServerMessageListener(sml);
Thread thread = new Thread(svc);
thread.start();
GGPackageHeader packageHeader = new GGPackageHeader(CommunicatorConstans.GG_LOGIN_PACKAGE, 0);
GGLoginPackage loginPackage = new GGLoginPackage(packageHeader);
loginPackage.setNumber(numer_gg);
loginPackage.setLanguage(new byte[]{'p','l'});
loginPackage.setHashType(CommunicatorConstans.SHA1_ALGORITM);
loginPackage.setPasswordHash("hasło", "otrzymane_ziarno"));
loginPackage.setStatus(14);
loginPackage.setFlags(0);
loginPackage.setFeatures(871);
loginPackage.setImageSize((byte)100);
loginPackage.setVersion(new byte[]{'1','.','0'});
loginPackage.calculateLenght();
sc.getOutputStream().write(loginPackage.getPackageContent());
sc.getOutputStream().flush();
System.out.println(sc.getRequester().getInputStream().read());
//zawsze jest puste
}
package communicator.server.communication;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class ServerMessageChecker implements Runnable{
private BufferedInputStream inputStream;
private List<IServerMessageEventListener> listeners = new ArrayList<IServerMessageEventListener>();
public ServerMessageChecker(BufferedInputStream inputStream) {
this.inputStream = inputStream;
}
public synchronized void addServerMessageListener (IServerMessageEventListener listener) {
listeners.add(listener);
}
public synchronized void removeServerMessageListener (IServerMessageEventListener listener) {
listeners.remove(listener);
}
@Override
public void run() {
try {
while (true) {
if (this.inputStream.available() != 0) {
for (IServerMessageEventListener listener:listeners){
listener.handleEvent(new ServerMessageEvent(this, this.inputStream));
//listener jak narazie wypisuje otrzymany pakiet
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
public BufferedInputStream getInputStream() {
return inputStream;
}
public void setInputStream(BufferedInputStream inputStream) {
this.inputStream = inputStream;
}
public List<IServerMessageEventListener> getListeners() {
return listeners;
}
public void setListeners(List<IServerMessageEventListener> listeners) {
this.listeners = listeners;
}
}
public class ServerCommunication {
private OutputStream outputStream;
private BufferedInputStream inputStream;
private Socket requester = null;
public Host preConnect(int number) throws Exception {
URL url = new URL("http://appmsg.gadu-gadu.pl/appsvc/appmsg_ver8.asp?fmnumber=" + number + "&lastmsg=0&version=11.2.35.10307");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
long timeStart = System.currentTimeMillis();
while (!reader.ready()){
if (timeStart - System.currentTimeMillis() > 3000)
throw new Exception("Connection timeout");
}
String tmp, response = "";
while ((tmp = reader.readLine()) != null) {
response += tmp;
System.out.println("response" + response + "/response");
}
Host host = new Host();
host.setUrl(response.split("\\s")[2].split(":")[0]);
host.setPort(Integer.valueOf(response.split("\\s")[2].split(":")[1]));
return host;
}
public void connect(Host host) throws UnknownHostException, IOException {
this.requester = new Socket();
SocketAddress socketAddress = new InetSocketAddress(host.getUrl(), host.getPort());
this.requester.connect(socketAddress, 3000);
this.requester.setKeepAlive(true);
this.outputStream = requester.getOutputStream();
this.outputStream.flush();
this.inputStream = new BufferedInputStream(requester.getInputStream());
}
public void disconnect() throws IOException {
if (this.requester != null)
this.requester.close();
}
public Socket getRequester() {
return requester;
}
public void setRequester(Socket requester) {
this.requester = requester;
}
public OutputStream getOutputStream() {
return outputStream;
}
public void setOutputStream(OutputStream outputStream) {
this.outputStream = outputStream;
}
public BufferedInputStream getInputStream() {
return inputStream;
}
public void setInputStream(BufferedInputStream inputStream) {
this.inputStream = inputStream;
}
}
//dla czytelności zostawiłem tylko istone pola i metody
public class GGLoginPackage extends GGPackageHeader implements Serializable, OutgoingPackage{
private static final long serialVersionUID = -3727130558660044185L;
private int number;
private byte language[] = new byte[2];
private byte hashType;
private byte passwordHash[] = new byte[64];
private int status;
private int flags;
private int features;
private int localIP = 0;
private short localPort = 0;
private int externalIP = 0;
private short externalPort = 0;
private byte imageSize;
private byte unknown = 100;
private int versionLenght;
private byte version[];
private int descriptionSize;
private byte description[];
@Override
public byte[] getPackageContent() {
byte[] result;
ByteBuffer buf = ByteBuffer.allocate(this.getLenght());
buf.order(ByteOrder.LITTLE_ENDIAN);
buf.putInt(this.getType());
buf.putInt(this.getLenght() - 8);
buf.put(this.language);
buf.put(this.hashType);
buf.put(this.passwordHash);
buf.putInt(this.status);
buf.putInt(this.flags);
buf.putInt(this.features);
buf.putInt(this.localIP);
buf.putShort(this.localPort);
buf.putInt(this.externalIP);
buf.putShort(this.externalPort);
buf.put(this.imageSize);
buf.put(this.unknown);
buf.putInt(this.versionLenght);
buf.put(this.version);
buf.putInt(this.descriptionSize);
buf.put(this.description);
result = buf.array();
return result;
}
public void setPasswordHash(String password, byte[] seed) {
MessageDigest digest = null;
byte[] passwordHash = null;
try {
digest = MessageDigest.getInstance("SHA-1");
digest.reset();
digest.update(seed);
passwordHash = digest.digest(password.getBytes("UTF-8"));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
for (int i = 0; i < this.passwordHash.length; i++) {
this.passwordHash[i] = '\0';
if (i < passwordHash.length)
this.passwordHash[i] = passwordHash[i];
}
}
}