refactoring. Rewriting code to spring-boot service. x2

This commit is contained in:
Michael Wain 2024-05-30 03:45:07 +03:00
parent f3479a3a91
commit 544c778aba
17 changed files with 329 additions and 346 deletions

10
pom.xml
View File

@ -68,13 +68,9 @@
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-ip</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-core</artifactId>
<version>6.0.0</version>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>0.10.2</version>
</dependency>
</dependencies>

View File

@ -1,90 +0,0 @@
package com.alterdekim;
import com.alterdekim.db.Database;
import com.alterdekim.hearthhack.util.Util;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.net.ssl.*;
import java.io.IOException;
import java.util.LinkedList;
@Slf4j
public class Server implements Runnable {
private SSLServerSocket serverSocket;
private int portNumber;
private Thread acceptThread;
private LinkedList<Connection> connections;
private Database db;
public Server(int port) {
portNumber = port;
connections = new LinkedList<>();
db = new Database("localhost", 5984, "hs_lobby");
try {
//SSLServerSocketFactory sslssf = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
serverSocket = (SSLServerSocket) Util.getSocketFactory(
"test.com.crt",
"test.com.crt",
"test.com.key",
""
).createServerSocket(portNumber,15);
db.start();
} catch (Exception e) {
log.error("Init failed: " + e.getMessage());
}
}
public void startListening() {
acceptThread = new Thread(this);
acceptThread.start();
}
public void stopListening() {
for(Connection c:connections) {
c.stopListeningAndDisconnect();
}
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
try {
while(true) {
SSLSocket s = (SSLSocket) serverSocket.accept();
Connection c = new Connection(s, db);
connections.add(c);
log.info("New Connection Established From "+s.getInetAddress().toString());
}
} catch(java.net.SocketException e) {
log.error("Listening thread terminated with exception: " + e.getMessage());
} catch(IOException e) {
log.error(e.getMessage());
}
}
public void removeConnection(Connection c) {
connections.remove(c);
}
public void printConnections() {
log.info("Number of connections "+connections.toString());
for(int i=0; i<connections.size(); i++) {
log.info(connections.toString());
}
}
}

View File

@ -1,38 +1,30 @@
package com.alterdekim;
package com.alterdekim.hearthhack.component;
import com.alterdekim.db.Database;
import com.alterdekim.services.*;
import com.alterdekim.hearthhack.component.processor.*;
import com.alterdekim.hearthhack.util.BattleNetPacket;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.reflections.Reflections;
import javax.net.ssl.SSLSocket;
import java.io.*;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
@Slf4j
public class Connection extends Thread {
/*
All files were merged into protocol.proto
*/
public class TcpConnection extends Thread {
private final SSLSocket fromClient;
private OutputStream outToClient;
@Getter
private Map<Integer, Service> services;
private Map<Integer, Processor> processors;
@Getter
private final Database db;
public Connection(SSLSocket socket, Database db) {
public TcpConnection(SSLSocket socket) {
this.fromClient = socket;
this.db = db;
this.init();
this.start();
}
@ -42,7 +34,6 @@ public class Connection extends Thread {
}
public void send(BattleNetPacket bp) throws Exception {
// log.info("Sending response: " + bp.getHeader().getServiceId() + " / " + bp.getHeader().getMethodId());
this.outToClient.write(bp.Encode());
this.outToClient.flush();
}
@ -53,29 +44,31 @@ public class Connection extends Thread {
}
private void init() {
this.services = new HashMap<>();
this.services.put(0, new ConnectionService(""));
this.services.put(1, new AuthService("bnet.protocol.authentication.AuthenticationClient")); // Compute32.Hash("bnet.protocol.authentication.AuthenticationServer")
this.services.put(17, new AccountService("bnet.protocol.account.AccountNotify")); // Compute32.Hash("bnet.protocol.account.AccountService")
this.services.put(4, new PresenceService("bnet.protocol.presence.PresenceService")); // Compute32.Hash("bnet.protocol.presence.PresenceService")
this.services.put(6, new FriendsService("bnet.protocol.friends.FriendsNotify")); // Compute32.Hash("bnet.protocol.friends.FriendsService")
this.services.put(7, new ChannelService("bnet.protocol.channel.Channel")); // Compute32.Hash("bnet.protocol.channel.Channel")
this.services.put(16, new ResourcesService("bnet.protocol.resources.Resources"));
this.services.put(9, new GameUtilitiesService("bnet.protocol.game_utilities.GameUtilities"));
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();
this.processors.put(ci.getProcessorId(), ci);
} catch (Exception e) {
log.error(e.getMessage());
}
});
}
private void processPacket( BattleNetPacket packet ) {
try {
Service is = this.services.get(Integer.parseUnsignedInt(Integer.toUnsignedString(packet.getHeader().getServiceId())));
Processor is = this.processors.get(Integer.parseUnsignedInt(Integer.toUnsignedString(packet.getHeader().getServiceId())));
if( is == null ) {
log.error("Can't process weird ServiceId: " + Integer.parseUnsignedInt(Integer.toUnsignedString(packet.getHeader().getServiceId())));
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() + ")");
is.process(packet, this);
} catch ( Exception e ) {
e.printStackTrace();
log.error(e.getMessage());
}
}
@ -102,16 +95,12 @@ public class Connection extends Thread {
}
baos.close();
} catch (Exception e) {
e.printStackTrace();
log.error(e.getMessage());
break;
}
}
} catch ( Exception e ) {
e.printStackTrace();
log.error(e.getMessage());
}
/*
br.close();
fromClient.close();
*/
}
}

