Skip to content

Commit

Permalink
2.1.14
Browse files Browse the repository at this point in the history
  • Loading branch information
AnyBananaGAME committed Dec 20, 2024
1 parent 87a3396 commit ef925e7
Show file tree
Hide file tree
Showing 40 changed files with 341 additions and 3,017 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ client.on("spawn", () => {

## 📜 Changelog

### 2.1.14
- Use latest version of Raknet
- Fixes

### 2.1.13
- Added support for Minecraft 1.21.50.
- Fixed many bugs.
Expand Down
7 changes: 3 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@sanctumterra/client",
"version": "2.1.13",
"version": "2.1.14",
"minecraft": "1.21.50",
"description": "We'll be singing Baraye.",
"main": "./dist/index.js",
Expand Down Expand Up @@ -35,12 +35,11 @@
"why-is-node-running": "^3.2.0"
},
"dependencies": {
"@sanctumterra/raknet": "^1.3.60",
"@sanctumterra/rs-rak-client": "^1.0.63",
"@sanctumterra/raknet": "^1.3.66",
"@serenityjs/binarystream": "^2.6.6",
"@serenityjs/block": "^0.4.4",
"@serenityjs/network": "^0.4.4",
"@serenityjs/protocol": "^0.6.1-beta-20241119050127",
"@serenityjs/protocol": "^0.6.4-beta-20241210051348",
"@serenityjs/raknet": "^0.6.2-beta-20241128210118",
"@serenityjs/world": "^0.4.4",
"@types/node": "^22.7.5",
Expand Down
97 changes: 37 additions & 60 deletions src/Client.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,14 @@
import {
PlayerBlockActions,
BlockAction,
BlockFace,
BlockPosition,
ComplexInventoryTransaction,
InputMode,
InputTransaction,
InteractionMode,
InventoryTransaction,
InventoryTransactionPacket,
ItemUseInventoryTransaction,
ItemUseInventoryTransactionType,
LegacyTransaction,
type MovePlayerPacket,
NetworkItemStackDescriptor,
PlayerActionPacket,
PlayerAuthInputData,
PlayMode,
TextPacket,
TextPacketType,
Expand All @@ -25,15 +18,19 @@ import {
PlayerActionType,
PlayerBlockActionData,
InputData,
type PlayerAuthInputPacket as ProtocolPlayerAuthInputPacket,
} from "@serenityjs/protocol";
import { Priority } from "@serenityjs/raknet";
import type { ClientOptions } from "./client/ClientOptions";
import { Inventory } from "./client/inventory/Inventory";
import { Connection } from "./Connection";
import { Logger } from "./vendor/Logger";
import { Queue } from "./vendor/Queue";
import { PlayerAuthInputPacket } from "./vendor/packets/player-auth-input";
import type { PlayerAuthInputPacket as PAIP } from "@serenityjs/protocol";
import {
InputTransaction,
PlayerAuthInputData,
PlayerAuthInputPacket as CustomPlayerAuthInputPacket,
} from "./vendor/packets/player-auth-input";

class Client extends Connection {
private sneaking = false;
Expand Down Expand Up @@ -62,7 +59,12 @@ class Client extends Connection {
}

private onMovePlayer(instance: MovePlayerPacket): void {
this.position = instance.position;
if (instance.runtimeId === this.runtimeEntityId) {
this.position = instance.position;
this.pitch = instance.pitch;
this.yaw = instance.yaw;
this.headYaw = instance.headYaw;
}
}

private handleAuthInput(): void {
Expand All @@ -78,8 +80,8 @@ class Client extends Connection {
inputData.setFlag(InputData.Sneaking, true);
}

const packet = new PlayerAuthInputPacket();
packet.rotation = new Vector2f(this.velocity.x, this.velocity.z);
const packet = new CustomPlayerAuthInputPacket();
packet.rotation = new Vector2f(this.pitch, this.yaw);
packet.position = this.position;
packet.motion = new Vector2f(this.velocity.x, this.velocity.z);
packet.headYaw = this.headYaw;
Expand All @@ -88,19 +90,20 @@ class Client extends Connection {
packet.playMode = PlayMode.Screen;
packet.interactionMode = InteractionMode.Touch;
packet.interactRotation = new Vector2f(0, 0);
packet.tick = BigInt(this.tick);
packet.inputTick = BigInt(this.tick);
packet.positionDelta = new Vector3f(0, 0, 0);
packet.itemStackRequest = null;
packet.blockActions = null;
packet.predictedVehicle = null;
packet.analogueMotion = new Vector2f(0, 0);
packet.cameraOrientation = new Vector3f(0, 0, 0);
packet.rawMoveVector = new Vector2f(0, 0);
const cancel = false;
this.emit("PrePlayerAuthInputPacket", packet, cancel);
if (!cancel) {
// this.sendPacket(packet, Priority.Immediate);
this.sendPacket(packet, Priority.Immediate);
}
}, 100);
}, 50);
}

public sendMessage(text: string): void {
Expand Down Expand Up @@ -211,7 +214,7 @@ class Client extends Connection {
*/
public async breakBlock(position: Vector3f, ticks = 5): Promise<void> {
const MAX_DISTANCE = 5;
const TICK_INTERVAL = 100;
const TICK_INTERVAL = 50;

const isBlockTooFar = (
playerPosition: Vector3f,
Expand All @@ -225,38 +228,33 @@ class Client extends Connection {
};

const modifyNextPacket = (
modifier: (packet: PlayerAuthInputPacket) => void,
modifier: (packet: CustomPlayerAuthInputPacket) => void,
): Promise<void> => {
return new Promise((resolve) => {
this.once(
"PrePlayerAuthInputPacket",
// @ts-expect-error meh
(packet: PlayerAuthInputPacket, _cancel: boolean) => {
modifier(packet);
resolve();
},
);
const handler = (
packet: ProtocolPlayerAuthInputPacket,
cancel: boolean,
) => {
modifier(packet as unknown as CustomPlayerAuthInputPacket);
this.removeListener("PrePlayerAuthInputPacket", handler);
resolve();
};
this.on("PrePlayerAuthInputPacket", handler);
});
};

const sleep = (ms: number): Promise<void> =>
new Promise((resolve) => setTimeout(resolve, ms));

if (isBlockTooFar(this.position, position)) {
Logger.warn(
`The block is too far from the player. Max distance is ${MAX_DISTANCE} blocks.`,
);
return;
}

const startTick = Number(this.tick);
const endTick = startTick + ticks;

this.lookAt(position.x, position.y, position.z);

const face = this.calculateFace(position);

// Start Break
await modifyNextPacket((packet: PlayerAuthInputPacket) => {
await modifyNextPacket((packet: CustomPlayerAuthInputPacket) => {
packet.blockActions = new PlayerBlockActions([
new PlayerBlockActionData(
PlayerActionType.StartDestroyBlock,
Expand All @@ -265,13 +263,12 @@ class Client extends Connection {
),
new PlayerBlockActionData(PlayerActionType.CrackBlock, position, face),
]);
this.lookAt(position.x, position.y, position.z);
packet.inputData.setFlag(InputData.PerformBlockActions, true);
});

// Crack Break
for (let tick = startTick + 1; tick < endTick; tick++) {
await modifyNextPacket((packet: PlayerAuthInputPacket) => {
for (let i = 0; i < ticks; i++) {
await modifyNextPacket((packet: CustomPlayerAuthInputPacket) => {
this.lookAt(position.x, position.y, position.z);
packet.blockActions = new PlayerBlockActions([
new PlayerBlockActionData(
Expand All @@ -282,14 +279,15 @@ class Client extends Connection {
]);
packet.inputData.setFlag(InputData.PerformBlockActions, true);
});
await sleep(TICK_INTERVAL);
await new Promise((resolve) => setTimeout(resolve, TICK_INTERVAL));
}

// Stop Break
await modifyNextPacket((packet: PlayerAuthInputPacket) => {
await modifyNextPacket((packet: CustomPlayerAuthInputPacket) => {
this.lookAt(position.x, position.y, position.z);
packet.inputData.setFlag(InputData.PerformBlockActions, true);
packet.inputData.setFlag(InputData.StartUsingItem, true);
this.lookAt(position.x, position.y, position.z);
packet.inputData.setFlag(InputData.PerformItemInteraction, true);
packet.blockActions = new PlayerBlockActions([
new PlayerBlockActionData(
PlayerActionType.StopDestroyBlock,
Expand All @@ -313,28 +311,7 @@ class Client extends Connection {
false,
),
);

// packet.blockActions = new PlayerBlockActions([
// new PlayerBlockActionData(PlayerActionType.StopDestroyBlock, position, face),
// ]);
// packet.transaction = new InputTransaction(
// new LegacyTransaction(0, []),
// [],
// new ItemUseInventoryTransaction(
// ItemUseInventoryTransactionType.Destroy,
// TriggerType.Unknown,
// position,
// this.calculateFace(position),
// 0,
// new NetworkItemStackDescriptor(0),
// this.position,
// new Vector3f(0, 0, 0),
// 0,
// false,
// ),
// );
});
await sleep(TICK_INTERVAL);
}

/**
Expand Down
84 changes: 51 additions & 33 deletions src/Connection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,12 @@ class Connection extends Listener {

@measureExecutionTime
public async connect(): Promise<[Advertisement, StartGamePacket]> {
return await this.initializeSession();
try {
return await this.initializeSession();
} catch (error) {
Logger.error("Connection failed:", error as Error);
throw error;
}
}

public disconnect(clientSide = true, packet: DisconnectPacket | null = null) {
Expand All @@ -98,12 +103,10 @@ class Connection extends Listener {
disconnectPacket.message = new DisconnectMessage();
disconnectPacket.hideDisconnectScreen = true;
this.sendPacket(disconnectPacket, Priority.Immediate);
// this.raknet.close();
} else {
// this.raknet.close();
}
clearInterval(this.ticker);
this.removeAllListeners();
// this.raknet.close();
}

@measureExecutionTime
Expand All @@ -113,15 +116,16 @@ class Connection extends Listener {
): void {
const packetId = packet.getId();
const hexId = packetId.toString(16).padStart(2, "0");
if (this.options.debug)
if (this.options.debug) {
Logger.debug(
`Sending Game PACKET --> ${packetId} | 0x${hexId} ${new Date().toISOString()}`,
);
}
try {
this.packetSorter.sendPacket(packet, priority);
} catch (error) {
console.log(error);
Logger.error("Error sending packet: ", error as Error);
Logger.error("Error sending packet:", error as Error);
throw error;
}
}

Expand Down Expand Up @@ -153,24 +157,32 @@ class Connection extends Listener {
}

@measureExecutionTime
private initializeSession(): Promise<[Advertisement, StartGamePacket]> {
private async initializeSession(): Promise<[Advertisement, StartGamePacket]> {
return new Promise((resolve, reject) => {
let Advertisement_: Advertisement;
this.once("session", async () => {
Advertisement_ = await this.handleSessionStart();
console.timeEnd("RakConnect");
// this.raknet.frameAndSend(Buffer.from([254, 0, 236, 151, 151, 151]))
});
let startGamePacket: StartGamePacket;
this.once("StartGamePacket", (packet: StartGamePacket) => {
resolve([Advertisement_, packet]);
startGamePacket = packet;
this.once("spawn", () => {
resolve([Advertisement_, startGamePacket]);
});
});
this.options.offline ? createOfflineSession(this) : authenticate(this);
});
}

@measureExecutionTime
private async handleSessionStart(): Promise<Advertisement> {
return await this.raknet.connect();
try {
return await this.raknet.connect();
} catch (error) {
Logger.error("RakNet connection error:", error as Error);
throw error;
}
}

@measureExecutionTime
Expand Down Expand Up @@ -269,34 +281,40 @@ class Connection extends Listener {
publicKey: KeyObject,
): Buffer {
this.validateKeys(privateKey, publicKey);

const curve = privateKey.asymmetricKeyDetails?.namedCurve;
if (!curve) {
throw new Error(
"Invalid private key format. Expected JWK with named curve.",
);
throw new Error("Invalid private key format. Named curve is missing.");
}

const ecdh = createECDH(curve);
const privateKeyJwk = privateKey.export({ format: "jwk" }) as {
d?: string;
};
const publicKeyJwk = publicKey.export({ format: "jwk" }) as {
x?: string;
y?: string;
};

if (!privateKeyJwk.d || !publicKeyJwk.x || !publicKeyJwk.y) {
throw new Error("Invalid key format");
}
try {
const ecdh = createECDH(curve);
const privateKeyJwk = privateKey.export({ format: "jwk" }) as {
d?: string;
};
const publicKeyJwk = publicKey.export({ format: "jwk" }) as {
x?: string;
y?: string;
};

if (!privateKeyJwk.d || !publicKeyJwk.x || !publicKeyJwk.y) {
throw new Error(
"Invalid key format. Missing 'd', 'x', or 'y' parameters.",
);
}

ecdh.setPrivateKey(Buffer.from(privateKeyJwk.d, "base64"));
const publicKeyBuffer = Buffer.concat([
Buffer.from([0x04]),
Buffer.from(publicKeyJwk.x, "base64"),
Buffer.from(publicKeyJwk.y, "base64"),
]);
ecdh.setPrivateKey(Buffer.from(privateKeyJwk.d, "base64"));
const publicKeyBuffer = Buffer.concat([
Buffer.from([0x04]),
Buffer.from(publicKeyJwk.x, "base64"),
Buffer.from(publicKeyJwk.y, "base64"),
]);

return ecdh.computeSecret(publicKeyBuffer);
return ecdh.computeSecret(publicKeyBuffer);
} catch (error) {
Logger.error("Error computing shared secret:", error as Error);
throw new Error("Failed to create shared secret."); // More general error message
}
}

@measureExecutionTime
Expand Down
Loading

0 comments on commit ef925e7

Please sign in to comment.