diff --git a/src/main/java/com/alterdekim/hearthhack/Application.java b/src/main/java/com/alterdekim/hearthhack/Application.java
index c0a1fda..0f25d4f 100644
--- a/src/main/java/com/alterdekim/hearthhack/Application.java
+++ b/src/main/java/com/alterdekim/hearthhack/Application.java
@@ -3,10 +3,12 @@ package com.alterdekim.hearthhack;
 
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.scheduling.annotation.EnableAsync;
 import org.springframework.scheduling.annotation.EnableScheduling;
 
 @SpringBootApplication
 @EnableScheduling
+@EnableAsync
 public class Application {
     public static void main(String[] args) {
         SpringApplication.run(Application.class, args);
diff --git a/src/main/java/com/alterdekim/hearthhack/component/GameConnection.java b/src/main/java/com/alterdekim/hearthhack/component/GameConnection.java
new file mode 100644
index 0000000..8f61526
--- /dev/null
+++ b/src/main/java/com/alterdekim/hearthhack/component/GameConnection.java
@@ -0,0 +1,94 @@
+package com.alterdekim.hearthhack.component;
+
+import com.alterdekim.PegasusGame;
+import com.alterdekim.hearthhack.util.BattleNetPacket;
+import com.alterdekim.hearthhack.util.PegasusPacket;
+import com.alterdekim.hearthhack.util.Util;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Socket;
+
+@Slf4j
+@RequiredArgsConstructor
+public class GameConnection extends Thread {
+    private final Socket client;
+    private OutputStream outToClient;
+
+    public void stopListeningAndDisconnect() {
+        log.warn("Tried to stopListening");
+    }
+
+    private void processPacket( PegasusPacket packet ) throws Exception {
+        switch (packet.getType()) {
+            case 168:
+                PegasusGame.GameSetup setup = PegasusGame.GameSetup.newBuilder()
+                        .setBoard(0)
+                        .setMaxFriendlyMinionsPerPlayer(7)
+                        .setMaxSecretsPerPlayer(5)
+                        .setKeepAliveFrequencySeconds(30)
+                        .setDisconnectWhenStuckSeconds(500)
+                        .build();
+                PegasusPacket result = new PegasusPacket(16, 0, setup);
+                this.send(result);
+                break;
+            case 1:
+                // GetGameState
+                this.sendRaw(Util.hexStringToByteArray("0AA6022AA3020A2F0801120408351001120508C6011004120408311001120508CC011002120408141001120508CA0110011204080A1055127D0802120F08C786D1BAA58080800210E7F2AC251800226608031204083210021204083510031205088F031003120508B001100A12040807104B120408311001120508CA011002120508900210011204081D10041204081C100A1204081E10021204081F10021204081710011204081110011204081B104212040818100112710801120F08C786D1BAA58080800210B59DFA241800225A08021204083210011204083510021205088F031004120508B001100A12040807104B120508CA011002120508900210011204081D10041204081C100A1204081E10011204081F10011204083110011204081110011204081B10400A180A16082212001A04083510221A04083210021A04083110020A180A16082312001A04083510231A04083210021A04083110020A180A16082412001A04083510241A04083210021A04083110020A620A60082512074558315F3539331A04083510251A04083210021A0508870210031A04083110031A0508C10210011A0508B70110021A0508DA0110011A04082D10021A04082F10041A04083010041A0508CA0110041A0508CB0110021A0508C90110030A93010A9001082612074558315F3338331A04083510261A04083210021A0508870210011A04083110031A0508FB0110011A0508C20110001A0508C10210011A0508B70110031A0508BE0110001A0508CA0210001A0508CB0210001A04082D10101A04082F10031A04087210011A04083010031A0508C70110051A0508CA0110041A0508CB0110051A0508D90110001A0508C90110030A180A16082712001A04083510271A04083210021A04083110020A180A16082812001A04083510281A04083210021A04083110020A180A16082912001A04083510291A04083210021A04083110020A180A16082A12001A040835102A1A04083210021A04083110020A180A16082B12001A040835102B1A04083210021A04083110020A180A16082C12001A040835102C1A04083210021A04083110020A180A16082D12001A040835102D1A04083210021A04083110020A180A16082E12001A040835102E1A04083210021A04083110020A180A16082F12001A040835102F1A04083210021A04083110020A180A16083012001A04083510301A04083210021A04083110020A180A16083112001A04083510311A04083210021A04083110020A180A16083212001A04083510321A04083210021A04083110020A180A16083312001A04083510331A04083210021A04083110020A180A16083412001A04083510341A04083210021A04083110020A180A16083512001A04083510351A04083210021A04083110020A490A47083612084C4F454131365F391A04083510361A04083210021A0508870210021A04083110031A04083010001A0508CA0210001A0508CB0210001A0508CA0110051A0508B70110140A180A16083712001A04083510371A04083210021A04083110020A180A16083812001A04083510381A04083210021A04083110020A180A16083912001A04083510391A04083210021A04083110020A180A16083A12001A040835103A1A04083210021A04083110020A180A16083B12001A040835103B1A04083210021A04083110020A180A16083C12001A040835103C1A04083210021A04083110020A180A16083D12001A040835103D1A04083210021A04083110020A180A16083E12001A040835103E1A04083210021A04083110020A180A16083F12001A040835103F1A04083210021A04083110020A180A16080412001A04083510041A04083210011A04083110020A180A16080512001A04083510051A04083210011A04083110020A180A16080612001A04083510061A04083210011A04083110020A180A16080712001A04083510071A04083210011A04083110020A180A16080812001A04083510081A04083210011A04083110020A180A16080912001A04083510091A04083210011A04083110020A180A16080A12001A040835100A1A04083210011A04083110020A1F0A1D080B12001A040835100B1A04083210011A0508870210041A04083110030A180A16080C12001A040835100C1A04083210011A04083110020A180A16080D12001A040835100D1A04083210011A04083110020A180A16080E12001A040835100E1A04083210011A04083110020A180A16080F12001A040835100F1A04083210011A04083110020A180A16081012001A04083510101A04083210011A04083110020A1F0A1D081112001A04083510111A04083210011A0508870210031A04083110030A180A16081212001A04083510121A04083210011A04083110020A180A16081312001A04083510131A04083210011A04083110020A180A16081412001A04083510141A04083210011A04083110020A1F0A1D081512001A04083510151A04083210011A0508870210011A04083110030A180A16081612001A04083510161A04083210011A04083110020A180A16081712001A04083510171A04083210011A04083110020A180A16081812001A04083510181A04083210011A04083110020A180A16081912001A04083510191A04083210011A04083110020A1F0A1D081A12001A040835101A1A04083210011A0508870210021A04083110030A180A16081B12001A040835101B1A04083210011A04083110020A180A16081C12001A040835101C1A04083210011A04083110020A180A16081D12001A040835101D1A04083210011A04083110020A180A16081E12001A040835101E1A04083210011A04083110020A180A16081F12001A040835101F1A04083210011A04083110020A180A16082012001A04083510201A04083210011A04083110020A180A16082112001A04083510211A04083210011A04083110020A4B0A49084212094C4F454130345F30311A04083110011A04083510421A04083210021A0508B70110141A0608FC0210E77E1A0508CA0210001A0508CB0210001A04082D101E1A0508CA0110030A5D0A5B08431208435331685F3030311A0508B90210421A04083110011A04083510431A04083210021A04083110011A0508FB0110011A0508B70110021A04083010021A0508C70110061A0508CA01100A1A0508CB0110021A0508C90110030A460A440840120B54425F5350545F426F73731A04083110011A04083510401A04083210011A04082F10001A04082D101E1A0508CA0110031A0508B70110121A0708FC0210F1B4020A5D0A5B08411208435331685F3030311A0508B90210401A04083110011A04083510411A04083210011A04083110011A0508FB0110011A0508B70110021A04083010021A0508C70110061A0508CA01100A1A0508CB0110021A0508C90110030A1F0A1D084412001A04083510441A04083210011A0508870210051A0408311003"));
+                break;
+            case 115:
+                PegasusGame.Pong pong = PegasusGame.Pong.newBuilder().build();
+                result = new PegasusPacket(116, 0, pong);
+                this.send(result);
+                break;
+            default:
+                log.info("PegasusPacket: type={}, context={}, size={}", packet.getType(), packet.getContext(), packet.getSize());
+                break;
+        }
+    }
+
+    public void send(PegasusPacket pp) throws Exception {
+        this.outToClient.write(pp.Encode());
+        this.outToClient.flush();
+    }
+
+    public void sendRaw(byte[] data) throws Exception {
+        this.outToClient.write(data);
+        this.outToClient.flush();
+    }
+
+    @Override
+    public void run() {
+        try {
+            InputStream is = client.getInputStream();
+            outToClient = client.getOutputStream();
+            while (true) {
+                try {
+                    int count;
+                    byte[] buffer = new byte[4096]; // or 4096, or more
+                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                    while ((count = is.read(buffer)) > 0) {
+                        baos.write(buffer, 0, count);
+                        byte[] r = baos.toByteArray();
+                        PegasusPacket pp = new PegasusPacket();
+                        int offset = 0;
+                        while( offset < r.length ) {
+                            offset += pp.Decode(r, offset, r.length);
+                            processPacket(pp);
+                        }
+                        baos.reset();
+                    }
+                    baos.close();
+                } catch (Exception e) {
+                    log.error(e.getMessage());
+                    break;
+                }
+            }
+        } catch (Exception e) {
+            log.error(e.getMessage());
+        }
+    }
+}
diff --git a/src/main/java/com/alterdekim/hearthhack/component/GameServer.java b/src/main/java/com/alterdekim/hearthhack/component/GameServer.java
new file mode 100644
index 0000000..5cbbb5f
--- /dev/null
+++ b/src/main/java/com/alterdekim/hearthhack/component/GameServer.java
@@ -0,0 +1,52 @@
+package com.alterdekim.hearthhack.component;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.LinkedList;
+import java.util.List;
+
+@Slf4j
+@Component
+public class GameServer {
+
+    private final int port = 3724;
+
+    private ServerSocket serverSocket;
+
+    private List<GameConnection> connections;
+
+    @Scheduled(fixedDelay = 5000)
+    private void start() {
+        try {
+            this.connections = new LinkedList<>();
+            this.serverSocket = new ServerSocket(this.port);
+            while(true) {
+                Socket client = this.serverSocket.accept();
+                log.info("New WOW Connection Established From {}", client.getInetAddress().toString());
+                GameConnection c = new GameConnection(client);
+                this.connections.add(c);
+                c.start();
+            }
+        } catch (IOException e) {
+            log.error(e.getMessage());
+        }
+    }
+
+    public void stopListening() {
+        connections.forEach(GameConnection::stopListeningAndDisconnect);
+        try {
+            serverSocket.close();
+        } catch (IOException e) {
+            log.error(e.getMessage());
+        }
+    }
+
+    public void removeConnection(TcpConnection c) {
+        connections.remove(c);
+    }
+}
diff --git a/src/main/java/com/alterdekim/hearthhack/component/TcpConnection.java b/src/main/java/com/alterdekim/hearthhack/component/TcpConnection.java
index e0ecb2e..33f8531 100644
--- a/src/main/java/com/alterdekim/hearthhack/component/TcpConnection.java
+++ b/src/main/java/com/alterdekim/hearthhack/component/TcpConnection.java
@@ -4,6 +4,7 @@ import com.alterdekim.hearthhack.component.processor.*;
 import com.alterdekim.hearthhack.util.BattleNetPacket;
 import com.alterdekim.hearthhack.util.Util;
 import lombok.Getter;
+import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 
 import javax.net.ssl.SSLSocket;
@@ -13,6 +14,7 @@ import java.io.OutputStream;
 import java.util.Map;
 
 @Slf4j
+@RequiredArgsConstructor
 public class TcpConnection extends Thread {
 
     private final SSLSocket fromClient;
@@ -24,18 +26,12 @@ public class TcpConnection extends Thread {
     @Getter
     private final Map<Integer, Processor> processors;
 
-    public TcpConnection(SSLSocket socket, Map<Integer, Processor> processors) {
-        this.fromClient = socket;
-        this.processors = processors;
-        this.start();
-    }
-
     public void stopListeningAndDisconnect() {
         log.warn("Tried to stopListening");
     }
 
     public void send(BattleNetPacket bp) throws Exception {
-        log.info("TcpConnection.send: service={}, method={}, body={}", bp.getHeader().getServiceId(), bp.getHeader().getMethodId(), Util.bytesToHex(bp.getBody()));
+        //log.info("TcpConnection.send: service={}, method={}, body={}", bp.getHeader().getServiceId(), bp.getHeader().getMethodId(), Util.bytesToHex(bp.getBody()));
         this.outToClient.write(bp.Encode());
         this.outToClient.flush();
     }
diff --git a/src/main/java/com/alterdekim/hearthhack/component/TcpServer.java b/src/main/java/com/alterdekim/hearthhack/component/TcpServer.java
index 4255f82..5a74283 100644
--- a/src/main/java/com/alterdekim/hearthhack/component/TcpServer.java
+++ b/src/main/java/com/alterdekim/hearthhack/component/TcpServer.java
@@ -44,6 +44,7 @@ public class TcpServer extends ReflectionLoader<Processor> {
                 SSLSocket s = (SSLSocket) serverSocket.accept();
                 TcpConnection c = new TcpConnection(s, this.getParsers());
                 connections.add(c);
+                c.start();
                 log.info("New Connection Established From {}", s.getInetAddress().toString());
             }
         } catch (IOException e) {
diff --git a/src/main/java/com/alterdekim/hearthhack/component/processor/ChannelSubProcessor.java b/src/main/java/com/alterdekim/hearthhack/component/processor/ChannelSubProcessor.java
new file mode 100644
index 0000000..97d6ff2
--- /dev/null
+++ b/src/main/java/com/alterdekim/hearthhack/component/processor/ChannelSubProcessor.java
@@ -0,0 +1,30 @@
+package com.alterdekim.hearthhack.component.processor;
+
+import com.alterdekim.Protocol;
+import com.alterdekim.hearthhack.component.TcpConnection;
+import com.alterdekim.hearthhack.util.BattleNetPacket;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class ChannelSubProcessor extends Processor {
+
+    public ChannelSubProcessor() {
+        this.setProcessorId(5);
+    }
+
+    @Override
+    public void process(BattleNetPacket packet, TcpConnection conn) throws Exception {
+        if( packet.getHeader().getMethodId() != 3 ) return;
+        Protocol.JoinChannelRequest request = Protocol.JoinChannelRequest.parseFrom(packet.getBody());
+        Protocol.JoinChannelResponse response = Protocol.JoinChannelResponse.newBuilder()
+                        .setObjectId(request.getObjectId())
+                        .build();
+        Protocol.Header header = generateResponse(response.getSerializedSize(), packet.getHeader().getToken(), 0, (int) packet.getHeader().getObjectId());
+        conn.send(new BattleNetPacket(header, response.toByteArray()));
+    }
+
+    @Override
+    public String getExportName() {
+        return "bnet.protocol.channel.Channel";
+    }
+}
diff --git a/src/main/java/com/alterdekim/hearthhack/component/processor/GameMasterProcessor.java b/src/main/java/com/alterdekim/hearthhack/component/processor/GameMasterProcessor.java
new file mode 100644
index 0000000..53738a3
--- /dev/null
+++ b/src/main/java/com/alterdekim/hearthhack/component/processor/GameMasterProcessor.java
@@ -0,0 +1,193 @@
+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.GameType;
+import com.alterdekim.hearthhack.util.Util;
+import com.google.protobuf.ByteString;
+import lombok.extern.slf4j.Slf4j;
+
+import java.nio.charset.StandardCharsets;
+
+import static com.alterdekim.hearthhack.util.GameUtilities.generateSmallNotification;
+
+@Slf4j
+public class GameMasterProcessor extends Processor {
+
+    public GameMasterProcessor() {
+        this.setProcessorId(8);
+    }
+
+    private void processFindGame(BattleNetPacket packet, TcpConnection conn) throws Exception {
+        // FindGameRequest FindGameResponse game_master
+        // GameType
+        Protocol.FindGameRequest gameRequest = Protocol.FindGameRequest.parseFrom(packet.getBody());
+        log.info("FindGameRequest: {}", gameRequest);
+
+        Protocol.Attribute a = gameRequest.getProperties().getCreationAttributesList().stream()
+                .filter(p -> p.hasName() && p.getName().equals("type"))
+                .findFirst()
+                .get();
+        GameType gameType = GameType.parseFromInt((int) a.getValue().getIntValue());
+        log.info("YUUUP {}", gameType);
+        if( gameType != GameType.GT_CASUAL ) return;
+        Protocol.FindGameResponse response = Protocol.FindGameResponse.newBuilder()
+                .setQueued(true)
+                .build();
+
+        Protocol.Header header = Processor.generateResponse(response.getSerializedSize(), packet.getHeader().getToken(), 0, 0);
+        conn.send(new BattleNetPacket(header, response.toByteArray()));
+
+
+        Protocol.GameFoundNotification notification = Protocol.GameFoundNotification.newBuilder()
+                .setRequestId(gameRequest.getRequestId())
+                //.setGameHandle(Protocol.GameHandle.newBuilder().setFactoryId(gameRequest.getFactoryId()))
+                .addConnectInfo(Protocol.ConnectInfo.newBuilder()
+                        .setHost("localhost")
+                        .setPort(1119)
+                        .setMemberId(Protocol.EntityId.newBuilder()
+                                .setHigh(72057594037927936L)
+                                .setLow(437154195L))
+                ).build();
+
+        // method_id = 1
+        // service = 3
+
+        header = Protocol.Header.newBuilder()
+                .setServiceId(3)
+                .setMethodId(1)
+                .setSize(notification.getSerializedSize())
+                .setToken(conn.nextToken())
+                .setObjectId(0)
+                .setStatus(0)
+                .build();
+
+        conn.send(new BattleNetPacket(header, notification.toByteArray()));
+
+
+   /*     byte[] ip = "localhost".getBytes(StandardCharsets.US_ASCII);
+        log.info("ip: {} lenhex: {}, len: {}", Util.bytesToHex(ip), Util.intToHex(ip.length), ip.length);
+        byte[] bb = Util.hexStringToByteArray("0A120900000000000000021100000000000000001212094743545702000002116739AB04000000001A08475F524553554C54221E0A0F67616D655F726571756573745F6964120B48B6D2A3C7A4FCA2E1B901220B0A056572726F7212024800222E0A0B67616D655F68616E646C65121F3A1D09F64263F5D33456C7121209EEA60D5703000006118C270B000A62A3AB22B3010A0F636F6E6E656374696F6E5F696E666F129F013A9C010A12094743545702000002116739AB040000000012"+Util.intToHex(ip.length)+Util.bytesToHex(ip)+"188C1D2206456A634465492A130A0776657273696F6E12082A0665694B3271762A0D0A0467616D65120518AA80C4062A0C0A06706C61796572120218012A0B0A026964120518B2B0AA1C2A0F0A09726573756D61626C65120210012A1E0A12737065637461746F725F70617373776F726412082A066F44697049664A0A0895A56710E9E6ACB90552150A050D93710E1A120C0D6739AB0415474354571802");
+
+        header = Protocol.Header.newBuilder()
+                .setServiceId(4)
+                .setMethodId(1)
+                .setSize(bb.length)
+                .setToken(conn.nextToken())
+                .setObjectId(0)
+                .setStatus(0)
+                .build();
+
+        conn.send(new BattleNetPacket(header, bb));
+
+        Protocol.Notification n = Protocol.Notification.parseFrom(bb);
+        Protocol.ConnectInfo ci = Protocol.ConnectInfo.parseFrom(
+                n.getAttributeList().stream().filter(p -> p.hasName() && p.getName().equals("connection_info")).findFirst().get().getValue().getMessageValue()
+        );
+        log.info("GGGG: {}", ci);*/
+
+        Protocol.Notification n1 = Protocol.Notification.newBuilder()
+                .setType("G_RESULT")
+                .setSenderId(Protocol.EntityId.newBuilder()
+                        .setLow(0)
+                        .setHigh(144115188075855872L))
+                .setTargetId(Protocol.EntityId.newBuilder()
+                        .setLow(78330215L)
+                        .setHigh(144115198130930503L))
+                .addAttribute(Protocol.Attribute.newBuilder()
+                        .setName("game_request_id")
+                        .setValue(
+                                Protocol.Variant.newBuilder()
+                                        .setUintValue(1338541484650062879L * 10L)
+                        )
+                )
+                .addAttribute(Protocol.Attribute.newBuilder()
+                        .setName("game_handle")
+                        .setValue(
+                                Protocol.Variant.newBuilder()
+                                        .setMessageValue(
+                                            Protocol.GameHandle.newBuilder()
+                                                    .setFactoryId( (143637261465044426L * 100L) + 14L )
+                                                    .setGameId(Protocol.EntityId.newBuilder()
+                                                            .setHigh(432345578572981998L)
+                                                            .setLow((123678367967794400L * 100L) + 12L))
+                                                    .build()
+                                                    .toByteString()
+                                        )
+                        )
+                )
+                .addAttribute(Protocol.Attribute.newBuilder()
+                        .setName("connection_info")
+                        .setValue(
+                                Protocol.Variant.newBuilder()
+                                        .setMessageValue(
+                                            Protocol.ConnectInfo.newBuilder()
+                                                    .setMemberId(Protocol.EntityId.newBuilder()
+                                                            .setHigh(144115198130930503L)
+                                                            .setLow(78330215L)
+                                                    )
+                                                    .setHost("192.168.0.9")
+                                                    .setPort(3724)
+                                                    .setToken(ByteString.copyFromUtf8("EjcDeI"))
+                                                    .addAttribute(Protocol.Attribute
+                                                            .newBuilder()
+                                                            .setName("version")
+                                                            .setValue(Protocol.Variant.newBuilder().setStringValue("eiK2qv")))
+                                                    .addAttribute(Protocol.Attribute
+                                                            .newBuilder()
+                                                            .setName("game")
+                                                            .setValue(Protocol.Variant.newBuilder().setIntValue(13697066L)))
+                                                    .addAttribute(Protocol.Attribute
+                                                            .newBuilder()
+                                                            .setName("player")
+                                                            .setValue(Protocol.Variant.newBuilder().setIntValue(1L)))
+                                                    .addAttribute(Protocol.Attribute
+                                                            .newBuilder()
+                                                            .setName("id")
+                                                            .setValue(Protocol.Variant.newBuilder().setIntValue(59414578L)))
+                                                    .addAttribute(Protocol.Attribute
+                                                            .newBuilder()
+                                                            .setName("resumable")
+                                                            .setValue(Protocol.Variant.newBuilder().setBoolValue(true)))
+                                                    .addAttribute(Protocol.Attribute
+                                                            .newBuilder()
+                                                            .setName("spectator_password")
+                                                            .setValue(Protocol.Variant.newBuilder().setStringValue("oDipIf")))
+                                                    .build().toByteString()
+                                        )
+                        )
+                )
+                .addAttribute(Protocol.Attribute.newBuilder()
+                        .setName("error")
+                        .setValue(
+                                Protocol.Variant.newBuilder()
+                                        .setUintValue(0)
+                        )
+                ).build();
+
+        header = Protocol.Header.newBuilder()
+                .setServiceId(4)
+                .setMethodId(1)
+                .setSize(n1.getSerializedSize())
+                .setToken(conn.nextToken())
+                .setObjectId(0)
+                .setStatus(0)
+                .build();
+
+        conn.send(new BattleNetPacket(header, n1.toByteArray()));
+    }
+
+    @Override
+    public void process(BattleNetPacket packet, TcpConnection conn) throws Exception {
+        switch(packet.getHeader().getMethodId()) {
+            case 3 -> processFindGame(packet, conn);
+            default -> log.info("Weird method id: {}", packet.getHeader().getMethodId());
+        }
+    }
+
+    @Override
+    public String getExportName() {
+        return "bnet.protocol.channel_invitation.ChannelInvitationService";
+    }
+}
diff --git a/src/main/java/com/alterdekim/hearthhack/component/processor/GameUtilitiesProcessor.java b/src/main/java/com/alterdekim/hearthhack/component/processor/GameUtilitiesProcessor.java
index 4f05b04..c05c630 100644
--- a/src/main/java/com/alterdekim/hearthhack/component/processor/GameUtilitiesProcessor.java
+++ b/src/main/java/com/alterdekim/hearthhack/component/processor/GameUtilitiesProcessor.java
@@ -90,7 +90,7 @@ public class GameUtilitiesProcessor extends Processor {
         ClientRequestBody p = parseClientRequest(cr);
         int type = p != null ? p.getType() : 0;
 
-        if( type != 314 && type != 255 ) {
+        if( type != 314 && type != 255 && type != 214 ) {
             Protocol.GenericResponse genericResponse = Protocol.GenericResponse
                     .newBuilder()
                     .setRequestId(type)
diff --git a/src/main/java/com/alterdekim/hearthhack/component/processor/PresenceProcessor.java b/src/main/java/com/alterdekim/hearthhack/component/processor/PresenceProcessor.java
index fcba44f..1823af7 100644
--- a/src/main/java/com/alterdekim/hearthhack/component/processor/PresenceProcessor.java
+++ b/src/main/java/com/alterdekim/hearthhack/component/processor/PresenceProcessor.java
@@ -43,8 +43,8 @@ public class PresenceProcessor extends Processor {
                             .setStatus(0)
                             .build();
                     // FIRST
-                    /*Protocol.AddNotification addNotification = Protocol.AddNotification.parseFrom(Util.hexStringToByteArray("1A71AA066E0A120900000000000000011193710E1A0000000012190A170A0A08CE84011001180620001209189AB1D8B499BCCC02121A0A180A0A08CE8401100118012000120A2A086A6F686E20626F6E12210A1F0A0A08CE840110011804200012112A0F517569726B794F7263233239363838"));
-                    System.out.println(addNotification);*/
+                    Protocol.AddNotification addNotification = Protocol.AddNotification.parseFrom(Util.hexStringToByteArray("1A71AA066E0A120900000000000000011193710E1A0000000012190A170A0A08CE84011001180620001209189AB1D8B499BCCC02121A0A180A0A08CE8401100118012000120A2A086A6F686E20626F6E12210A1F0A0A08CE840110011804200012112A0F517569726B794F7263233239363838"));
+                    //log.info("AddNotification: {}", addNotification);
 
                     //System.out.println(Util.bytesToHex(bb));
 
@@ -85,15 +85,17 @@ public class PresenceProcessor extends Processor {
                 }
                 break;
             case 3:
+                header = Processor.generateResponse(0, packet.getHeader().getToken(), 0, 0);
+                conn.send(new BattleNetPacket(header, new byte[0]));
                 if( packet.getHeader().getToken() == 12 ) {
                   /*  Protocol.Header header1 = Processor.generateResponse(0, packet.getHeader().getToken(), 0, 0);
                     conn.send(new BattleNetPacket(header1, new byte[0]));*/
                     conn.sendRaw(Util.hexStringToByteArray("000c08fe011800200028950130000a0c08f4c9ccf30d10c687bcb805120a0889ff5c1092e5a1b9051800220e0a0c0109080a04030507060211102a2e0a2c0d55450000157a72746d1a206ff4fdd5fa5f6d62a278a04403e075d69d734cd4880732dce8edc6a3f528089230a08a95f4cebdcc02422e0a2c0d55450000157a72746d1a20b4bd0f0096a7648de1d19042fb7a79b96c0df48eea3488f498b08ad3d38fb2cc"));
                 } else if( packet.getHeader().getToken() == 13 ) {
-                    Protocol.Header header1 = Processor.generateResponse(0, packet.getHeader().getToken(), 0, 0);
-                    conn.send(new BattleNetPacket(header1, new byte[0]));
+                   /* Protocol.Header header1 = Processor.generateResponse(0, packet.getHeader().getToken(), 0, 0);
+                    conn.send(new BattleNetPacket(header1, new byte[0]));*/
 
-                    header1 = Protocol.Header.newBuilder()
+                    Protocol.Header header1 = Protocol.Header.newBuilder()
                             .setServiceId(5)
                             .setMethodId(6)
                             .setToken(conn.nextToken())
@@ -104,12 +106,12 @@ public class PresenceProcessor extends Processor {
 
                     conn.send(new BattleNetPacket(header1, Util.hexStringToByteArray("1233AA06300A12094743545702000002116739AB0400000000121A0A180A0A08C786D1BA0510021813120A2A083833383836303830")));
                 } else if( packet.getHeader().getToken() == 18 ) {
-                    Protocol.Header header1 = Processor.generateResponse(0, packet.getHeader().getToken(), 0, 0);
-                    conn.send(new BattleNetPacket(header1, new byte[0]));
+                   /* Protocol.Header header1 = Processor.generateResponse(0, packet.getHeader().getToken(), 0, 0);
+                    conn.send(new BattleNetPacket(header1, new byte[0]));*/
 
                     byte[] b = Util.hexStringToByteArray("122BAA06280A12094743545702000002116739AB040000000012120A100A0A08C786D1BA051002180112021000");
 
-                    header1 = Protocol.Header.newBuilder()
+                    Protocol.Header header1 = Protocol.Header.newBuilder()
                             .setServiceId(5)
                             .setMethodId(6)
                             .setToken(conn.nextToken())
@@ -134,8 +136,8 @@ public class PresenceProcessor extends Processor {
                     conn.send(new BattleNetPacket(header, b));
 
                 } else if( packet.getHeader().getToken() == 26 ) {
-                    Protocol.Header header1 = Processor.generateResponse(0, packet.getHeader().getToken(), 0, 0);
-                    conn.send(new BattleNetPacket(header1, new byte[0]));
+                   /* Protocol.Header header1 = Processor.generateResponse(0, packet.getHeader().getToken(), 0, 0);
+                    conn.send(new BattleNetPacket(header1, new byte[0]));*/
 
                     byte[] b = Util.hexStringToByteArray("1231AA062E0A12094743545702000002116739AB040000000012180A160A0A08C786D1BA051002181212083206190000190000");
 
@@ -153,7 +155,7 @@ public class PresenceProcessor extends Processor {
                     byte[] b = Util.hexStringToByteArray("0D5545000015737368001A20BEC5292231D7686AF00CE64E0C58CC6E360EA950AAFFAC6A114F03A958E275F3");
 
                     Protocol.Header header1 = Processor.generateResponse(b.length, packet.getHeader().getToken(), 0, 0);
-                    conn.send(new BattleNetPacket(header1, b));
+                    //conn.send(new BattleNetPacket(header1, b));
 
                     b = Util.hexStringToByteArray("1230AA062D0A12094743545702000002116739AB040000000012170A150A0A08C786D1BA0510021811120732050103000000");
 
@@ -170,12 +172,12 @@ public class PresenceProcessor extends Processor {
                     byte[] b = Util.hexStringToByteArray("0D5545000015737368001A20BEC5292231D7686AF00CE64E0C58CC6E360EA950AAFFAC6A114F03A958E275F3");
 
                     Protocol.Header header1 = Processor.generateResponse(b.length, packet.getHeader().getToken(), 0, 0);
-                    conn.send(new BattleNetPacket(header1, b));
+                   // conn.send(new BattleNetPacket(header1, b));
                 } else if( packet.getHeader().getToken() == 36 ) {
                     byte[] b = Util.hexStringToByteArray("0A090A026964120318C6020A120A0570726F746F12093207080110C9011806");
 
                     Protocol.Header header1 = Processor.generateResponse(b.length, packet.getHeader().getToken(), 0, 0);
-                    conn.send(new BattleNetPacket(header1, b));
+                   // conn.send(new BattleNetPacket(header1, b));
 
                     b = Util.hexStringToByteArray("0A120900000000000000021100000000000000001212094743545702000002116739AB04000000001A1C575443472E5574696C4E6F74696669636174696F6E4D65737361676522130A0C6D6573736167655F74797065120318E00122120A0C6D6573736167655F73697A65120218002A1209000000000000000111000000000000000032120900000000000000011193710E1A000000003A004A0A0889FF5C1092E5A1B90552150A050D93710E1A120C0D6739AB0415474354571802");
 
diff --git a/src/main/java/com/alterdekim/hearthhack/component/processor/client/request/GetDeck.java b/src/main/java/com/alterdekim/hearthhack/component/processor/client/request/GetDeck.java
new file mode 100644
index 0000000..e8dd3bb
--- /dev/null
+++ b/src/main/java/com/alterdekim/hearthhack/component/processor/client/request/GetDeck.java
@@ -0,0 +1,96 @@
+package com.alterdekim.hearthhack.component.processor.client.request;
+
+import com.alterdekim.Protocol;
+import com.alterdekim.hearthhack.component.TcpConnection;
+import com.alterdekim.hearthhack.component.processor.Processor;
+import com.alterdekim.hearthhack.util.BattleNetPacket;
+import com.alterdekim.hearthhack.util.ClientRequestBody;
+import com.alterdekim.hearthhack.util.Util;
+import com.google.protobuf.ByteString;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static com.alterdekim.hearthhack.util.GameUtilities.generateNotification;
+
+@Slf4j
+public class GetDeck extends ClientRequestParser {
+    @Override
+    public void parse(BattleNetPacket packet, ClientRequestBody body, TcpConnection conn) throws Exception {
+        Protocol.GetDeckContents request = Protocol.GetDeckContents.parseFrom(body.getBody());
+
+        List<Protocol.DeckCardData> ddl = new ArrayList<>();
+        for( int i = 0; i < 10; i++ ) {
+            ddl.add(Protocol.DeckCardData.newBuilder()
+                    .setDef(Protocol.CardDef.newBuilder().setAsset(242)).setHandle(0).setQty(2).setPrev(0).build());
+        }
+        for( int i = 0; i < 10; i++ ) {
+            ddl.add(Protocol.DeckCardData.newBuilder()
+                    .setDef(Protocol.CardDef.newBuilder().setAsset(670)).setHandle(0).setQty(2).setPrev(0).build());
+        }
+        for( int i = 0; i < 5; i++ ) {
+            ddl.add(Protocol.DeckCardData.newBuilder()
+                    .setDef(Protocol.CardDef.newBuilder().setAsset(555)).setHandle(0).setQty(2).setPrev(0).build());
+        }
+        for( int i = 0; i < 5; i++ ) {
+            ddl.add(Protocol.DeckCardData.newBuilder()
+                    .setDef(Protocol.CardDef.newBuilder().setAsset(289)).setHandle(0).setQty(2).setPrev(0).build());
+        }
+        Protocol.GetDeckContentsResponse.Builder deckContentsResponse = Protocol.GetDeckContentsResponse.newBuilder();
+
+        for( long id : request.getDeckIdList() ) {
+            log.info("DeckId: {}", id);
+            deckContentsResponse.addDecks(
+                    Protocol.DeckContents.newBuilder()
+                    .setSuccess(true)
+                    .setDeckId(id)
+                    .addAllCards(ddl)
+            );
+        }
+
+      //  Protocol.GetDeckContentsResponse dd = deckContentsResponse.build();
+
+      //  Protocol.Notification n = generateNotification(215,
+       //         dd.toByteString(),
+       //         dd.getSerializedSize());
+
+     /*   Protocol.Header header = Protocol.Header.newBuilder()
+                .setServiceId(4)
+                .setMethodId(1)
+                .setToken(conn.nextToken())
+                .setObjectId(0)
+                .setSize(n.getSerializedSize())
+                .setStatus(0)
+                .build();*/
+
+     //   conn.send(new BattleNetPacket(header, n.toByteArray()));
+
+
+        /////////////////////
+
+        byte[] bb = Util.hexStringToByteArray("08CFED81FB02120D0A05089E051000100018022800120D0A0508AB041000100018022800120C0A04084D1000100018022800120D0A0508FB041000100018022800120D0A0508A1021000100018022800120D0A0508BB021000100018022800120D0A05089C021000100018022800120D0A0508BF011000100018022800120D0A0508DA0A1000100018022800120D0A0508BF031000100018022800120D0A0508960D1000100018022800120D0A0508F90A1000100018022800120D0A0508D8011000100018022800120D0A0508D90A1000100018022800120D0A0508B40410001000180228001AE801080110CFED81FB021A0D0A05089E0510001000180228001A0D0A0508AB0410001000180228001A0C0A04084D10001000180228001A0D0A0508FB0410001000180228001A0D0A0508A10210001000180228001A0D0A0508BB0210001000180228001A0D0A05089C0210001000180228001A0D0A0508BF0110001000180228001A0D0A0508DA0A10001000180228001A0D0A0508BF0310001000180228001A0D0A0508960D10001000180228001A0D0A0508F90A10001000180228001A0D0A0508D80110001000180228001A0D0A0508D90A10001000180228001A0D0A0508B40410001000180228001AE801080110969787FB021A0D0A0508EB0710001000180228001A0D0A0508DE0410001000180228001A0D0A0508970810001000180228001A0C0A04084310001000180228001A0D0A0508970D10001000180228001A0D0A0508D30210001000180228001A0D0A0508880510001000180228001A0D0A05089D0310001000180228001A0D0A0508810210001000180228001A0D0A0508DA0A10001000180228001A0D0A0508F90A10001000180228001A0D0A0508A40210001000180228001A0D0A0508D80110001000180228001A0D0A0508ED0610001000180228001A0D0A0508D90A1000100018022800");
+
+
+        Protocol.ClientResponse clResponse = Protocol.ClientResponse.newBuilder()
+                .addAttribute(Protocol.Attribute.newBuilder()
+                        .setName("id")
+                        .setValue(Protocol.Variant.newBuilder()
+                                .setIntValue(215)
+                        ))
+                .addAttribute(Protocol.Attribute.newBuilder()
+                        .setName("proto")
+                        .setValue(Protocol.Variant.newBuilder()
+                                .setBlobValue(ByteString.copyFrom(bb))
+                        ))
+                .build();
+
+        Protocol.Header header = Processor.generateResponse(clResponse.getSerializedSize(), packet.getHeader().getToken(), 0, 0);
+        conn.send(new BattleNetPacket(header, clResponse.toByteArray()));
+    }
+
+    @Override
+    public int getId() {
+        return 214;
+    }
+}
diff --git a/src/main/java/com/alterdekim/hearthhack/component/processor/client/request/generic/AvailableFeatures.java b/src/main/java/com/alterdekim/hearthhack/component/processor/client/request/generic/AvailableFeatures.java
index 06bb74c..a60e395 100644
--- a/src/main/java/com/alterdekim/hearthhack/component/processor/client/request/generic/AvailableFeatures.java
+++ b/src/main/java/com/alterdekim/hearthhack/component/processor/client/request/generic/AvailableFeatures.java
@@ -3,17 +3,20 @@ package com.alterdekim.hearthhack.component.processor.client.request.generic;
 import com.alterdekim.Protocol;
 import com.alterdekim.hearthhack.component.TcpConnection;
 import com.alterdekim.hearthhack.util.BattleNetPacket;
-import com.alterdekim.hearthhack.util.GetAccountInfoRequest;
+import lombok.AllArgsConstructor;
+import lombok.RequiredArgsConstructor;
+import lombok.Setter;
 import lombok.extern.slf4j.Slf4j;
 
 import static com.alterdekim.hearthhack.util.GameUtilities.generateNotification;
 import static com.alterdekim.hearthhack.util.GetAccountInfoRequest.FEATURES;
-import static com.alterdekim.hearthhack.util.Util.setInterval;
 
 @Slf4j
 public class AvailableFeatures extends GenericParser {
 
-    private void executeFeatures(TcpConnection conn) {
+    private Executor executor;
+
+    private void executeFeatures(TcpConnection conn) throws Exception {
         Protocol.GuardianVars guardianVars = Protocol.GuardianVars.newBuilder()
                 .setShowUserUi(1)
                 .setClientOptionsUpdateIntervalSeconds(300)
@@ -30,20 +33,38 @@ public class AvailableFeatures extends GenericParser {
                 .setSize(n.getSerializedSize())
                 .build();
 
-        try {
-            conn.send(new BattleNetPacket(header, n.toByteArray()));
-        } catch (Exception e) {
-            log.error(e.getMessage());
-        }
+        conn.send(new BattleNetPacket(header, n.toByteArray()));
     }
 
     @Override
     public void parseGenericRequest(int token, TcpConnection conn) throws Exception {
-        setInterval(() -> executeFeatures(conn), 4000);
+        if( this.executor != null ) this.executor.setRunning(false);
+        this.executor = new Executor(conn);
+        this.executor.start();
     }
 
     @Override
     public int getId() {
         return FEATURES.getValue();
     }
+
+    @RequiredArgsConstructor
+    private class Executor extends Thread {
+
+        private final TcpConnection conn;
+        @Setter
+        private boolean isRunning = true;
+
+        @Override
+        public void run() {
+            try {
+                while(isRunning) {
+                    Thread.sleep(2500);
+                    executeFeatures(conn);
+                }
+            } catch (Exception e) {
+                log.error(e.getMessage());
+            }
+        }
+    }
 }
diff --git a/src/main/java/com/alterdekim/hearthhack/component/processor/client/request/generic/Boosters.java b/src/main/java/com/alterdekim/hearthhack/component/processor/client/request/generic/Boosters.java
index 77a292f..8d689bc 100644
--- a/src/main/java/com/alterdekim/hearthhack/component/processor/client/request/generic/Boosters.java
+++ b/src/main/java/com/alterdekim/hearthhack/component/processor/client/request/generic/Boosters.java
@@ -6,14 +6,16 @@ import com.alterdekim.hearthhack.util.BattleNetPacket;
 import com.alterdekim.hearthhack.util.GetAccountInfoRequest;
 
 import static com.alterdekim.hearthhack.util.GameUtilities.generateEmptyNotification;
+import static com.alterdekim.hearthhack.util.GameUtilities.generateNotification;
 import static com.alterdekim.hearthhack.util.GetAccountInfoRequest.BOOSTERS;
 
 public class Boosters extends GenericParser {
     @Override
     public void parseGenericRequest(int token, TcpConnection conn) throws Exception {
-        //Protocol.BoosterList boosterList = Protocol.BoosterList.newBuilder().build();
+        Protocol.BoosterList boosterList = Protocol.BoosterList.newBuilder()
+                .build();
 
-        Protocol.Notification n = generateEmptyNotification(224);
+        Protocol.Notification n = generateNotification(224, boosterList.toByteString(), boosterList.getSerializedSize());
 
         Protocol.Header header = Protocol.Header.newBuilder()
                 .setServiceId(4)
diff --git a/src/main/java/com/alterdekim/hearthhack/component/processor/client/request/generic/PlayQueue.java b/src/main/java/com/alterdekim/hearthhack/component/processor/client/request/generic/PlayQueue.java
new file mode 100644
index 0000000..e24af6a
--- /dev/null
+++ b/src/main/java/com/alterdekim/hearthhack/component/processor/client/request/generic/PlayQueue.java
@@ -0,0 +1,39 @@
+package com.alterdekim.hearthhack.component.processor.client.request.generic;
+
+import com.alterdekim.Protocol;
+import com.alterdekim.hearthhack.component.TcpConnection;
+import com.alterdekim.hearthhack.util.BattleNetPacket;
+import com.alterdekim.hearthhack.util.GetAccountInfoRequest;
+import lombok.extern.slf4j.Slf4j;
+
+import static com.alterdekim.hearthhack.util.GameUtilities.generateNotification;
+import static com.alterdekim.hearthhack.util.GetAccountInfoRequest.PVP_QUEUE;
+
+@Slf4j
+public class PlayQueue extends GenericParser {
+    @Override
+    public void parseGenericRequest(int token, TcpConnection conn) throws Exception {
+        Protocol.PlayQueue playQueue = Protocol.PlayQueue.newBuilder()
+                .setQueue(Protocol.PlayQueueInfo.newBuilder()
+                        .setGameType(Protocol.BnetGameType.BGT_RANKED_STANDARD))
+                .build();
+
+        Protocol.Notification n = generateNotification(286, playQueue.toByteString(), playQueue.getSerializedSize());
+
+        Protocol.Header header = Protocol.Header.newBuilder()
+                .setServiceId(4)
+                .setMethodId(1)
+                .setToken(conn.nextToken())
+                .setObjectId(0)
+                .setSize(n.getSerializedSize())
+                .setStatus(0)
+                .build();
+
+        conn.send(new BattleNetPacket(header, n.toByteArray()));
+    }
+
+    @Override
+    public int getId() {
+        return PVP_QUEUE.getValue();
+    }
+}
diff --git a/src/main/java/com/alterdekim/hearthhack/component/processor/client/request/generic/ProfileNotices.java b/src/main/java/com/alterdekim/hearthhack/component/processor/client/request/generic/ProfileNotices.java
index 19b98c6..4d44564 100644
--- a/src/main/java/com/alterdekim/hearthhack/component/processor/client/request/generic/ProfileNotices.java
+++ b/src/main/java/com/alterdekim/hearthhack/component/processor/client/request/generic/ProfileNotices.java
@@ -4,15 +4,26 @@ import com.alterdekim.Protocol;
 import com.alterdekim.hearthhack.component.TcpConnection;
 import com.alterdekim.hearthhack.util.BattleNetPacket;
 import com.alterdekim.hearthhack.util.GetAccountInfoRequest;
+import lombok.AllArgsConstructor;
+import lombok.RequiredArgsConstructor;
+import lombok.Setter;
+import lombok.extern.slf4j.Slf4j;
 
 import static com.alterdekim.hearthhack.util.GameUtilities.generateEmptyNotification;
+import static com.alterdekim.hearthhack.util.GameUtilities.generateNotification;
 import static com.alterdekim.hearthhack.util.GetAccountInfoRequest.NOTICES;
 
+
+@Slf4j
 public class ProfileNotices extends GenericParser {
-    @Override
-    public void parseGenericRequest(int token, TcpConnection conn) throws Exception {
-        // Protocol.ProfileNotices
-        Protocol.Notification n = generateEmptyNotification(212);
+
+    private Executor executor;
+
+    private void sendNotices(TcpConnection conn) throws Exception {
+        Protocol.ProfileNotices notices = Protocol.ProfileNotices.newBuilder()
+                .build();
+
+        Protocol.Notification n = generateNotification(212, notices.toByteString(), notices.getSerializedSize());
 
         Protocol.Header header = Protocol.Header.newBuilder()
                 .setServiceId(4)
@@ -26,8 +37,36 @@ public class ProfileNotices extends GenericParser {
         conn.send(new BattleNetPacket(header, n.toByteArray()));
     }
 
+    @Override
+    public void parseGenericRequest(int token, TcpConnection conn) throws Exception {
+        if( this.executor != null ) this.executor.setRunning(false);
+        this.executor = new Executor(conn);
+        this.executor.start();
+    }
+
     @Override
     public int getId() {
         return NOTICES.getValue();
     }
+
+
+    @RequiredArgsConstructor
+    private class Executor extends Thread {
+
+        private final TcpConnection conn;
+        @Setter
+        private boolean isRunning = true;
+
+        @Override
+        public void run() {
+            try {
+                while(isRunning) {
+                    Thread.sleep(7500);
+                    sendNotices(conn);
+                }
+            } catch (Exception e) {
+                log.error(e.getMessage());
+            }
+        }
+    }
 }
diff --git a/src/main/java/com/alterdekim/hearthhack/util/GameType.java b/src/main/java/com/alterdekim/hearthhack/util/GameType.java
new file mode 100644
index 0000000..74fbf5d
--- /dev/null
+++ b/src/main/java/com/alterdekim/hearthhack/util/GameType.java
@@ -0,0 +1,42 @@
+package com.alterdekim.hearthhack.util;
+
+public enum GameType {
+    // Token: 0x04000710 RID: 1808
+    GT_UNKNOWN,
+    // Token: 0x04000711 RID: 1809
+    GT_VS_AI,
+    // Token: 0x04000712 RID: 1810
+    GT_VS_FRIEND,
+    // Token: 0x04000713 RID: 1811
+    GT_TUTORIAL, // =4
+    // Token: 0x04000714 RID: 1812
+    GT_ARENA,
+    // Token: 0x04000715 RID: 1813
+    GT_TEST,
+    // Token: 0x04000716 RID: 1814
+    GT_RANKED,
+    // Token: 0x04000717 RID: 1815
+    GT_CASUAL,
+    // Token: 0x04000719 RID: 1817
+    GT_TB_1P_VS_AI,
+    // Token: 0x0400071A RID: 1818
+    GT_TB_2P_COOP,
+    // Token: 0x0400071B RID: 1819
+    GT_LAST;
+
+    /*
+        // Token: 0x04000718 RID: 1816
+    GT_TAVERNBRAWL, // = 16
+     */
+
+    public int getValue() {
+        return ordinal() + 3;
+    }
+
+    public static GameType parseFromInt(long val) {
+        for( GameType r : values() ) {
+            if( r.getValue() == val ) return r;
+        }
+        return GT_LAST;
+    }
+}
diff --git a/src/main/java/com/alterdekim/hearthhack/util/GameUtilities.java b/src/main/java/com/alterdekim/hearthhack/util/GameUtilities.java
index 284b5ab..3f1f4ca 100644
--- a/src/main/java/com/alterdekim/hearthhack/util/GameUtilities.java
+++ b/src/main/java/com/alterdekim/hearthhack/util/GameUtilities.java
@@ -35,6 +35,16 @@ public class GameUtilities {
                 .build();
     }
 
+    public static Protocol.Notification.Builder generateSmallNotification() {
+        return Protocol.Notification.newBuilder()
+                .setSenderId(Protocol.EntityId.newBuilder()
+                        .setHigh(144115188075855872L)
+                        .setLow(0))
+                .setTargetId(Protocol.EntityId.newBuilder()
+                        .setHigh(144115198130930503L)
+                        .setLow(78330215));
+    }
+
     public static Protocol.Notification generateEmptyNotification(int message_type) {
         return Protocol.Notification.newBuilder()
                 .setSenderId(Protocol.EntityId.newBuilder()
diff --git a/src/main/java/com/alterdekim/hearthhack/util/PegasusPacket.java b/src/main/java/com/alterdekim/hearthhack/util/PegasusPacket.java
index cf68bb2..fa888f5 100644
--- a/src/main/java/com/alterdekim/hearthhack/util/PegasusPacket.java
+++ b/src/main/java/com/alterdekim/hearthhack/util/PegasusPacket.java
@@ -1,8 +1,12 @@
 package com.alterdekim.hearthhack.util;
 
 import com.google.protobuf.GeneratedMessageV3;
+import lombok.Getter;
 import lombok.NoArgsConstructor;
 
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
 @NoArgsConstructor
 public class PegasusPacket {
 
@@ -10,12 +14,16 @@ public class PegasusPacket {
 
     private final int SIZE_BYTES = 4;
 
+    @Getter
     public int size;
 
+    @Getter
     public int type;
 
+    @Getter
     public int context;
 
+    @Getter
     public Object body;
 
     private boolean sizeRead;
@@ -79,21 +87,28 @@ public class PegasusPacket {
         return num2;
     }
 
-   /* public byte[] Encode() {
+    public byte[] Encode() {
         if (this.body instanceof GeneratedMessageV3) {
             GeneratedMessageV3 protoBuf = (GeneratedMessageV3) this.body;
-            this.size = (int) protoBuf.GetSerializedSize();
+            this.size = protoBuf.getSerializedSize();
             byte[] array = new byte[this.size + 4 + 4];
-            Array.Copy(BitConverter.GetBytes(this.Type), 0, array, 0, 4);
-            Array.Copy(BitConverter.GetBytes(this.Size), 0, array, 4, 4);
-            protoBuf.Serialize(new MemoryStream(array, 8, this.Size));
+            System.arraycopy(getBytes(this.type), 0, array, 0, 4);
+            System.arraycopy(getBytes(this.size), 0, array, 4, 4);
+            System.arraycopy(protoBuf.toByteArray(), 0, array, 8, this.size);
             return array;
         }
         return null;
-    }*/
+    }
 
     private int toInt32_2(byte[] bytes, int index) {
         int a = (int)((int)(0xff & bytes[index]) << 32 | (int)(0xff & bytes[index + 1]) << 40 | (int)(0xff & bytes[index + 2]) << 48 | (int)(0xff & bytes[index + 3]) << 56);
         return a;
     }
+
+    private static byte[] getBytes(int value) {
+        return ByteBuffer.allocate(4)
+                .order(ByteOrder.nativeOrder())
+                .putInt(value)
+                .array();
+    }
 }
diff --git a/src/main/java/com/alterdekim/hearthhack/util/Util.java b/src/main/java/com/alterdekim/hearthhack/util/Util.java
index 9799b49..58d6f8d 100644
--- a/src/main/java/com/alterdekim/hearthhack/util/Util.java
+++ b/src/main/java/com/alterdekim/hearthhack/util/Util.java
@@ -137,17 +137,4 @@ public class Util {
         String s = Integer.toHexString(i).toUpperCase();
         return s.length() % 2 == 0 ? s : "0" + s;
     }
-
-    public static void setInterval(Runnable runnable, int interval) {
-        new Thread(() -> {
-            try {
-                while(true) {
-                    Thread.sleep(interval);
-                    runnable.run();
-                }
-            } catch (Exception e){
-                log.error(e.getMessage());
-            }
-        }).start();
-    }
 }
diff --git a/src/main/proto/bnet/protocol/protocol.proto b/src/main/proto/bnet/protocol/protocol.proto
index 9c83285..3f96391 100644
--- a/src/main/proto/bnet/protocol/protocol.proto
+++ b/src/main/proto/bnet/protocol/protocol.proto
@@ -3173,4 +3173,79 @@ message PurchaseError {
 	required Error error = 1;
 	optional string purchase_in_progress = 2;
 	optional string error_code = 3;
+}
+
+// ref: PegasusUtil.PlayQueue
+message PlayQueue {
+	// ref: PegasusUtil.PlayQueue/PacketID
+	enum PacketID {
+		ID = 286;
+	}
+
+	required PlayQueueInfo queue = 1;
+}
+
+// ref: PegasusShared.PlayQueueInfo
+message PlayQueueInfo {
+	required BnetGameType game_type = 1;
+}
+
+// ref: PegasusShared.BnetGameType
+enum BnetGameType {
+	BGT_UNKNOWN = 0;
+	BGT_FRIENDS = 1;
+	BGT_RANKED_STANDARD = 2;
+	BGT_ARENA = 3;
+	BGT_VS_AI = 4;
+	BGT_TUTORIAL = 5;
+	BGT_ASYNC = 6;
+	BGT_NEWBIE = 9;
+	BGT_CASUAL_STANDARD = 10;
+	BGT_TEST1 = 11;
+	BGT_TEST2 = 12;
+	BGT_TEST3 = 13;
+	BGT_TAVERNBRAWL_PVP = 16;
+	BGT_TAVERNBRAWL_1P_VERSUS_AI = 17;
+	BGT_TAVERNBRAWL_2P_COOP = 18;
+	BGT_RANKED_WILD = 30;
+	BGT_CASUAL_WILD = 31;
+	BGT_LAST = 32;
+}
+
+// ref: PegasusUtil.GetDeckContents
+message GetDeckContents {
+	// ref: PegasusUtil.GetDeckContents/PacketID
+	enum PacketID {
+		system = 0;
+		ID = 214;
+	}
+
+	repeated int64 deck_id = 1;
+}
+
+// ref: PegasusUtil.GetDeckContentsResponse
+message GetDeckContentsResponse {
+	// ref: PegasusUtil.GetDeckContentsResponse/PacketID
+	enum PacketID {
+		ID = 215;
+	}
+
+	optional int64 deprecated_deck_id = 1;
+	repeated DeckCardData deprecated_cards = 2;
+	repeated DeckContents decks = 3;
+}
+
+// ref: PegasusShared.DeckCardData
+message DeckCardData {
+	required CardDef def = 1;
+	required int32 handle = 2 [default = 0];
+	optional int32 qty = 3;
+	required int32 prev = 5 [default = 0];
+}
+
+// ref: PegasusUtil.DeckContents
+message DeckContents {
+	required bool success = 1;
+	required int64 deck_id = 2;
+	repeated DeckCardData cards = 3;
 }
\ No newline at end of file
diff --git a/src/main/proto/pegasus/pegasusgame/pegasusgame.proto b/src/main/proto/pegasus/pegasusgame/pegasusgame.proto
new file mode 100644
index 0000000..d99333c
--- /dev/null
+++ b/src/main/proto/pegasus/pegasusgame/pegasusgame.proto
@@ -0,0 +1,448 @@
+syntax = "proto2";
+package pegasus.pegasusgame;
+
+// Proto extractor compiled unit - https://github.com/HearthSim/proto-extractor
+
+import "pegasus/pegasusshared/pegasusshared.proto";
+
+option java_package = "com.alterdekim";
+option java_outer_classname = "PegasusGame";
+
+// ref: PegasusGame.AllOptions
+message AllOptions {
+	// ref: PegasusGame.AllOptions/PacketID
+	enum PacketID {
+		ID = 14;
+	}
+
+	required int32 id = 1;
+	repeated Option options = 2;
+}
+
+// ref: PegasusGame.ChooseEntities
+message ChooseEntities {
+	// ref: PegasusGame.ChooseEntities/PacketID
+	enum PacketID {
+		ID = 3;
+	}
+
+	required int32 id = 1;
+	repeated int32 entities = 2 [packed=true];
+}
+
+// ref: PegasusGame.ChooseOption
+message ChooseOption {
+	// ref: PegasusGame.ChooseOption/PacketID
+	enum PacketID {
+		ID = 2;
+	}
+
+	required int32 id = 1;
+	required int32 index = 2;
+	required int32 target = 3;
+	optional int32 sub_option = 4;
+	optional int32 position = 5;
+}
+
+// ref: PegasusGame.ClientHistoryMeta
+message ClientHistoryMeta {
+	// ref: PegasusGame.ClientHistoryMeta/Type
+	enum Type {
+		INVALID = 0;
+		SHOW_BIG_CARD = 1;
+		EFFECT_TIMING_HINT = 2;
+	}
+
+}
+
+// ref: PegasusGame.Concede
+message Concede {
+	// ref: PegasusGame.Concede/PacketID
+	enum PacketID {
+		ID = 11;
+	}
+
+}
+
+// ref: PegasusGame.DebugMessage
+message DebugMessage {
+	// ref: PegasusGame.DebugMessage/PacketID
+	enum PacketID {
+		ID = 5;
+	}
+
+	required string message = 1;
+}
+
+// ref: PegasusGame.EntitiesChosen
+message EntitiesChosen {
+	// ref: PegasusGame.EntitiesChosen/PacketID
+	enum PacketID {
+		ID = 13;
+	}
+
+	required ChooseEntities choose_entities = 3;
+	required int32 player_id = 4;
+}
+
+// ref: PegasusGame.Entity
+message Entity {
+	required int32 id = 1;
+	repeated Tag tags = 2;
+}
+
+// ref: PegasusGame.EntityChoices
+message EntityChoices {
+	// ref: PegasusGame.EntityChoices/PacketID
+	enum PacketID {
+		ID = 17;
+	}
+
+	required int32 id = 1;
+	required int32 choice_type = 2;
+	required int32 count_min = 4;
+	required int32 count_max = 5;
+	repeated int32 entities = 6 [packed=true];
+	optional int32 source = 7;
+	required int32 player_id = 8;
+}
+
+// ref: PegasusGame.GameCanceled
+message GameCanceled {
+	// ref: PegasusGame.GameCanceled/PacketID
+	enum PacketID {
+		ID = 12;
+	}
+
+	// ref: PegasusGame.GameCanceled/Reason
+	enum Reason {
+		OPPONENT_TIMEOUT = 1;
+	}
+
+	required Reason reason = 1;
+}
+
+// ref: PegasusGame.GameSetup
+message GameSetup {
+	// ref: PegasusGame.GameSetup/PacketID
+	enum PacketID {
+		ID = 16;
+	}
+
+	required int32 board = 1;
+	required int32 max_secrets_per_player = 2;
+	required int32 max_friendly_minions_per_player = 3;
+	optional int32 keep_alive_frequency_seconds = 4;
+	optional int32 disconnect_when_stuck_seconds = 5;
+}
+
+// ref: PegasusGame.GetGameState
+message GetGameState {
+	// ref: PegasusGame.GetGameState/PacketID
+	enum PacketID {
+		ID = 1;
+	}
+
+}
+
+// ref: PegasusGame.Handshake
+message Handshake {
+	// ref: PegasusGame.Handshake/PacketID
+	enum PacketID {
+		ID = 168;
+	}
+
+	required int32 game_handle = 1;
+	required string password = 2;
+	required int64 client_handle = 3;
+	optional int32 mission = 4;
+	required string version = 5;
+	required pegasus.pegasusshared.Platform platform = 7;
+}
+
+// ref: PegasusGame.HistoryBlock
+message HistoryBlock {
+	// ref: PegasusGame.HistoryBlock/Type
+	enum Type {
+		INVALID = 0;
+		ATTACK = 1;
+		JOUST = 2;
+		POWER = 3;
+		TRIGGER = 5;
+		DEATHS = 6;
+		PLAY = 7;
+		FATIGUE = 8;
+		RITUAL = 9;
+	}
+
+}
+
+// ref: PegasusGame.HistoryMeta
+message HistoryMeta {
+	// ref: PegasusGame.HistoryMeta/Type
+	enum Type {
+		TARGET = 0;
+		DAMAGE = 1;
+		HEALING = 2;
+		JOUST = 3;
+		CLIENT_HISTORY = 4;
+	}
+
+}
+
+// ref: PegasusGame.InviteToSpectate
+message InviteToSpectate {
+	// ref: PegasusGame.InviteToSpectate/PacketID
+	enum PacketID {
+		ID = 25;
+	}
+
+	optional pegasus.pegasusshared.BnetId target_bnet_account_id = 1;
+	required pegasus.pegasusshared.BnetId target_game_account_id = 2;
+}
+
+// ref: PegasusGame.MouseInfo
+message MouseInfo {
+	required int32 arrow_origin = 1;
+	required int32 held_card = 2;
+	required int32 over_card = 3;
+	required int32 x = 4;
+	required int32 y = 5;
+}
+
+// ref: PegasusGame.NAckOption
+message NAckOption {
+	// ref: PegasusGame.NAckOption/PacketID
+	enum PacketID {
+		ID = 10;
+	}
+
+	required int32 id = 1;
+}
+
+// ref: PegasusGame.Option
+message Option {
+	// ref: PegasusGame.Option/Type
+	enum Type {
+		PASS = 1;
+		END_TURN = 2;
+		POWER = 3;
+	}
+
+	required Type type = 1;
+	optional SubOption main_option = 2;
+	repeated SubOption sub_options = 3;
+}
+
+// ref: PegasusGame.Ping
+message Ping {
+	// ref: PegasusGame.Ping/PacketID
+	enum PacketID {
+		ID = 115;
+	}
+
+}
+
+// ref: PegasusGame.Player
+message Player {
+	required int32 id = 1;
+	required pegasus.pegasusshared.BnetId game_account_id = 2;
+	required int32 card_back = 3;
+	required Entity entity = 4;
+}
+
+// ref: PegasusGame.Pong
+message Pong {
+	// ref: PegasusGame.Pong/PacketID
+	enum PacketID {
+		ID = 116;
+	}
+
+}
+
+// ref: PegasusGame.PowerHistory
+message PowerHistory {
+	// ref: PegasusGame.PowerHistory/PacketID
+	enum PacketID {
+		ID = 19;
+	}
+
+	repeated PowerHistoryData list = 1;
+}
+
+// ref: PegasusGame.PowerHistoryCreateGame
+message PowerHistoryCreateGame {
+	required Entity game_entity = 1;
+	repeated Player players = 2;
+}
+
+// ref: PegasusGame.PowerHistoryData
+message PowerHistoryData {
+	optional PowerHistoryEntity full_entity = 1;
+	optional PowerHistoryEntity show_entity = 2;
+	optional PowerHistoryHide hide_entity = 3;
+	optional PowerHistoryTagChange tag_change = 4;
+	optional PowerHistoryCreateGame create_game = 5;
+	optional PowerHistoryStart power_start = 6;
+	optional PowerHistoryEnd power_end = 7;
+	optional PowerHistoryMetaData meta_data = 8;
+	optional PowerHistoryEntity change_entity = 9;
+}
+
+// ref: PegasusGame.PowerHistoryEnd
+message PowerHistoryEnd {
+}
+
+// ref: PegasusGame.PowerHistoryEntity
+message PowerHistoryEntity {
+	required int32 entity = 1;
+	required string name = 2;
+	repeated Tag tags = 3;
+}
+
+// ref: PegasusGame.PowerHistoryHide
+message PowerHistoryHide {
+	required int32 entity = 1;
+	required int32 zone = 2;
+}
+
+// ref: PegasusGame.PowerHistoryMetaData
+message PowerHistoryMetaData {
+	repeated int32 info = 2 [packed=true];
+	optional HistoryMeta.Type type = 3 [default = TARGET];
+	optional int32 data = 4;
+}
+
+// ref: PegasusGame.PowerHistoryStart
+message PowerHistoryStart {
+	required HistoryBlock.Type type = 1;
+	required int32 index = 2;
+	required int32 source = 3;
+	required int32 target = 4;
+	optional string effect_card_id = 5;
+}
+
+// ref: PegasusGame.PowerHistoryTagChange
+message PowerHistoryTagChange {
+	required int32 entity = 1;
+	required int32 tag = 2;
+	required int32 value = 3;
+}
+
+// ref: PegasusGame.RemoveSpectators
+message RemoveSpectators {
+	// ref: PegasusGame.RemoveSpectators/PacketID
+	enum PacketID {
+		ID = 26;
+	}
+
+	repeated pegasus.pegasusshared.BnetId target_gameaccount_ids = 1;
+	optional bool kick_all_spectators = 2 [default = false];
+	optional bool regenerate_spectator_password = 3 [default = false];
+}
+
+// ref: PegasusGame.ServerResult
+message ServerResult {
+	// ref: PegasusGame.ServerResult/Code
+	enum Code {
+		RESULT_OK = 0;
+		RESULT_RETRY = 1;
+		RESULT_NOT_EXISTS = 2;
+	}
+
+	// ref: PegasusGame.ServerResult/Constants
+	enum Constants {
+		DEFAULT_RETRY_SECONDS = 2;
+	}
+
+	// ref: PegasusGame.ServerResult/PacketID
+	enum PacketID {
+		ID = 23;
+	}
+
+	required int32 result_code = 1;
+	optional float retry_delay_seconds = 2;
+}
+
+// ref: PegasusGame.SpectatorChange
+message SpectatorChange {
+	required pegasus.pegasusshared.BnetId game_account_id = 1;
+	required bool is_removed = 2;
+}
+
+// ref: PegasusGame.SpectatorHandshake
+message SpectatorHandshake {
+	// ref: PegasusGame.SpectatorHandshake/PacketID
+	enum PacketID {
+		ID = 22;
+	}
+
+	required int32 game_handle = 1;
+	required string password = 2;
+	required string version = 3;
+	required pegasus.pegasusshared.Platform platform = 4;
+	required pegasus.pegasusshared.BnetId game_account_id = 5;
+}
+
+// ref: PegasusGame.SpectatorNotify
+message SpectatorNotify {
+	// ref: PegasusGame.SpectatorNotify/PacketID
+	enum PacketID {
+		ID = 24;
+	}
+
+	required int32 player_id = 1;
+	optional ChooseOption choose_option = 2;
+	repeated SpectatorChange spectator_change = 4;
+	optional string spectator_password_update = 5;
+	optional SpectatorRemoved spectator_removed = 6;
+}
+
+// ref: PegasusGame.SpectatorRemoved
+message SpectatorRemoved {
+	// ref: PegasusGame.SpectatorRemoved/SpectatorRemovedReason
+	enum SpectatorRemovedReason {
+		SPECTATOR_REMOVED_REASON_KICKED = 0;
+		SPECTATOR_REMOVED_REASON_GAMEOVER = 1;
+	}
+
+	required int32 reason_code = 1;
+	optional pegasus.pegasusshared.BnetId removed_by = 2;
+}
+
+// ref: PegasusGame.SubOption
+message SubOption {
+	required int32 id = 1;
+	repeated int32 targets = 3 [packed=true];
+}
+
+// ref: PegasusGame.Tag
+message Tag {
+	required int32 name = 1;
+	required int32 value = 2;
+}
+
+// ref: PegasusGame.TurnTimer
+message TurnTimer {
+	// ref: PegasusGame.TurnTimer/PacketID
+	enum PacketID {
+		ID = 9;
+	}
+
+	required int32 seconds = 1;
+	required int32 turn = 2;
+	required bool show = 3;
+}
+
+// ref: PegasusGame.UserUI
+message UserUI {
+	// ref: PegasusGame.UserUI/PacketID
+	enum PacketID {
+		ID = 15;
+	}
+
+	optional MouseInfo mouse_info = 1;
+	optional int32 emote = 2;
+	optional int32 player_id = 3;
+}
+
diff --git a/src/main/proto/pegasus/pegasusshared/pegasusshared.proto b/src/main/proto/pegasus/pegasusshared/pegasusshared.proto
new file mode 100644
index 0000000..b8e15f3
--- /dev/null
+++ b/src/main/proto/pegasus/pegasusshared/pegasusshared.proto
@@ -0,0 +1,662 @@
+syntax = "proto2";
+package pegasus.pegasusshared;
+
+// Proto extractor compiled unit - https://github.com/HearthSim/proto-extractor
+
+option java_package = "com.alterdekim";
+option java_outer_classname = "PegasusShared";
+
+// ref: PegasusShared.AssetType
+enum AssetType {
+	ASSET_TYPE_SCENARIO = 1;
+	ASSET_TYPE_SUBSET_CARD = 2;
+	ASSET_TYPE_DECK_RULESET = 3;
+}
+
+// ref: PegasusShared.BattlePayProvider
+enum BattlePayProvider {
+	BP_PROVIDER_BLIZZARD = 1;
+	BP_PROVIDER_APPLE = 2;
+	BP_PROVIDER_GOOGLE_PLAY = 3;
+	BP_PROVIDER_AMAZON = 4;
+}
+
+// ref: PegasusShared.BnetGameType
+enum BnetGameType {
+	BGT_UNKNOWN = 0;
+	BGT_FRIENDS = 1;
+	BGT_RANKED_STANDARD = 2;
+	BGT_ARENA = 3;
+	BGT_VS_AI = 4;
+	BGT_TUTORIAL = 5;
+	BGT_ASYNC = 6;
+	BGT_NEWBIE = 9;
+	BGT_CASUAL_STANDARD = 10;
+	BGT_TEST1 = 11;
+	BGT_TEST2 = 12;
+	BGT_TEST3 = 13;
+	BGT_TAVERNBRAWL_PVP = 16;
+	BGT_TAVERNBRAWL_1P_VERSUS_AI = 17;
+	BGT_TAVERNBRAWL_2P_COOP = 18;
+	BGT_RANKED_WILD = 30;
+	BGT_CASUAL_WILD = 31;
+	BGT_LAST = 32;
+}
+
+// ref: PegasusShared.DatabaseAction
+enum DatabaseAction {
+	DB_A_UNKNOWN = 0;
+	DB_A_GET_DECK = 1;
+	DB_A_CREATE_DECK = 2;
+	DB_A_RENAME_DECK = 3;
+	DB_A_DELETE_DECK = 4;
+	DB_A_SET_DECK = 5;
+	DB_A_OPEN_BOOSTER = 6;
+	DB_A_GAMES_INFO = 7;
+}
+
+// ref: PegasusShared.DatabaseResult
+enum DatabaseResult {
+	DB_E_SQL_EX = -1;
+	DB_E_UNKNOWN = 0;
+	DB_E_SUCCESS = 1;
+	DB_E_NOT_OWNED = 2;
+	DB_E_CONSTRAINT = 3;
+	DB_E_NOT_FOUND = 4;
+	DB_E_EXCEPTION = 9;
+	DB_E_BAD_PARAM = 11;
+}
+
+// ref: PegasusShared.DeckSourceType
+enum DeckSourceType {
+	DECK_SOURCE_TYPE_UNKNOWN = 0;
+	DECK_SOURCE_TYPE_NORMAL = 1;
+	DECK_SOURCE_TYPE_TEMPLATE = 2;
+	DECK_SOURCE_TYPE_BASIC_DECK = 3;
+}
+
+// ref: PegasusShared.DeckType
+enum DeckType {
+	NORMAL_DECK = 1;
+	AI_DECK = 2;
+	DRAFT_DECK = 4;
+	PRECON_DECK = 5;
+	TAVERN_BRAWL_DECK = 6;
+	HIDDEN_DECK = 1000;
+}
+
+// ref: PegasusShared.ErrorCode
+enum ErrorCode {
+	ERROR_OK = 0;
+	ERROR_HEARTHSTONE_BEGIN = 1000000;
+	ERROR_GLOBAL_INVALID_INPUT = 1000001;
+	ERROR_GLOBAL_NO_DATA = 1000002;
+	ERROR_GLOBAL_NOT_YET_IMPLEMENTED = 1000003;
+	ERROR_GLOBAL_DATA_MODIFIED = 1000004;
+	ERROR_SCENARIO_INCORRECT_NUM_PLAYERS = 1000500;
+	ERROR_SCENARIO_NO_DECK_SPECIFIED = 1000501;
+	ERROR_SCENARIO_MUST_BE_SERVER_ONLY = 1000502;
+	ERROR_TAVERN_BRAWL_SEASON_INCREMENTED = 1001000;
+	ERROR_TAVERN_BRAWL_NOT_ACTIVE = 1001001;
+	ERROR_DECK_RULESET_RULE_UNKNOWN_TYPE = 1002000;
+	ERROR_DECK_RULESET_RULE_DB_READ_ERROR = 1002001;
+	ERROR_DECK_RULESET_RULE_VIOLATION = 1002002;
+	ERROR_DECK_RULESET_DECK_CARD_ID_UNKNOWN = 1002003;
+	ERROR_DECK_RULESET_HERO_CARD_GUID_UNKNOWN = 1002004;
+	ERROR_DECK_RULESET_DECK_CARD_GUID_UNKNOWN = 1002005;
+	ERROR_DECK_VALIDATION_DB_WRITE_ERROR = 1002006;
+	ERROR_DECK_VALIDATION_WRONG_FORMAT = 1002007;
+}
+
+// ref: PegasusShared.GameType
+enum GameType {
+	GT_UNKNOWN = 0;
+	GT_VS_AI = 1;
+	GT_VS_FRIEND = 2;
+	GT_TUTORIAL = 4;
+	GT_ARENA = 5;
+	GT_TEST = 6;
+	GT_RANKED = 7;
+	GT_CASUAL = 8;
+	GT_TAVERNBRAWL = 16;
+	GT_TB_1P_VS_AI = 17;
+	GT_TB_2P_COOP = 18;
+	GT_LAST = 19;
+}
+
+// ref: PegasusShared.RewardTrigger
+enum RewardTrigger {
+	REWARD_TRIGGER_UNKNOWN = 0;
+	REWARD_TRIGGER_NONE = 1;
+	REWARD_TRIGGER_WIN_GAME = 2;
+	REWARD_TRIGGER_FINISH_GAME = 3;
+}
+
+// ref: PegasusShared.RewardType
+enum RewardType {
+	REWARD_UNKNOWN = 0;
+	REWARD_NONE = 1;
+	REWARD_ADVENTURE_PROGRESS = 2;
+	REWARD_ARCANE_DUST = 3;
+	REWARD_BASIC_CARD = 4;
+	REWARD_BOOSTER_PACKS = 5;
+	REWARD_CARD_BACK = 6;
+	REWARD_CARD_ID = 7;
+	REWARD_CARD_ID_2X = 8;
+	REWARD_CARD_SET = 9;
+	DEPRECATED_REWARD_CRAFTABLE_GOLDEN = 10;
+	REWARD_GOLD = 11;
+	REWARD_GOLD_HERO = 12;
+	REWARD_FORGE_TICKETS = 13;
+	REWARD_HERO = 14;
+	REWARD_EXTERNAL_GAME_MOUNT = 15;
+}
+
+// ref: PegasusShared.RuleType
+enum RuleType {
+	RULE_NONE = 0;
+	RULE_CHOOSE_HERO = 1;
+	RULE_CHOOSE_DECK = 2;
+}
+
+// ref: PegasusShared.AccountLicenseInfo
+message AccountLicenseInfo {
+	// ref: PegasusShared.AccountLicenseInfo/Flags
+	enum Flags {
+		OWNED = 1;
+	}
+
+	required int64 license = 1;
+	required uint64 flags = 2;
+	required int64 cas_id = 3;
+}
+
+// ref: PegasusShared.AdventureProgress
+message AdventureProgress {
+	// ref: PegasusShared.AdventureProgress/Flags
+	enum Flags {
+		OWNED = 1;
+		DEFEAT_HEROIC_MISSION_1 = 2;
+		DEFEAT_HEROIC_MISSION_2 = 4;
+		DEFEAT_HEROIC_MISSION_3 = 8;
+		DEFEAT_HEROIC_MISSION_4 = 16;
+		DEFEAT_CLASS_CHALLENGE_MISSION_1 = 256;
+		DEFEAT_CLASS_CHALLENGE_MISSION_2 = 512;
+	}
+
+	required int32 wing_id = 1;
+	required int32 progress = 2;
+	optional int32 ack = 3 [default = 0];
+	required uint64 flags = 4;
+}
+
+// ref: PegasusShared.AssetKey
+message AssetKey {
+	required AssetType type = 1;
+	optional int32 asset_id = 2;
+}
+
+// ref: PegasusShared.AssetRecordInfo
+message AssetRecordInfo {
+	required AssetKey asset = 1;
+	required uint32 record_byte_size = 2;
+	required bytes record_hash = 3;
+}
+
+// ref: PegasusShared.BnetId
+message BnetId {
+	required uint64 hi = 1;
+	required uint64 lo = 2;
+}
+
+// ref: PegasusShared.BoosterInfo
+message BoosterInfo {
+	required int32 type = 2;
+	required int32 count = 3;
+}
+
+// ref: PegasusShared.CachedCard
+message CachedCard {
+	required int64 card_id = 1;
+	required int32 asset_card_id = 2;
+	required Date insert_date = 3;
+	required bool is_seen = 4;
+	required int32 premium = 5;
+}
+
+// ref: PegasusShared.CachedCollection
+message CachedCollection {
+	repeated CachedCard card_collection = 1;
+}
+
+// ref: PegasusShared.CardDef
+message CardDef {
+	required int32 asset = 1;
+	optional int32 premium = 2;
+}
+
+// ref: PegasusShared.CardStack
+message CardStack {
+	required CardDef card_def = 1;
+	required Date latest_insert_date = 2;
+	required int32 count = 3;
+	required int32 num_seen = 4;
+}
+
+// ref: PegasusShared.DatabaseDeckCard
+message DatabaseDeckCard {
+	required int32 asset_card_id = 1;
+	required int32 premium = 2;
+	required int32 quantity = 3;
+}
+
+// ref: PegasusShared.DatabaseDeckContent
+message DatabaseDeckContent {
+	repeated DatabaseDeckCard deck_cards = 1;
+}
+
+// ref: PegasusShared.Date
+message Date {
+	required int32 year = 1;
+	required int32 month = 2;
+	required int32 day = 3;
+	required int32 hours = 4;
+	required int32 min = 5;
+	required int32 sec = 6;
+}
+
+// ref: PegasusShared.DeckCardData
+message DeckCardData {
+	required CardDef def = 1;
+	required int32 handle = 2 [default = 0];
+	optional int32 qty = 3;
+	required int32 prev = 5 [default = 0];
+}
+
+// ref: PegasusShared.DeckInfo
+message DeckInfo {
+	// ref: PegasusShared.DeckInfo/ValidityFlags
+	enum ValidityFlags {
+		UNLOCKED_HERO_CLASS = 1;
+		OWNS_CARDS = 2;
+		HAS_30_CARDS = 4;
+		OBEYS_MAXES = 8;
+		CLASS_MATCHES = 16;
+		OWNS_CARD_BACK = 32;
+		OWNS_HERO = 64;
+		TAGGED_STANDARD = 128;
+		NEEDS_VALIDATION = 256;
+		NEEDS_NAME = 512;
+	}
+
+	required int64 id = 1;
+	required string name = 2;
+	required int32 card_back = 3;
+	required int32 hero = 4;
+	required DeckType deck_type = 5;
+	required uint64 validity = 6;
+	required int32 hero_premium = 7;
+	required bool card_back_override = 8;
+	required bool hero_override = 9;
+	optional int64 last_modified = 10;
+	optional int32 season_id = 11;
+	optional int64 sort_order = 12;
+	optional int64 create_date = 13;
+	optional DeckSourceType source_type = 14 [default = DECK_SOURCE_TYPE_UNKNOWN];
+}
+
+// ref: PegasusShared.DeckRulesetDbRecord
+message DeckRulesetDbRecord {
+	required int32 id = 1;
+	repeated DeckRulesetRuleDbRecord rules = 2;
+}
+
+// ref: PegasusShared.DeckRulesetRuleDbRecord
+message DeckRulesetRuleDbRecord {
+	required int32 id = 1;
+	required int32 deck_ruleset_id = 2;
+	optional int32 applies_to_subset_id = 3;
+	optional bool applies_to_is_not = 4;
+	required string rule_type = 5;
+	required bool rule_is_not = 6;
+	optional int32 min_value = 7;
+	optional int32 max_value = 8;
+	optional int32 tag = 9;
+	optional int32 tag_min_value = 10;
+	optional int32 tag_max_value = 11;
+	optional string string_value = 12;
+	repeated int32 target_subset_ids = 13;
+	repeated LocalizedString strings = 100;
+}
+
+// ref: PegasusShared.DeckRulesetValidationResults
+message DeckRulesetValidationResults {
+	required int32 deck_ruleset_id = 1 [default = 0];
+	optional ErrorCode error_code = 2 [default = ERROR_OK];
+	repeated DeckRulesetViolation violations = 3;
+}
+
+// ref: PegasusShared.DeckRulesetViolation
+message DeckRulesetViolation {
+	optional CardDef card = 1;
+	optional int32 count = 2;
+	required int32 deck_rule_id = 100;
+	optional string deck_rule_desc = 101;
+}
+
+// ref: PegasusShared.FavoriteHero
+message FavoriteHero {
+	required int32 class_id = 1;
+	required CardDef hero = 2;
+}
+
+// ref: PegasusShared.GameSetupRule
+message GameSetupRule {
+	required int32 id = 1;
+	required RuleType rule_type = 2;
+	required int64 data1 = 3;
+	required int64 data2 = 4;
+	required int64 data3 = 5;
+}
+
+// ref: PegasusShared.LocalizedString
+message LocalizedString {
+	required string key = 1;
+	optional string deprecated_value = 2;
+	optional int32 deprecated_locale = 3;
+	repeated LocalizedStringValue values = 4;
+}
+
+// ref: PegasusShared.LocalizedStringValue
+message LocalizedStringValue {
+	required int32 locale = 1;
+	required string value = 2;
+}
+
+// ref: PegasusShared.Platform
+message Platform {
+	required int32 os = 1;
+	required int32 screen = 2;
+	required string name = 3;
+	optional int32 store = 4;
+}
+
+// ref: PegasusShared.PlayQueueInfo
+message PlayQueueInfo {
+	required BnetGameType game_type = 1;
+}
+
+// ref: PegasusShared.ProfileNoticeAccountLicense
+message ProfileNoticeAccountLicense {
+	// ref: PegasusShared.ProfileNoticeAccountLicense/NoticeID
+	enum NoticeID {
+		ID = 16;
+	}
+
+	required int64 license = 1;
+	required int64 cas_id = 2;
+}
+
+// ref: PegasusShared.ProfileNoticeAdventureProgress
+message ProfileNoticeAdventureProgress {
+	// ref: PegasusShared.ProfileNoticeAdventureProgress/NoticeID
+	enum NoticeID {
+		ID = 14;
+	}
+
+	required int32 wing_id = 1;
+}
+
+// ref: PegasusShared.ProfileNoticeBonusStars
+message ProfileNoticeBonusStars {
+	// ref: PegasusShared.ProfileNoticeBonusStars/NoticeID
+	enum NoticeID {
+		ID = 12;
+	}
+
+	required int32 star_level = 1;
+	required int32 stars = 2;
+}
+
+// ref: PegasusShared.ProfileNoticeCardBack
+message ProfileNoticeCardBack {
+	// ref: PegasusShared.ProfileNoticeCardBack/NoticeID
+	enum NoticeID {
+		ID = 11;
+	}
+
+	required int32 card_back = 1;
+}
+
+// ref: PegasusShared.ProfileNoticeDisconnectedGameResult
+message ProfileNoticeDisconnectedGameResult {
+	// ref: PegasusShared.ProfileNoticeDisconnectedGameResult/GameResult
+	enum GameResult {
+		GR_UNKNOWN = 0;
+		GR_PLAYING = 1;
+		GR_WINNER = 2;
+		GR_TIE = 3;
+	}
+
+	// ref: PegasusShared.ProfileNoticeDisconnectedGameResult/NoticeID
+	enum NoticeID {
+		ID = 4;
+	}
+
+	// ref: PegasusShared.ProfileNoticeDisconnectedGameResult/PlayerResult
+	enum PlayerResult {
+		PR_UNKNOWN = 0;
+		PR_WON = 1;
+		PR_LOST = 2;
+		PR_DISCONNECTED = 3;
+		PR_QUIT = 4;
+	}
+
+	optional GameType game_type = 8 [default = GT_UNKNOWN];
+	optional int32 mission_id = 9;
+	optional GameResult game_result = 10 [default = GR_UNKNOWN];
+	optional PlayerResult your_result = 11 [default = PR_UNKNOWN];
+	optional PlayerResult opponent_result = 12 [default = PR_UNKNOWN];
+}
+
+// ref: PegasusShared.ProfileNoticeLevelUp
+message ProfileNoticeLevelUp {
+	// ref: PegasusShared.ProfileNoticeLevelUp/NoticeID
+	enum NoticeID {
+		ID = 15;
+	}
+
+	required int32 hero_class = 1;
+	required int32 new_level = 2;
+}
+
+// ref: PegasusShared.ProfileNoticeMedal
+message ProfileNoticeMedal {
+	// ref: PegasusShared.ProfileNoticeMedal/MedalType
+	enum MedalType {
+		UNKNOWN_MEDAL = 0;
+		STANDARD_MEDAL = 1;
+		WILD_MEDAL = 2;
+	}
+
+	// ref: PegasusShared.ProfileNoticeMedal/NoticeID
+	enum NoticeID {
+		ID = 1;
+	}
+
+	required int32 star_level = 1;
+	optional int32 legend_rank = 2;
+	optional int32 best_star_level = 3;
+	optional RewardChest chest = 4;
+	optional MedalType medal_type = 5 [default = UNKNOWN_MEDAL];
+}
+
+// ref: PegasusShared.ProfileNoticePreconDeck
+message ProfileNoticePreconDeck {
+	// ref: PegasusShared.ProfileNoticePreconDeck/NoticeID
+	enum NoticeID {
+		ID = 5;
+	}
+
+	required int64 deck = 1;
+	required int32 hero = 2;
+}
+
+// ref: PegasusShared.ProfileNoticePurchase
+message ProfileNoticePurchase {
+	// ref: PegasusShared.ProfileNoticePurchase/NoticeID
+	enum NoticeID {
+		ID = 10;
+	}
+
+	required string product_id = 1;
+	optional int64 data = 2;
+	optional int32 currency = 3;
+}
+
+// ref: PegasusShared.ProfileNoticeRewardBooster
+message ProfileNoticeRewardBooster {
+	// ref: PegasusShared.ProfileNoticeRewardBooster/NoticeID
+	enum NoticeID {
+		ID = 2;
+	}
+
+	required int32 booster_type = 1;
+	required int32 booster_count = 2;
+}
+
+// ref: PegasusShared.ProfileNoticeRewardCard
+message ProfileNoticeRewardCard {
+	// ref: PegasusShared.ProfileNoticeRewardCard/NoticeID
+	enum NoticeID {
+		ID = 3;
+	}
+
+	required CardDef card = 1;
+	optional int32 quantity = 2;
+}
+
+// ref: PegasusShared.ProfileNoticeRewardCard2x
+message ProfileNoticeRewardCard2x {
+	// ref: PegasusShared.ProfileNoticeRewardCard2x/NoticeID
+	enum NoticeID {
+		ID = 13;
+	}
+
+}
+
+// ref: PegasusShared.ProfileNoticeRewardDust
+message ProfileNoticeRewardDust {
+	// ref: PegasusShared.ProfileNoticeRewardDust/NoticeID
+	enum NoticeID {
+		ID = 6;
+	}
+
+	required int32 amount = 1;
+}
+
+// ref: PegasusShared.ProfileNoticeRewardForge
+message ProfileNoticeRewardForge {
+	// ref: PegasusShared.ProfileNoticeRewardForge/NoticeID
+	enum NoticeID {
+		ID = 8;
+	}
+
+	required int32 quantity = 1;
+}
+
+// ref: PegasusShared.ProfileNoticeRewardGold
+message ProfileNoticeRewardGold {
+	// ref: PegasusShared.ProfileNoticeRewardGold/NoticeID
+	enum NoticeID {
+		ID = 9;
+	}
+
+	required int32 amount = 1;
+}
+
+// ref: PegasusShared.ProfileNoticeRewardMount
+message ProfileNoticeRewardMount {
+	// ref: PegasusShared.ProfileNoticeRewardMount/NoticeID
+	enum NoticeID {
+		ID = 7;
+	}
+
+	required int32 mount_id = 1;
+}
+
+// ref: PegasusShared.RewardBag
+message RewardBag {
+	optional ProfileNoticeRewardBooster reward_booster = 1;
+	optional ProfileNoticeRewardCard reward_card = 2;
+	optional ProfileNoticeRewardDust reward_dust = 3;
+	optional ProfileNoticeRewardGold reward_gold = 4;
+	optional ProfileNoticeCardBack reward_card_back = 5;
+}
+
+// ref: PegasusShared.RewardChest
+message RewardChest {
+	optional RewardBag bag1 = 1;
+	optional RewardBag bag2 = 2;
+	optional RewardBag bag3 = 3;
+	optional RewardBag bag4 = 4;
+	optional RewardBag bag5 = 5;
+}
+
+// ref: PegasusShared.ScenarioDbRecord
+message ScenarioDbRecord {
+	required int32 id = 1;
+	optional string note_desc = 2;
+	required int32 num_players = 3;
+	required int64 player1_hero_card_id = 4;
+	required int64 player2_hero_card_id = 5;
+	required bool is_expert = 6;
+	required int32 adventure_id = 7;
+	optional int32 adventure_mode_id = 8;
+	required int32 wing_id = 9;
+	required int32 sort_order = 10;
+	optional int64 client_player2_hero_card_id = 11;
+	optional string tavern_brawl_texture = 12;
+	optional string tavern_brawl_texture_phone = 13;
+	optional Vector2 tavern_brawl_texture_phone_offset = 14;
+	optional bool is_coop = 15;
+	optional int32 deck_ruleset_id = 16;
+	repeated LocalizedString strings = 100;
+	repeated GameSetupRule rules = 101;
+}
+
+// ref: PegasusShared.SubsetCardListDbRecord
+message SubsetCardListDbRecord {
+	required int32 subset_id = 1;
+	repeated int32 card_ids = 2;
+}
+
+// ref: PegasusShared.TavernBrawlPlayerRecord
+message TavernBrawlPlayerRecord {
+	required int32 reward_progress = 1;
+	optional int32 games_played = 2;
+	required int32 games_won = 3;
+	optional int32 win_streak = 4;
+}
+
+// ref: PegasusShared.TavernBrawlSpec
+message TavernBrawlSpec {
+	optional uint64 end_seconds_from_now = 1;
+	required int32 scenario_id = 2;
+	required uint32 scenario_record_byte_size = 3;
+	required bytes scenario_record_hash = 4;
+	required RewardType reward_type = 5;
+	required int64 reward_data1 = 6;
+	required int64 reward_data2 = 7;
+	optional RewardTrigger reward_trigger = 8 [default = REWARD_TRIGGER_UNKNOWN];
+	required int32 season_id = 11;
+	repeated AssetRecordInfo additional_assets = 100;
+	required TavernBrawlPlayerRecord my_record = 105;
+}
+
+// ref: PegasusShared.Vector2
+message Vector2 {
+	required float x = 1 [default = 0];
+	required float y = 2 [default = 0];
+}
+