View File

@ -0,0 +1,62 @@
package com.alterdekim.hearthhack.component;
import com.alterdekim.hearthhack.util.Util;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLSocket;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
@Slf4j
@Component
public class TcpServer {
private final int socketPort = 1119;
private SSLServerSocket serverSocket;
private List<TcpConnection> connections;
@Scheduled(fixedDelay = 5000)
private void start() {
try {
if( serverSocket != null && !serverSocket.isClosed() ) {
serverSocket.close();
serverSocket = null;
}
this.connections = new LinkedList<>();
this.serverSocket = (SSLServerSocket) Util.getSocketFactory(
"test.com.crt", // "test.com.crt"
"test.com.crt", // "test.com.crt"
"test.com.key", // "test.com.key"
""
).createServerSocket(this.socketPort, 15);
while(true) {
SSLSocket s = (SSLSocket) serverSocket.accept();
TcpConnection c = new TcpConnection(s);
connections.add(c);
log.info("New Connection Established From {}", s.getInetAddress().toString());
}
} catch (IOException e) {
log.error(e.getMessage());
}
}
public void stopListening() {
connections.forEach(TcpConnection::stopListeningAndDisconnect);
try {
serverSocket.close();
} catch (IOException e) {
log.error(e.getMessage());
}
}
public void removeConnection(TcpConnection c) {
connections.remove(c);
}
}

View File

