From 04e4c9eea1fe84995b417f3e6210524d07179380 Mon Sep 17 00:00:00 2001 From: Kamigen <46357922+Edouard127@users.noreply.github.com> Date: Fri, 19 Apr 2024 17:48:44 -0400 Subject: [PATCH 1/9] Test: Trident flight --- .../com/lambda/mixin/world/WorldMixin.java | 17 +++++ .../module/modules/movement/TridentFlight.kt | 67 +++++++++++++++++++ .../main/resources/lambda.mixins.common.json | 5 +- 3 files changed, 87 insertions(+), 2 deletions(-) create mode 100644 common/src/main/java/com/lambda/mixin/world/WorldMixin.java create mode 100644 common/src/main/kotlin/com/lambda/module/modules/movement/TridentFlight.kt diff --git a/common/src/main/java/com/lambda/mixin/world/WorldMixin.java b/common/src/main/java/com/lambda/mixin/world/WorldMixin.java new file mode 100644 index 000000000..948516ce0 --- /dev/null +++ b/common/src/main/java/com/lambda/mixin/world/WorldMixin.java @@ -0,0 +1,17 @@ +package com.lambda.mixin.world; + +import com.lambda.module.modules.movement.TridentFlight; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(World.class) +public class WorldMixin { + @Inject(method = "hasRain", at = @At("HEAD"), cancellable = true) + private void hasRain(BlockPos pos, CallbackInfoReturnable cir) { + if (TridentFlight.INSTANCE.isEnabled()) cir.setReturnValue(TridentFlight.INSTANCE.getRain()); + } +} diff --git a/common/src/main/kotlin/com/lambda/module/modules/movement/TridentFlight.kt b/common/src/main/kotlin/com/lambda/module/modules/movement/TridentFlight.kt new file mode 100644 index 000000000..a06481b56 --- /dev/null +++ b/common/src/main/kotlin/com/lambda/module/modules/movement/TridentFlight.kt @@ -0,0 +1,67 @@ +package com.lambda.module.modules.movement + +import baritone.api.utils.Helper +import com.lambda.event.events.TickEvent +import com.lambda.event.listener.SafeListener.Companion.listener +import com.lambda.module.Module +import com.lambda.module.tag.ModuleTag +import net.minecraft.entity.MovementType +import net.minecraft.item.TridentItem +import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket +import net.minecraft.network.packet.c2s.play.UpdateSelectedSlotC2SPacket +import net.minecraft.util.math.BlockPos +import net.minecraft.util.math.Direction +import net.minecraft.util.math.Vec3d +import kotlin.math.cos +import kotlin.math.sin +import kotlin.math.sqrt + + +object TridentFlight : Module( + name = "TridentFlight", + description = "Allows you to fly with tridents", + defaultTags = setOf(ModuleTag.MOVEMENT, ModuleTag.BYPASS, ModuleTag.GRIM), +) { + private val delay by setting("Delay", 0, 0..20, 1, description = "Delay in ticks before releasing the trident") + private val grimBypass by setting("Grim Bypass", true, description = "Bypass Grim's trident flight check") + val rain by setting("Rain", true, description = "Set rain client-side to allow flight") + + private var ticks = 0 + + init { + listener { + if (ticks >= delay && + player.activeItem.item is TridentItem) + { + val tridentSlot = player.inventory.selectedSlot + val spoofSlot = player.inventory.swappableHotbarSlot + + connection.sendPacket(UpdateSelectedSlotC2SPacket(tridentSlot)) + connection.sendPacket(PlayerActionC2SPacket(PlayerActionC2SPacket.Action.RELEASE_USE_ITEM, BlockPos.ORIGIN, Direction.DOWN)) + + if (grimBypass) { + val yaw = player.yaw * (Math.PI / 180) + val pitch = player.pitch * (Math.PI / 180) + + val x = -sin(yaw) * cos(pitch) + val y = -sin(pitch) + val z = cos(yaw) * cos(pitch) + + val dot = sqrt(x * x + y * y + z * z) + val multiplier = 3 / dot + + player.addVelocity(x * multiplier, y * multiplier, z * multiplier) + + if (player.isOnGround) + player.move(MovementType.SELF, Vec3d(0.0, 1.2, 0.0)) + } + + connection.sendPacket(UpdateSelectedSlotC2SPacket(spoofSlot)) + + ticks = 0 + } + + ticks++ + } + } +} diff --git a/common/src/main/resources/lambda.mixins.common.json b/common/src/main/resources/lambda.mixins.common.json index e73266017..14a12d089 100644 --- a/common/src/main/resources/lambda.mixins.common.json +++ b/common/src/main/resources/lambda.mixins.common.json @@ -22,11 +22,12 @@ "render.GameRendererMixin", "render.GlStateManagerMixin", "render.InGameHudMixin", - "render.VertexBufferMixin", "render.LightmapTextureManagerMixin", "render.LivingEntityRendererMixin", "render.RenderTickCounterMixin", - "render.WorldRendererMixin" + "render.VertexBufferMixin", + "render.WorldRendererMixin", + "world.WorldMixin" ], "injectors": { "defaultRequire": 1 From 2ae37a1b7b30d10cb1da105731673373c7ee93f9 Mon Sep 17 00:00:00 2001 From: Kamigen <46357922+Edouard127@users.noreply.github.com> Date: Sat, 20 Apr 2024 11:54:15 -0400 Subject: [PATCH 2/9] Feature: Trident boost --- .../com/lambda/mixin/items/TridentMixin.java | 24 +++++++++++++ .../module/modules/movement/TridentBoost.kt | 13 +++++++ .../module/modules/movement/TridentFlight.kt | 35 +++++++++++-------- .../main/resources/lambda.mixins.common.json | 3 +- 4 files changed, 59 insertions(+), 16 deletions(-) create mode 100644 common/src/main/java/com/lambda/mixin/items/TridentMixin.java create mode 100644 common/src/main/kotlin/com/lambda/module/modules/movement/TridentBoost.kt diff --git a/common/src/main/java/com/lambda/mixin/items/TridentMixin.java b/common/src/main/java/com/lambda/mixin/items/TridentMixin.java new file mode 100644 index 000000000..7b4fc5a5d --- /dev/null +++ b/common/src/main/java/com/lambda/mixin/items/TridentMixin.java @@ -0,0 +1,24 @@ +package com.lambda.mixin.items; + +import com.lambda.module.modules.movement.TridentBoost; +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import net.minecraft.item.TridentItem; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyArg; + +@Mixin(TridentItem.class) +public class TridentMixin { + // Forge doesn't support the @ModityArgs annotation, so we have to chain multiple @ModifyArg + @ModifyArg(method = "onStoppedUsing", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/PlayerEntity;addVelocity(DDD)V"), index = 0) + private double modifyVelocity0(double velocity) { return TridentBoost.INSTANCE.isEnabled() ? velocity * TridentBoost.INSTANCE.getTridentSpeed() : velocity; } + + @ModifyArg(method = "onStoppedUsing", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/PlayerEntity;addVelocity(DDD)V"), index = 1) + private double modifyVelocity1(double velocity) { return TridentBoost.INSTANCE.isEnabled() ? velocity * TridentBoost.INSTANCE.getTridentSpeed() : velocity; } + + @ModifyArg(method = "onStoppedUsing", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/PlayerEntity;addVelocity(DDD)V"), index = 2) + private double modifyVelocity2(double velocity) { return TridentBoost.INSTANCE.isEnabled() ? velocity * TridentBoost.INSTANCE.getTridentSpeed() : velocity; } + + @ModifyExpressionValue(method = {"onStoppedUsing", "use"}, at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/PlayerEntity;isTouchingWaterOrRain()Z")) + private boolean modifyIsTouchingWaterOrRain(boolean original) { return TridentBoost.INSTANCE.isEnabled() ? TridentBoost.INSTANCE.getForceUse() : original; } +} diff --git a/common/src/main/kotlin/com/lambda/module/modules/movement/TridentBoost.kt b/common/src/main/kotlin/com/lambda/module/modules/movement/TridentBoost.kt new file mode 100644 index 000000000..0725c5b13 --- /dev/null +++ b/common/src/main/kotlin/com/lambda/module/modules/movement/TridentBoost.kt @@ -0,0 +1,13 @@ +package com.lambda.module.modules.movement + +import com.lambda.module.Module +import com.lambda.module.tag.ModuleTag + +object TridentBoost : Module( + name = "TridentBoost", + description = "Boosts you with tridents", + defaultTags = setOf(ModuleTag.MOVEMENT) +) { + val tridentSpeed by setting("Speed Factor", 2.0, 0.1..3.0, 0.1, description = "Speed factor of the trident boost") + val forceUse by setting("Force Use", true, description = "Try to use the trident outside of water or rain") +} diff --git a/common/src/main/kotlin/com/lambda/module/modules/movement/TridentFlight.kt b/common/src/main/kotlin/com/lambda/module/modules/movement/TridentFlight.kt index a06481b56..a76273fe3 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/movement/TridentFlight.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/movement/TridentFlight.kt @@ -1,10 +1,10 @@ package com.lambda.module.modules.movement -import baritone.api.utils.Helper import com.lambda.event.events.TickEvent import com.lambda.event.listener.SafeListener.Companion.listener import com.lambda.module.Module import com.lambda.module.tag.ModuleTag +import net.minecraft.enchantment.EnchantmentHelper import net.minecraft.entity.MovementType import net.minecraft.item.TridentItem import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket @@ -22,8 +22,10 @@ object TridentFlight : Module( description = "Allows you to fly with tridents", defaultTags = setOf(ModuleTag.MOVEMENT, ModuleTag.BYPASS, ModuleTag.GRIM), ) { - private val delay by setting("Delay", 0, 0..20, 1, description = "Delay in ticks before releasing the trident") - private val grimBypass by setting("Grim Bypass", true, description = "Bypass Grim's trident flight check") + private val bounce by setting("Bounce", true, description = "Automatically use the trident") + private val delay by setting("Delay", 0, 0..20, 1, description = "Delay in ticks before releasing the trident", visibility = { bounce }) + private val tridentSpeed by setting("Speed Factor", 1.0, 0.1..5.0, 0.1, description = "Speed factor of the trident flight") + val rain by setting("Rain", true, description = "Set rain client-side to allow flight") private var ticks = 0 @@ -39,22 +41,25 @@ object TridentFlight : Module( connection.sendPacket(UpdateSelectedSlotC2SPacket(tridentSlot)) connection.sendPacket(PlayerActionC2SPacket(PlayerActionC2SPacket.Action.RELEASE_USE_ITEM, BlockPos.ORIGIN, Direction.DOWN)) - if (grimBypass) { - val yaw = player.yaw * (Math.PI / 180) - val pitch = player.pitch * (Math.PI / 180) + val level = EnchantmentHelper.getRiptide(player.activeItem) + val yaw = player.yaw * (Math.PI / 180) + val pitch = player.pitch * (Math.PI / 180) - val x = -sin(yaw) * cos(pitch) - val y = -sin(pitch) - val z = cos(yaw) * cos(pitch) + val x = -sin(yaw) * cos(pitch) + val y = -sin(pitch) + val z = cos(yaw) * cos(pitch) - val dot = sqrt(x * x + y * y + z * z) - val multiplier = 3 / dot + val dot = sqrt(x * x + y * y + z * z) + val multiplier = (3 * ((1.0 + level) / 4.0)) / dot - player.addVelocity(x * multiplier, y * multiplier, z * multiplier) + player.addVelocity( + x * multiplier * tridentSpeed, + y * multiplier * tridentSpeed, + z * multiplier * tridentSpeed + ) - if (player.isOnGround) - player.move(MovementType.SELF, Vec3d(0.0, 1.2, 0.0)) - } + if (player.isOnGround) + player.move(MovementType.SELF, Vec3d(0.0, 1.19999, 0.0)) connection.sendPacket(UpdateSelectedSlotC2SPacket(spoofSlot)) diff --git a/common/src/main/resources/lambda.mixins.common.json b/common/src/main/resources/lambda.mixins.common.json index 14a12d089..a7cd81fd5 100644 --- a/common/src/main/resources/lambda.mixins.common.json +++ b/common/src/main/resources/lambda.mixins.common.json @@ -27,7 +27,8 @@ "render.RenderTickCounterMixin", "render.VertexBufferMixin", "render.WorldRendererMixin", - "world.WorldMixin" + "world.WorldMixin", + "items.TridentMixin" ], "injectors": { "defaultRequire": 1 From 519714bdf88eebd029ce628da9e71e66b1f6c142 Mon Sep 17 00:00:00 2001 From: Kamigen <46357922+Edouard127@users.noreply.github.com> Date: Sat, 20 Apr 2024 16:59:14 -0400 Subject: [PATCH 3/9] Added iterator property to entity utils --- .../com/lambda/util/world/EntityUtils.kt | 31 ++++++++++++------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/util/world/EntityUtils.kt b/common/src/main/kotlin/com/lambda/util/world/EntityUtils.kt index c8c14ca3c..ec2767ea4 100644 --- a/common/src/main/kotlin/com/lambda/util/world/EntityUtils.kt +++ b/common/src/main/kotlin/com/lambda/util/world/EntityUtils.kt @@ -22,20 +22,23 @@ object EntityUtils { range: Double = 6.0, noinline predicate: (T) -> Boolean = { true }, ): T? { + var closest: T? = null + var closestDistance = Double.MAX_VALUE + + val iterator: (T) -> Any = { + val distance = it.squaredDistanceTo(pos) + if (distance < closestDistance) { + closest = it + closestDistance = distance + } + } + // Speculative execution trolling val entities = ArrayList() - if (range > 64) getEntities(entities, predicate) - // I have an idea for optimization. - // - // Since the search operates linearly, eventually it will reach the midpoint. - // Calculate the distance between the first and last entities. - // Obtain the delta value. - // Theoretically, the closest entity should be within a cubic space of delta^3 blocks. - // If there are no entities within this delta box, examine the outer box. (Although this is unlikely given the fact that the closest entity is within the delta box.) - // The performance improvement is relative to the initial state. - else getFastEntities(pos, range, entities, predicate) + if (range > 64) getEntities(entities, predicate, iterator) + else getFastEntities(pos, range, entities, predicate, iterator) - return entities.minByOrNull { it.squaredDistanceTo(pos) } + return closest } /** @@ -71,6 +74,7 @@ object EntityUtils { distance: Double, pointer: MutableList, noinline predicate: (T) -> Boolean = { true }, + noinline iterator: (T) -> Unit = { }, ) { val chunks = ceil(distance / 16).toInt() val sectionX = pos.x.toInt() shr 4 @@ -85,6 +89,7 @@ object EntityUtils { for (z in sectionZ - chunks..sectionZ + chunks) { val section = world.entityManager.cache.findTrackingSection(ChunkSectionPos.asLong(x, y, z)) ?: continue section.collection.filterIsInstanceTo(pointer) { entity -> + iterator(entity) entity != player && entity.squaredDistanceTo(pos) <= distance * distance && predicate(entity) } } @@ -103,9 +108,11 @@ object EntityUtils { */ inline fun SafeContext.getEntities( pointer: MutableList, - noinline predicate: (T) -> Boolean = { true } + noinline predicate: (T) -> Boolean = { true }, + noinline iterator: (T) -> Unit = { }, ) { world.entities.filterIsInstanceTo(pointer) { entity -> + iterator(entity) entity != player && predicate(entity) } } From 51c5c3c6f4a22ebf4a6e229f4ac62a511e80c4aa Mon Sep 17 00:00:00 2001 From: Kamigen <46357922+Edouard127@users.noreply.github.com> Date: Sat, 20 Apr 2024 17:01:12 -0400 Subject: [PATCH 4/9] Can pass null array to not store --- .../main/kotlin/com/lambda/util/collections/Extensions.kt | 3 ++- common/src/main/kotlin/com/lambda/util/world/EntityUtils.kt | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/util/collections/Extensions.kt b/common/src/main/kotlin/com/lambda/util/collections/Extensions.kt index 4d938d1c7..90bcf5c4d 100644 --- a/common/src/main/kotlin/com/lambda/util/collections/Extensions.kt +++ b/common/src/main/kotlin/com/lambda/util/collections/Extensions.kt @@ -14,8 +14,9 @@ package com.lambda.util.collections * @param predicate The predicate function that determines whether an element should be included based on its type and other criteria. */ inline fun > Iterable<*>.filterIsInstanceTo( - destination: C, + destination: C? = null, predicate: (R) -> Boolean ) { + if (destination == null) return for (element in this) if (element is R && predicate(element)) destination.add(element) } diff --git a/common/src/main/kotlin/com/lambda/util/world/EntityUtils.kt b/common/src/main/kotlin/com/lambda/util/world/EntityUtils.kt index ec2767ea4..c6fbccb81 100644 --- a/common/src/main/kotlin/com/lambda/util/world/EntityUtils.kt +++ b/common/src/main/kotlin/com/lambda/util/world/EntityUtils.kt @@ -25,7 +25,7 @@ object EntityUtils { var closest: T? = null var closestDistance = Double.MAX_VALUE - val iterator: (T) -> Any = { + val iterator: (T) -> Unit = { val distance = it.squaredDistanceTo(pos) if (distance < closestDistance) { closest = it @@ -72,7 +72,7 @@ object EntityUtils { inline fun SafeContext.getFastEntities( pos: Vec3d, distance: Double, - pointer: MutableList, + pointer: MutableList? = null, noinline predicate: (T) -> Boolean = { true }, noinline iterator: (T) -> Unit = { }, ) { @@ -107,7 +107,7 @@ object EntityUtils { * @return A list of entities of type [T] within the specified distance from the position without the player. */ inline fun SafeContext.getEntities( - pointer: MutableList, + pointer: MutableList? = null, noinline predicate: (T) -> Boolean = { true }, noinline iterator: (T) -> Unit = { }, ) { From 7a48550842b7ba0453e804bed6847014ac48ef70 Mon Sep 17 00:00:00 2001 From: Kamigen <46357922+Edouard127@users.noreply.github.com> Date: Sat, 20 Apr 2024 20:36:35 -0400 Subject: [PATCH 5/9] Feature: Horse utils --- .../module/modules/movement/HorseUtils.kt | 49 +++++++++++++++++++ .../com/lambda/util/world/EntityUtils.kt | 17 ++++--- .../src/main/resources/lambda.accesswidener | 7 +++ 3 files changed, 66 insertions(+), 7 deletions(-) create mode 100644 common/src/main/kotlin/com/lambda/module/modules/movement/HorseUtils.kt diff --git a/common/src/main/kotlin/com/lambda/module/modules/movement/HorseUtils.kt b/common/src/main/kotlin/com/lambda/module/modules/movement/HorseUtils.kt new file mode 100644 index 000000000..c5ad344b4 --- /dev/null +++ b/common/src/main/kotlin/com/lambda/module/modules/movement/HorseUtils.kt @@ -0,0 +1,49 @@ +package com.lambda.module.modules.movement + +import com.lambda.event.events.PacketEvent +import com.lambda.event.events.TickEvent +import com.lambda.event.listener.SafeListener.Companion.listener +import com.lambda.module.Module +import com.lambda.module.tag.ModuleTag +import com.lambda.util.world.EntityUtils.getEntities +import net.minecraft.entity.passive.AbstractHorseEntity +import net.minecraft.network.packet.c2s.play.PlayerInteractEntityC2SPacket + +object HorseUtils : Module( + name = "HorseUtils", + description = "Various utilities for horses.", + defaultTags = setOf(ModuleTag.MOVEMENT, ModuleTag.BYPASS) +) { + private val page by setting("Page", Page.General) + + /* General */ + private val forceMount by setting("Force Mount", true, description = "Attempts to force mount chested entities.", visibility = { page == Page.General }) + private val tameHorses by setting("Tame Horses", true, description = "Automatically tames horses (client-side only).", visibility = { page == Page.General }) + + /* Rendering */ + private val showInfo by setting("Show Info", true, description = "Renders information about entities.", visibility = { page == Page.Rendering }) + + private val theHonses = mutableListOf() // Petah, the honse is here + private val tame: (AbstractHorseEntity) -> Unit = { horse -> if (tameHorses) horse.setHorseFlag(4, true) } + + private enum class Page { + General, Rendering + } + + init { + listener { + getEntities(theHonses, iterator = tame) + } + + listener { event -> + if (!forceMount) return@listener + if (event.packet !is PlayerInteractEntityC2SPacket) return@listener + if (event.packet.type !is PlayerInteractEntityC2SPacket.InteractAtHandler) return@listener + + val entity = world.getEntityById(event.packet.entityId) ?: return@listener + if (entity !is AbstractHorseEntity) return@listener + + event.cancel() + } + } +} diff --git a/common/src/main/kotlin/com/lambda/util/world/EntityUtils.kt b/common/src/main/kotlin/com/lambda/util/world/EntityUtils.kt index c6fbccb81..9a938d3ae 100644 --- a/common/src/main/kotlin/com/lambda/util/world/EntityUtils.kt +++ b/common/src/main/kotlin/com/lambda/util/world/EntityUtils.kt @@ -7,6 +7,7 @@ import net.minecraft.util.math.ChunkSectionPos import net.minecraft.util.math.Vec3d import kotlin.math.ceil +val nullptr = null object EntityUtils { /** @@ -34,9 +35,8 @@ object EntityUtils { } // Speculative execution trolling - val entities = ArrayList() - if (range > 64) getEntities(entities, predicate, iterator) - else getFastEntities(pos, range, entities, predicate, iterator) + if (range > 64) getEntities(nullptr, predicate, iterator) + else getFastEntities(pos, range, nullptr, predicate, iterator) return closest } @@ -65,14 +65,16 @@ object EntityUtils { * * @param pos The position to search from. * @param distance The maximum distance to search for entities. + * @param pointer The mutable list to store the entities in. * @param predicate Optional predicate to filter entities. It allows custom filtering based on entity properties. + * @param iterator Optional iterator to perform operations on each entity. * @return A list of entities of type [T] within the specified distance from the position, excluding the player. * */ inline fun SafeContext.getFastEntities( pos: Vec3d, distance: Double, - pointer: MutableList? = null, + pointer: MutableList? = nullptr, noinline predicate: (T) -> Boolean = { true }, noinline iterator: (T) -> Unit = { }, ) { @@ -103,11 +105,12 @@ object EntityUtils { * This function retrieves entities of type [T] within a specified distance from a given position. Unlike * [getFastEntities], it traverses all entities in the world to find matches, while also excluding the player entity. * - * @param predicate Optional predicate to filter entities. - * @return A list of entities of type [T] within the specified distance from the position without the player. + * @param pointer The mutable list to store the entities in. + * @param predicate Optional predicate to filter entities. It allows custom filtering based on entity properties. + * @param iterator Optional iterator to perform operations on each entity. */ inline fun SafeContext.getEntities( - pointer: MutableList? = null, + pointer: MutableList? = nullptr, noinline predicate: (T) -> Boolean = { true }, noinline iterator: (T) -> Unit = { }, ) { diff --git a/common/src/main/resources/lambda.accesswidener b/common/src/main/resources/lambda.accesswidener index e95982c8a..6f140e333 100644 --- a/common/src/main/resources/lambda.accesswidener +++ b/common/src/main/resources/lambda.accesswidener @@ -11,6 +11,7 @@ accessible field net/minecraft/client/world/ClientWorld entityManager Lnet/minec # Entity accessible field net/minecraft/entity/projectile/FireworkRocketEntity shooter Lnet/minecraft/entity/LivingEntity; accessible method net/minecraft/entity/Entity movementInputToVelocity (Lnet/minecraft/util/math/Vec3d;FF)Lnet/minecraft/util/math/Vec3d; +accessible method net/minecraft/entity/passive/AbstractHorseEntity setHorseFlag (IZ)V # Camera accessible method net/minecraft/client/render/Camera setPos (DDD)V @@ -34,6 +35,12 @@ accessible field net/minecraft/text/Style insertion Ljava/lang/String; accessible field net/minecraft/text/Style font Lnet/minecraft/util/Identifier; accessible method net/minecraft/text/Style (Lnet/minecraft/text/TextColor;Ljava/lang/Boolean;Ljava/lang/Boolean;Ljava/lang/Boolean;Ljava/lang/Boolean;Ljava/lang/Boolean;Lnet/minecraft/text/ClickEvent;Lnet/minecraft/text/HoverEvent;Ljava/lang/String;Lnet/minecraft/util/Identifier;)V +# Packet +accessible field net/minecraft/network/packet/c2s/play/PlayerInteractEntityC2SPacket entityId I +accessible field net/minecraft/network/packet/c2s/play/PlayerInteractEntityC2SPacket type Lnet/minecraft/network/packet/c2s/play/PlayerInteractEntityC2SPacket$InteractTypeHandler; +accessible class net/minecraft/network/packet/c2s/play/PlayerInteractEntityC2SPacket$InteractTypeHandler +accessible class net/minecraft/network/packet/c2s/play/PlayerInteractEntityC2SPacket$InteractAtHandler + # Other accessible field net/minecraft/client/world/ClientEntityManager cache Lnet/minecraft/world/entity/SectionedEntityCache; accessible field net/minecraft/world/entity/EntityTrackingSection collection Lnet/minecraft/util/collection/TypeFilterableList; From d726baeb2ff2471ccf8167299b85e56f90eea262 Mon Sep 17 00:00:00 2001 From: Kamigen <46357922+Edouard127@users.noreply.github.com> Date: Sun, 21 Apr 2024 11:57:19 -0400 Subject: [PATCH 6/9] Refactor!: Mutable settings --- common/src/main/kotlin/com/lambda/Lambda.kt | 2 + .../kotlin/com/lambda/config/Configurable.kt | 16 +++---- .../kotlin/com/lambda/config/Configuration.kt | 3 +- .../config/configurations/ModuleConfig.kt | 3 +- .../serializer/GameProfileSerializer.kt | 34 ++++++++++++++ .../settings/collections/ListSetting.kt | 8 ++-- .../src/main/kotlin/com/lambda/core/Loader.kt | 11 +++-- .../kotlin/com/lambda/friend/FriendManager.kt | 44 +++++++++++++++++++ .../gui/impl/clickgui/GuiConfigurable.kt | 7 +-- .../com/lambda/module/modules/Packetlogger.kt | 6 +-- 10 files changed, 111 insertions(+), 23 deletions(-) create mode 100644 common/src/main/kotlin/com/lambda/config/serializer/GameProfileSerializer.kt create mode 100644 common/src/main/kotlin/com/lambda/friend/FriendManager.kt diff --git a/common/src/main/kotlin/com/lambda/Lambda.kt b/common/src/main/kotlin/com/lambda/Lambda.kt index 3a861bd35..13822b7da 100644 --- a/common/src/main/kotlin/com/lambda/Lambda.kt +++ b/common/src/main/kotlin/com/lambda/Lambda.kt @@ -9,6 +9,7 @@ import com.lambda.core.Loader import com.lambda.gui.impl.clickgui.windows.TagWindow import com.lambda.module.tag.ModuleTag import com.lambda.util.KeyCode +import com.mojang.authlib.GameProfile import net.minecraft.block.Block import net.minecraft.client.MinecraftClient import net.minecraft.util.math.BlockPos @@ -32,6 +33,7 @@ object Lambda { .registerTypeAdapter(Color::class.java, ColorSerializer) .registerTypeAdapter(BlockPos::class.java, BlockPosSerializer) .registerTypeAdapter(Block::class.java, BlockSerializer) + .registerTypeAdapter(GameProfile::class.java, GameProfileSerializer) .create() fun initialize() = Loader.initialize() diff --git a/common/src/main/kotlin/com/lambda/config/Configurable.kt b/common/src/main/kotlin/com/lambda/config/Configurable.kt index 00e091f41..dd4ad4f00 100644 --- a/common/src/main/kotlin/com/lambda/config/Configurable.kt +++ b/common/src/main/kotlin/com/lambda/config/Configurable.kt @@ -151,23 +151,23 @@ abstract class Configurable(configuration: Configuration) : Jsonable, Nameable { * The type parameter [T] must either be a primitive type or a type with a registered type adapter in [Lambda.gson]. * * @param name The unique identifier for the setting. - * @param defaultValue The default [List] value of type [T] for the setting. + * @param defaultValue The default [ArrayList] value of type [T] for the setting. * @param description A brief explanation of the setting's purpose and behavior. * @param visibility A lambda expression that determines the visibility status of the setting. * * ```kotlin * // the parameter type is inferred from the defaultValue - * private val foo by setting("Foo", listOf("bar", "baz")) + * private val foo by setting("Foo", arrayListOf("bar", "baz")) * ``` * * @return The created [ListSetting]. */ inline fun setting( name: String, - defaultValue: List, + defaultValue: ArrayList, description: String = "", noinline visibility: () -> Boolean = { true }, - ) = ListSetting(name, defaultValue, object : TypeToken>() {}.type, description, visibility).also { + ) = ListSetting(name, defaultValue, TypeToken.getParameterized(ArrayList::class.java, T::class.java).type, description, visibility).also { settings.add(it) } @@ -188,12 +188,12 @@ abstract class Configurable(configuration: Configuration) : Jsonable, Nameable { * * @return The created [MapSetting]. */ - inline fun setting( + inline fun setting( name: String, defaultValue: Map, description: String = "", noinline visibility: () -> Boolean = { true }, - ) = MapSetting(name, defaultValue, object : TypeToken>() {}.type, description, visibility).also { + ) = MapSetting(name, defaultValue, TypeToken.getParameterized(Map::class.java, K::class.java, V::class.java).type, description, visibility).also { settings.add(it) } @@ -219,7 +219,7 @@ abstract class Configurable(configuration: Configuration) : Jsonable, Nameable { defaultValue: Set, description: String = "", noinline visibility: () -> Boolean = { true }, - ) = SetSetting(name, defaultValue, object : TypeToken>() {}.type, description, visibility).also { + ) = SetSetting(name, defaultValue, TypeToken.getParameterized(Set::class.java, T::class.java).type, description, visibility).also { settings.add(it) } @@ -448,4 +448,4 @@ abstract class Configurable(configuration: Configuration) : Jsonable, Nameable { ) = BlockSetting(name, defaultValue, description, visibility).also { settings.add(it) } -} \ No newline at end of file +} diff --git a/common/src/main/kotlin/com/lambda/config/Configuration.kt b/common/src/main/kotlin/com/lambda/config/Configuration.kt index 3dc6768a7..6e45e9427 100644 --- a/common/src/main/kotlin/com/lambda/config/Configuration.kt +++ b/common/src/main/kotlin/com/lambda/config/Configuration.kt @@ -99,7 +99,8 @@ abstract class Configuration : Jsonable { this@Configuration.info(message) } .onFailure { - val message = "Failed to load ${configName.capitalize()} config from backup, unrecoverable error" + val message = + "Failed to load ${configName.capitalize()} config from backup, unrecoverable error" LOG.error(message, it) this@Configuration.logError(message) } diff --git a/common/src/main/kotlin/com/lambda/config/configurations/ModuleConfig.kt b/common/src/main/kotlin/com/lambda/config/configurations/ModuleConfig.kt index 98965aa36..f87720324 100644 --- a/common/src/main/kotlin/com/lambda/config/configurations/ModuleConfig.kt +++ b/common/src/main/kotlin/com/lambda/config/configurations/ModuleConfig.kt @@ -4,7 +4,6 @@ import com.lambda.config.Configuration import com.lambda.config.configurations.ModuleConfig.configName import com.lambda.config.configurations.ModuleConfig.primary import com.lambda.util.FolderRegister -import java.io.File /** @@ -18,4 +17,4 @@ import java.io.File object ModuleConfig : Configuration() { override val configName = "modules" override val primary = FolderRegister.config.resolve("$configName.json") -} \ No newline at end of file +} diff --git a/common/src/main/kotlin/com/lambda/config/serializer/GameProfileSerializer.kt b/common/src/main/kotlin/com/lambda/config/serializer/GameProfileSerializer.kt new file mode 100644 index 000000000..48691d3cc --- /dev/null +++ b/common/src/main/kotlin/com/lambda/config/serializer/GameProfileSerializer.kt @@ -0,0 +1,34 @@ +package com.lambda.config.serializer + +import com.google.gson.* +import com.mojang.authlib.GameProfile +import java.lang.reflect.Type +import java.util.* + +// Yeah yeah I know, there's already a serializer for GameProfile in the Minecraft codebase. +// But who cares, I'm doing it again. +// What you gon' do bout it, huh? +// That's what I thought. +object GameProfileSerializer : JsonSerializer, JsonDeserializer { + override fun serialize( + src: GameProfile?, + typeOfSrc: Type?, + context: JsonSerializationContext?, + ): JsonElement = + src?.let { + JsonObject().apply { + addProperty("name", it.name) + addProperty("uuid", it.id.toString()) + } + } ?: JsonNull.INSTANCE + + override fun deserialize( + json: JsonElement?, + typeOfT: Type?, + context: JsonDeserializationContext?, + ): GameProfile = + GameProfile( + UUID.fromString(json?.asJsonObject?.get("uuid")?.asString), + json?.asJsonObject?.get("name")?.asString + ) +} diff --git a/common/src/main/kotlin/com/lambda/config/settings/collections/ListSetting.kt b/common/src/main/kotlin/com/lambda/config/settings/collections/ListSetting.kt index cb6452996..5df6c75e7 100644 --- a/common/src/main/kotlin/com/lambda/config/settings/collections/ListSetting.kt +++ b/common/src/main/kotlin/com/lambda/config/settings/collections/ListSetting.kt @@ -1,17 +1,19 @@ package com.lambda.config.settings.collections import com.google.gson.JsonElement +import com.google.gson.reflect.TypeToken import com.lambda.Lambda.gson import com.lambda.config.AbstractSetting import java.lang.reflect.Type +import java.util.ArrayList class ListSetting( override val name: String, - defaultValue: List, + defaultValue: ArrayList, private val type: Type, description: String, visibility: () -> Boolean, -) : AbstractSetting>( +) : AbstractSetting>( defaultValue, description, visibility @@ -19,4 +21,4 @@ class ListSetting( override fun loadFromJson(serialized: JsonElement) { value = gson.fromJson(serialized, type) } -} \ No newline at end of file +} diff --git a/common/src/main/kotlin/com/lambda/core/Loader.kt b/common/src/main/kotlin/com/lambda/core/Loader.kt index ff7ab72ef..a58560823 100644 --- a/common/src/main/kotlin/com/lambda/core/Loader.kt +++ b/common/src/main/kotlin/com/lambda/core/Loader.kt @@ -4,6 +4,7 @@ import com.lambda.Lambda import com.lambda.Lambda.LOG import com.lambda.command.CommandManager import com.lambda.config.configurations.GuiConfig +import com.lambda.friend.FriendManager import com.lambda.graphics.renderer.gui.font.LambdaFont import com.lambda.gui.impl.clickgui.GuiConfigurable import com.lambda.gui.impl.clickgui.LambdaClickGui @@ -11,6 +12,8 @@ import com.lambda.interaction.PlayerPacketManager import com.lambda.interaction.RotationManager import com.lambda.module.ModuleRegistry import com.lambda.util.Communication.ascii +import com.mojang.authlib.GameProfile +import java.util.* import kotlin.system.measureTimeMillis object Loader { @@ -19,7 +22,9 @@ object Loader { CommandManager, RotationManager, PlayerPacketManager, - LambdaFont.Loader + LambdaFont.Loader, + GuiConfigurable, + FriendManager, ) fun initialize() { @@ -37,8 +42,8 @@ object Loader { } } - LOG.info("${Lambda.MOD_NAME} ${Lambda.VERSION} was successfully initialized (${initTime}ms)") + FriendManager.add(GameProfile(UUID.randomUUID(), "Lambda")) - GuiConfigurable // ToDo: Find more elegant solution + LOG.info("${Lambda.MOD_NAME} ${Lambda.VERSION} was successfully initialized (${initTime}ms)") } } diff --git a/common/src/main/kotlin/com/lambda/friend/FriendManager.kt b/common/src/main/kotlin/com/lambda/friend/FriendManager.kt new file mode 100644 index 000000000..cf4696b0f --- /dev/null +++ b/common/src/main/kotlin/com/lambda/friend/FriendManager.kt @@ -0,0 +1,44 @@ +package com.lambda.friend + +import com.lambda.config.Configurable +import com.lambda.config.configurations.FriendConfig +import com.lambda.core.Loadable +import com.lambda.event.events.TickEvent +import com.lambda.event.listener.SafeListener.Companion.listener +import com.lambda.util.world.EntityUtils.getEntities +import com.mojang.authlib.GameProfile +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.server.network.ServerPlayerEntity +import net.minecraft.world.event.listener.EntityGameEventHandler +import java.util.Arrays +import java.util.UUID + +object FriendManager : Configurable(FriendConfig), Loadable { + override val name = "FriendManager" + + private val friends by setting("friends", arrayListOf()) + + fun add(vararg profile: GameProfile) = + friends.addAll(profile) + + fun remove(vararg profile: GameProfile) = + friends.removeAll(profile.toSet()) + + fun get(name: String) = friends.firstOrNull { it.name == name } + fun get(uuid: UUID) = friends.firstOrNull { it.id == uuid } + + fun contains(profile: GameProfile) = friends.contains(profile) + fun contains(name: String) = friends.any { it.name == name } + fun contains(uuid: UUID) = friends.any { it.id == uuid } + + fun clear() = friends.clear() + + val ServerPlayerEntity.isFriend: Boolean + get() = contains(gameProfile) + + override fun load(): String { + if (friends.isEmpty()) return "No friends loaded, damn bro you don't have to be antisocial online too," + val word = if (friends.size == 1) "friend" else "friends" + return "Loaded ${friends.size} $word." + } +} diff --git a/common/src/main/kotlin/com/lambda/gui/impl/clickgui/GuiConfigurable.kt b/common/src/main/kotlin/com/lambda/gui/impl/clickgui/GuiConfigurable.kt index 79158c61d..3b4ad6afc 100644 --- a/common/src/main/kotlin/com/lambda/gui/impl/clickgui/GuiConfigurable.kt +++ b/common/src/main/kotlin/com/lambda/gui/impl/clickgui/GuiConfigurable.kt @@ -2,9 +2,10 @@ package com.lambda.gui.impl.clickgui import com.lambda.config.Configurable import com.lambda.config.configurations.GuiConfig +import com.lambda.core.Loadable import com.lambda.gui.impl.clickgui.windows.TagWindow -object GuiConfigurable : Configurable(GuiConfig) { +object GuiConfigurable : Configurable(GuiConfig), Loadable { override val name = "gui" - val windows = setting("windows", listOf(TagWindow())) -} \ No newline at end of file + val windows = setting("windows", arrayListOf(TagWindow())) +} diff --git a/common/src/main/kotlin/com/lambda/module/modules/Packetlogger.kt b/common/src/main/kotlin/com/lambda/module/modules/Packetlogger.kt index f2a44e6e4..6338d8b7d 100644 --- a/common/src/main/kotlin/com/lambda/module/modules/Packetlogger.kt +++ b/common/src/main/kotlin/com/lambda/module/modules/Packetlogger.kt @@ -38,8 +38,8 @@ object Packetlogger : Module( private val networkSide by setting("Network Side", NetworkSide.ANY, "Side of the network to log packets from") private val logTicks by setting("Log Ticks", true, "Show game ticks in the log") private val scope by setting("Scope", Scope.ANY, "Scope of packets to log") - private val whitelist by setting("Whitelist Packets", listOf(), "Packets to whitelist") { scope == Scope.WHITELIST } - private val blacklist by setting("Blacklist Packets", listOf(), "Packets to blacklist") { scope == Scope.BLACKLIST } + private val whitelist by setting("Whitelist Packets", arrayListOf(), "Packets to whitelist") { scope == Scope.WHITELIST } + private val blacklist by setting("Blacklist Packets", arrayListOf(), "Packets to blacklist") { scope == Scope.BLACKLIST } private val maxRecursionDepth by setting("Max Recursion Depth", 6, 1..10, 1, "Maximum recursion depth for packet serialization") private val logConcurrent by setting("Build Data Concurrent", false, "Whether to serialize packets concurrently. Will not save packets in chronological order but wont lag the game.") @@ -187,4 +187,4 @@ object Packetlogger : Module( private fun Packet<*>.logSent() { storageFlow.tryEmit("Sent at ${getTime(entryFormatter)}\n${dynamicString(maxRecursionDepth)}\n") } -} \ No newline at end of file +} From b836878d89ee39f59e832a845a0bf3681aff305f Mon Sep 17 00:00:00 2001 From: Kamigen <46357922+Edouard127@users.noreply.github.com> Date: Sun, 21 Apr 2024 11:57:47 -0400 Subject: [PATCH 7/9] Feature: Friends i fucked up the commits :trollface: --- .../com/lambda/config/configurations/FriendConfig.kt | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 common/src/main/kotlin/com/lambda/config/configurations/FriendConfig.kt diff --git a/common/src/main/kotlin/com/lambda/config/configurations/FriendConfig.kt b/common/src/main/kotlin/com/lambda/config/configurations/FriendConfig.kt new file mode 100644 index 000000000..8d80efeaf --- /dev/null +++ b/common/src/main/kotlin/com/lambda/config/configurations/FriendConfig.kt @@ -0,0 +1,9 @@ +package com.lambda.config.configurations + +import com.lambda.config.Configuration +import com.lambda.util.FolderRegister + +object FriendConfig : Configuration() { + override val configName = "friends" + override val primary = FolderRegister.config.resolve("$configName.json") +} From 5290e4c4a84bb54d8e6f1294f55429b266393e0d Mon Sep 17 00:00:00 2001 From: Kamigen <46357922+Edouard127@users.noreply.github.com> Date: Sun, 21 Apr 2024 20:27:47 -0400 Subject: [PATCH 8/9] Feature: Mutable collection settings --- .../src/main/kotlin/com/lambda/config/Configurable.kt | 8 ++++---- .../lambda/config/settings/collections/ListSetting.kt | 11 +++++++---- .../lambda/config/settings/collections/MapSetting.kt | 11 ++++++++--- .../lambda/config/settings/collections/SetSetting.kt | 11 ++++++++--- common/src/main/kotlin/com/lambda/core/Loader.kt | 2 -- .../com/lambda/gui/impl/clickgui/GuiConfigurable.kt | 2 +- 6 files changed, 28 insertions(+), 17 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/config/Configurable.kt b/common/src/main/kotlin/com/lambda/config/Configurable.kt index dd4ad4f00..f73573004 100644 --- a/common/src/main/kotlin/com/lambda/config/Configurable.kt +++ b/common/src/main/kotlin/com/lambda/config/Configurable.kt @@ -164,10 +164,10 @@ abstract class Configurable(configuration: Configuration) : Jsonable, Nameable { */ inline fun setting( name: String, - defaultValue: ArrayList, + defaultValue: List, description: String = "", noinline visibility: () -> Boolean = { true }, - ) = ListSetting(name, defaultValue, TypeToken.getParameterized(ArrayList::class.java, T::class.java).type, description, visibility).also { + ) = ListSetting(name, defaultValue.toMutableList(), TypeToken.getParameterized(MutableList::class.java, T::class.java).type, description, visibility).also { settings.add(it) } @@ -193,7 +193,7 @@ abstract class Configurable(configuration: Configuration) : Jsonable, Nameable { defaultValue: Map, description: String = "", noinline visibility: () -> Boolean = { true }, - ) = MapSetting(name, defaultValue, TypeToken.getParameterized(Map::class.java, K::class.java, V::class.java).type, description, visibility).also { + ) = MapSetting(name, defaultValue.toMutableMap(), TypeToken.getParameterized(Map::class.java, K::class.java, V::class.java).type, description, visibility).also { settings.add(it) } @@ -219,7 +219,7 @@ abstract class Configurable(configuration: Configuration) : Jsonable, Nameable { defaultValue: Set, description: String = "", noinline visibility: () -> Boolean = { true }, - ) = SetSetting(name, defaultValue, TypeToken.getParameterized(Set::class.java, T::class.java).type, description, visibility).also { + ) = SetSetting(name, defaultValue.toMutableSet(), TypeToken.getParameterized(Set::class.java, T::class.java).type, description, visibility).also { settings.add(it) } diff --git a/common/src/main/kotlin/com/lambda/config/settings/collections/ListSetting.kt b/common/src/main/kotlin/com/lambda/config/settings/collections/ListSetting.kt index 5df6c75e7..ed100d8c7 100644 --- a/common/src/main/kotlin/com/lambda/config/settings/collections/ListSetting.kt +++ b/common/src/main/kotlin/com/lambda/config/settings/collections/ListSetting.kt @@ -1,19 +1,17 @@ package com.lambda.config.settings.collections import com.google.gson.JsonElement -import com.google.gson.reflect.TypeToken import com.lambda.Lambda.gson import com.lambda.config.AbstractSetting import java.lang.reflect.Type -import java.util.ArrayList class ListSetting( override val name: String, - defaultValue: ArrayList, + private val defaultValue: MutableList, private val type: Type, description: String, visibility: () -> Boolean, -) : AbstractSetting>( +) : AbstractSetting>( defaultValue, description, visibility @@ -21,4 +19,9 @@ class ListSetting( override fun loadFromJson(serialized: JsonElement) { value = gson.fromJson(serialized, type) } + + override fun toJson(): JsonElement { + value = defaultValue.toMutableList() // Hack the Delegates.observable + return gson.toJsonTree(value) + } } diff --git a/common/src/main/kotlin/com/lambda/config/settings/collections/MapSetting.kt b/common/src/main/kotlin/com/lambda/config/settings/collections/MapSetting.kt index a9190f4d5..7ec0492dd 100644 --- a/common/src/main/kotlin/com/lambda/config/settings/collections/MapSetting.kt +++ b/common/src/main/kotlin/com/lambda/config/settings/collections/MapSetting.kt @@ -7,11 +7,11 @@ import java.lang.reflect.Type class MapSetting( override val name: String, - defaultValue: Map, + private val defaultValue: MutableMap, private val type: Type, description: String, visibility: () -> Boolean, -) : AbstractSetting>( +) : AbstractSetting>( defaultValue, description, visibility @@ -19,4 +19,9 @@ class MapSetting( override fun loadFromJson(serialized: JsonElement) { value = gson.fromJson(serialized, type) } -} \ No newline at end of file + + override fun toJson(): JsonElement { + value = defaultValue.toMutableMap() // Hack the Delegates.observable + return gson.toJsonTree(value) + } +} diff --git a/common/src/main/kotlin/com/lambda/config/settings/collections/SetSetting.kt b/common/src/main/kotlin/com/lambda/config/settings/collections/SetSetting.kt index 5bc7b8264..482fbb4a1 100644 --- a/common/src/main/kotlin/com/lambda/config/settings/collections/SetSetting.kt +++ b/common/src/main/kotlin/com/lambda/config/settings/collections/SetSetting.kt @@ -7,11 +7,11 @@ import java.lang.reflect.Type class SetSetting( override val name: String, - defaultValue: Set, + private val defaultValue: MutableSet, private val type: Type, description: String, visibility: () -> Boolean, -) : AbstractSetting>( +) : AbstractSetting>( defaultValue, description, visibility @@ -19,4 +19,9 @@ class SetSetting( override fun loadFromJson(serialized: JsonElement) { value = gson.fromJson(serialized, type) } -} \ No newline at end of file + + override fun toJson(): JsonElement { + value = defaultValue.toMutableSet() // Hack the Delegates.observable + return gson.toJsonTree(value) + } +} diff --git a/common/src/main/kotlin/com/lambda/core/Loader.kt b/common/src/main/kotlin/com/lambda/core/Loader.kt index a58560823..a5d82ca3d 100644 --- a/common/src/main/kotlin/com/lambda/core/Loader.kt +++ b/common/src/main/kotlin/com/lambda/core/Loader.kt @@ -42,8 +42,6 @@ object Loader { } } - FriendManager.add(GameProfile(UUID.randomUUID(), "Lambda")) - LOG.info("${Lambda.MOD_NAME} ${Lambda.VERSION} was successfully initialized (${initTime}ms)") } } diff --git a/common/src/main/kotlin/com/lambda/gui/impl/clickgui/GuiConfigurable.kt b/common/src/main/kotlin/com/lambda/gui/impl/clickgui/GuiConfigurable.kt index 3b4ad6afc..41c6ec57a 100644 --- a/common/src/main/kotlin/com/lambda/gui/impl/clickgui/GuiConfigurable.kt +++ b/common/src/main/kotlin/com/lambda/gui/impl/clickgui/GuiConfigurable.kt @@ -7,5 +7,5 @@ import com.lambda.gui.impl.clickgui.windows.TagWindow object GuiConfigurable : Configurable(GuiConfig), Loadable { override val name = "gui" - val windows = setting("windows", arrayListOf(TagWindow())) + val windows = setting("windows", listOf(TagWindow())) } From 5674bb398ab7832b7e11ed9225c325fee3fbff10 Mon Sep 17 00:00:00 2001 From: Kamigen <46357922+Edouard127@users.noreply.github.com> Date: Sun, 21 Apr 2024 20:27:55 -0400 Subject: [PATCH 9/9] Fix: Friends not saving --- .../kotlin/com/lambda/friend/FriendManager.kt | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/common/src/main/kotlin/com/lambda/friend/FriendManager.kt b/common/src/main/kotlin/com/lambda/friend/FriendManager.kt index cf4696b0f..9ec8a0ae6 100644 --- a/common/src/main/kotlin/com/lambda/friend/FriendManager.kt +++ b/common/src/main/kotlin/com/lambda/friend/FriendManager.kt @@ -3,26 +3,18 @@ package com.lambda.friend import com.lambda.config.Configurable import com.lambda.config.configurations.FriendConfig import com.lambda.core.Loadable -import com.lambda.event.events.TickEvent -import com.lambda.event.listener.SafeListener.Companion.listener -import com.lambda.util.world.EntityUtils.getEntities import com.mojang.authlib.GameProfile -import net.minecraft.entity.player.PlayerEntity import net.minecraft.server.network.ServerPlayerEntity -import net.minecraft.world.event.listener.EntityGameEventHandler -import java.util.Arrays import java.util.UUID object FriendManager : Configurable(FriendConfig), Loadable { override val name = "FriendManager" - private val friends by setting("friends", arrayListOf()) + private var friends by setting("friends", listOf()) - fun add(vararg profile: GameProfile) = - friends.addAll(profile) + fun add(profile: GameProfile) = friends.add(profile) - fun remove(vararg profile: GameProfile) = - friends.removeAll(profile.toSet()) + fun remove(profile: GameProfile) = friends.remove(profile) fun get(name: String) = friends.firstOrNull { it.name == name } fun get(uuid: UUID) = friends.firstOrNull { it.id == uuid } @@ -36,6 +28,9 @@ object FriendManager : Configurable(FriendConfig), Loadable { val ServerPlayerEntity.isFriend: Boolean get() = contains(gameProfile) + fun ServerPlayerEntity.befriend() = add(gameProfile) + fun ServerPlayerEntity.unfriend() = remove(gameProfile) + override fun load(): String { if (friends.isEmpty()) return "No friends loaded, damn bro you don't have to be antisocial online too," val word = if (friends.size == 1) "friend" else "friends"