Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
3a3feba
aaaaaaa
emyfops Feb 5, 2025
b4950c8
Merge branch 'master' into feat/auth
emyfops Feb 14, 2025
1a57f45
Merge branch 'master' into feat/auth
emyfops Feb 14, 2025
d78be35
Merge branch 'master' into feat/auth
emyfops Feb 15, 2025
a863267
Discord and Network refactor
emyfops Feb 15, 2025
060a13b
Refactored the network, discord and http
emyfops Feb 17, 2025
9b8a9a9
Refactored the discord module
emyfops Feb 22, 2025
cfa2e3f
Fixed world join event
emyfops Feb 22, 2025
f049fab
Update common/src/main/kotlin/com/lambda/module/modules/client/Discor…
emyfops Feb 22, 2025
8608e25
Fixed discord delete logic
emyfops Feb 22, 2025
36f5737
Merge branch 'feat/auth' of https://github.com/Avanatiker/NeoLambda i…
emyfops Feb 22, 2025
7aae60e
Removed extra bracket
emyfops Feb 22, 2025
29b0709
Fixed code flow on failure
emyfops Feb 22, 2025
e757afc
Fixed stupid gson
emyfops Feb 22, 2025
a2f9a66
Updated logic and fixed bugs
emyfops Feb 23, 2025
db413fa
Parked the party feature locally
emyfops Feb 23, 2025
b925daa
Removed useless code
emyfops Feb 23, 2025
87a9700
Delete DiscordCommand.kt
emyfops Feb 23, 2025
dae5659
Added module description
emyfops Feb 23, 2025
106d137
Removed todo
emyfops Feb 23, 2025
9eb26ad
Push capes
emyfops Feb 28, 2025
68b483d
Merge branch 'master' into feat/auth
emyfops Feb 28, 2025
e070b3c
Update API to v1.1.0
emyfops Mar 7, 2025
ccb863f
Fold api responses
emyfops Mar 7, 2025
aa90562
Fix capes folder
emyfops Mar 7, 2025
2943614
Fixed texture downloading
emyfops Mar 7, 2025
13e692f
Cape feature
emyfops Mar 7, 2025
cf29f96
Fixed missing dependency
emyfops Mar 7, 2025
26d28a3
Update Discord.kt
emyfops Mar 14, 2025
21a89e0
Return if no values
emyfops Mar 14, 2025
3dd0fa2
Merge branch 'master' into feat/auth
emyfops Mar 14, 2025
acfd1aa
Merge conflict
emyfops Mar 14, 2025
f2fa357
Removed fix me
emyfops Mar 14, 2025
b5d1896
Fixed hash utils
emyfops Mar 14, 2025
d79aac4
Unused import
emyfops Mar 14, 2025
aa4206f
Log error instead of propagate
emyfops Mar 14, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,12 @@ subprojects {

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

loom.runs {
all {
property("lambda.dev", "youtu.be/RYnFIRc0k6E")
}
}

tasks {
register<Exec>("renderDoc") {
val javaHome = Jvm.current().javaHome
Expand Down Expand Up @@ -144,7 +150,7 @@ allprojects {
tasks {
compileKotlin {
compilerOptions {
jvmTarget.set(JvmTarget.JVM_17)
jvmTarget = JvmTarget.JVM_17
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@

import com.lambda.event.EventFlow;
import com.lambda.event.events.InventoryEvent;
import com.lambda.event.events.WorldEvent;
import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.network.packet.s2c.play.GameJoinS2CPacket;
import net.minecraft.network.packet.s2c.play.ScreenHandlerSlotUpdateS2CPacket;
import net.minecraft.network.packet.s2c.play.UpdateSelectedSlotS2CPacket;
import org.spongepowered.asm.mixin.Mixin;
Expand All @@ -29,6 +31,11 @@

@Mixin(ClientPlayNetworkHandler.class)
public class ClientPlayNetworkHandlerMixin {
@Inject(method = "onGameJoin(Lnet/minecraft/network/packet/s2c/play/GameJoinS2CPacket;)V", at = @At("TAIL"))
void injectJoinPacket(GameJoinS2CPacket packet, CallbackInfo ci) {
EventFlow.post(new WorldEvent.Join());
}

@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)
private void onUpdateSelectedSlot(UpdateSelectedSlotS2CPacket packet, CallbackInfo ci) {
if (EventFlow.post(new InventoryEvent.HotbarSlot.Sync(packet.getSlot())).isCanceled()) ci.cancel();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,12 @@
import com.lambda.module.modules.render.WorldColors;
import com.lambda.util.math.ColorKt;
import net.minecraft.block.BlockState;
import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.client.render.WorldRenderer;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.entity.Entity;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import org.spongepowered.asm.mixin.Mixin;
Expand All @@ -33,6 +37,8 @@
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;

import java.util.function.Supplier;

@Mixin(ClientWorld.class)
public class ClientWorldMixin {
@Inject(method = "addEntity", at = @At("HEAD"), cancellable = true)
Expand Down
45 changes: 45 additions & 0 deletions common/src/main/kotlin/com/lambda/Lambda.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@

package com.lambda

import com.github.kittinunf.fuel.Fuel
import com.github.kittinunf.fuel.core.await
import com.github.kittinunf.fuel.core.awaitResponse
import com.github.kittinunf.fuel.core.awaitUnit
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.lambda.config.serializer.*
Expand All @@ -27,6 +31,7 @@ import com.lambda.core.Loader
import com.lambda.gui.impl.clickgui.windows.tag.CustomModuleWindow
import com.lambda.gui.impl.clickgui.windows.tag.TagWindow
import com.lambda.module.tag.ModuleTag
import com.lambda.threading.runConcurrent
import com.lambda.util.KeyCode
import com.mojang.authlib.GameProfile
import com.mojang.blaze3d.systems.RenderSystem.recordRenderCall
Expand All @@ -38,7 +43,12 @@ import net.minecraft.util.math.BlockPos
import org.apache.logging.log4j.LogManager
import org.apache.logging.log4j.Logger
import java.awt.Color
import java.net.URI
import java.net.http.HttpClient
import java.net.http.HttpRequest
import java.net.http.HttpResponse
import java.util.*
import java.util.concurrent.CountDownLatch


object Lambda {
Expand All @@ -52,6 +62,8 @@ object Lambda {
@JvmStatic
val mc: MinecraftClient by lazy { MinecraftClient.getInstance() }

val isDebug = System.getProperty("lambda.dev") != null

val gson: Gson = GsonBuilder()
.setPrettyPrinting()
.registerTypeAdapter(ModuleTag::class.java, ModuleTagSerializer)
Expand All @@ -68,6 +80,39 @@ object Lambda {
.create()

fun initialize(block: (Long) -> Unit) {
runConcurrent {
// Create an HttpClient
val client = HttpClient.newHttpClient()

// Define the URI for the SSE stream
val uri = URI.create("http://localhost:8080/api/v1/party/listen")

// Create an HttpRequest for the SSE stream
val request = HttpRequest.newBuilder()
.uri(uri)
.header("Accept", "text/event-stream")
.build()

// Create a CountDownLatch to wait for the events
val latch = CountDownLatch(1)

// Send the request and handle the response asynchronously
client.sendAsync(request, HttpResponse.BodyHandlers.ofLines())
.thenAccept { response ->
println("Connected to SSE stream")
response.body().forEach { line ->
if (line.startsWith("data:")) {
val data = line.substring(5).trim()
println("Received event data: $data")
}
}
latch.countDown()
}

// Wait until the response is received and handled
latch.await()
}

recordRenderCall {
block(Loader.initialize())
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
* Copyright 2024 Lambda
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package com.lambda.command.commands

import com.lambda.brigadier.argument.literal
import com.lambda.brigadier.argument.value
import com.lambda.brigadier.argument.word
import com.lambda.brigadier.execute
import com.lambda.brigadier.required
import com.lambda.command.LambdaCommand
import com.lambda.module.modules.client.Discord.partyCreate
import com.lambda.module.modules.client.Discord.partyJoin
import com.lambda.module.modules.client.Discord.partyLeave
import com.lambda.module.modules.client.Discord.rpc
import com.lambda.network.api.v1.endpoints.leaveParty
import com.lambda.threading.runConcurrent
import com.lambda.threading.runSafe
import com.lambda.util.extension.CommandBuilder

object DiscordCommand : LambdaCommand(
name = "discord",
description = "Discord Rich Presence commands",
usage = "rpc <create | leave | delete | join [id] | accept [user] | refuse [user]>"
) {
override fun CommandBuilder.create() {
required(literal("create")) {
execute {
runSafe { partyCreate() }
}
}

required(literal("leave")) {
execute {
runSafe { partyLeave() }
}
}

required(literal("delete")) {
execute {
runSafe { partyCreate() }
}
}

required(literal("join")) {
required(word("id")) { id ->
execute {
runSafe { partyJoin(id().value()) }
}
}
}

required(literal("accept")) {
required(word("user")) { user ->
execute {
runConcurrent { rpc.activityManager.acceptJoinRequest(user().value()) }
}
}
}

required(literal("refuse")) {
required(word("user")) { user ->
execute {
runConcurrent { rpc.activityManager.refuseJoinRequest(user().value()) }
}
}
}
}
}
43 changes: 0 additions & 43 deletions common/src/main/kotlin/com/lambda/command/commands/RpcCommand.kt

This file was deleted.

4 changes: 4 additions & 0 deletions common/src/main/kotlin/com/lambda/event/events/WorldEvent.kt
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ import net.minecraft.world.chunk.WorldChunk
* occurrences in the game world.
*/
sealed class WorldEvent {
// ToDo: Add doc and determine if there's a better place for this event
// Represents the player joining the world
class Join() : Event

/**
* Represents an event specific to chunk operations within the world.
*
Expand Down
20 changes: 8 additions & 12 deletions common/src/main/kotlin/com/lambda/event/listener/SafeListener.kt
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,8 @@ class SafeListener<T : Event>(

/**
* This function registers a new [SafeListener] for a generic [Event] type [T].
* The [transform] is executed on the same thread where the [Event] was dispatched.
* The [transform] will only be executed when the context satisfies certain safety conditions.
* The [predicate] is executed on the same thread where the [Event] was dispatched.
* The [predicate] will only be executed when the context satisfies certain safety conditions.
* These conditions are met when none of the following [SafeContext] properties are null:
* - [SafeContext.world]
* - [SafeContext.player]
Expand All @@ -142,7 +142,7 @@ class SafeListener<T : Event>(
*
* This typically occurs when the user is in-game.
*
* After the [transform] is executed once, the [SafeListener] will be automatically unsubscribed.
* After the [predicate] is executed once, the [SafeListener] will be automatically unsubscribed.
*
* Usage:
* ```kotlin
Expand All @@ -156,24 +156,20 @@ class SafeListener<T : Event>(
* @param T The type of the event to listen for. This should be a subclass of Event.
* @param priority The priority of the listener. Listeners with higher priority will be executed first. The Default value is 0.
* @param alwaysListen If true, the listener will be executed even if it is muted. The Default value is false.
* @param transform The function used to transform the event into a value.
* @return The newly created and registered [SafeListener].
*/
inline fun <reified T : Event, reified E> Any.listenOnce(
inline fun <reified T : Event> Any.listenOnce(
priority: Int = 0,
alwaysListen: Boolean = false,
noinline predicate: SafeContext.(T) -> Boolean = { true },
noinline transform: SafeContext.(T) -> E? = { null },
): ReadWriteProperty<Any?, E?> {
val pointer = Pointer<E>()
): ReadWriteProperty<Any?, T?> {
val pointer = Pointer<T>()

val destroyable by selfReference<SafeListener<T>> {
SafeListener(priority, this@listenOnce, alwaysListen) { event ->
pointer.value = transform(event)
pointer.value = event

if (predicate(event) &&
pointer.value != null
) {
if (predicate(event)) {
val self by this@selfReference
EventFlow.syncListeners.unsubscribe(self)
}
Expand Down
26 changes: 14 additions & 12 deletions common/src/main/kotlin/com/lambda/event/listener/UnsafeListener.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,11 @@ import com.lambda.context.SafeContext
import com.lambda.event.Event
import com.lambda.event.EventFlow
import com.lambda.event.Muteable
import com.lambda.threading.runConcurrent
import com.lambda.util.Pointer
import com.lambda.util.selfReference
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import kotlin.properties.ReadOnlyProperty
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
Expand Down Expand Up @@ -136,24 +139,20 @@ class UnsafeListener<T : Event>(
* @param T The type of the event to listen for. This should be a subclass of Event.
* @param priority The priority of the listener. Listeners with higher priority will be executed first.
* @param alwaysListen If true, the listener will be executed even if it is muted.
* @param transform The function used to transform the event into a value.
* @return The newly created and registered [UnsafeListener].
*/
inline fun <reified T : Event, reified E> Any.listenOnceUnsafe(
inline fun <reified T : Event> Any.listenOnceUnsafe(
priority: Int = 0,
alwaysListen: Boolean = false,
noinline transform: (T) -> E? = { null },
noinline predicate: (T) -> Boolean = { true },
): ReadWriteProperty<Any?, E?> {
val pointer = Pointer<E>()
noinline function: (T) -> Boolean = { true },
): ReadWriteProperty<Any?, T?> {
val pointer = Pointer<T>()

val destroyable by selfReference<UnsafeListener<T>> {
UnsafeListener(priority, this@listenOnceUnsafe, alwaysListen) { event ->
pointer.value = transform(event)
pointer.value = event

if (predicate(event) &&
pointer.value != null
) {
if (function(event)) {
val self by this@selfReference
EventFlow.syncListeners.unsubscribe(self)
}
Expand Down Expand Up @@ -194,10 +193,13 @@ class UnsafeListener<T : Event>(
inline fun <reified T : Event> Any.listenUnsafeConcurrently(
priority: Int = 0,
alwaysListen: Boolean = false,
noinline function: (T) -> Unit = {},
scheduler: CoroutineDispatcher = Dispatchers.Default,
noinline function: suspend (T) -> Unit = {},
): UnsafeListener<T> {
val listener = UnsafeListener<T>(priority, this, alwaysListen) { event ->
function(event)
runConcurrent(scheduler) {
function(event)
}
}

EventFlow.concurrentListeners.subscribe<T>(listener)
Expand Down
Loading
Loading