refactoring. Rewriting code to spring-boot service. x3

This commit is contained in:
Michael Wain 2024-05-30 16:14:48 +03:00
parent 544c778aba
commit c405fe60ba
14 changed files with 920 additions and 1066 deletions

View File

@ -4,7 +4,6 @@ import com.alterdekim.hearthhack.component.processor.*;
import com.alterdekim.hearthhack.util.BattleNetPacket;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.reflections.Reflections;
import javax.net.ssl.SSLSocket;
import java.io.ByteArrayOutputStream;
@ -23,9 +22,9 @@ public class TcpConnection extends Thread {
@Getter
private Map<Integer, Processor> processors;
public TcpConnection(SSLSocket socket) {
public TcpConnection(SSLSocket socket, Set<Class<? extends Processor>> processorClasses) {
this.fromClient = socket;
this.init();
this.init(processorClasses);
this.start();
}
@ -38,15 +37,13 @@ public class TcpConnection extends Thread {
this.outToClient.flush();
}
public void _send( byte[] b ) throws Exception {
public void sendRaw( byte[] b ) throws Exception {
this.outToClient.write(b);
this.outToClient.flush();
}
private void init() {
private void init(Set<Class<? extends Processor>> classes) {
this.processors = new HashMap<>();
Reflections reflections = new Reflections(this.getClass().getPackageName());
Set<Class<? extends Processor>> classes = reflections.getSubTypesOf(Processor.class);
classes.forEach(c -> {
try {
var ci = c.getDeclaredConstructor().newInstance();
@ -59,13 +56,12 @@ public class TcpConnection extends Thread {
private void processPacket( BattleNetPacket packet ) {
try {
Processor is = this.processors.get(Integer.parseUnsignedInt(Integer.toUnsignedString(packet.getHeader().getServiceId())));
if( is == null ) {
log.error("Can't process weird ProcessorId: " + Integer.parseUnsignedInt(Integer.toUnsignedString(packet.getHeader().getServiceId())));
return;
}
log.info("Incoming: " + is.getClass().getSimpleName() + " / " + packet.getHeader().getMethodId() + " (Token: " + packet.getHeader().getToken() + ")");
//log.info("Incoming: {} / head: {}; body: {} ", is.getClass().getSimpleName(), packet.getHeader(), Util.bytesToHex(packet.getBody()));
is.process(packet, this);
} catch ( Exception e ) {
log.error(e.getMessage());

View File

@ -1,8 +1,10 @@
package com.alterdekim.hearthhack.component;
import com.alterdekim.hearthhack.component.processor.Processor;
import com.alterdekim.hearthhack.util.Util;
import lombok.extern.slf4j.Slf4j;
import org.reflections.Reflections;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@ -11,6 +13,7 @@ import javax.net.ssl.SSLSocket;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
@Slf4j
@Component
@ -21,9 +24,12 @@ public class TcpServer {
private SSLServerSocket serverSocket;
private List<TcpConnection> connections;
private Set<Class<? extends Processor>> processorClasses;
@Scheduled(fixedDelay = 5000)
private void start() {
try {
processorClasses = new Reflections(this.getClass().getPackageName()).getSubTypesOf(Processor.class);
if( serverSocket != null && !serverSocket.isClosed() ) {
serverSocket.close();
serverSocket = null;
@ -38,7 +44,7 @@ public class TcpServer {
while(true) {
SSLSocket s = (SSLSocket) serverSocket.accept();
TcpConnection c = new TcpConnection(s);
TcpConnection c = new TcpConnection(s, processorClasses);
connections.add(c);
log.info("New Connection Established From {}", s.getInetAddress().toString());
}

View File

@ -37,25 +37,12 @@ public class AccountProcessor extends Processor {
.setAccountLevelInfoTag(-577802125).build())
.build();
Protocol.Header header = Protocol.Header.newBuilder(packet.getHeader())
.setSize(getAccountStateResponse.getSerializedSize())
.setServiceId(254)
.setToken(packet.getHeader().getToken())
.setObjectId(0)
.setStatus(0)
.build();
Protocol.Header header = Processor.generateResponse(getAccountStateResponse.getSerializedSize(), packet.getHeader().getToken(), 0, 0);
conn.send(new BattleNetPacket(header, getAccountStateResponse.toByteArray()));
break;
case 34:
Protocol.Header header1 = Protocol.Header.newBuilder()
.setServiceId(254)
.setToken(packet.getHeader().getToken())
.setObjectId(0)
.setSize(53)
.setStatus(0)
.build();
Protocol.Header header1 = Processor.generateResponse(53, packet.getHeader().getToken(), 0, 0);
conn.send(new BattleNetPacket(header1, Util.hexStringToByteArray("12331880B5B9F50E221F0A0D36322E3139372E3234332E383810CBA6011A0A4272617469736C617661280030003800409AE5A1B905")));
break;
default:

View File

@ -5,10 +5,7 @@ import com.alterdekim.Protocol;
import com.alterdekim.hearthhack.component.TcpConnection;
import com.alterdekim.hearthhack.util.BattleNetPacket;
import com.alterdekim.hearthhack.util.Util;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.nio.charset.StandardCharsets;
@ -21,14 +18,7 @@ public class AuthProcessor extends Processor {
private void logonRequest(BattleNetPacket packet, TcpConnection conn ) throws Exception {
// Protocol.LogonRequest lr = Protocol.LogonRequest.parseFrom(packet.getBody());
Protocol.Header h = Protocol.Header.newBuilder()
.setServiceId(254)
.setObjectId(0)
.setToken(packet.getHeader().getToken())
.setStatus(0)
.setSize(0)
.build();
Protocol.Header h = Processor.generateResponse(0, packet.getHeader().getToken(), 0, 0);
conn.send(new BattleNetPacket(h, new byte[0]));
@ -56,7 +46,7 @@ public class AuthProcessor extends Processor {
conn.send(new BattleNetPacket(h, new byte[0]));
//120C7765625F617574685F75726C1A16687474703A2F2F68732F6C6F67696E2F7A2E68746D6C
byte[] us = "http://10.66.66.3:8080".getBytes(StandardCharsets.UTF_8);
byte[] us = "http://0.0.0.0:8080".getBytes(StandardCharsets.UTF_8);
byte[] bb = Util.hexStringToByteArray("120C7765625F617574685F75726C1A"+Util.intToHex(us.length)+Util.bytesToHex(us));
h = Protocol.Header.newBuilder()
@ -71,35 +61,17 @@ public class AuthProcessor extends Processor {
conn.send(new BattleNetPacket(h, bb));
}
@Override
public void process(BattleNetPacket packet, TcpConnection conn) throws Exception {
switch (packet.getHeader().getMethodId()) {
case 1:
logonRequest(packet, conn);
break;
case 4:
Protocol.Header nnh = Protocol.Header.newBuilder()
.setStatus(0)
.setServiceId(254)
.setObjectId(0)
.setToken(packet.getHeader().getToken())
.setSize(0)
.build();
private void selectGameAccount(BattleNetPacket packet, TcpConnection conn) throws Exception {
Protocol.Header nnh = Processor.generateResponse(0, packet.getHeader().getToken(), 0, 0);
conn.send(new BattleNetPacket(nnh, new byte[0]));
break;
case 7:
}
private void verifyWebCredentials(BattleNetPacket packet, TcpConnection conn) throws Exception {
Protocol.VerifyWebCredentialsRequest verifyWebCredentialsRequest
= Protocol.VerifyWebCredentialsRequest.parseFrom(packet.getBody());
log.info( new String( verifyWebCredentialsRequest.getWebCredentials().toByteArray() ) );
Protocol.Header h = Protocol.Header.newBuilder()
.setServiceId(254)
.setToken(packet.getHeader().getToken())
.setObjectId(0)
.setSize(0)
.setStatus(0)
.build();
Protocol.Header h = Processor.generateResponse(0, packet.getHeader().getToken(), 0, 0);
conn.send(new BattleNetPacket(h, new byte[0]));
@ -152,10 +124,15 @@ public class AuthProcessor extends Processor {
.build();
conn.send(new BattleNetPacket(h, logonResult.toByteArray()));
break;
default:
log.error("Can't process weird AuthProcessor method: " + packet.getHeader().getMethodId());
break;
}
@Override
public void process(BattleNetPacket packet, TcpConnection conn) throws Exception {
switch (packet.getHeader().getMethodId()) {
case 1 -> logonRequest(packet, conn);
case 4 -> selectGameAccount(packet, conn);
case 7 -> verifyWebCredentials(packet, conn);
default -> log.error("Can't process weird AuthProcessor method: {}", packet.getHeader().getMethodId());
}
}

View File

@ -20,11 +20,10 @@ public class ChannelProcessor extends Processor {
public void process(BattleNetPacket packet, TcpConnection conn) throws Exception {
switch (packet.getHeader().getMethodId()) {
case 1:
Protocol.CISubscribeRequest ciSubscribeRequest = Protocol.CISubscribeRequest.parseFrom(packet.getBody());
Protocol.CISubscribeResponse ciSubscribeResponse = Protocol.CISubscribeResponse.getDefaultInstance();
Protocol.Header header = Protocol.Header.newBuilder(packet.getHeader())
.setServiceId(254)
.setSize(ciSubscribeResponse.getSerializedSize())
.setSize(0)
.build();
conn.send(new BattleNetPacket(header, ciSubscribeResponse.toByteArray()));
break;

View File

@ -47,7 +47,7 @@ public class ConnectionProcessor extends Processor {
}
}
conn._send(Util.hexStringToByteArray("000c08fe011800200028950130000a0c08f4c9ccf30d10c687bcb805120a0889ff5c1092e5a1b9051800220e0a0c0109080a04030507060211102a2e0a2c0d55450000157a72746d1a206ff4fdd5fa5f6d62a278a04403e075d69d734cd4880732dce8edc6a3f528089230a08a95f4cebdcc02422e0a2c0d55450000157a72746d1a20b4bd0f0096a7648de1d19042fb7a79b96c0df48eea3488f498b08ad3d38fb2cc"));
conn.sendRaw(Util.hexStringToByteArray("000c08fe011800200028950130000a0c08f4c9ccf30d10c687bcb805120a0889ff5c1092e5a1b9051800220e0a0c0109080a04030507060211102a2e0a2c0d55450000157a72746d1a206ff4fdd5fa5f6d62a278a04403e075d69d734cd4880732dce8edc6a3f528089230a08a95f4cebdcc02422e0a2c0d55450000157a72746d1a20b4bd0f0096a7648de1d19042fb7a79b96c0df48eea3488f498b08ad3d38fb2cc"));
}
@Override

View File

@ -3,10 +3,7 @@ package com.alterdekim.hearthhack.component.processor;
import com.alterdekim.Protocol;
import com.alterdekim.hearthhack.component.TcpConnection;
import com.alterdekim.hearthhack.util.BattleNetPacket;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Slf4j
public class FriendsProcessor extends Processor {
@ -15,13 +12,8 @@ public class FriendsProcessor extends Processor {
this.setProcessorId(6);
}
@Override
public void process(BattleNetPacket packet, TcpConnection conn) throws Exception {
switch (packet.getHeader().getMethodId()) {
case 1:
private void processSubscribeToFriends(BattleNetPacket packet, TcpConnection conn) throws Exception {
//Protocol.SubscribeToFriendsRequest subscribeToFriendsRequest = Protocol.SubscribeToFriendsRequest.parseFrom(packet.getBody());
if( packet.getHeader().getToken() == 6 ) {
Protocol.SubscribeToFriendsResponse subscribeToFriendsResponse = Protocol.SubscribeToFriendsResponse.newBuilder()
.setMaxFriends(200)
.setMaxReceivedInvitations(200)
@ -35,33 +27,17 @@ public class FriendsProcessor extends Processor {
.setName("real_id_friend")
.build())
.build();
Protocol.Header header = Protocol.Header.newBuilder()
.setServiceId(254)
.setStatus(0)
.setToken(packet.getHeader().getToken())
.setSize(subscribeToFriendsResponse.getSerializedSize())
.setObjectId(0)
.build();
Protocol.Header header = Processor.generateResponse(subscribeToFriendsResponse.getSerializedSize(), packet.getHeader().getToken(), 0, 0);
conn.send(new BattleNetPacket(header, subscribeToFriendsResponse.toByteArray()));
} else if( packet.getHeader().getToken() == 7 ) {
Protocol.Header header = Protocol.Header.newBuilder()
.setServiceId(254)
.setStatus(0)
.setToken(packet.getHeader().getToken())
.setSize(0)
.setObjectId(0)
.build();
}
conn.send(new BattleNetPacket(header, new byte[0]));
}
break;
default:
log.error("Can't process weird FriendsProcessor method: " + packet.getHeader().getMethodId());
break;
@Override
public void process(BattleNetPacket packet, TcpConnection conn) throws Exception {
if (packet.getHeader().getMethodId() == 1) {
processSubscribeToFriends(packet, conn);
return;
}
log.error("Can't process weird FriendsProcessor method: {}", packet.getHeader().getMethodId());
}
@Override

View File

@ -4,9 +4,14 @@ package com.alterdekim.hearthhack.component.processor;
import com.alterdekim.Protocol;
import com.alterdekim.hearthhack.component.TcpConnection;
import com.alterdekim.hearthhack.util.BattleNetPacket;
import com.alterdekim.hearthhack.util.ClientRequestBody;
import com.alterdekim.hearthhack.util.ClientRequestManager;
import com.alterdekim.hearthhack.util.Util;
import com.google.protobuf.InvalidProtocolBufferException;
import lombok.extern.slf4j.Slf4j;
import java.util.Optional;
@Slf4j
public class GameUtilitiesProcessor extends Processor {
@ -15,29 +20,34 @@ public class GameUtilitiesProcessor extends Processor {
this.setProcessorId(9);
}
@Override
public void process(BattleNetPacket packet, TcpConnection conn) throws Exception {
switch (packet.getHeader().getMethodId()) {
case 1:
private ClientRequestBody parseClientRequest(Protocol.ClientRequest request) {
Optional<Protocol.Attribute> at = request.getAttributeList()
.stream()
.filter(a -> a.hasName() && a.getName().equals("p"))
.findFirst();
if( !at.isPresent() ) return null;
byte[] b = at.get().getValue().getBlobValue().toByteArray();
ClientRequestBody requestBody = null;
try {
requestBody = ClientRequestManager.GetUtilPacketFromBytes(b);
} catch (InvalidProtocolBufferException e) {
log.error(e.getMessage());
}
return requestBody;
}
private void processClientRequest(BattleNetPacket packet, TcpConnection conn) throws Exception {
Protocol.ClientRequest cr = Protocol.ClientRequest.parseFrom(packet.getBody());
var p = parseClientRequest(cr);
log.info("processClientRequest: {}, token={}, body={}", p, packet.getHeader().getToken(), Protocol.Subscribe.parseFrom(p.getBody()));
if( packet.getHeader().getToken() == 10 ) {
Protocol.Header header = Protocol.Header.newBuilder()
.setServiceId(254)
.setToken(packet.getHeader().getToken())
.setObjectId(0)
.setSize(37)
.setStatus(0)
.build();
Protocol.Header header = Processor.generateResponse(37, packet.getHeader().getToken(), 0, 0);
conn.send(new BattleNetPacket(header, Util.hexStringToByteArray("0A090A026964120318BB020A180A0570726F746F120F320D084918AC0220002800300F4078")));
} else if( packet.getHeader().getToken() == 11 ) {
conn._send(Util.hexStringToByteArray("000d08041001180b200028d70130000a120900000000000000021100000000000000001212094743545702000002116739ab04000000001a1c575443472e5574696c4e6f74696669636174696f6e4d65737361676522130a0c6d6573736167655f74797065120318880222190a0c667261676d656e745f30303012093207800101a801ac0222120a0c6d6573736167655f73697a65120218072a1209000000000000000111000000000000000032120900000000000000011193710e1a000000003a004a0a0889ff5c1092e5a1b90552150a050d93710e1a120c0d6739ab0415474354571802000b08fe01180b2000281d30000a090a026964120318c6020a100a0570726f746f12073205080110af02000d08041001180c200028d70130000a120900000000000000021100000000000000001212094743545702000002116739ab04000000001a1c575443472e5574696c4e6f74696669636174696f6e4d65737361676522130a0c6d6573736167655f74797065120318880222190a0c667261676d656e745f30303012093207800101a801ac0222120a0c6d6573736167655f73697a65120218072a1209000000000000000111000000000000000032120900000000000000011193710e1a000000003a004a0a0889ff5c1092e5a1b90552150a050d93710e1a120c0d6739ab0415474354571802000d08041001180d200028d30130000a120900000000000000021100000000000000001212094743545702000002116739ab04000000001a1c575443472e5574696c4e6f74696669636174696f6e4d65737361676522130a0c6d6573736167655f74797065120318b00222150a0c667261676d656e745f3030301205320308a65622120a0c6d6573736167655f73697a65120218032a1209000000000000000111000000000000000032120900000000000000011193710e1a000000003a004a0a0889ff5c1092e5a1b90552150a050d93710e1a120c0d6739ab0415474354571802"));
conn.sendRaw(Util.hexStringToByteArray("000d08041001180b200028d70130000a120900000000000000021100000000000000001212094743545702000002116739ab04000000001a1c575443472e5574696c4e6f74696669636174696f6e4d65737361676522130a0c6d6573736167655f74797065120318880222190a0c667261676d656e745f30303012093207800101a801ac0222120a0c6d6573736167655f73697a65120218072a1209000000000000000111000000000000000032120900000000000000011193710e1a000000003a004a0a0889ff5c1092e5a1b90552150a050d93710e1a120c0d6739ab0415474354571802000b08fe01180b2000281d30000a090a026964120318c6020a100a0570726f746f12073205080110af02000d08041001180c200028d70130000a120900000000000000021100000000000000001212094743545702000002116739ab04000000001a1c575443472e5574696c4e6f74696669636174696f6e4d65737361676522130a0c6d6573736167655f74797065120318880222190a0c667261676d656e745f30303012093207800101a801ac0222120a0c6d6573736167655f73697a65120218072a1209000000000000000111000000000000000032120900000000000000011193710e1a000000003a004a0a0889ff5c1092e5a1b90552150a050d93710e1a120c0d6739ab0415474354571802000d08041001180d200028d30130000a120900000000000000021100000000000000001212094743545702000002116739ab04000000001a1c575443472e5574696c4e6f74696669636174696f6e4d65737361676522130a0c6d6573736167655f74797065120318b00222150a0c667261676d656e745f3030301205320308a65622120a0c6d6573736167655f73697a65120218032a1209000000000000000111000000000000000032120900000000000000011193710e1a000000003a004a0a0889ff5c1092e5a1b90552150a050d93710e1a120c0d6739ab0415474354571802"));
} else if( packet.getHeader().getToken() == 15 ) {
Protocol.Header header = Protocol.Header.newBuilder()
.setServiceId(254)
.setToken(packet.getHeader().getToken())
.setObjectId(0)
.setSize(29)
.setStatus(0)
.build();
Protocol.Header header = Processor.generateResponse(29, packet.getHeader().getToken(), 0, 0);
conn.send(new BattleNetPacket(header, Util.hexStringToByteArray("0A090A026964120318C6020A100A0570726F746F120732050801108B02")));
@ -52,34 +62,14 @@ public class GameUtilitiesProcessor extends Processor {
conn.send(new BattleNetPacket(header, Util.hexStringToByteArray("0A120900000000000000021100000000000000001212094743545702000002116739AB04000000001A1C575443472E5574696C4E6F74696669636174696F6E4D65737361676522130A0C6D6573736167655F74797065120318C60222170A0C667261676D656E745F303030120732050801108B0222120A0C6D6573736167655F73697A65120218052A1209000000000000000111000000000000000032120900000000000000011193710E1A000000003A004A0A0889FF5C1092E5A1B90552150A050D93710E1A120C0D6739AB0415474354571802")));
} else if( packet.getHeader().getToken() == 16 ) {
Protocol.Header header = Protocol.Header.newBuilder()
.setServiceId(254)
.setToken(packet.getHeader().getToken())
.setObjectId(0)
.setSize(29)
.setStatus(0)
.build();
Protocol.Header header = Processor.generateResponse(29, packet.getHeader().getToken(), 0, 0);
conn.send(new BattleNetPacket(header, Util.hexStringToByteArray("0A090A026964120318C6020A100A0570726F746F12073205080110CD01")));
} else if( packet.getHeader().getToken() == 17 ) {
Protocol.Header header = Protocol.Header.newBuilder()
.setServiceId(254)
.setToken(packet.getHeader().getToken())
.setObjectId(0)
.setSize(Util.hexStringToByteArray("0A090A026964120318BB020A180A0570726F746F120F320D081E18AC0220002800300F4078").length)
.setStatus(0)
.build();
Protocol.Header header = Processor.generateResponse(Util.hexStringToByteArray("0A090A026964120318BB020A180A0570726F746F120F320D081E18AC0220002800300F4078").length, packet.getHeader().getToken(), 0, 0);
conn.send(new BattleNetPacket(header, Util.hexStringToByteArray("0A090A026964120318BB020A180A0570726F746F120F320D081E18AC0220002800300F4078")));
} else if( packet.getHeader().getToken() == 19 ) {
Protocol.Header header = Protocol.Header.newBuilder()
.setServiceId(254)
.setToken(packet.getHeader().getToken())
.setObjectId(0)
.setSize(29)
.setStatus(0)
.build();
Protocol.Header header = Processor.generateResponse(29, packet.getHeader().getToken(), 0, 0);
conn.send(new BattleNetPacket(header, Util.hexStringToByteArray("0A090A026964120318C6020A100A0570726F746F120732050801109402")));
@ -137,13 +127,7 @@ public class GameUtilitiesProcessor extends Processor {
} else if (packet.getHeader().getToken() == 20) {
byte[] b = Util.hexStringToByteArray("0A090A026964120318C6020A100A0570726F746F12073205080110C702");
Protocol.Header header = Protocol.Header.newBuilder()
.setServiceId(254)
.setToken(packet.getHeader().getToken())
.setObjectId(0)
.setSize(b.length)
.setStatus(0)
.build();
Protocol.Header header = Processor.generateResponse(b.length, packet.getHeader().getToken(), 0, 0);
conn.send(new BattleNetPacket(header, b));
@ -175,13 +159,7 @@ public class GameUtilitiesProcessor extends Processor {
} else if( packet.getHeader().getToken() == 21 ) {
byte[] b = Util.hexStringToByteArray("0A090A026964120318C6020A100A0570726F746F12073205080110C702");
Protocol.Header header = Protocol.Header.newBuilder()
.setServiceId(254)
.setToken(packet.getHeader().getToken())
.setObjectId(0)
.setSize(b.length)
.setStatus(0)
.build();
Protocol.Header header = Processor.generateResponse(b.length, packet.getHeader().getToken(), 0, 0);
conn.send(new BattleNetPacket(header, b));
@ -239,13 +217,7 @@ public class GameUtilitiesProcessor extends Processor {
} else if( packet.getHeader().getToken() == 22 ) {
byte[] b = Util.hexStringToByteArray("0A090A026964120318C6020A100A0570726F746F12073205080110C702");
Protocol.Header header = Protocol.Header.newBuilder()
.setServiceId(254)
.setToken(packet.getHeader().getToken())
.setObjectId(0)
.setSize(b.length)
.setStatus(0)
.build();
Protocol.Header header = Processor.generateResponse(b.length, packet.getHeader().getToken(), 0, 0);
conn.send(new BattleNetPacket(header, b));
@ -303,28 +275,16 @@ public class GameUtilitiesProcessor extends Processor {
} else if( packet.getHeader().getToken() == 23 ) {
byte[] b = Util.hexStringToByteArray("0A090A026964120318C6020A100A0570726F746F12073205080110B102");
Protocol.Header header = Protocol.Header.newBuilder()
.setServiceId(254)
.setToken(packet.getHeader().getToken())
.setObjectId(0)
.setSize(b.length)
.setStatus(0)
.build();
Protocol.Header header = Processor.generateResponse(b.length, packet.getHeader().getToken(), 0, 0);
conn.send(new BattleNetPacket(header, b));
} else if( packet.getHeader().getToken() == 24 ) {
log.warn("GameUtils " + Util.bytesToHex(packet.getBody()));
// log.warn("GameUtils " + Util.bytesToHex(packet.getBody()));
byte[] b = Util.hexStringToByteArray("0A090A026964120318C6020A100A0570726F746F12073205080110C702");
Protocol.Header header = Protocol.Header.newBuilder()
.setServiceId(254)
.setToken(packet.getHeader().getToken())
.setObjectId(0)
.setSize(b.length)
.setStatus(0)
.build();
Protocol.Header header = Processor.generateResponse(b.length, packet.getHeader().getToken(), 0, 0);
conn.send(new BattleNetPacket(header, b));
@ -701,25 +661,13 @@ public class GameUtilitiesProcessor extends Processor {
.setCapWarning(2000)
.build().toByteArray();*/
//log.warn("GoldBalance " + Util.bytesToHex(b));
Protocol.Header header = Protocol.Header.newBuilder()
.setServiceId(254)
.setToken(packet.getHeader().getToken())
.setObjectId(0)
.setSize(b.length)
.setStatus(0)
.build();
Protocol.Header header = Processor.generateResponse(b.length, packet.getHeader().getToken(), 0, 0);
conn.send(new BattleNetPacket(header, b));
} else if( packet.getHeader().getToken() == 27 ) {
byte[] b = Util.hexStringToByteArray("0A090A026964120318C6020A100A0570726F746F12073205080110FD01");
Protocol.Header header = Protocol.Header.newBuilder()
.setServiceId(254)
.setToken(packet.getHeader().getToken())
.setObjectId(0)
.setSize(b.length)
.setStatus(0)
.build();
Protocol.Header header = Processor.generateResponse(b.length, packet.getHeader().getToken(), 0, 0);
conn.send(new BattleNetPacket(header, b));
@ -738,25 +686,13 @@ public class GameUtilitiesProcessor extends Processor {
} else if( packet.getHeader().getToken() == 28 ) {
byte[] b = Util.hexStringToByteArray("0A090A02696412031889020A0F0A0570726F746F1206320408002001");
Protocol.Header header = Protocol.Header.newBuilder()
.setServiceId(254)
.setToken(packet.getHeader().getToken())
.setObjectId(0)
.setSize(b.length)
.setStatus(0)
.build();
Protocol.Header header = Processor.generateResponse(b.length, packet.getHeader().getToken(), 0, 0);
conn.send(new BattleNetPacket(header, b));
} else if( packet.getHeader().getToken() == 29 ) {
byte[] b = Util.hexStringToByteArray("0A090A026964120318C6020A100A0570726F746F12073205080110C702");
Protocol.Header header = Protocol.Header.newBuilder()
.setServiceId(254)
.setToken(packet.getHeader().getToken())
.setObjectId(0)
.setSize(b.length)
.setStatus(0)
.build();
Protocol.Header header = Processor.generateResponse(29, packet.getHeader().getToken(), 0, 0);
conn.send(new BattleNetPacket(header, b));
@ -786,13 +722,7 @@ public class GameUtilitiesProcessor extends Processor {
conn.send(new BattleNetPacket(header, b));
} else if( packet.getHeader().getToken() == 30 ) {
Protocol.Header header = Protocol.Header.newBuilder()
.setServiceId(254)
.setToken(packet.getHeader().getToken())
.setObjectId(0)
.setSize(0)
.setStatus(0)
.build();
Protocol.Header header = Processor.generateResponse(0, packet.getHeader().getToken(), 0, 0);
conn.send(new BattleNetPacket(header, new byte[0]));
@ -810,23 +740,11 @@ public class GameUtilitiesProcessor extends Processor {
conn.send(new BattleNetPacket(header, b));
} else if( packet.getHeader().getToken() == 34 || packet.getHeader().getToken() == 35 ) {
Protocol.Header header = Protocol.Header.newBuilder()
.setServiceId(254)
.setToken(12)
.setObjectId(0)
.setSize(0)
.setStatus(0)
.build();
Protocol.Header header = Processor.generateResponse(0, 12, 0, 0);
conn.send(new BattleNetPacket(header, new byte[0]));
header = Protocol.Header.newBuilder()
.setServiceId(254)
.setToken(packet.getHeader().getToken())
.setObjectId(0)
.setSize(0)
.setStatus(0)
.build();
header = Processor.generateResponse(0, packet.getHeader().getToken(), 0, 0);
conn.send(new BattleNetPacket(header, new byte[0]));
@ -856,11 +774,15 @@ public class GameUtilitiesProcessor extends Processor {
conn.send(new BattleNetPacket(header, b));
}
break;
default:
log.error("Can't process weird GameUtilitiesProcessor method: " + packet.getHeader().getMethodId());
break;
}
@Override
public void process(BattleNetPacket packet, TcpConnection conn) throws Exception {
if( packet.getHeader().getMethodId() == 1 ) {
processClientRequest(packet, conn);
return;
}
log.error("Can't process weird GameUtilitiesProcessor method: {}", packet.getHeader().getMethodId());
}
@Override

View File

@ -24,13 +24,7 @@ public class PresenceProcessor extends Processor {
switch (packet.getHeader().getMethodId()) {
case 1:
Protocol.SubscribeRequest subscribeRequest = Protocol.SubscribeRequest.parseFrom(packet.getBody());
Protocol.Header header = Protocol.Header.newBuilder(packet.getHeader())
.setServiceId(254)
.setSize(0)
.setObjectId(0)
.setToken(packet.getHeader().getToken())
.setStatus(0)
.build();
Protocol.Header header = Processor.generateResponse(0, packet.getHeader().getToken(), 0, 0);
conn.send(new BattleNetPacket(header, new byte[0]));
if( subscribeRequest.getObjectId() == 1 ) {
@ -91,23 +85,11 @@ public class PresenceProcessor extends Processor {
break;
case 3:
if( packet.getHeader().getToken() == 12 ) {
/* Protocol.Header header1 = Protocol.Header.newBuilder()
.setServiceId(254)
.setToken(packet.getHeader().getToken())
.setObjectId(0)
.setSize(0)
.setStatus(0)
.build();
/* Protocol.Header header1 = Processor.generateResponse(0, packet.getHeader().getToken(), 0, 0);
conn.send(new BattleNetPacket(header1, new byte[0]));*/
conn._send(Util.hexStringToByteArray("000c08fe011800200028950130000a0c08f4c9ccf30d10c687bcb805120a0889ff5c1092e5a1b9051800220e0a0c0109080a04030507060211102a2e0a2c0d55450000157a72746d1a206ff4fdd5fa5f6d62a278a04403e075d69d734cd4880732dce8edc6a3f528089230a08a95f4cebdcc02422e0a2c0d55450000157a72746d1a20b4bd0f0096a7648de1d19042fb7a79b96c0df48eea3488f498b08ad3d38fb2cc"));
conn.sendRaw(Util.hexStringToByteArray("000c08fe011800200028950130000a0c08f4c9ccf30d10c687bcb805120a0889ff5c1092e5a1b9051800220e0a0c0109080a04030507060211102a2e0a2c0d55450000157a72746d1a206ff4fdd5fa5f6d62a278a04403e075d69d734cd4880732dce8edc6a3f528089230a08a95f4cebdcc02422e0a2c0d55450000157a72746d1a20b4bd0f0096a7648de1d19042fb7a79b96c0df48eea3488f498b08ad3d38fb2cc"));
} else if( packet.getHeader().getToken() == 13 ) {
Protocol.Header header1 = Protocol.Header.newBuilder()
.setServiceId(254)
.setToken(packet.getHeader().getToken())
.setObjectId(0)
.setSize(0)
.setStatus(0)
.build();
Protocol.Header header1 = Processor.generateResponse(0, packet.getHeader().getToken(), 0, 0);
conn.send(new BattleNetPacket(header1, new byte[0]));
header1 = Protocol.Header.newBuilder()
@ -121,13 +103,7 @@ public class PresenceProcessor extends Processor {
conn.send(new BattleNetPacket(header1, Util.hexStringToByteArray("1233AA06300A12094743545702000002116739AB0400000000121A0A180A0A08C786D1BA0510021813120A2A083833383836303830")));
} else if( packet.getHeader().getToken() == 18 ) {
Protocol.Header header1 = Protocol.Header.newBuilder()
.setServiceId(254)
.setToken(packet.getHeader().getToken())
.setObjectId(0)
.setSize(0)
.setStatus(0)
.build();
Protocol.Header header1 = Processor.generateResponse(0, packet.getHeader().getToken(), 0, 0);
conn.send(new BattleNetPacket(header1, new byte[0]));
byte[] b = Util.hexStringToByteArray("122BAA06280A12094743545702000002116739AB040000000012120A100A0A08C786D1BA051002180112021000");
@ -157,13 +133,7 @@ public class PresenceProcessor extends Processor {
conn.send(new BattleNetPacket(header, b));
} else if( packet.getHeader().getToken() == 26 ) {
Protocol.Header header1 = Protocol.Header.newBuilder()
.setServiceId(254)
.setToken(packet.getHeader().getToken())
.setObjectId(0)
.setSize(0)
.setStatus(0)
.build();
Protocol.Header header1 = Processor.generateResponse(0, packet.getHeader().getToken(), 0, 0);
conn.send(new BattleNetPacket(header1, new byte[0]));
byte[] b = Util.hexStringToByteArray("1231AA062E0A12094743545702000002116739AB040000000012180A160A0A08C786D1BA051002181212083206190000190000");
@ -181,13 +151,7 @@ public class PresenceProcessor extends Processor {
} else if( packet.getHeader().getToken() == 32 ) {
byte[] b = Util.hexStringToByteArray("0D5545000015737368001A20BEC5292231D7686AF00CE64E0C58CC6E360EA950AAFFAC6A114F03A958E275F3");
Protocol.Header header1 = Protocol.Header.newBuilder()
.setServiceId(254)
.setToken(packet.getHeader().getToken())
.setObjectId(0)
.setSize(b.length)
.setStatus(0)
.build();
Protocol.Header header1 = Processor.generateResponse(b.length, packet.getHeader().getToken(), 0, 0);
conn.send(new BattleNetPacket(header1, b));
b = Util.hexStringToByteArray("1230AA062D0A12094743545702000002116739AB040000000012170A150A0A08C786D1BA0510021811120732050103000000");
@ -204,24 +168,12 @@ public class PresenceProcessor extends Processor {
} else if( packet.getHeader().getToken() == 33 ) {
byte[] b = Util.hexStringToByteArray("0D5545000015737368001A20BEC5292231D7686AF00CE64E0C58CC6E360EA950AAFFAC6A114F03A958E275F3");
Protocol.Header header1 = Protocol.Header.newBuilder()
.setServiceId(254)
.setToken(packet.getHeader().getToken())
.setObjectId(0)
.setSize(b.length)
.setStatus(0)
.build();
Protocol.Header header1 = Processor.generateResponse(b.length, packet.getHeader().getToken(), 0, 0);
conn.send(new BattleNetPacket(header1, b));
} else if( packet.getHeader().getToken() == 36 ) {
byte[] b = Util.hexStringToByteArray("0A090A026964120318C6020A120A0570726F746F12093207080110C9011806");
Protocol.Header header1 = Protocol.Header.newBuilder()
.setServiceId(254)
.setToken(packet.getHeader().getToken())
.setObjectId(0)
.setSize(b.length)
.setStatus(0)
.build();
Protocol.Header header1 = Processor.generateResponse(b.length, packet.getHeader().getToken(), 0, 0);
conn.send(new BattleNetPacket(header1, b));
b = Util.hexStringToByteArray("0A120900000000000000021100000000000000001212094743545702000002116739AB04000000001A1C575443472E5574696C4E6F74696669636174696F6E4D65737361676522130A0C6D6573736167655F74797065120318E00122120A0C6D6573736167655F73697A65120218002A1209000000000000000111000000000000000032120900000000000000011193710E1A000000003A004A0A0889FF5C1092E5A1B90552150A050D93710E1A120C0D6739AB0415474354571802");

View File

@ -23,30 +23,12 @@ public abstract class Processor {
public abstract void process(BattleNetPacket packet, TcpConnection conn) throws Exception;
public static Protocol.Header generateResponse(int size, int token) {
return Protocol.Header.newBuilder()
.setServiceId(254)
.setSize(size)
.setToken(token)
.build();
}
public static Protocol.Header generateResponse(int size, int token, int status, int object_id) {
return Protocol.Header.newBuilder()
.setServiceId(254)
.setSize(size)
.setStatus(status)
.setToken(token)
.setObjectId(object_id)
.build();
}
public static Protocol.Header generateResponse(int size, int token, int object_id) {
return Protocol.Header.newBuilder()
.setServiceId(254)
.setSize(size)
.setToken(token)
.setObjectId(object_id)
.build();
public static Protocol.Header generateResponse(Integer size, Integer token, Integer status, Integer object_id) {
Protocol.Header.Builder b = Protocol.Header.newBuilder().setServiceId(254);
if(size != null) b = b.setSize(size);
if(token != null) b = b.setToken(token);
if(status != null) b = b.setStatus(status);
if(object_id != null) b = b.setObjectId(object_id);
return b.build();
}
}

View File

@ -26,13 +26,8 @@ public class ResourcesProcessor extends Processor {
.setHash(ByteString.copyFrom(Util.hexStringToByteArray("5b2f9b39434a1c4e3f970a76c1e97a8548c95da2ad52a6d37cf9d793dedd887d")))
.build();
Protocol.Header header = Protocol.Header.newBuilder()
.setServiceId(254)
.setSize(contentHandle.getSerializedSize())
.setStatus(0)
.setToken(packet.getHeader().getToken())
.setObjectId(0)
.build();
Protocol.Header header = Processor.generateResponse(contentHandle.getSerializedSize(), packet.getHeader().getToken(), 0, 0);
conn.send(new BattleNetPacket(header, contentHandle.toByteArray()));
break;
default:

View File

@ -0,0 +1,11 @@
package com.alterdekim.hearthhack.util;
import lombok.*;
@Data
public class ClientRequestBody {
private int sendCount;
private byte[] body;
private int type;
}

View File

@ -0,0 +1,30 @@
package com.alterdekim.hearthhack.util;
import com.alterdekim.Protocol;
import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
public class ClientRequestManager {
// Rewritten method from hearthstone source code
public static byte[] GetUtilPacketBytes( ClientRequestBody body ) {
Protocol.RpcHeader.Builder rpcHeader = Protocol.RpcHeader.newBuilder();
rpcHeader.setType(body.getType()); // (ulong)
if (body.getSendCount() > 0) rpcHeader.setRetryCount(body.getSendCount()); // (ulong)
Protocol.RpcMessage.Builder rpcMessage = Protocol.RpcMessage.newBuilder();
rpcMessage.setRpcHeader(rpcHeader);
if (body.getBody() != null && body.getBody().length > 0) rpcMessage.setMessageBody(ByteString.copyFrom(body.getBody()));
return rpcMessage.build().toByteArray();
}
// Inverted GetUtilPacketBytes method
public static ClientRequestBody GetUtilPacketFromBytes( byte[] data ) throws InvalidProtocolBufferException {
Protocol.RpcMessage rpcMessage = Protocol.RpcMessage.parseFrom(data);
ClientRequestBody body = new ClientRequestBody();
body.setBody(rpcMessage.getMessageBody().toByteArray());
body.setType((int) rpcMessage.getRpcHeader().getType());
body.setSendCount((int)rpcMessage.getRpcHeader().getRetryCount());
return body;
}
}

View File

@ -6,6 +6,18 @@ package bnet.protocol;
option java_package = "com.alterdekim";
option java_outer_classname = "Protocol";
// ref: PegasusUtil.RpcHeader
message RpcHeader {
required uint64 type = 1;
optional uint64 retry_count = 2 [default = 0];
}
// ref: PegasusUtil.RpcMessage
message RpcMessage {
required RpcHeader rpc_header = 1;
optional bytes message_body = 2;
}
// ref: bnet.protocol.attribute.Attribute
message Attribute {
required string name = 1;
@ -2070,3 +2082,12 @@ message GoldBalance {
optional int64 cap = 3;
optional int64 cap_warning = 4;
}
// ref: PegasusUtil.Subscribe
message Subscribe {
// ref: PegasusUtil.Subscribe/PacketID
enum PacketID {
ID = 314;
}
}