├── .gitattributes
├── .gitignore
├── README.md
├── pom.xml
└── src
└── main
└── java
└── me
└── pringles
└── lcwebsocketclient
├── Main.java
├── assets
├── AssetsPacket.java
├── ServerStatus.java
├── Websocket.java
├── packet
│ ├── CPacketMods.java
│ ├── SPacketAuthentication.java
│ ├── SPacketBulkFriends.java
│ ├── SPacketConnection.java
│ ├── SPacketCosmetics.java
│ ├── SPacketEmotes.java
│ ├── SPacketFormattedConsoleOutput.java
│ ├── SPacketFriendUpdate.java
│ ├── ShPacketConsole.java
│ ├── ShPacketFriendRemove.java
│ ├── ShPacketFriendRequest.java
│ ├── ShPacketFriendRequestUpdate.java
│ ├── ShPacketFriendUpdate.java
│ ├── ShPacketMessage.java
│ └── ShPacketStatusUpdate.java
└── user
│ └── Status.java
├── auth
├── AuthWebsocket.java
└── packet
│ ├── AuthPacket.java
│ ├── Packet.java
│ └── auth
│ ├── CPacketEncryptionResponse.java
│ ├── SPacketAuthenticatedRequest.java
│ └── SPacketEncryptionRequest.java
└── util
├── AuthUtil.java
├── ByteBufWrapper.java
├── Config.java
└── CryptManager.java
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 | pom.xml.tag
3 | pom.xml.releaseBackup
4 | pom.xml.versionsBackup
5 | pom.xml.next
6 | release.properties
7 | dependency-reduced-pom.xml
8 | buildNumber.properties
9 | .mvn/timing.properties
10 | .mvn/wrapper/maven-wrapper.jar
11 | *.properties
12 | # Eclipse stuff
13 | .classpath
14 | .project
15 | .settings/
16 |
17 | # netbeans
18 | nbproject/
19 | nbactions.xml
20 |
21 | # we use maven!
22 | build.xml
23 |
24 | # maven
25 | target/
26 | dependency-reduced-pom.xml
27 |
28 | # vim
29 | .*.sw[a-p]
30 |
31 | # various other potential build files
32 | build/
33 | bin/
34 | dist/
35 | manifest.mf
36 |
37 | # Mac filesystem dust
38 | .DS_Store/
39 | .DS_Store
40 |
41 | # intellij
42 | *.iml
43 | *.ipr
44 | *.iws
45 | .idea/
46 |
47 | working-dir/
48 | config.properties
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # LCWebsocket
2 |
3 | ### What dis?
4 | This is a console version of Lunar Client. It connects to their assets websocket, you can do basically everything with this.
5 |
6 | ### How to use?
7 | Rename the `config.properties.example` to `config.properties` then fill it in. Run it using IntellIJ.
8 |
9 | ### Update???
10 | It works again!!!
11 |
12 | ### Why???
13 | I made this so I could play around with the actual websocket, and try to find out how it actually works.
14 |
15 | ### Credits
16 | [Decencies](https://github.com/Decencies) for helping with with some of the packet names
17 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | me.pringles
8 | LunarWebsocketClient
9 | 1.0-SNAPSHOT
10 |
11 |
12 | 8
13 | 8
14 |
15 |
16 |
17 |
18 | minecraft-repo
19 | https://libraries.minecraft.net/
20 |
21 |
22 |
23 |
24 |
25 | com.google.guava
26 | guava
27 | 30.1.1-jre
28 |
29 |
30 | org.java-websocket
31 | Java-WebSocket
32 | 1.5.2
33 |
34 |
35 | com.google.code.gson
36 | gson
37 | 2.8.6
38 |
39 |
40 | com.mojang
41 | authlib
42 | 1.5.21
43 | compile
44 |
45 |
46 | io.netty
47 | netty-all
48 | 4.1.63.Final
49 |
50 |
51 | org.projectlombok
52 | lombok
53 | 1.16.18
54 |
55 |
56 |
--------------------------------------------------------------------------------
/src/main/java/me/pringles/lcwebsocketclient/Main.java:
--------------------------------------------------------------------------------
1 | package me.pringles.lcwebsocketclient;
2 |
3 | import com.google.common.collect.ImmutableMap;
4 | import com.google.gson.Gson;
5 | import com.google.gson.GsonBuilder;
6 | import lombok.Getter;
7 | import me.pringles.lcwebsocketclient.assets.Websocket;
8 | import me.pringles.lcwebsocketclient.assets.packet.ShPacketConsole;
9 | import me.pringles.lcwebsocketclient.assets.packet.ShPacketFriendRequest;
10 | import me.pringles.lcwebsocketclient.assets.packet.ShPacketMessage;
11 | import me.pringles.lcwebsocketclient.auth.AuthWebsocket;
12 | import me.pringles.lcwebsocketclient.util.Config;
13 |
14 | import java.io.BufferedReader;
15 | import java.io.IOException;
16 | import java.io.InputStreamReader;
17 | import java.net.URISyntaxException;
18 | import java.util.function.Consumer;
19 |
20 | public class Main {
21 | public static Gson gson = new GsonBuilder().create();
22 | @Getter private static Config config;
23 |
24 | public static void main(String[] args) throws IOException {
25 | config = new Config();
26 | new Thread(() -> connectToAuth(s -> {
27 | try {
28 | System.out.println("Got auth key, connecting to assets websocket");
29 | Websocket websocket = new Websocket(ImmutableMap.builder().put("accountType", "MOJANG").put("version", "v1_8").put("gitCommit", "2ef0680874b1d11cea10a4b969c6f5ec1f804d70").put("branch", "master").put("os", System.getProperty("os.name")).put("arch", "").put("server", "pornhub.com").put("launcherVersion", "2.4.1").put("username", config.getUsername()).put("playerId", config.getUuid()).put("Authorization", s).put("clothCloak", "false").put("hwid", "myHWID").build());
30 | websocket.connect();
31 | } catch (URISyntaxException e) {
32 | e.printStackTrace();
33 | }
34 | })).start();
35 | while (true) {
36 | BufferedReader reader = new BufferedReader(
37 | new InputStreamReader(System.in));
38 |
39 | String message = reader.readLine();
40 | Websocket.getInstance().sendPacket(new ShPacketMessage(Websocket.getLastMessage(), message));
41 | }
42 | }
43 |
44 | public static void connectToAuth(Consumer consumer) {
45 | try {
46 | new AuthWebsocket(ImmutableMap.builder().put("username", config.getUsername()).put("playerId", config.getUuid()).build(), consumer).connect();
47 | } catch (URISyntaxException e) {
48 | e.printStackTrace();
49 | consumer.accept(null);
50 | }
51 |
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/main/java/me/pringles/lcwebsocketclient/assets/AssetsPacket.java:
--------------------------------------------------------------------------------
1 | package me.pringles.lcwebsocketclient.assets;
2 |
3 |
4 | import com.google.common.collect.BiMap;
5 | import com.google.common.collect.HashBiMap;
6 | import io.netty.buffer.ByteBuf;
7 | import me.pringles.lcwebsocketclient.assets.packet.*;
8 | import me.pringles.lcwebsocketclient.util.ByteBufWrapper;
9 |
10 | import java.io.IOException;
11 |
12 | public abstract class AssetsPacket {
13 |
14 | public static BiMap, Integer> REGISTRY = HashBiMap.create();
15 |
16 | public abstract void write(ByteBufWrapper var1);
17 |
18 | public abstract void read(ByteBufWrapper var1) throws IOException;
19 |
20 | public abstract void handle(Websocket var1);
21 |
22 | protected void writeKey(ByteBuf byteBuf, byte[] key) {
23 | byteBuf.writeShort(key.length);
24 | byteBuf.writeBytes(key);
25 | }
26 |
27 | protected byte[] readKey(ByteBuf byteBuf) {
28 | short keySize = byteBuf.readShort();
29 | if (keySize >= 0) {
30 | byte[] key = new byte[keySize];
31 | byteBuf.readBytes(key);
32 | return key;
33 | }
34 | return new byte[0];
35 | }
36 |
37 | static {
38 | REGISTRY.put(SPacketAuthentication.class, 1);
39 | REGISTRY.put(ShPacketConsole.class, 2);
40 | REGISTRY.put(SPacketFormattedConsoleOutput.class, 3);
41 | REGISTRY.put(SPacketConnection.class, 4);
42 | REGISTRY.put(ShPacketMessage.class, 5);
43 | REGISTRY.put(ShPacketStatusUpdate.class, 6);
44 | REGISTRY.put(SPacketBulkFriends.class, 7);
45 | REGISTRY.put(SPacketCosmetics.class, 8);
46 | REGISTRY.put(ShPacketFriendRequest.class, 9);
47 | REGISTRY.put(SPacketFriendUpdate.class, 16);
48 | REGISTRY.put(ShPacketFriendRemove.class, 17);
49 | REGISTRY.put(ShPacketFriendUpdate.class, 18);
50 | REGISTRY.put(ShPacketFriendRequestUpdate.class, 21);
51 | REGISTRY.put(SPacketEmotes.class, 57);
52 | REGISTRY.put(CPacketMods.class, 64);
53 | }
54 |
55 | @Override
56 | public String toString() {
57 | return this.getClass().getSimpleName();
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/main/java/me/pringles/lcwebsocketclient/assets/ServerStatus.java:
--------------------------------------------------------------------------------
1 | package me.pringles.lcwebsocketclient.assets;
2 |
3 | public enum ServerStatus {
4 | DISCONNECTED,
5 | AWAITING_ENCRYPTION_REQUEST,
6 | AUTHENTICATING,
7 | READY
8 | }
9 |
--------------------------------------------------------------------------------
/src/main/java/me/pringles/lcwebsocketclient/assets/Websocket.java:
--------------------------------------------------------------------------------
1 | package me.pringles.lcwebsocketclient.assets;
2 |
3 | import io.netty.buffer.Unpooled;
4 | import lombok.Getter;
5 | import me.pringles.lcwebsocketclient.assets.packet.*;
6 | import me.pringles.lcwebsocketclient.assets.user.Status;
7 | import me.pringles.lcwebsocketclient.util.ByteBufWrapper;
8 | import org.java_websocket.client.WebSocketClient;
9 | import org.java_websocket.drafts.Draft_6455;
10 | import org.java_websocket.handshake.ServerHandshake;
11 |
12 | import java.net.URI;
13 | import java.net.URISyntaxException;
14 | import java.nio.ByteBuffer;
15 | import java.util.Date;
16 | import java.util.Map;
17 | import java.util.regex.Matcher;
18 | import java.util.regex.Pattern;
19 |
20 | public class Websocket extends WebSocketClient {
21 |
22 | private ServerStatus status = ServerStatus.DISCONNECTED;
23 | private String server;
24 | @Getter
25 | public static String lastMessage;
26 |
27 | @Getter
28 | public static Websocket instance;
29 |
30 | public Websocket(final Map map) throws URISyntaxException {
31 | super(new URI("wss://assetserver.lunarclientprod.com/connect"), new Draft_6455(), map, 0);
32 | server = null;
33 | instance = this;
34 | }
35 |
36 | @Override
37 | public void onOpen(ServerHandshake serverHandshake) {
38 | this.status = ServerStatus.AWAITING_ENCRYPTION_REQUEST;
39 | }
40 |
41 | @Override
42 | public void onMessage(String s) {
43 | }
44 |
45 | @Override
46 | public void onMessage(ByteBuffer bytes) {
47 | this.handleIncoming(new ByteBufWrapper(Unpooled.wrappedBuffer(bytes.array())));
48 |
49 | }
50 |
51 | public void handleIncoming(ByteBufWrapper buf) {
52 | int n = buf.readVarInt();
53 | Class extends AssetsPacket> packetClass = AssetsPacket.REGISTRY.inverse().get(n);
54 | try {
55 | AssetsPacket packet = packetClass == null ? null : packetClass.newInstance();
56 | if (packet == null) {
57 | System.out.println("Got unknown packet: " + n);
58 | return;
59 | }
60 | System.out.println("Got packet: " + packet);
61 | packet.read(buf);
62 | packet.handle(this);
63 | } catch (Exception exception) {
64 | System.out.println("Error from: " + packetClass);
65 | exception.printStackTrace();
66 | }
67 | }
68 |
69 | @Override
70 | public void onClose(int i, String s, boolean b) {
71 | System.out.println(i + s);
72 | this.status = ServerStatus.DISCONNECTED;
73 | }
74 |
75 | public void handleAuthentication(SPacketAuthentication packetAuthentication) {
76 | this.status = ServerStatus.AUTHENTICATING;
77 | }
78 |
79 | public void sendConsoleMessage(String command){
80 | sendPacket(new ShPacketConsole(command));
81 | System.out.println("Sending " + command + " to lunar console");
82 | }
83 |
84 | @Override
85 | public void onError(Exception e) {
86 | e.printStackTrace();
87 | }
88 |
89 | public void sendPacket(AssetsPacket packet) {
90 | if (!this.isOpen()) {
91 | return;
92 | }
93 | ByteBufWrapper buf = new ByteBufWrapper(Unpooled.buffer());
94 | buf.writeVarInt(AssetsPacket.REGISTRY.get(packet.getClass()));
95 | try {
96 | packet.write(buf);
97 | byte[] bytes = new byte[buf.buf().readableBytes()];
98 | buf.buf().readBytes(bytes);
99 | buf.buf().release();
100 | this.send(bytes);
101 | } catch (Exception e) {
102 | e.printStackTrace();
103 | }
104 | }
105 |
106 | private void setServer(String server) {
107 | final Matcher ipRegex = Pattern.compile("(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)").matcher(server);
108 | ;
109 | this.server = server;
110 | if (!ipRegex.find()) {
111 | //Ip not numeric.. Sending it.
112 | this.sendPacket(new ShPacketStatusUpdate("", server));
113 | } else {
114 | this.sendPacket(new ShPacketStatusUpdate("", "_numeric_"));
115 | }
116 | }
117 |
118 | public void handleConnection(SPacketConnection packetConnection) {
119 | this.status = ServerStatus.READY;
120 | setServer("hypixel.net");
121 |
122 | new Thread(() -> {
123 | while (true) {
124 | sendPacket(new CPacketMods());
125 | try {
126 | Thread.sleep(60);
127 | } catch (InterruptedException e) {
128 | e.printStackTrace();
129 | }
130 | }
131 | }).start();
132 |
133 | }
134 |
135 | public void handleServerChange(ShPacketStatusUpdate packetServerUpdate) {
136 | System.out.println("Server changed for user: " + packetServerUpdate.getPlayerId() + " to: " + packetServerUpdate.getServer());
137 | }
138 |
139 | public void handleFriendRequest(ShPacketFriendRequest packetFriendRequest) {
140 | System.out.println("Got friend request from: " + packetFriendRequest.getName() + ", accepting it.");
141 | this.sendPacket(new ShPacketFriendRequestUpdate(true, packetFriendRequest.getPlayerId()));
142 | }
143 |
144 | public void handleMessage(ShPacketMessage packetMessage) {
145 | System.out.println("Got message: " + packetMessage.getMessage() + " From: " + packetMessage.getPlayerId() + " Setting user as console target.");
146 | lastMessage = packetMessage.getPlayerId();
147 |
148 | if(packetMessage.getMessage().startsWith("!")){
149 | String[] args = packetMessage.getMessage().substring("!".length()).split(" ");
150 | if(args[0].equals("setserver")){
151 | setServer(args[1]);
152 | sendPacket(new ShPacketMessage(packetMessage.getPlayerId(), "Set server to " + args[1]));
153 | }
154 |
155 | }
156 | }
157 |
158 | public void handleConsole(SPacketFormattedConsoleOutput packetFormattedConsoleOutput) {
159 | System.out.println("[" + packetFormattedConsoleOutput.getPrefix() + "] " + packetFormattedConsoleOutput.getContent());
160 | }
161 |
162 | public void handleRawConsole(ShPacketConsole packetConsole) {
163 | System.out.println(packetConsole.getOutput());
164 | }
165 |
166 | public void handleFriendUpdate(ShPacketFriendUpdate packetFriendUpdate) {
167 | if(packetFriendUpdate.getStatus() < 10L){
168 | Status status = Status.ONLINE;
169 | for(Status status1 : Status.values()){
170 | if(status1.ordinal() == packetFriendUpdate.getStatus()){
171 | status = status1;
172 | }
173 | }
174 | System.out.println(packetFriendUpdate.getName() + " went on status " + status.getName());
175 | return;
176 | }
177 | System.out.println(packetFriendUpdate.getName() + " went offline! they were last seen at: " + new Date(packetFriendUpdate.getStatus()));
178 | }
179 |
180 | public void handleFriendRemove(ShPacketFriendRemove packetClientFriendRemove){
181 | System.out.println(packetClientFriendRemove.getPlayerId() + " Removed us as friend! Sending new friend request.");
182 | this.sendPacket(new ShPacketFriendRequest(packetClientFriendRemove.getPlayerId(), ""));
183 | }
184 |
185 | public void handleFriendUpdate(SPacketFriendUpdate packetFriendUpdate){
186 | System.out.println("Got friend update, " + packetFriendUpdate.toString());
187 | }
188 | }
189 |
--------------------------------------------------------------------------------
/src/main/java/me/pringles/lcwebsocketclient/assets/packet/CPacketMods.java:
--------------------------------------------------------------------------------
1 | package me.pringles.lcwebsocketclient.assets.packet;
2 |
3 |
4 | import me.pringles.lcwebsocketclient.assets.AssetsPacket;
5 | import me.pringles.lcwebsocketclient.assets.Websocket;
6 | import me.pringles.lcwebsocketclient.util.ByteBufWrapper;
7 |
8 | import java.util.HashMap;
9 | import java.util.Map;
10 |
11 | public class CPacketMods extends AssetsPacket {
12 |
13 | private final String string;
14 | private final Map map ;
15 |
16 |
17 | public CPacketMods(){
18 | map = new HashMap<>();
19 | this.string = "";
20 | this.map.put("skyblockaddons", false);
21 | }
22 | @Override
23 | public void write(ByteBufWrapper wrapper) {
24 | wrapper.writeVarInt(map.size());
25 | this.map.forEach((s, aBoolean) -> {
26 | wrapper.writeString(s);
27 | wrapper.buf().writeBoolean(aBoolean);
28 | });
29 | wrapper.writeString(string);
30 | }
31 |
32 | @Override
33 | public void read(ByteBufWrapper wrapper) {
34 | }
35 |
36 | @Override
37 | public void handle(Websocket websocket) {
38 | }
39 |
40 | }
41 |
42 |
--------------------------------------------------------------------------------
/src/main/java/me/pringles/lcwebsocketclient/assets/packet/SPacketAuthentication.java:
--------------------------------------------------------------------------------
1 | package me.pringles.lcwebsocketclient.assets.packet;
2 |
3 |
4 | import me.pringles.lcwebsocketclient.assets.AssetsPacket;
5 | import me.pringles.lcwebsocketclient.assets.Websocket;
6 | import me.pringles.lcwebsocketclient.util.ByteBufWrapper;
7 |
8 | public class SPacketAuthentication extends AssetsPacket {
9 |
10 | @Override
11 | public void write(ByteBufWrapper wrapper) {
12 | }
13 |
14 | @Override
15 | public void read(ByteBufWrapper wrapper) {
16 | }
17 |
18 | @Override
19 | public void handle(Websocket websocket) {
20 | websocket.handleAuthentication(this);
21 | }
22 |
23 | }
24 |
25 |
--------------------------------------------------------------------------------
/src/main/java/me/pringles/lcwebsocketclient/assets/packet/SPacketBulkFriends.java:
--------------------------------------------------------------------------------
1 | package me.pringles.lcwebsocketclient.assets.packet;
2 |
3 |
4 | import com.google.gson.JsonArray;
5 | import com.google.gson.JsonObject;
6 | import com.google.gson.JsonParser;
7 | import lombok.Getter;
8 | import me.pringles.lcwebsocketclient.assets.AssetsPacket;
9 | import me.pringles.lcwebsocketclient.assets.Websocket;
10 | import me.pringles.lcwebsocketclient.util.ByteBufWrapper;
11 |
12 | import java.io.IOException;
13 |
14 | @Getter
15 | public class SPacketBulkFriends extends AssetsPacket {
16 |
17 | private String rawRequests;
18 | private JsonArray friends;
19 |
20 | @Override
21 | public void write(ByteBufWrapper wrapper) {
22 | }
23 |
24 | @Override
25 | public void read(ByteBufWrapper wrapper) throws IOException {
26 | this.rawRequests = wrapper.readString();
27 | JsonObject jsonObject = new JsonParser().parse(this.rawRequests).getAsJsonObject();
28 | System.out.println(jsonObject);
29 | this.friends = jsonObject.getAsJsonArray("bulk");
30 | }
31 |
32 | @Override
33 | public void handle(Websocket websocket) {
34 | //websocket.handleAuthentication(this);
35 | }
36 |
37 | }
38 |
39 |
--------------------------------------------------------------------------------
/src/main/java/me/pringles/lcwebsocketclient/assets/packet/SPacketConnection.java:
--------------------------------------------------------------------------------
1 | package me.pringles.lcwebsocketclient.assets.packet;
2 |
3 | import com.google.common.collect.ImmutableList;
4 | import lombok.*;
5 | import me.pringles.lcwebsocketclient.assets.AssetsPacket;
6 | import me.pringles.lcwebsocketclient.assets.Websocket;
7 | import me.pringles.lcwebsocketclient.util.ByteBufWrapper;
8 |
9 | import java.io.IOException;
10 | import java.util.HashMap;
11 | import java.util.Map;
12 |
13 | @Getter
14 | @ToString
15 | public class SPacketConnection extends AssetsPacket {
16 |
17 | private boolean consoleAllowed;
18 | public boolean friendRequestsEnabled;
19 | public Map> onlineFriends;
20 | public Map> offlineFriends;
21 |
22 | @Override
23 | public void write(ByteBufWrapper var1) {
24 |
25 | }
26 |
27 | @Override
28 | public void read(ByteBufWrapper var1) throws IOException {
29 | int n;
30 | this.consoleAllowed = var1.buf().readBoolean();
31 | this.friendRequestsEnabled = var1.buf().readBoolean();
32 | int n2 = var1.buf().readInt();
33 | int n3 = var1.buf().readInt();;
34 | this.onlineFriends = new HashMap<>();
35 | for (n = 0; n < n2; ++n) {
36 | this.onlineFriends.put(var1.readStringFromBuffer(52), ImmutableList.of(var1.readStringFromBuffer(32), String.valueOf(var1.buf().readInt()), var1.readStringFromBuffer(256)));
37 | }
38 | this.offlineFriends = new HashMap<>();
39 | for (n = 0; n < n3; ++n) {
40 | this.offlineFriends.put(var1.readStringFromBuffer(52), ImmutableList.of(var1.readStringFromBuffer(32), String.valueOf(var1.buf().readLong())));
41 | }
42 | System.out.println(this);
43 | }
44 |
45 | @Override
46 | public void handle(Websocket var1) {
47 | var1.handleConnection(this);
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/main/java/me/pringles/lcwebsocketclient/assets/packet/SPacketCosmetics.java:
--------------------------------------------------------------------------------
1 | package me.pringles.lcwebsocketclient.assets.packet;
2 |
3 | import me.pringles.lcwebsocketclient.assets.AssetsPacket;
4 |
5 | import me.pringles.lcwebsocketclient.assets.Websocket;
6 | import me.pringles.lcwebsocketclient.util.ByteBufWrapper;
7 |
8 | import java.util.ArrayList;
9 | import java.util.List;
10 | import java.util.UUID;
11 |
12 | public class SPacketCosmetics extends AssetsPacket {
13 | private UUID target;
14 | private List cosmetics;
15 | private int color = -1;
16 | private boolean thing;
17 | private boolean thing2;
18 | private boolean thing3;
19 |
20 | @Override
21 | public void write(ByteBufWrapper var1) {
22 |
23 | }
24 |
25 | @Override
26 | public void read(ByteBufWrapper var1) {
27 | target = new UUID(var1.buf().readLong(), var1.buf().readLong());
28 | int n = var1.readVarInt();
29 | cosmetics = new ArrayList(n);
30 | for (int i = 0; i < n; ++i) {
31 | int n2 = var1.readVarInt();
32 | boolean bl = var1.buf().readBoolean();
33 | System.out.println("Got cosmetic with id: " + n2 + " enabled: " + bl);
34 | try {
35 | this.cosmetics.add(n2);
36 | continue;
37 | }
38 | catch (Exception exception) {
39 | exception.printStackTrace();
40 | }
41 | }
42 | this.color = var1.buf().readInt();
43 | this.thing = var1.buf().readBoolean();
44 | this.thing2 = var1.buf().readBoolean();
45 | //this.thing3 = var1.buf().readBoolean();
46 | }
47 |
48 | @Override
49 | public void handle(Websocket var1) {
50 |
51 | }
52 |
53 |
54 | @Override
55 | public String toString() {
56 | return "SPacketCosmetics{" +
57 | "target=" + target +
58 | ", cosmetics=" + cosmetics +
59 | ", color=" + color +
60 | ", thing=" + thing +
61 | ", thing2=" + thing2 +
62 | ", thing3=" + thing3 +
63 | '}';
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/main/java/me/pringles/lcwebsocketclient/assets/packet/SPacketEmotes.java:
--------------------------------------------------------------------------------
1 | package me.pringles.lcwebsocketclient.assets.packet;
2 |
3 |
4 | import me.pringles.lcwebsocketclient.assets.AssetsPacket;
5 | import me.pringles.lcwebsocketclient.assets.Websocket;
6 | import me.pringles.lcwebsocketclient.util.ByteBufWrapper;
7 |
8 | import java.util.ArrayList;
9 | import java.util.List;
10 |
11 | public class SPacketEmotes extends AssetsPacket {
12 | private List list1;
13 | private List list2;
14 |
15 | @Override
16 | public void write(ByteBufWrapper wrapper) {
17 | }
18 |
19 | @Override
20 | public void read(ByteBufWrapper wrapper) {
21 | int n;
22 | int n2 = wrapper.readVarInt();
23 | this.list1 = new ArrayList();
24 | for (n = 0; n < n2; ++n) {
25 | this.list1.add(wrapper.readVarInt());
26 | }
27 | this.list2 = new ArrayList<>();
28 | for (n = 0; n < n2; ++n) {
29 | this.list2.add(wrapper.readVarInt());
30 | }
31 | }
32 |
33 | @Override
34 | public void handle(Websocket websocket) {
35 |
36 | }
37 |
38 | }
39 |
40 |
--------------------------------------------------------------------------------
/src/main/java/me/pringles/lcwebsocketclient/assets/packet/SPacketFormattedConsoleOutput.java:
--------------------------------------------------------------------------------
1 | package me.pringles.lcwebsocketclient.assets.packet;
2 |
3 |
4 | import lombok.AllArgsConstructor;
5 | import lombok.NoArgsConstructor;
6 | import me.pringles.lcwebsocketclient.assets.AssetsPacket;
7 | import me.pringles.lcwebsocketclient.assets.Websocket;
8 | import me.pringles.lcwebsocketclient.util.ByteBufWrapper;
9 |
10 | import java.io.IOException;
11 |
12 | @AllArgsConstructor
13 | @NoArgsConstructor
14 | public class SPacketFormattedConsoleOutput
15 | extends AssetsPacket {
16 | private String prefix;
17 | private String content;
18 |
19 | @Override
20 | public void write(ByteBufWrapper buf) {
21 | buf.writeString(this.prefix);
22 | buf.writeString(this.content);
23 | }
24 |
25 | @Override
26 | public void read(ByteBufWrapper buf) throws IOException {
27 | this.prefix = buf.readStringFromBuffer(128);
28 | this.content = buf.readStringFromBuffer(512);
29 | }
30 |
31 | @Override
32 | public void handle(Websocket websocket) {
33 | websocket.handleConsole(this);
34 | }
35 |
36 | public String getPrefix() {
37 | return this.prefix;
38 | }
39 |
40 | public String getContent() {
41 | return this.content;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/main/java/me/pringles/lcwebsocketclient/assets/packet/SPacketFriendUpdate.java:
--------------------------------------------------------------------------------
1 | package me.pringles.lcwebsocketclient.assets.packet;
2 |
3 |
4 | import lombok.AllArgsConstructor;
5 | import lombok.Getter;
6 | import lombok.NoArgsConstructor;
7 | import lombok.ToString;
8 | import me.pringles.lcwebsocketclient.assets.AssetsPacket;
9 | import me.pringles.lcwebsocketclient.assets.Websocket;
10 | import me.pringles.lcwebsocketclient.util.ByteBufWrapper;
11 |
12 | import java.io.IOException;
13 |
14 | @AllArgsConstructor
15 | @NoArgsConstructor
16 | @Getter
17 | @ToString
18 | public class SPacketFriendUpdate extends AssetsPacket {
19 | private String playerId;
20 | private String name;
21 | private boolean friend;
22 |
23 | @Override
24 | public void write(ByteBufWrapper wrapper) {
25 | wrapper.writeString(this.playerId);
26 | wrapper.writeString(this.name);
27 | wrapper.buf().writeBoolean(this.friend);
28 | }
29 |
30 | @Override
31 | public void read(ByteBufWrapper wrapper) throws IOException {
32 | this.playerId = wrapper.readStringFromBuffer(52);
33 | this.name = wrapper.readStringFromBuffer(32);
34 | this.friend = wrapper.buf().readBoolean();
35 | }
36 |
37 | @Override
38 | public void handle(Websocket websocket) {
39 | websocket.handleFriendUpdate(this);
40 | }
41 |
42 | }
43 |
44 |
--------------------------------------------------------------------------------
/src/main/java/me/pringles/lcwebsocketclient/assets/packet/ShPacketConsole.java:
--------------------------------------------------------------------------------
1 | package me.pringles.lcwebsocketclient.assets.packet;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Getter;
5 | import lombok.NoArgsConstructor;
6 | import me.pringles.lcwebsocketclient.assets.AssetsPacket;
7 | import me.pringles.lcwebsocketclient.assets.Websocket;
8 | import me.pringles.lcwebsocketclient.util.ByteBufWrapper;
9 |
10 | import java.io.IOException;
11 |
12 | @AllArgsConstructor
13 | @NoArgsConstructor
14 | public class ShPacketConsole extends AssetsPacket {
15 | @Getter
16 | private String output;
17 |
18 | @Override
19 | public void write(ByteBufWrapper buf) {
20 | buf.writeString(this.output);
21 | }
22 |
23 | @Override
24 | public void read(ByteBufWrapper buf) throws IOException {
25 | this.output = buf.readStringFromBuffer(32767);
26 | }
27 |
28 | @Override
29 | public void handle(Websocket websocket) {
30 | websocket.handleRawConsole(this);
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/me/pringles/lcwebsocketclient/assets/packet/ShPacketFriendRemove.java:
--------------------------------------------------------------------------------
1 | package me.pringles.lcwebsocketclient.assets.packet;
2 |
3 |
4 | import lombok.AllArgsConstructor;
5 | import lombok.Getter;
6 | import lombok.NoArgsConstructor;
7 | import me.pringles.lcwebsocketclient.assets.AssetsPacket;
8 | import me.pringles.lcwebsocketclient.assets.Websocket;
9 | import me.pringles.lcwebsocketclient.util.ByteBufWrapper;
10 |
11 | import java.io.IOException;
12 |
13 | @Getter
14 | @NoArgsConstructor
15 | @AllArgsConstructor
16 | public class ShPacketFriendRemove extends AssetsPacket {
17 | private String playerId;
18 |
19 | @Override
20 | public void write(ByteBufWrapper buf) {
21 | buf.writeString(this.playerId);
22 | }
23 |
24 | @Override
25 | public void read(ByteBufWrapper buf) throws IOException {
26 | this.playerId = buf.readStringFromBuffer(52);
27 | }
28 |
29 | @Override
30 | public void handle(Websocket websocket) {
31 | websocket.handleFriendRemove(this);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/me/pringles/lcwebsocketclient/assets/packet/ShPacketFriendRequest.java:
--------------------------------------------------------------------------------
1 | package me.pringles.lcwebsocketclient.assets.packet;
2 |
3 |
4 | import me.pringles.lcwebsocketclient.assets.AssetsPacket;
5 | import me.pringles.lcwebsocketclient.assets.Websocket;
6 | import me.pringles.lcwebsocketclient.util.ByteBufWrapper;
7 |
8 | import java.io.IOException;
9 |
10 | public class ShPacketFriendRequest
11 | extends AssetsPacket {
12 | private String playerId;
13 | private String name;
14 |
15 | public ShPacketFriendRequest() {
16 | }
17 |
18 | public ShPacketFriendRequest(String playerId, String name) {
19 | this.playerId = playerId;
20 | this.name = name;
21 | }
22 |
23 | @Override
24 | public void write(ByteBufWrapper buf) {
25 | buf.writeString(this.playerId);
26 | buf.writeString(this.name);
27 | }
28 |
29 | @Override
30 | public void read(ByteBufWrapper buf) throws IOException {
31 | this.playerId = buf.readStringFromBuffer(52);
32 | this.name = buf.readStringFromBuffer(32);
33 | }
34 |
35 | @Override
36 | public void handle(Websocket websocket) {
37 | websocket.handleFriendRequest(this);
38 | }
39 |
40 | public String getPlayerId() {
41 | return this.playerId;
42 | }
43 |
44 | public String getName() {
45 | return this.name;
46 | }
47 | }
48 |
49 |
--------------------------------------------------------------------------------
/src/main/java/me/pringles/lcwebsocketclient/assets/packet/ShPacketFriendRequestUpdate.java:
--------------------------------------------------------------------------------
1 | package me.pringles.lcwebsocketclient.assets.packet;
2 |
3 |
4 | import lombok.AllArgsConstructor;
5 | import lombok.NoArgsConstructor;
6 | import me.pringles.lcwebsocketclient.assets.AssetsPacket;
7 | import me.pringles.lcwebsocketclient.assets.Websocket;
8 | import me.pringles.lcwebsocketclient.util.ByteBufWrapper;
9 |
10 | import java.io.IOException;
11 |
12 | @NoArgsConstructor
13 | @AllArgsConstructor
14 | public class ShPacketFriendRequestUpdate
15 | extends AssetsPacket {
16 | private boolean add;
17 | private String playerId;
18 |
19 |
20 | @Override
21 | public void write(ByteBufWrapper buf) {
22 | buf.buf().writeBoolean(this.add);
23 | buf.writeString(this.playerId);
24 | }
25 |
26 | @Override
27 | public void read(ByteBufWrapper buf) throws IOException {
28 | this.add = buf.buf().readBoolean();
29 | this.playerId = buf.readStringFromBuffer(52);
30 | }
31 |
32 | @Override
33 | public void handle(Websocket websocket) {
34 | }
35 |
36 | public boolean isAdd() {
37 | return this.add;
38 | }
39 |
40 | public String lIIIIIIIIIlIllIIllIlIIlIl() {
41 | return this.playerId;
42 | }
43 | }
--------------------------------------------------------------------------------
/src/main/java/me/pringles/lcwebsocketclient/assets/packet/ShPacketFriendUpdate.java:
--------------------------------------------------------------------------------
1 | package me.pringles.lcwebsocketclient.assets.packet;
2 |
3 | import lombok.AllArgsConstructor;
4 | import lombok.Getter;
5 | import lombok.NoArgsConstructor;
6 | import me.pringles.lcwebsocketclient.assets.AssetsPacket;
7 | import me.pringles.lcwebsocketclient.assets.Websocket;
8 | import me.pringles.lcwebsocketclient.util.ByteBufWrapper;
9 |
10 | import java.io.IOException;
11 |
12 | @AllArgsConstructor
13 | @NoArgsConstructor
14 | @Getter
15 | public class ShPacketFriendUpdate extends AssetsPacket {
16 | private String playerId;
17 | private String name;
18 | private long status;
19 | private boolean online;
20 |
21 | @Override
22 | public void write(ByteBufWrapper buf) {
23 | buf.writeString(this.playerId);
24 | buf.writeString(this.name);
25 | buf.buf().writeLong(status);
26 | buf.buf().writeBoolean(online);
27 | }
28 |
29 | @Override
30 | public void read(ByteBufWrapper buf) throws IOException {
31 | this.playerId = buf.readStringFromBuffer(52);
32 | this.name = buf.readStringFromBuffer(32);
33 | this.status = buf.buf().readLong();
34 | this.online = buf.buf().readBoolean();
35 | }
36 |
37 | @Override
38 | public void handle(Websocket var1) {
39 | var1.handleFriendUpdate(this);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/me/pringles/lcwebsocketclient/assets/packet/ShPacketMessage.java:
--------------------------------------------------------------------------------
1 | package me.pringles.lcwebsocketclient.assets.packet;
2 |
3 |
4 | import lombok.AllArgsConstructor;
5 | import lombok.NoArgsConstructor;
6 | import me.pringles.lcwebsocketclient.assets.AssetsPacket;
7 | import me.pringles.lcwebsocketclient.assets.Websocket;
8 | import me.pringles.lcwebsocketclient.util.ByteBufWrapper;
9 |
10 | import java.io.IOException;
11 |
12 | @AllArgsConstructor
13 | @NoArgsConstructor
14 | public class ShPacketMessage
15 | extends AssetsPacket {
16 | private String playerId;
17 | private String message;
18 |
19 | @Override
20 | public void write(ByteBufWrapper buf) {
21 | buf.writeString(this.playerId);
22 | buf.writeString(this.message);
23 | }
24 |
25 | @Override
26 | public void read(ByteBufWrapper buf) throws IOException {
27 | this.playerId = buf.readStringFromBuffer(52);
28 | this.message = buf.readStringFromBuffer(1024);
29 | }
30 |
31 | @Override
32 | public void handle(Websocket websocket) {
33 | websocket.handleMessage(this);
34 | }
35 |
36 | public String getPlayerId() {
37 | return this.playerId;
38 | }
39 |
40 | public String getMessage() {
41 | return this.message;
42 | }
43 | }
44 |
45 |
--------------------------------------------------------------------------------
/src/main/java/me/pringles/lcwebsocketclient/assets/packet/ShPacketStatusUpdate.java:
--------------------------------------------------------------------------------
1 | package me.pringles.lcwebsocketclient.assets.packet;
2 |
3 |
4 | import lombok.AllArgsConstructor;
5 | import lombok.NoArgsConstructor;
6 | import me.pringles.lcwebsocketclient.assets.AssetsPacket;
7 | import me.pringles.lcwebsocketclient.assets.Websocket;
8 | import me.pringles.lcwebsocketclient.util.ByteBufWrapper;
9 |
10 | import java.io.IOException;
11 |
12 | @AllArgsConstructor
13 | @NoArgsConstructor
14 | public class ShPacketStatusUpdate extends AssetsPacket {
15 | private String playerId;
16 | private String server;
17 |
18 |
19 | @Override
20 | public void write(ByteBufWrapper buf) {
21 | buf.writeString(this.playerId);
22 | buf.writeString(this.server);
23 | }
24 |
25 | @Override
26 | public void read(ByteBufWrapper buf) throws IOException {
27 | this.playerId = buf.readStringFromBuffer(52);
28 | this.server = buf.readStringFromBuffer(100);
29 | }
30 |
31 | public void handle(Websocket websocket) {
32 | websocket.handleServerChange(this);
33 | }
34 |
35 | public String getServer() {
36 | return this.server;
37 | }
38 |
39 | public String getPlayerId() {
40 | return this.playerId;
41 | }
42 | }
--------------------------------------------------------------------------------
/src/main/java/me/pringles/lcwebsocketclient/assets/user/Status.java:
--------------------------------------------------------------------------------
1 | package me.pringles.lcwebsocketclient.assets.user;
2 |
3 | public enum Status {
4 | ONLINE( "Online"),
5 | AWAY("Away"),
6 | BUSY("Busy"),
7 | OFFLINE( "Offline");
8 |
9 | public final String name;
10 |
11 | Status(final String name) {
12 | this.name = name;
13 | }
14 |
15 | public String getName() {
16 | return this.name;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/me/pringles/lcwebsocketclient/auth/AuthWebsocket.java:
--------------------------------------------------------------------------------
1 | package me.pringles.lcwebsocketclient.auth;
2 |
3 | import com.google.gson.JsonObject;
4 | import com.google.gson.JsonParser;
5 | import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService;
6 | import com.mojang.authlib.yggdrasil.YggdrasilUserAuthentication;
7 | import me.pringles.lcwebsocketclient.Main;
8 | import me.pringles.lcwebsocketclient.auth.packet.AuthPacket;
9 | import me.pringles.lcwebsocketclient.auth.packet.auth.CPacketEncryptionResponse;
10 | import me.pringles.lcwebsocketclient.auth.packet.auth.SPacketAuthenticatedRequest;
11 | import me.pringles.lcwebsocketclient.auth.packet.auth.SPacketEncryptionRequest;
12 | import me.pringles.lcwebsocketclient.util.AuthUtil;
13 | import me.pringles.lcwebsocketclient.util.CryptManager;
14 | import org.java_websocket.client.WebSocketClient;
15 | import org.java_websocket.drafts.Draft_6455;
16 | import org.java_websocket.handshake.ServerHandshake;
17 |
18 | import javax.crypto.SecretKey;
19 | import java.math.BigInteger;
20 | import java.net.Proxy;
21 | import java.net.URI;
22 | import java.net.URISyntaxException;
23 | import java.nio.ByteBuffer;
24 | import java.nio.charset.StandardCharsets;
25 | import java.security.PublicKey;
26 | import java.util.Map;
27 | import java.util.UUID;
28 | import java.util.function.Consumer;
29 |
30 | public class AuthWebsocket extends WebSocketClient {
31 |
32 | public final Consumer consumer;
33 |
34 | public AuthWebsocket(final Map map, Consumer consumer) throws URISyntaxException {
35 | super(new URI("wss://authenticator.lunarclientprod.com"), new Draft_6455(), map, 3000);
36 | this.consumer = consumer;
37 | System.out.println("Connecting to authenticator websocket for authentication key.");
38 | }
39 |
40 | @Override
41 | public void onOpen(ServerHandshake serverHandshake) {
42 |
43 | }
44 |
45 | @Override
46 | public void onMessage(String s) {
47 | System.out.println(s);
48 | }
49 |
50 | @Override
51 | public void onMessage(ByteBuffer bytes) {
52 | JsonObject jsonObject = new JsonParser().parse(new String(bytes.array())).getAsJsonObject();
53 | System.out.println(jsonObject.toString());
54 | handleJson(jsonObject);
55 | }
56 |
57 | public void handleJson(JsonObject jsonObject) {
58 | AuthPacket authPacket;
59 | switch (jsonObject.get("packetType").getAsString()) {
60 | case "SPacketEncryptionRequest": {
61 | authPacket = new SPacketEncryptionRequest();
62 | break;
63 | }
64 | case "SPacketAuthenticatedRequest":{
65 | authPacket = new SPacketAuthenticatedRequest();
66 | break;
67 | }
68 | default:
69 | return;
70 | }
71 | authPacket.handle2(jsonObject);
72 | authPacket.handle(this);
73 | }
74 |
75 | public void handleEncryptionRequest(SPacketEncryptionRequest packetEncryptionRequest) {
76 | PublicKey publicKey = packetEncryptionRequest.publicKey;
77 | SecretKey secretKey = CryptManager.createNewSharedKey();
78 | byte[] byArray = CryptManager.getServerIdHash("", publicKey, secretKey);
79 | if (byArray == null) {
80 | return;
81 | }
82 |
83 | String serverId = new BigInteger(byArray).toString(16);
84 | System.out.println("Server ID: " + serverId);
85 | YggdrasilUserAuthentication auth = AuthUtil.getAuth(Main.getConfig().getEmail(), Main.getConfig().getPassword());
86 | try{
87 | new YggdrasilAuthenticationService(Proxy.NO_PROXY, UUID.randomUUID().toString()).createMinecraftSessionService().joinServer(auth.getSelectedProfile() ,auth.getAuthenticatedToken(), serverId);
88 | }catch (Exception e){
89 | e.printStackTrace();
90 | }
91 | this.sendPacket(new CPacketEncryptionResponse(secretKey, publicKey, packetEncryptionRequest.randomBytes));
92 | }
93 |
94 | public void handleAuthenticated(SPacketAuthenticatedRequest packetAuthenticatedRequest){
95 | this.close();
96 | this.consumer.accept(packetAuthenticatedRequest.jwtKey);
97 | }
98 | public void sendPacket(AuthPacket authPacket) {
99 | if(!this.isOpen()){
100 | return;
101 | }
102 | JsonObject jsonObject = new JsonObject();
103 | jsonObject.addProperty("packetType", authPacket.getName());
104 | try{
105 | authPacket.handle1(jsonObject);
106 | this.send(Main.gson.toJson(jsonObject).getBytes(StandardCharsets.UTF_8));
107 | System.out.println("Sent packet " + jsonObject);
108 | }catch (Exception e){
109 | e.printStackTrace();
110 | }
111 | }
112 |
113 |
114 | @Override
115 | public void onClose(int i, String s, boolean b) {
116 | }
117 |
118 | @Override
119 | public void onError(Exception e) {
120 | e.printStackTrace();
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/src/main/java/me/pringles/lcwebsocketclient/auth/packet/AuthPacket.java:
--------------------------------------------------------------------------------
1 | package me.pringles.lcwebsocketclient.auth.packet;
2 |
3 | import me.pringles.lcwebsocketclient.auth.AuthWebsocket;
4 |
5 | public abstract class AuthPacket extends Packet{
6 |
7 | public abstract void handle(AuthWebsocket websocket);
8 |
9 | public abstract String getName();
10 | }
11 |
--------------------------------------------------------------------------------
/src/main/java/me/pringles/lcwebsocketclient/auth/packet/Packet.java:
--------------------------------------------------------------------------------
1 | package me.pringles.lcwebsocketclient.auth.packet;
2 |
3 | public abstract class Packet {
4 |
5 | public abstract void handle1(Object var1);
6 |
7 | public abstract void handle2(Object var1);
8 | }
9 |
--------------------------------------------------------------------------------
/src/main/java/me/pringles/lcwebsocketclient/auth/packet/auth/CPacketEncryptionResponse.java:
--------------------------------------------------------------------------------
1 | package me.pringles.lcwebsocketclient.auth.packet.auth;
2 |
3 | import com.google.gson.JsonObject;
4 | import me.pringles.lcwebsocketclient.auth.AuthWebsocket;
5 | import me.pringles.lcwebsocketclient.auth.packet.AuthPacket;
6 | import me.pringles.lcwebsocketclient.util.CryptManager;
7 |
8 | import javax.crypto.SecretKey;
9 | import java.security.PublicKey;
10 | import java.util.Base64;
11 |
12 | public class CPacketEncryptionResponse extends AuthPacket {
13 |
14 | public final byte[] secretKey;
15 | public final byte[] publicKey;
16 |
17 | public CPacketEncryptionResponse(SecretKey secretKey, PublicKey publicKey, byte[] bytes) {
18 | this.secretKey = CryptManager.encryptData(publicKey, secretKey.getEncoded());
19 | this.publicKey = CryptManager.encryptData(publicKey, bytes);
20 | }
21 |
22 | @Override
23 | public void handle(AuthWebsocket websocket) {
24 |
25 | }
26 |
27 | @Override
28 | public String getName() {
29 | return "CPacketEncryptionResponse";
30 | }
31 |
32 | @Override
33 | public void handle1(Object var1) {
34 | this.parseJson((JsonObject) var1);
35 |
36 | }
37 |
38 | public void parseJson(JsonObject jsonObject){
39 | Base64.Encoder encoder = Base64.getUrlEncoder();
40 | jsonObject.addProperty("secretKey", new String(encoder.encode(this.secretKey)));
41 | jsonObject.addProperty("publicKey", new String(encoder.encode(this.publicKey)));
42 | }
43 |
44 | @Override
45 | public void handle2(Object var1) {
46 | this.parseJson((JsonObject) var1);
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/main/java/me/pringles/lcwebsocketclient/auth/packet/auth/SPacketAuthenticatedRequest.java:
--------------------------------------------------------------------------------
1 | package me.pringles.lcwebsocketclient.auth.packet.auth;
2 |
3 | import com.google.gson.JsonObject;
4 | import me.pringles.lcwebsocketclient.auth.AuthWebsocket;
5 | import me.pringles.lcwebsocketclient.auth.packet.AuthPacket;
6 |
7 | public class SPacketAuthenticatedRequest extends AuthPacket {
8 |
9 | public String jwtKey;
10 |
11 | @Override
12 | public void handle(AuthWebsocket websocket) {
13 | websocket.handleAuthenticated(this);
14 | }
15 |
16 | @Override
17 | public String getName() {
18 | return "SPacketAuthenticatedRequest";
19 | }
20 |
21 | public void handleJson(JsonObject jsonObject){
22 | this.jwtKey = jsonObject.get("jwtKey").getAsString();
23 | }
24 |
25 | @Override
26 | public void handle1(Object var1) {
27 | this.handleJson((JsonObject) var1);
28 | }
29 |
30 | @Override
31 | public void handle2(Object var1) {
32 | this.handleJson((JsonObject) var1);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/me/pringles/lcwebsocketclient/auth/packet/auth/SPacketEncryptionRequest.java:
--------------------------------------------------------------------------------
1 | package me.pringles.lcwebsocketclient.auth.packet.auth;
2 |
3 | import com.google.gson.JsonObject;
4 | import me.pringles.lcwebsocketclient.auth.AuthWebsocket;
5 | import me.pringles.lcwebsocketclient.auth.packet.AuthPacket;
6 |
7 | import java.security.KeyFactory;
8 | import java.security.NoSuchAlgorithmException;
9 | import java.security.PublicKey;
10 | import java.security.spec.InvalidKeySpecException;
11 | import java.security.spec.X509EncodedKeySpec;
12 | import java.util.Base64;
13 |
14 | public class SPacketEncryptionRequest extends AuthPacket {
15 |
16 | public PublicKey publicKey;
17 | public byte[] randomBytes;
18 | @Override
19 | public void handle(AuthWebsocket websocket) {
20 | websocket.handleEncryptionRequest(this);
21 | }
22 |
23 | @Override
24 | public String getName() {
25 | return "SPacketEncryptionRequest";
26 | }
27 |
28 | public void getFromJson(JsonObject jsonObject){
29 | Base64.Decoder decoder = Base64.getUrlDecoder();
30 | this.publicKey =getPublicKey(decoder.decode(jsonObject.get("publicKey").getAsString()));
31 | this.randomBytes = decoder.decode(jsonObject.get("randomBytes").getAsString());
32 |
33 | }
34 | @Override
35 | public void handle1(Object var1) {
36 | this.getFromJson(((JsonObject) var1));
37 | }
38 |
39 | @Override
40 | public void handle2(Object var1) {
41 | this.getFromJson(((JsonObject) var1));
42 | }
43 |
44 | public PublicKey getPublicKey(byte[] key){
45 | X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(key);
46 | try {
47 | KeyFactory kf = KeyFactory.getInstance("RSA");
48 | return kf.generatePublic(x509EncodedKeySpec);
49 | } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
50 | e.printStackTrace();
51 | }
52 | return null;
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/main/java/me/pringles/lcwebsocketclient/util/AuthUtil.java:
--------------------------------------------------------------------------------
1 | package me.pringles.lcwebsocketclient.util;
2 |
3 | import com.mojang.authlib.Agent;
4 | import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService;
5 | import com.mojang.authlib.yggdrasil.YggdrasilUserAuthentication;
6 |
7 | import java.net.Proxy;
8 |
9 | public class AuthUtil {
10 |
11 | public static YggdrasilUserAuthentication getAuth(final String username, final String password) {
12 | final YggdrasilAuthenticationService service = new YggdrasilAuthenticationService(Proxy.NO_PROXY, "");
13 | final YggdrasilUserAuthentication auth = (YggdrasilUserAuthentication) service.createUserAuthentication(Agent.MINECRAFT);
14 | auth.setUsername(username);
15 | auth.setPassword(password);
16 | try {
17 | auth.logIn();
18 | return auth;
19 | } catch (com.mojang.authlib.exceptions.AuthenticationException localAuthenticationException) {
20 | localAuthenticationException.printStackTrace();
21 | return null;
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/me/pringles/lcwebsocketclient/util/ByteBufWrapper.java:
--------------------------------------------------------------------------------
1 | package me.pringles.lcwebsocketclient.util;
2 |
3 | import com.google.common.base.Charsets;
4 | import io.netty.buffer.ByteBuf;
5 | import io.netty.buffer.ByteBufUtil;
6 |
7 | import java.io.IOException;
8 | import java.util.UUID;
9 | import java.util.function.Consumer;
10 | import java.util.function.Supplier;
11 |
12 | public class ByteBufWrapper {
13 |
14 | private final ByteBuf buf;
15 |
16 | public ByteBufWrapper(ByteBuf buf) {
17 | this.buf = buf;
18 | }
19 |
20 | public void writeVarInt(int b) {
21 | while ((b & 0xFFFFFF80) != 0x0) {
22 | this.buf.writeByte((b & 0x7F) | 0x80);
23 | b >>>= 7;
24 | }
25 | this.buf.writeByte(b);
26 | }
27 |
28 | public int readVarInt() {
29 | int i = 0;
30 | int chunk = 0;
31 | byte b;
32 | do {
33 | b = this.buf.readByte();
34 | i |= (b & 0x7F) << chunk++ * 7;
35 | if (chunk > 5) {
36 | throw new RuntimeException("VarInt too big");
37 | }
38 | } while ((b & 0x80) == 0x80);
39 | return i;
40 | }
41 |
42 | public String readStringFromBuffer(int p_150789_1_) throws IOException {
43 | int var2 = this.readVarInt();
44 |
45 | if (var2 > p_150789_1_ * 4) {
46 | throw new IOException("The received encoded string buffer length is longer than maximum allowed (" + var2 + " > " + p_150789_1_ * 4 + ")");
47 | } else if (var2 < 0) {
48 | throw new IOException("The received encoded string buffer length is less than zero! Weird string!");
49 | } else {
50 | String var3 = new String(ByteBufUtil.getBytes(this.buf.readBytes(var2)), Charsets.UTF_8);
51 |
52 | if (var3.length() > p_150789_1_) {
53 | throw new IOException("The received string length is longer than maximum allowed (" + var2 + " > " + p_150789_1_ + ")");
54 | } else {
55 | return var3;
56 | }
57 | }
58 | }
59 |
60 | public void writeOptional(T obj, Consumer consumer) {
61 | this.buf.writeBoolean(obj != null);
62 | if (obj != null) {
63 | consumer.accept(obj);
64 | }
65 | }
66 |
67 | public T readOptional(Supplier supplier) {
68 | boolean isPresent = this.buf.readBoolean();
69 | return isPresent ? supplier.get() : null;
70 | }
71 |
72 | public void writeString(String s) {
73 | byte[] arr = s.getBytes(Charsets.UTF_8);
74 | this.writeVarInt(arr.length);
75 | this.buf.writeBytes(arr);
76 | }
77 |
78 | public String readString() {
79 | int len = this.readVarInt();
80 | byte[] buffer = new byte[len];
81 | this.buf.readBytes(buffer);
82 | return new String(buffer, Charsets.UTF_8);
83 | }
84 |
85 | public void writeUUID(UUID uuid) {
86 | this.buf.writeLong(uuid.getMostSignificantBits());
87 | this.buf.writeLong(uuid.getLeastSignificantBits());
88 | }
89 |
90 | public UUID readUUID() {
91 | long mostSigBits = this.buf.readLong();
92 | long leastSigBits = this.buf.readLong();
93 | return new UUID(mostSigBits, leastSigBits);
94 | }
95 |
96 | public ByteBuf buf() {
97 | return this.buf;
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/src/main/java/me/pringles/lcwebsocketclient/util/Config.java:
--------------------------------------------------------------------------------
1 | package me.pringles.lcwebsocketclient.util;
2 |
3 | import lombok.Getter;
4 |
5 | import java.io.FileInputStream;
6 | import java.io.IOException;
7 | import java.io.InputStream;
8 | import java.util.Properties;
9 |
10 | @Getter
11 | public class Config {
12 | private String uuid;
13 | private String username;
14 | private String email;
15 | private String password;
16 |
17 | public Config(){
18 | Properties properties = new Properties();
19 | InputStream inputStream = null;
20 | try{
21 | inputStream = new FileInputStream("config.properties");
22 | properties.load(inputStream);
23 |
24 | this.uuid = properties.getProperty("uuid");
25 | this.username = properties.getProperty("user");
26 | this.email = properties.getProperty("email");
27 | this.password = properties.getProperty("password");
28 | }catch (Exception ignored){}
29 | finally {
30 | if (inputStream != null) {
31 | try {
32 | inputStream.close();
33 | } catch (IOException e) {
34 | e.printStackTrace();
35 | }
36 | }
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/me/pringles/lcwebsocketclient/util/CryptManager.java:
--------------------------------------------------------------------------------
1 | package me.pringles.lcwebsocketclient.util;
2 |
3 |
4 |
5 | import javax.crypto.*;
6 | import javax.crypto.spec.IvParameterSpec;
7 | import javax.crypto.spec.SecretKeySpec;
8 | import java.io.UnsupportedEncodingException;
9 | import java.security.*;
10 | import java.security.spec.EncodedKeySpec;
11 | import java.security.spec.InvalidKeySpecException;
12 | import java.security.spec.X509EncodedKeySpec;
13 |
14 | public class CryptManager
15 | {
16 |
17 | /**
18 | * Generate a new shared secret AES key from a secure random source
19 | */
20 | public static SecretKey createNewSharedKey()
21 | {
22 | try
23 | {
24 | KeyGenerator keygenerator = KeyGenerator.getInstance("AES");
25 | keygenerator.init(128);
26 | return keygenerator.generateKey();
27 | }
28 | catch (NoSuchAlgorithmException nosuchalgorithmexception)
29 | {
30 | throw new Error(nosuchalgorithmexception);
31 | }
32 | }
33 |
34 | /**
35 | * Generates RSA KeyPair
36 | */
37 | public static KeyPair generateKeyPair()
38 | {
39 | try
40 | {
41 | KeyPairGenerator keypairgenerator = KeyPairGenerator.getInstance("RSA");
42 | keypairgenerator.initialize(1024);
43 | return keypairgenerator.generateKeyPair();
44 | }
45 | catch (NoSuchAlgorithmException nosuchalgorithmexception)
46 | {
47 | nosuchalgorithmexception.printStackTrace();
48 | return null;
49 | }
50 | }
51 |
52 | /**
53 | * Compute a serverId hash for use by sendSessionRequest()
54 | */
55 | public static byte[] getServerIdHash(String serverId, PublicKey publicKey, SecretKey secretKey)
56 | {
57 | try
58 | {
59 | return digestOperation("SHA-1", serverId.getBytes("ISO_8859_1"), secretKey.getEncoded(), publicKey.getEncoded());
60 | }
61 | catch (UnsupportedEncodingException unsupportedencodingexception)
62 | {
63 | unsupportedencodingexception.printStackTrace();
64 | return null;
65 | }
66 | }
67 |
68 | /**
69 | * Compute a message digest on arbitrary byte[] data
70 | */
71 | private static byte[] digestOperation(String algorithm, byte[]... data)
72 | {
73 | try
74 | {
75 | MessageDigest messagedigest = MessageDigest.getInstance(algorithm);
76 |
77 | for (byte[] abyte : data)
78 | {
79 | messagedigest.update(abyte);
80 | }
81 |
82 | return messagedigest.digest();
83 | }
84 | catch (NoSuchAlgorithmException nosuchalgorithmexception)
85 | {
86 | nosuchalgorithmexception.printStackTrace();
87 | return null;
88 | }
89 | }
90 |
91 | /**
92 | * Create a new PublicKey from encoded X.509 data
93 | */
94 | public static PublicKey decodePublicKey(byte[] encodedKey)
95 | {
96 | try
97 | {
98 | EncodedKeySpec encodedkeyspec = new X509EncodedKeySpec(encodedKey);
99 | KeyFactory keyfactory = KeyFactory.getInstance("RSA");
100 | return keyfactory.generatePublic(encodedkeyspec);
101 | }
102 | catch (NoSuchAlgorithmException var3)
103 | {
104 | ;
105 | }
106 | catch (InvalidKeySpecException var4)
107 | {
108 | ;
109 | }
110 |
111 | return null;
112 | }
113 |
114 | /**
115 | * Decrypt shared secret AES key using RSA private key
116 | */
117 | public static SecretKey decryptSharedKey(PrivateKey key, byte[] secretKeyEncrypted)
118 | {
119 | return new SecretKeySpec(decryptData(key, secretKeyEncrypted), "AES");
120 | }
121 |
122 | /**
123 | * Encrypt byte[] data with RSA public key
124 | */
125 | public static byte[] encryptData(Key key, byte[] data)
126 | {
127 | return cipherOperation(1, key, data);
128 | }
129 |
130 | /**
131 | * Decrypt byte[] data with RSA private key
132 | */
133 | public static byte[] decryptData(Key key, byte[] data)
134 | {
135 | return cipherOperation(2, key, data);
136 | }
137 |
138 | /**
139 | * Encrypt or decrypt byte[] data using the specified key
140 | */
141 | private static byte[] cipherOperation(int opMode, Key key, byte[] data)
142 | {
143 | try
144 | {
145 | return createTheCipherInstance(opMode, key.getAlgorithm(), key).doFinal(data);
146 | }
147 | catch (IllegalBlockSizeException illegalblocksizeexception)
148 | {
149 | illegalblocksizeexception.printStackTrace();
150 | }
151 | catch (BadPaddingException badpaddingexception)
152 | {
153 | badpaddingexception.printStackTrace();
154 | }
155 |
156 | return null;
157 | }
158 |
159 | /**
160 | * Creates the Cipher Instance.
161 | */
162 | private static Cipher createTheCipherInstance(int opMode, String transformation, Key key)
163 | {
164 | try
165 | {
166 | Cipher cipher = Cipher.getInstance(transformation);
167 | cipher.init(opMode, key);
168 | return cipher;
169 | }
170 | catch (InvalidKeyException invalidkeyexception)
171 | {
172 | invalidkeyexception.printStackTrace();
173 | }
174 | catch (NoSuchAlgorithmException nosuchalgorithmexception)
175 | {
176 | nosuchalgorithmexception.printStackTrace();
177 | }
178 | catch (NoSuchPaddingException nosuchpaddingexception)
179 | {
180 | nosuchpaddingexception.printStackTrace();
181 | }
182 |
183 | return null;
184 | }
185 |
186 | /**
187 | * Creates an Cipher instance using the AES/CFB8/NoPadding algorithm. Used for protocol encryption.
188 | */
189 | public static Cipher createNetCipherInstance(int opMode, Key key)
190 | {
191 | try
192 | {
193 | Cipher cipher = Cipher.getInstance("AES/CFB8/NoPadding");
194 | cipher.init(opMode, key, new IvParameterSpec(key.getEncoded()));
195 | return cipher;
196 | }
197 | catch (GeneralSecurityException generalsecurityexception)
198 | {
199 | throw new RuntimeException(generalsecurityexception);
200 | }
201 | }
202 | }
203 |
--------------------------------------------------------------------------------