@ -1,22 +1,24 @@
package com.alterdekim.services;
package com.alterdekim.hearthhack.component.processor;
import com.alterdekim.Connection;
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;
public class AccountService extends Service {
@Slf4j
public class AccountProcessor extends Processor {
private static final Logger log = LoggerFactory.getLogger(AccountService.class);
public AccountService(String export_name) {
super(export_name);
public AccountProcessor() {
this.setProcessorId(17);
}
@Override
public void process(BattleNetPacket packet, Connection conn) throws Exception {
public void process(BattleNetPacket packet, TcpConnection conn) throws Exception {
switch (packet.getHeader().getMethodId()) {
case 30:
// Protocol.GetAccountStateRequest getAccountStateRequest = Protocol.GetAccountStateRequest.parseFrom(packet.getBody());
@ -57,8 +59,13 @@ public class AccountService extends Service {
conn.send(new BattleNetPacket(header1, Util.hexStringToByteArray("12331880B5B9F50E221F0A0D36322E3139372E3234332E383810CBA6011A0A4272617469736C617661280030003800409AE5A1B905")));
break;
default:
log.error("Can't process weird AccountService method: " + packet.getHeader().getMethodId());
log.error("Can't process weird AccountProcessor method: " + packet.getHeader().getMethodId());
break;
}
}
@Override
public String getExportName() {
return "bnet.protocol.account.AccountNotify";
}
}

View File

@ -1,24 +1,25 @@
package com.alterdekim.services;
package com.alterdekim.hearthhack.component.processor;
import com.alterdekim.Connection;
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;
public class AuthService extends Service {
@Slf4j
public class AuthProcessor extends Processor {
private static final Logger log = LoggerFactory.getLogger(AuthService.class);
public AuthService(String export_name) {
super(export_name);
public AuthProcessor() {
this.setProcessorId(1);
}
private void logonRequest( BattleNetPacket packet, Connection conn ) throws Exception {
private void logonRequest(BattleNetPacket packet, TcpConnection conn ) throws Exception {
// Protocol.LogonRequest lr = Protocol.LogonRequest.parseFrom(packet.getBody());
Protocol.Header h = Protocol.Header.newBuilder()
@ -71,7 +72,7 @@ public class AuthService extends Service {
}
@Override
public void process(BattleNetPacket packet, Connection conn) throws Exception {
public void process(BattleNetPacket packet, TcpConnection conn) throws Exception {
switch (packet.getHeader().getMethodId()) {
case 1:
logonRequest(packet, conn);
@ -153,8 +154,13 @@ public class AuthService extends Service {
conn.send(new BattleNetPacket(h, logonResult.toByteArray()));
break;
default:
log.error("Can't process weird AuthService method: " + packet.getHeader().getMethodId());
log.error("Can't process weird AuthProcessor method: " + packet.getHeader().getMethodId());
break;
}
}
@Override
public String getExportName() {
return "bnet.protocol.authentication.AuthenticationClient";
}
}

View File

@ -1,21 +1,23 @@
package com.alterdekim.services;
package com.alterdekim.hearthhack.component.processor;
import com.alterdekim.Connection;
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;
public class ChannelService extends Service {
@Slf4j
public class ChannelProcessor extends Processor {
private static final Logger log = LoggerFactory.getLogger(ChannelService.class);
public ChannelService(String export_name) {
super(export_name);
public ChannelProcessor() {
this.setProcessorId(7);
}
@Override
public void process(BattleNetPacket packet, Connection conn) throws Exception {
public void process(BattleNetPacket packet, TcpConnection conn) throws Exception {
switch (packet.getHeader().getMethodId()) {
case 1:
Protocol.CISubscribeRequest ciSubscribeRequest = Protocol.CISubscribeRequest.parseFrom(packet.getBody());
@ -27,8 +29,13 @@ public class ChannelService extends Service {
conn.send(new BattleNetPacket(header, ciSubscribeResponse.toByteArray()));
break;
default:
log.error("Can't process weird ChannelService method: " + packet.getHeader().getMethodId());
log.error("Can't process weird ChannelProcessor method: " + packet.getHeader().getMethodId());
break;
}
}
@Override
public String getExportName() {
return "bnet.protocol.channel.Channel";
}
}

View File

@ -0,0 +1,72 @@
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.Util;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import java.util.List;
import java.util.Set;
@Slf4j
public class ConnectionProcessor extends Processor {
public ConnectionProcessor() {
this.setProcessorId(0);
}
/*int GameUtilityProcessor = Compute32.Hash("bnet.protocol.game_utilities.GameUtilities");
int GameMasterProcessor = Compute32.Hash("bnet.protocol.game_master.GameMaster");
int NotificationProcessor = Compute32.Hash("bnet.protocol.notification.NotificationProcessor");
int ChannelOwnerProcessor = Compute32.Hash("bnet.protocol.channel.ChannelOwner");
int ChannelInvitationProcessor = Compute32.Hash("bnet.protocol.channel_invitation.ChannelInvitationProcessor");
int ChallengeProcessor = Compute32.Hash("bnet.protocol.challenge.ChallengeProcessor");
int ResourcesProcessor = Compute32.Hash("bnet.protocol.resources.Resources"); */
private void processConnect( BattleNetPacket packet, TcpConnection conn ) throws Exception {
Protocol.ConnectRequest cr = Protocol.ConnectRequest.parseFrom(packet.getBody());
Protocol.BindResponse.Builder b = Protocol.BindResponse.newBuilder();
List<Integer> hashes = cr.getBindRequest().getImportedServiceHashList();
for( Integer hash : hashes ) {
b.addImportedServiceId(hash);
}
List<Protocol.BoundService> bs = cr.getBindRequest().getExportedServiceList();
for( Protocol.BoundService s : bs ) {
Set<Integer> ks = conn.getProcessors().keySet();
for( Integer c : ks ) {
Processor ss = conn.getProcessors().get(c);
if( ss != null && ss.getProcessorHash() == s.getHash() ) {
ss.setProcessorId(s.getId());
break;
}
}
}
conn._send(Util.hexStringToByteArray("000c08fe011800200028950130000a0c08f4c9ccf30d10c687bcb805120a0889ff5c1092e5a1b9051800220e0a0c0109080a04030507060211102a2e0a2c0d55450000157a72746d1a206ff4fdd5fa5f6d62a278a04403e075d69d734cd4880732dce8edc6a3f528089230a08a95f4cebdcc02422e0a2c0d55450000157a72746d1a20b4bd0f0096a7648de1d19042fb7a79b96c0df48eea3488f498b08ad3d38fb2cc"));
}
@Override
public void process(BattleNetPacket packet, TcpConnection conn) throws Exception {
switch (packet.getHeader().getMethodId()) {
case 1:
processConnect(packet, conn);
break;
case 5:
// FUCK NODATA
break;
default:
log.error("Can't process weird ConnectionProcessor method: " + packet.getHeader().getMethodId());
break;
}
}
@Override
public String getExportName() {
return super.getExportName();
}
}

View File

@ -1,21 +1,22 @@
package com.alterdekim.services;
package com.alterdekim.hearthhack.component.processor;
import com.alterdekim.Connection;
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;
public class FriendsService extends Service {
@Slf4j
public class FriendsProcessor extends Processor {
private static final Logger log = LoggerFactory.getLogger(FriendsService.class);
public FriendsService(String export_name) {
super(export_name);
public FriendsProcessor() {
this.setProcessorId(6);
}
@Override
public void process(BattleNetPacket packet, Connection conn) throws Exception {
public void process(BattleNetPacket packet, TcpConnection conn) throws Exception {
switch (packet.getHeader().getMethodId()) {
case 1:
//Protocol.SubscribeToFriendsRequest subscribeToFriendsRequest = Protocol.SubscribeToFriendsRequest.parseFrom(packet.getBody());
@ -35,6 +36,7 @@ public class FriendsService extends Service {
.build())
.build();
Protocol.Header header = Protocol.Header.newBuilder()
.setServiceId(254)
.setStatus(0)
@ -57,8 +59,13 @@ public class FriendsService extends Service {
}
break;
default:
log.error("Can't process weird FriendsService method: " + packet.getHeader().getMethodId());
log.error("Can't process weird FriendsProcessor method: " + packet.getHeader().getMethodId());
break;
}
}
@Override
public String getExportName() {
return "bnet.protocol.friends.FriendsNotify";
}
}

View File

@ -1,21 +1,22 @@
package com.alterdekim.services;
package com.alterdekim.hearthhack.component.processor;
import com.alterdekim.Connection;
import com.alterdekim.Protocol;
import com.alterdekim.hearthhack.component.TcpConnection;
import com.alterdekim.hearthhack.util.BattleNetPacket;
import com.alterdekim.hearthhack.util.Util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import lombok.extern.slf4j.Slf4j;
public class GameUtilitiesService extends Service {
private static final Logger log = LoggerFactory.getLogger(GameUtilitiesService.class);
public GameUtilitiesService(String export_name) {
super(export_name);
@Slf4j
public class GameUtilitiesProcessor extends Processor {
public GameUtilitiesProcessor() {
this.setProcessorId(9);
}
@Override
public void process(BattleNetPacket packet, Connection conn) throws Exception {
public void process(BattleNetPacket packet, TcpConnection conn) throws Exception {
switch (packet.getHeader().getMethodId()) {
case 1:
if( packet.getHeader().getToken() == 10 ) {
@ -857,8 +858,13 @@ public class GameUtilitiesService extends Service {
}
break;
default:
log.error("Can't process weird GameUtilitiesService method: " + packet.getHeader().getMethodId());
log.error("Can't process weird GameUtilitiesProcessor method: " + packet.getHeader().getMethodId());
break;
}
}
@Override
public String getExportName() {
return "bnet.protocol.game_utilities.GameUtilities";
}
}

View File

@ -1,24 +1,26 @@
package com.alterdekim.services;
package com.alterdekim.hearthhack.component.processor;
import com.alterdekim.Connection;
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;
public class PresenceService extends Service {
@Slf4j
public class PresenceProcessor extends Processor {
private static final Logger log = LoggerFactory.getLogger(PresenceService.class);
public PresenceService(String export_name) {
super(export_name);
public PresenceProcessor() {
this.setProcessorId(4);
}
@Override
public void process(BattleNetPacket packet, Connection conn) throws Exception {
public void process(BattleNetPacket packet, TcpConnection conn) throws Exception {
switch (packet.getHeader().getMethodId()) {
case 1:
Protocol.SubscribeRequest subscribeRequest = Protocol.SubscribeRequest.parseFrom(packet.getBody());
@ -236,8 +238,13 @@ public class PresenceService extends Service {
}
break;
default:
log.error("Can't process weird PresenceService method: " + packet.getHeader().getMethodId());
log.error("Can't process weird PresenceProcessor method: " + packet.getHeader().getMethodId());
break;
}
}
@Override
public String getExportName() {
return "bnet.protocol.presence.PresenceProcessor";
}
}

View File

@ -0,0 +1,52 @@
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.Compute32;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@NoArgsConstructor
public abstract class Processor {
@Setter
private int processorId;
public int getProcessorHash() { return Compute32.Hash(getExportName()); }
public String getExportName() {
return "";
}
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();
}
}

View File

@ -1,23 +1,22 @@
package com.alterdekim.services;
package com.alterdekim.hearthhack.component.processor;
import com.alterdekim.Connection;
import com.alterdekim.Protocol;
import com.alterdekim.hearthhack.component.TcpConnection;
import com.alterdekim.hearthhack.util.BattleNetPacket;
import com.alterdekim.hearthhack.util.Util;
import com.google.protobuf.ByteString;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import lombok.extern.slf4j.Slf4j;
public class ResourcesService extends Service {
@Slf4j
public class ResourcesProcessor extends Processor {
private static final Logger log = LoggerFactory.getLogger(ResourcesService.class);
public ResourcesService(String export_name) {
super(export_name);
public ResourcesProcessor() {
this.setProcessorId(16);
}
@Override
public void process(BattleNetPacket packet, Connection conn) throws Exception {
public void process(BattleNetPacket packet, TcpConnection conn) throws Exception {
switch (packet.getHeader().getMethodId()) {
case 1:
// Protocol.ContentHandleRequest contentHandleRequest = Protocol.ContentHandleRequest.parseFrom(packet.getBody());
@ -37,8 +36,13 @@ public class ResourcesService extends Service {
conn.send(new BattleNetPacket(header, contentHandle.toByteArray()));
break;
default:
log.error("Can't process weird ResourcesService method: " + packet.getHeader().getMethodId());
log.error("Can't process weird ResourcesProcessor method: " + packet.getHeader().getMethodId());
break;
}
}
@Override
public String getExportName() {
return "bnet.protocol.resources.Resources";
}
}

View File

@ -1,42 +0,0 @@
package com.alterdekim.hearthhack.config;
import com.alterdekim.hearthhack.handler.BattleNetSocketHandler;
import com.alterdekim.hearthhack.parser.BattleNetSerializerDeserializer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.config.EnableIntegration;
import org.springframework.integration.dsl.IntegrationFlow;
import org.springframework.integration.ip.dsl.Tcp;
import org.springframework.integration.ip.dsl.TcpInboundGatewaySpec;
import org.springframework.integration.ip.dsl.TcpServerConnectionFactorySpec;
@Slf4j
@Configuration
@EnableIntegration
public class TcpServerSocketConfiguration {
private final int socketPort = 1119;
@Bean
public IntegrationFlow server(BattleNetSocketHandler serverSocketHandler) {
TcpServerConnectionFactorySpec connectionFactory =
Tcp.netServer(socketPort)
.deserializer(new BattleNetSerializerDeserializer())
.serializer(new BattleNetSerializerDeserializer())
.soTcpNoDelay(true);
TcpInboundGatewaySpec inboundGateway =
Tcp.inboundGateway(connectionFactory);
return IntegrationFlow
.from(inboundGateway)
.handle(serverSocketHandler::handleMessage)
.get();
}
@Bean
public BattleNetSocketHandler serverSocketHandler() {
return new BattleNetSocketHandler();
}
}

View File

@ -1,14 +1,10 @@
package com.alterdekim.hearthhack.handler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHeaders;
@Slf4j
public class BattleNetSocketHandler {
public String handleMessage(Message<?> message, MessageHeaders messageHeaders) {
log.info(message.getPayload() + "");
// TODO implement something useful to process the incoming message here...
return message.getPayload().toString();
public String handleMessage() {
return "";
}
}

View File

@ -1,67 +0,0 @@
package com.alterdekim.services;
import com.alterdekim.Connection;
import com.alterdekim.Protocol;
import com.alterdekim.hearthhack.util.BattleNetPacket;
import com.alterdekim.hearthhack.util.Util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.Set;
public class ConnectionService extends Service {
private static final Logger log = LoggerFactory.getLogger(ConnectionService.class);
public ConnectionService(String export_name) {
super(export_name);
}
/*int GameUtilityService = Compute32.Hash("bnet.protocol.game_utilities.GameUtilities");
int GameMasterService = Compute32.Hash("bnet.protocol.game_master.GameMaster");
int NotificationService = Compute32.Hash("bnet.protocol.notification.NotificationService");
int ChannelOwnerService = Compute32.Hash("bnet.protocol.channel.ChannelOwner");
int ChannelInvitationService = Compute32.Hash("bnet.protocol.channel_invitation.ChannelInvitationService");
int ChallengeService = Compute32.Hash("bnet.protocol.challenge.ChallengeService");
int ResourcesService = Compute32.Hash("bnet.protocol.resources.Resources"); */
private void processConnect( BattleNetPacket packet, Connection conn ) throws Exception {
Protocol.ConnectRequest cr = Protocol.ConnectRequest.parseFrom(packet.getBody());
Protocol.BindResponse.Builder b = Protocol.BindResponse.newBuilder();
List<Integer> hashes = cr.getBindRequest().getImportedServiceHashList();
for( Integer hash : hashes ) {
b.addImportedServiceId(hash);
}
List<Protocol.BoundService> bs = cr.getBindRequest().getExportedServiceList();
for( Protocol.BoundService s : bs ) {
Set<Integer> ks = conn.getServices().keySet();
for( Integer c : ks ) {
Service ss = conn.getServices().get(c);
if( ss != null && ss.getSERVICE_HASH() == s.getHash() ) {
ss.setSERVICE_ID(s.getId());
break;
}
}
}
conn._send(Util.hexStringToByteArray("000c08fe011800200028950130000a0c08f4c9ccf30d10c687bcb805120a0889ff5c1092e5a1b9051800220e0a0c0109080a04030507060211102a2e0a2c0d55450000157a72746d1a206ff4fdd5fa5f6d62a278a04403e075d69d734cd4880732dce8edc6a3f528089230a08a95f4cebdcc02422e0a2c0d55450000157a72746d1a20b4bd0f0096a7648de1d19042fb7a79b96c0df48eea3488f498b08ad3d38fb2cc"));
}
@Override
public void process(BattleNetPacket packet, Connection conn) throws Exception {
switch (packet.getHeader().getMethodId()) {
case 1:
processConnect(packet, conn);
break;
case 5:
// FUCK NODATA
break;
default:
log.error("Can't process weird ConnectionService method: " + packet.getHeader().getMethodId());
break;
}
}
}

View File

@ -1,29 +0,0 @@
package com.alterdekim.services;
import com.alterdekim.Connection;
import com.alterdekim.hearthhack.util.BattleNetPacket;
import com.alterdekim.hearthhack.util.Compute32;
public abstract class Service {
private final int SERVICE_HASH;
private int SERVICE_ID;
public Service( String export_name ) {
this.SERVICE_HASH = Compute32.Hash(export_name);
}
public int getSERVICEID() {
return this.SERVICE_ID;
}
public void setSERVICE_ID(int SERVICE_ID) {
this.SERVICE_ID = SERVICE_ID;
}
public int getSERVICE_HASH() {
return SERVICE_HASH;
}
public abstract void process(BattleNetPacket packet, Connection conn) throws Exception;
}