Skip to content

Commit e0416a7

Browse files
committed
Merge branch 'master' into feature/taskflow
2 parents 50bdef8 + 8c4047d commit e0416a7

File tree

12 files changed

+85
-128
lines changed

12 files changed

+85
-128
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.lambda.mixin.render;
2+
3+
import net.minecraft.client.gui.screen.SplashOverlay;
4+
import net.minecraft.util.Identifier;
5+
import net.minecraft.util.math.ColorHelper;
6+
import org.spongepowered.asm.mixin.Final;
7+
import org.spongepowered.asm.mixin.Mixin;
8+
import org.spongepowered.asm.mixin.Mutable;
9+
import org.spongepowered.asm.mixin.Shadow;
10+
import org.spongepowered.asm.mixin.injection.*;
11+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
12+
13+
import java.util.function.IntSupplier;
14+
15+
@Mixin(SplashOverlay.class)
16+
public class SplashOverlayMixin {
17+
@Mutable
18+
@Shadow @Final
19+
static Identifier LOGO;
20+
21+
@Redirect(method = "render", at = @At(value = "INVOKE", target = "Ljava/util/function/IntSupplier;getAsInt()I"))
22+
private int redirectBrandArgb(IntSupplier originalSupplier) {
23+
return ColorHelper.Argb.getArgb(255, 35, 35, 35);
24+
}
25+
26+
@Inject(method = "<init>", at = @At("RETURN"))
27+
private void onInit(CallbackInfo ci) {
28+
LOGO = Identifier.of("lambda", "textures/lambda_banner.png");
29+
}
30+
}

common/src/main/kotlin/com/lambda/graphics/renderer/gui/font/glyph/EmojiGlyphs.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,6 @@ class EmojiGlyphs(zipUrl: String) {
107107

108108
companion object {
109109
private const val STEP = 2
110-
private const val GL_TEXTURE_SLOT = 1 // TODO: Texture slot borrowing
110+
private const val GL_TEXTURE_SLOT = 1
111111
}
112112
}

common/src/main/kotlin/com/lambda/http/Request.kt

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,8 @@ package com.lambda.http
22

