Skip to content

Commit 5d63517

Browse files
committed
Merge branch 'master' into feature/packetmine-rewrite
2 parents edfa84d + 0837af3 commit 5d63517

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+895
-641
lines changed

build.gradle.kts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,12 @@ subprojects {
8585

8686
if (path == ":common") return@subprojects
8787

88+
loom.runs {
89+
all {
90+
property("lambda.dev", "youtu.be/RYnFIRc0k6E")
91+
}
92+
}
93+
8894
tasks {
8995
register<Exec>("renderDoc") {
9096
val javaHome = Jvm.current().javaHome
@@ -144,7 +150,7 @@ allprojects {
144150
tasks {
145151
compileKotlin {
146152
compilerOptions {
147-
jvmTarget.set(JvmTarget.JVM_17)
153+
jvmTarget = JvmTarget.JVM_17
148154
}
149155
}
150156
}

common/build.gradle.kts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ val fabricLoaderVersion: String by project
2222
val kotlinxCoroutinesVersion: String by project
2323
val discordIPCVersion: String by project
2424
val fuelVersion: String by project
25+
val resultVersion: String by project
2526

2627
base.archivesName = "${base.archivesName.get()}-api"
2728

@@ -46,9 +47,10 @@ dependencies {
4647
implementation("com.github.Edouard127:KDiscordIPC:$discordIPCVersion")
4748
implementation("com.pngencoder:pngencoder:0.15.0")
4849

49-
// Fuel HTTP library
50+
// Fuel HTTP library and dependencies
5051
implementation("com.github.kittinunf.fuel:fuel:$fuelVersion")
5152
implementation("com.github.kittinunf.fuel:fuel-gson:$fuelVersion")
53+
implementation("com.github.kittinunf.result:result-jvm:$resultVersion")
5254

5355
// Add Kotlin
5456
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlinxCoroutinesVersion")

common/src/main/java/com/lambda/mixin/network/ClientPlayNetworkHandlerMixin.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,11 @@
2020
import com.lambda.event.EventFlow;
2121
import com.lambda.event.events.InventoryEvent;
2222
import com.lambda.module.modules.render.NoRender;
23+
import com.lambda.event.events.WorldEvent;
2324
import net.minecraft.client.network.ClientPlayNetworkHandler;
25+
import net.minecraft.client.network.PlayerListEntry;
26+
import net.minecraft.network.packet.s2c.play.GameJoinS2CPacket;
27+
import net.minecraft.network.packet.s2c.play.PlayerListS2CPacket;
2428
import net.minecraft.network.packet.s2c.play.ScreenHandlerSlotUpdateS2CPacket;
2529
import net.minecraft.network.packet.s2c.play.UpdateSelectedSlotS2CPacket;
2630
import org.spongepowered.asm.mixin.Mixin;
@@ -31,6 +35,24 @@
3135

3236
@Mixin(ClientPlayNetworkHandler.class)
3337
public class ClientPlayNetworkHandlerMixin {
38+
@Inject(method = "onGameJoin(Lnet/minecraft/network/packet/s2c/play/GameJoinS2CPacket;)V", at = @At("TAIL"))
39+
void injectJoinPacket(GameJoinS2CPacket packet, CallbackInfo ci) {
40+
EventFlow.post(new WorldEvent.Join());
41+
}
42+
43+
@Inject(method = "handlePlayerListAction(Lnet/minecraft/network/packet/s2c/play/PlayerListS2CPacket$Action;Lnet/minecraft/network/packet/s2c/play/PlayerListS2CPacket$Entry;Lnet/minecraft/client/network/PlayerListEntry;)V", at = @At("TAIL"))
44+
void injectPlayerList(PlayerListS2CPacket.Action action, PlayerListS2CPacket.Entry receivedEntry, PlayerListEntry currentEntry, CallbackInfo ci) {
45+
if (action != PlayerListS2CPacket.Action.ADD_PLAYER) return;
46+
47+
var name = currentEntry.getProfile().getName();
48+
var uuid = currentEntry.getProfile().getId();
49+
50+
if (receivedEntry.listed())
51+
EventFlow.post(new WorldEvent.Player.Join(name, uuid, currentEntry));
52+
else
53+
EventFlow.post(new WorldEvent.Player.Leave(name, uuid, currentEntry));
54+
}
55+
3456
@Inject(method = "onUpdateSelectedSlot", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/NetworkThreadUtils;forceMainThread(Lnet/minecraft/network/packet/Packet;Lnet/minecraft/network/listener/PacketListener;Lnet/minecraft/util/thread/ThreadExecutor;)V", shift = At.Shift.AFTER), cancellable = true)
3557
private void onUpdateSelectedSlot(UpdateSelectedSlotS2CPacket packet, CallbackInfo ci) {
3658
if (EventFlow.post(new InventoryEvent.HotbarSlot.Sync(packet.getSlot())).isCanceled()) ci.cancel();
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Copyright 2025 Lambda
3+
*
4+
* This program is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation, either version 3 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
package com.lambda.mixin.render;
19+
20+
import com.lambda.module.modules.client.Capes;
21+
import com.lambda.network.CapeManager;
22+
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
23+
import net.minecraft.client.network.AbstractClientPlayerEntity;
24+
import net.minecraft.client.render.VertexConsumerProvider;
25+
import net.minecraft.client.render.entity.feature.CapeFeatureRenderer;
26+
import net.minecraft.client.util.math.MatrixStack;
27+
import net.minecraft.util.Identifier;
28+
import org.spongepowered.asm.mixin.Mixin;
29+
import org.spongepowered.asm.mixin.injection.At;
30+
31+
@Mixin(CapeFeatureRenderer.class)
32+
public class CapeFeatureRendererMixin {
33+
@ModifyExpressionValue(method = "render(Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;ILnet/minecraft/client/network/AbstractClientPlayerEntity;FFFFFF)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/util/SkinTextures;capeTexture()Lnet/minecraft/util/Identifier;"))
34+
Identifier renderCape(Identifier original, MatrixStack matrixStack, VertexConsumerProvider vertexConsumerProvider, int i, AbstractClientPlayerEntity player, float f, float g, float h, float j, float k, float l) {
35+
if (!Capes.INSTANCE.isEnabled() || !CapeManager.INSTANCE.containsKey(player.getUuid())) return original;
36+
37+
return Identifier.of("lambda", CapeManager.INSTANCE.get(player.getUuid()));
38+
}
39+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Copyright 2025 Lambda
3+
*
4+
* This program is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation, either version 3 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
package com.lambda.mixin.render;
19+
20+
import com.lambda.module.modules.client.Capes;
21+
import com.lambda.network.CapeManager;
22+
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
23+
import net.minecraft.client.render.VertexConsumerProvider;
24+
import net.minecraft.client.render.entity.feature.ElytraFeatureRenderer;
25+
import net.minecraft.client.util.math.MatrixStack;
26+
import net.minecraft.entity.LivingEntity;
27+
import net.minecraft.util.Identifier;
28+
import org.spongepowered.asm.mixin.Mixin;
29+
import org.spongepowered.asm.mixin.injection.At;
30+
31+
@Mixin(ElytraFeatureRenderer.class)
32+
public class ElytraFeatureRendererMixin<T extends LivingEntity> {
33+
@ModifyExpressionValue(method = "render(Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;ILnet/minecraft/entity/LivingEntity;FFFFFF)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/util/SkinTextures;elytraTexture()Lnet/minecraft/util/Identifier;"))
34+
Identifier renderElytra(Identifier original, MatrixStack matrixStack, VertexConsumerProvider vertexConsumerProvider, int i, T livingEntity, float f, float g, float h, float j, float k, float l) {
35+
if (!Capes.INSTANCE.isEnabled() || !CapeManager.INSTANCE.containsKey(livingEntity.getUuid())) return original;
36+
37+
return Identifier.of("lambda", CapeManager.INSTANCE.get(livingEntity.getUuid()));
38+
}
39+
}

common/src/main/java/com/lambda/mixin/world/ClientWorldMixin.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,12 @@
2323
import com.lambda.module.modules.render.WorldColors;
2424
import com.lambda.util.math.ColorKt;
2525
import net.minecraft.block.BlockState;
26+
import net.minecraft.client.network.ClientPlayNetworkHandler;
27+
import net.minecraft.client.render.WorldRenderer;
2628
import net.minecraft.client.world.ClientWorld;
2729
import net.minecraft.entity.Entity;
30+
import net.minecraft.registry.RegistryKey;
31+
import net.minecraft.registry.entry.RegistryEntry;
2832
import net.minecraft.util.math.BlockPos;
2933
import net.minecraft.util.math.Vec3d;
3034
import org.spongepowered.asm.mixin.Mixin;
@@ -33,6 +37,8 @@
3337
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
3438
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
3539

40+
import java.util.function.Supplier;
41+
3642
@Mixin(ClientWorld.class)
3743
public class ClientWorldMixin {
3844
@Inject(method = "addEntity", at = @At("HEAD"), cancellable = true)

common/src/main/kotlin/com/lambda/Lambda.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ object Lambda {
4747
@JvmStatic
4848
val mc: MinecraftClient by lazy { MinecraftClient.getInstance() }
4949

50+
val isDebug = System.getProperty("lambda.dev") != null
51+
5052
val gson: Gson = GsonBuilder()
5153
.setPrettyPrinting()
5254
.registerTypeAdapter(KeyCode::class.java, KeyCodeSerializer)

common/src/main/kotlin/com/lambda/command/commands/RpcCommand.kt renamed to common/src/main/kotlin/com/lambda/command/commands/CapeCommand.kt

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2024 Lambda
2+
* Copyright 2025 Lambda
33
*
44
* This program is free software: you can redistribute it and/or modify
55
* it under the terms of the GNU General Public License as published by
@@ -18,24 +18,36 @@
1818
package com.lambda.command.commands
1919

2020
import com.lambda.brigadier.argument.literal
21+
import com.lambda.brigadier.argument.string
2122
import com.lambda.brigadier.argument.value
22-
import com.lambda.brigadier.argument.word
2323
import com.lambda.brigadier.execute
2424
import com.lambda.brigadier.required
2525
import com.lambda.command.LambdaCommand
26-
import com.lambda.module.modules.client.DiscordRPC
26+
import com.lambda.network.CapeManager.updateCape
27+
import com.lambda.network.NetworkManager
28+
import com.lambda.threading.runSafe
2729
import com.lambda.util.extension.CommandBuilder
2830

29-
object RpcCommand : LambdaCommand(
30-
name = "rpc",
31-
description = "Discord Rich Presence commands.",
32-
usage = "rpc <join [id] | accept>"
33-
) {
31+
object CapeCommand : LambdaCommand(
32+
name = "cape",
33+
usage = "set <id>",
34+
description = "Sets your cape",
35+
) {
3436
override fun CommandBuilder.create() {
35-
required(literal("join")) {
36-
required(word("id")) { id ->
37+
required(literal("set")) {
38+
required(string("id")) { id ->
39+
suggests { _, builder ->
40+
NetworkManager.capes
41+
.forEach { builder.suggest(it) }
42+
43+
builder.buildFuture()
44+
}
45+
3746
execute {
38-
DiscordRPC.join(id().value())
47+
runSafe {
48+
val cape = id().value()
49+
updateCape(cape)
50+
}
3951
}
4052
}
4153
}

common/src/main/kotlin/com/lambda/http/api/rpc/v1/endpoints/DeleteParty.kt renamed to common/src/main/kotlin/com/lambda/config/configurations/UserConfig.kt

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2024 Lambda
2+
* Copyright 2025 Lambda
33
*
44
* This program is free software: you can redistribute it and/or modify
55
* it under the terms of the GNU General Public License as published by
@@ -15,15 +15,13 @@
1515
* along with this program. If not, see <http://www.gnu.org/licenses/>.
1616
*/
1717

18-
package com.lambda.http.api.rpc.v1.endpoints
18+
package com.lambda.config.configurations
1919

20-
import com.github.kittinunf.fuel.Fuel
21-
import com.github.kittinunf.fuel.gson.responseObject
22-
import com.lambda.http.api.rpc.v1.models.Party
20+
import com.lambda.config.Configuration
21+
import com.lambda.util.FolderRegister
22+
import java.io.File
2323

24-
fun deleteParty(
25-
endpoint: String,
26-
version: String,
27-
) =
28-
Fuel.delete("$endpoint/api/$version/party/delete")
29-
.responseObject<Party>().third
24+
object UserConfig : Configuration() {
25+
override val configName get() = "preferences"
26+
override val primary: File = FolderRegister.config.resolve("$configName.json").toFile()
27+
}

common/src/main/kotlin/com/lambda/event/events/WorldEvent.kt

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,12 @@ import com.lambda.threading.runSafe
2424
import com.lambda.util.BlockUtils.blockState
2525
import net.minecraft.block.BlockState
2626
import net.minecraft.block.Blocks
27+
import net.minecraft.client.network.PlayerListEntry
2728
import net.minecraft.util.math.BlockPos
2829
import net.minecraft.util.shape.VoxelShape
2930
import net.minecraft.world.chunk.WorldChunk
31+
import java.util.UUID
32+
import kotlin.uuid.Uuid
3033

3134
/**
3235
* Represents various events that can occur within the world.
@@ -36,6 +39,31 @@ import net.minecraft.world.chunk.WorldChunk
3639
* occurrences in the game world.
3740
*/
3841
sealed class WorldEvent {
42+
// ToDo: Add doc and determine if there's a better place for this event
43+
// Represents the player joining the world
44+
class Join() : Event
45+
46+
// ToDo: Maybe create a network event seal with some s2c events
47+
sealed class Player {
48+
/**
49+
* Event triggered upon player joining
50+
*/
51+
data class Join(
52+
val name: String,
53+
val uuid: UUID,
54+
val entry: PlayerListEntry,
55+
) : Event
56+
57+
/**
58+
* Event triggered upon player leaving
59+
*/
60+
data class Leave(
61+
val name: String,
62+
val uuid: UUID,
63+
val entry: PlayerListEntry,
64+
) : Event
65+
}
66+
3967
/**
4068
* Represents an event specific to chunk operations within the world.
4169
*

0 commit comments

Comments
 (0)