33
import com.lambda.Lambda
44
import com.lambda.util.FolderRegister.cache
5-
import com.lambda.util.FolderRegister.createFileIfNotExists
65
import com.lambda.util.FolderRegister.createIfNotExists
76
import java.io.File
8-
import java.io.OutputStream
97
import java.net.HttpURLConnection
108
import java.net.URL
119
import kotlin.time.Duration
@@ -44,12 +42,12 @@ data class Request(
4442
name: String,
4543
maxAge: Duration = 7.days,
4644
): File {
47-
val (file, wasCreated) = createFileIfNotExists(name, cache, true)
45+
val file = cache.resolve(name).createIfNotExists()
4846

49-
if (System.currentTimeMillis() - file.lastModified() < maxAge.inWholeMilliseconds
47+
if (
48+
System.currentTimeMillis() - file.lastModified() < maxAge.inWholeMilliseconds
5049
&& file.length() > 0
51-
&& !wasCreated)
52-
return file
50+
) return file
5351

5452
file.writeText("") // Clear the file before writing to it.
5553

common/src/main/kotlin/com/lambda/module/modules/movement/EntityControl.kt

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,30 +6,26 @@ import com.lambda.event.listener.SafeListener.Companion.listener
66
import com.lambda.module.Module
77
import com.lambda.module.tag.ModuleTag
88
import com.lambda.util.world.entitySearch
9+
import com.lambda.util.world.fastEntitySearch
910
import net.minecraft.entity.passive.AbstractHorseEntity
11+
import net.minecraft.entity.passive.PigEntity
1012
import net.minecraft.network.packet.c2s.play.PlayerInteractEntityC2SPacket
1113

12-
// ToDo: Rework this module. All mountables should work, solution should be more elegant.
1314
object EntityControl : Module(
1415
name = "EntityControl",
1516
description = "Control mountable entities",
1617
defaultTags = setOf(ModuleTag.MOVEMENT)
1718
) {
18-
private val forceMount by setting("Force Mount", true, description = "Attempts to force mount chested entities.").apply {
19-
onValueChange { _, _ ->
20-
resetMounts()
21-
}
22-
}
23-
private val modified = mutableSetOf<AbstractHorseEntity>()
19+
private val forceMount by setting("Force Mount", true, description = "Attempts to force mount chested entities.")
20+
21+
private val saddledHorses = mutableSetOf<AbstractHorseEntity>()
2422

2523
init {
2624
listener<TickEvent.Pre> {
27-
if (!forceMount) return@listener
28-
29-
entitySearch<AbstractHorseEntity>(8.0)
25+
fastEntitySearch<AbstractHorseEntity>(8.0)
3026
.forEach {
27+
if (!it.isSaddled) saddledHorses.add(it)
3128
it.setHorseFlag(4, true)
32-
modified.add(it)
3329
}
3430
}
3531

@@ -45,11 +41,8 @@ object EntityControl : Module(
4541
}
4642

4743
onDisable {
48-
resetMounts()
44+
saddledHorses.forEach { it.setHorseFlag(4, false) }
45+
saddledHorses.clear()
4946
}
5047
}
51-
52-
private fun resetMounts() {
53-
modified.forEach { it.updateSaddle() }
54-
}
5548
}

common/src/main/kotlin/com/lambda/module/modules/movement/RocketExtend.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import com.lambda.event.events.PacketEvent
55
import com.lambda.event.listener.SafeListener.Companion.listener
66
import com.lambda.module.Module
77
import com.lambda.module.tag.ModuleTag
8-
import com.lambda.util.collections.filterPointer
8+
import com.lambda.util.extension.filterPointer
99
import net.minecraft.entity.projectile.FireworkRocketEntity
1010
import net.minecraft.network.packet.c2s.common.CommonPongC2SPacket
1111
import net.minecraft.network.packet.s2c.play.EntitiesDestroyS2CPacket
Lines changed: 28 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,9 @@
11
package com.lambda.util
22

33
import com.lambda.Lambda.mc
4-
import com.lambda.util.FolderRegister.config
5-
import com.lambda.util.FolderRegister.lambda
6-
import com.lambda.util.FolderRegister.minecraft
7-
import com.lambda.util.FolderRegister.mods
8-
import com.lambda.util.FolderRegister.packetLogs
9-
import com.lambda.util.FolderRegister.replay
104
import com.lambda.util.StringUtils.sanitizeForFilename
11-
import org.apache.commons.codec.digest.DigestUtils
125
import java.io.File
13-
import java.io.InputStream
146
import java.net.InetSocketAddress
15-
import java.security.MessageDigest
167

178
/**
189
* The [FolderRegister] object is responsible for managing the directory structure of the application.
@@ -34,12 +25,36 @@ object FolderRegister {
3425
val cache: File = File(lambda, "cache")
3526
val structure: File = File(lambda, "structure")
3627

37-
fun File.createIfNotExists() {
38-
createFileIfNotExists(this.name, this.parentFile)
39-
}
28+
/**
29+
* Ensures the current file exists by creating it if it does not.
30+
*
31+
* If the file already exists, it will not be recreated. The necessary
32+
* parent directories will be created if they do not exist.
33+
*/
34+
fun File.createIfNotExists(): File = also { parentFile.mkdirs(); createNewFile() }
4035

41-
fun File.listRecursive(predicate: (File) -> Boolean = { true }) = walk().filter(predicate)
36+
/**
37+
* Returns a sequence of all the files in a tree that matches the [predicate]
38+
*/
39+
fun File.listRecursive(predicate: (File) -> Boolean) = walk().filter(predicate)
4240

41+
/**
42+
* Retrieves or creates a directory based on the current network connection and world dimension.
43+
*
44+
* The directory is determined by the host name of the current network connection (or "singleplayer" if offline)
45+
* and the dimension key of the current world. These values are sanitized for use as filenames and combined
46+
* to form a path under the current file. If the directory does not exist, it will be created.
47+
*
48+
* @receiver The base directory where the location-bound directory will be created.
49+
* @return A `File` object representing the location-bound directory.
50+
*
51+
* The path is structured as:
52+
* - `[base directory]/[host name]/[dimension key]`
53+
*
54+
* Example:
55+
* If playing on a server with hostname "example.com" and in the "overworld" dimension, the path would be:
56+
* - `[base directory]/example.com/overworld`
57+
*/
4358
fun File.locationBoundDirectory(): File {
4459
val hostName = (mc.networkHandler?.connection?.address as? InetSocketAddress)?.hostName ?: "singleplayer"
4560
val path = resolve(
@@ -50,72 +65,4 @@ object FolderRegister {
5065
path.createIfNotExists()
5166
return path
5267
}
53-
54-
/**
55-
* Returns a file with the given name in the specified directory, creating it if it does not exist.
56-
* If the directory is not specified, it will try to parse it from the name.
57-
* Otherwise, it will default to the Lambda directory.
58-
*
59-
* @param name The name of the file.
60-
* @param directory The directory in which the file is located. Default is the Lambda directory.
61-
* @param hash Whether to hash the name of the file.
62-
* @return A pair containing the file and a boolean indicating whether the file was created.
63-
*/
64-
fun createFileIfNotExists(name: String, directory: File? = null, hash: Boolean = false): Pair<File, Boolean> {
65-
var parsedDir: File = directory ?: lambda
66-
67-
if (directory == null) {
68-
parsedDir = name.substringAfterLast('/').substringBeforeLast('.')
69-
.let { if (it.isEmpty()) lambda else File(it) }
70-
}
71-
72-
val compiledName =
73-
if (hash) DigestUtils.sha256Hex(name)
74-
else name
75-
76-
val file = File(parsedDir, compiledName)
77-
val created = !file.exists()
78-
79-
if (created) {
80-
file.parentFile.mkdirs()
81-
file.createNewFile()
82-
}
83-
84-
return file to created
85-
}
86-
87-
88-
/**
89-
* Returns a file with the given name in the specified directory, creating it if it does not exist.
90-
* If the directory is not specified, it will try to parse it from the name.
91-
* Otherwise, it will default to the Lambda directory.
92-
*
93-
* @param name The name of the file.
94-
* @param directory The directory in which the file is located. Default is the Lambda directory.
95-
* @param compute A lambda function to compute the file contents if it was created.
96-
*/
97-
@JvmName("getFileOrComputeByteArray")
98-
inline fun getFileOrCompute(name: String, directory: File? = null, compute: () -> ByteArray): File {
99-
val (file, wasCreated) = createFileIfNotExists(name, directory)
100-
if (wasCreated) file.outputStream().use { it.write(compute()) }
101-
102-
return file
103-
}
104-
105-
/**
106-
* Returns a file with the given name in the specified directory, creating it if it does not exist.
107-
* If the directory is not specified, it will try to parse it from the name.
108-
* Otherwise, it will default to the Lambda directory.
109-
*
110-
* @param name The name of the file.
111-
* @param directory The directory in which the file is located. Default is the Lambda directory.
112-
* @param compute A lambda function to compute the file contents if it was created.
113-
*/
114-
@JvmName("getFileOrComputeInputStream")
115-
inline fun getFileOrCompute(name: String, directory: File? = null, compute: () -> InputStream): File {
116-
val (file, wasCreated) = createFileIfNotExists(name, directory)
117-
if (wasCreated) file.outputStream().use { compute().copyTo(it) }
118-
119-
return file
120-
}
12168
}

common/src/main/kotlin/com/lambda/util/StringUtils.kt

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,18 @@
11
package com.lambda.util
22

33
object StringUtils {
4+
/**
5+
* Returns a sanitized file path for both Unix and Linux systems
6+
*/
47
fun String.sanitizeForFilename() =
5-
replace("\\", "_")
6-
.replace("/", "_")
7-
.replace(":", "_")
8-
.replace("*", "_")
9-
.replace("?", "_")
10-
.replace("\"", "_")
11-
.replace("<", "_")
12-
.replace(">", "_")
13-
.replace("|", "_")
8+
replace(Regex("[\\\\/:*?\"<>|]"), "_")
149
.trim()
1510
.take(255) // truncate to 255 characters for Windows compatibility
1611

17-
// ToDo: Fix this. Does not work for some reason
18-
// fun String.sanitizeForFilename(): String {
19-
// val invalidChars = Regex.fromLiteral("[\\\\/*?|<>:\"\\[\\]\\(\\)\\s]")
20-
// val safeChars = Regex.fromLiteral("[^\\p{L}\\p{N}_\\-~]")
21-
// return replace(invalidChars, "_")
22-
// .replace(safeChars, "")
23-
// .trim()
24-
// .take(255) // truncate to 255 characters for Windows compatibility
25-
// }
26-
2712

13+
/**
14+
* Capitalizes the first character of a string using its Unicode mapping
15+
*/
2816
fun String.capitalize() = replaceFirstChar { it.titlecase() }
2917

3018
/**
@@ -84,4 +72,4 @@ object StringUtils {
8472

8573
return cost[len0 - 1]
8674
}
87-
}
75+
}

common/src/main/kotlin/com/lambda/util/collections/Extensions.kt renamed to common/src/main/kotlin/com/lambda/util/extension/Collections.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.lambda.util.collections
1+
package com.lambda.util.extension
22

33
import kotlin.reflect.KClass
44

common/src/main/kotlin/com/lambda/util/world/EntityDsl.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,5 +95,5 @@ inline fun <reified T : Entity> SafeContext.entitySearch(
9595
inline fun <reified T : Entity> SafeContext.fastEntitySearch(
9696
range: Double,
9797
pos: BlockPos = player.blockPos,
98-
noinline predicate: (T) -> Boolean
98+
noinline predicate: (T) -> Boolean = { true }
9999
): List<T> = EntityDsl(this, T::class, pos, range, predicate).buildFast()

common/src/main/kotlin/com/lambda/util/world/WorldUtils.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ package com.lambda.util.world
22

33
import com.lambda.context.SafeContext
44
import com.lambda.core.annotations.InternalApi
5-
import com.lambda.util.collections.filterPointer
5+
import com.lambda.util.extension.filterPointer
66
import com.lambda.util.extension.getBlockState
77
import com.lambda.util.extension.getFluidState
88
import net.minecraft.block.BlockState

0 commit comments

Comments
 (0)