Skip to content

Commit f9dcafb

Browse files
emyfopsAvanatiker
andauthored
Testing pipeline (#110)
Co-authored-by: Constructor <fractalminds@protonmail.com>
1 parent 1c6f2a7 commit f9dcafb

File tree

20 files changed

+1489
-81
lines changed

20 files changed

+1489
-81
lines changed

.github/workflows/build.yml

Lines changed: 9 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -3,60 +3,26 @@ name: Build Lambda
33
on:
44
push:
55
branches:
6-
- '**'
6+
- 'master'
7+
pull_request:
78

89
jobs:
9-
check-runner:
10-
name: Check Runner Availability
11-
runs-on: ubuntu-latest
12-
13-
outputs:
14-
runner-label: ${{ steps.set-runner.outputs.runner-label }}
15-
16-
steps:
17-
- name: Set runner
18-
id: set-runner
19-
run: |
20-
runners=$(curl -v -s -H "Accept: application/vnd.github+json" -H "Authorization: token ${{ secrets.REPO_ACCESS_TOKEN }}" "https://api.github.com/repos/${{ github.repository }}/actions/runners" --http1.1)
21-
if [ $? -ne 0 ]; then
22-
echo "Error: Failed to fetch runners from GitHub API" >&2
23-
exit 1
24-
fi
25-
26-
runners_count=$(echo "$runners" | jq '.runners | length')
27-
if [ "$runners_count" -eq 0 ]; then
28-
echo "No runners available or failed to retrieve runners." >&2
29-
echo "runner-label=ubuntu-latest" >> $GITHUB_OUTPUT
30-
exit 0
31-
fi
32-
33-
available=$(echo "$runners" | jq '.runners[] | select(.status == "online" and .busy == false and .labels[] .name == "self-hosted")')
34-
if [ $? -ne 0 ]; then
35-
echo "Error: Failed to parse JSON response" >&2
36-
exit 1
37-
fi
38-
39-
if [ -n "$available" ]; then
40-
echo "runner-label=lambda-linux-runner" >> $GITHUB_OUTPUT
41-
else
42-
echo "runner-label=ubuntu-latest" >> $GITHUB_OUTPUT
43-
fi
4410
build:
4511
concurrency:
4612
group: ${{ github.workflow }}-${{ github.ref }}
4713
cancel-in-progress: true
48-
49-
needs: check-runner
50-
runs-on: ${{ needs.check-runner.outputs.runner-label }}
5114

5215
name: Build Lambda
16+
runs-on: ubuntu-latest
17+
5318
permissions:
5419
contents: write
20+
5521
env:
5622
SEGMENT_DOWNLOAD_TIMEOUT_MINS: '5'
5723
steps:
5824
- name: Checkout Repository
59-
uses: actions/checkout@v4.1.1
25+
uses: actions/checkout@v4
6026

6127
- name: Set current date as env variable
6228
run: echo "DATE=$(date +'%Y-%m-%dT%H:%M:%S')" >> $GITHUB_ENV
@@ -65,11 +31,11 @@ jobs:
6531
id: vars
6632
run: echo "COMMIT_HASH=$(git rev-parse --short HEAD)" >> $GITHUB_ENV
6733

68-
- name: Set-Up JDK 17
34+
- name: Set-Up JDK
6935
uses: actions/setup-java@v4
7036
with:
7137
distribution: 'temurin'
72-
java-version: '17'
38+
java-version: '21'
7339
architecture: x64
7440
cache: 'gradle'
7541

@@ -81,7 +47,7 @@ jobs:
8147
all: true
8248

8349
- name: Build Lambda
84-
run: ./gradlew build
50+
run: ./gradlew build --no-daemon
8551

8652
- name: Rename Files with Commit Hash
8753
run: |
@@ -111,8 +77,6 @@ jobs:
11177
### [Lambda Forge ${{ steps.all.outputs.modVersion }} ${{ steps.all.outputs.minecraftVersion }} (${{ env.COMMIT_HASH }})](https://r2-bucket.edouard127.christmas/${{ env.DATE }}-${{ env.COMMIT_HASH }}/lambda-forge-${{ steps.all.outputs.modVersion }}+${{ steps.all.outputs.minecraftVersion }}-${{ env.COMMIT_HASH }}.jar)
11278
11379
#### [API (Developer Dependency)](https://r2-bucket.edouard127.christmas/${{ env.DATE }}-${{ env.COMMIT_HASH }}/lambda-api-${{ steps.all.outputs.modVersion }}+${{ steps.all.outputs.minecraftVersion }}-${{ env.COMMIT_HASH }}.jar)
114-
115-
**Runner:** \`${{ needs.check-runner.outputs.runner-label }}\`
11680
EOF
11781
11882
- name: Failover Upload

common/build.gradle.kts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ val kotlinxCoroutinesVersion: String by project
2323
val discordIPCVersion: String by project
2424
val fuelVersion: String by project
2525
val resultVersion: String by project
26+
val mockitoKotlin: String by project
27+
val mockitoInline: String by project
28+
val mockkVersion: String by project
2629

2730
base.archivesName = "${base.archivesName.get()}-api"
2831

@@ -57,6 +60,10 @@ dependencies {
5760

5861
// Baritone
5962
modImplementation("baritone-api:baritone-unoptimized-fabric:1.10.2") { isTransitive = false }
63+
testImplementation(kotlin("test"))
64+
testImplementation("org.mockito.kotlin:mockito-kotlin:$mockitoKotlin")
65+
testImplementation("org.mockito:mockito-inline:$mockitoInline")
66+
testImplementation("io.mockk:mockk:${mockkVersion}")
6067
}
6168

6269
tasks {
@@ -66,5 +73,18 @@ tasks {
6673

6774
test {
6875
useJUnitPlatform()
76+
jvmArgs("-XX:+EnableDynamicAgentLoading", "-Xshare:off")
77+
}
78+
}
79+
80+
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
81+
kotlinOptions {
82+
jvmTarget = "17"
83+
}
84+
}
85+
86+
subprojects {
87+
tasks.named("build") {
88+
dependsOn("test")
6989
}
7090
}

common/src/main/kotlin/com/lambda/module/modules/network/PacketLimiter.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ object PacketLimiter : Module(
3535
) {
3636
private var packetQueue = LimitedDecayQueue<PacketEvent.Send.Pre>(99, 1000)
3737
private val limit by setting("Limit", 99, 1..100, 1, "The maximum amount of packets to send per given time interval", unit = " packets")
38-
.onValueChange { _, to -> packetQueue.setMaxSize(to) }
38+
.onValueChange { _, to -> packetQueue.setSizeLimit(to) }
3939

4040
private val interval by setting("Duration", 1000L, 1L..1000L, 50L, "The interval / duration in milliseconds to limit packets for", unit = " ms")
4141
.onValueChange { _, to -> packetQueue.setDecayTime(to) }

common/src/main/kotlin/com/lambda/task/Task.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,9 @@ typealias TaskGeneratorOrNull<R> = SafeContext.(R) -> Task<*>?
3737
typealias TaskGeneratorUnit<R> = SafeContext.(R) -> Unit
3838

3939
abstract class Task<Result> : Nameable, Muteable {
40-
private var parent: Task<*>? = null
41-
private val subTasks = mutableListOf<Task<*>>()
42-
private var state = State.INIT
40+
var parent: Task<*>? = null
41+
val subTasks = mutableListOf<Task<*>>()
42+
var state = State.INIT
4343
override val isMuted: Boolean get() = state == State.PAUSED || state == State.INIT
4444
var age = 0
4545
private val depth: Int get() = parent?.depth?.plus(1) ?: 0

common/src/main/kotlin/com/lambda/task/tasks/OpenContainer.kt

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,10 @@ class OpenContainer @Ta5kBuilder constructor(
3939
private val interact: InteractionConfig = TaskFlowModule.interact,
4040
private val sides: Set<Direction> = Direction.entries.toSet(),
4141
) : Task<ScreenHandler>() {
42-
override val name get() = "${state.description(inScope)} at ${blockPos.toShortString()}"
42+
override val name get() = "${containerState.description(inScope)} at ${blockPos.toShortString()}"
4343

4444
private var screenHandler: ScreenHandler? = null
45-
private var state = State.SCOPING
45+
private var containerState = State.SCOPING
4646
private var inScope = 0
4747

4848
enum class State {
@@ -57,39 +57,39 @@ class OpenContainer @Ta5kBuilder constructor(
5757

5858
init {
5959
listen<InventoryEvent.Open> {
60-
if (state != State.OPENING) return@listen
60+
if (containerState != State.OPENING) return@listen
6161

6262
screenHandler = it.screenHandler
63-
state = State.SLOT_LOADING
63+
containerState = State.SLOT_LOADING
6464

6565
if (!waitForSlotLoad) success(it.screenHandler)
6666
}
6767

6868
listen<InventoryEvent.Close> {
6969
if (screenHandler != it.screenHandler) return@listen
7070

71-
state = State.SCOPING
71+
containerState = State.SCOPING
7272
screenHandler = null
7373
}
7474

7575
listen<InventoryEvent.FullUpdate> {
76-
if (state != State.SLOT_LOADING) return@listen
76+
if (containerState != State.SLOT_LOADING) return@listen
7777

7878
screenHandler?.let {
7979
success(it)
8080
}
8181
}
8282

8383
listen<TickEvent.Pre> {
84-
if (state != State.SCOPING) return@listen
84+
if (containerState != State.SCOPING) return@listen
8585

8686
val target = lookAtBlock(blockPos, sides, config = interact)
8787
if (rotate && !target.requestBy(rotation).done) return@listen
8888

8989
val hitResult = target.hit?.hitIfValid()?.blockResult ?: return@listen
9090
interaction.interactBlock(player, Hand.MAIN_HAND, hitResult)
9191

92-
state = State.OPENING
92+
containerState = State.OPENING
9393
}
9494
}
9595
}

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

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@ package com.lambda.util
1919

2020
class VarIntIterator(
2121
private val bytes: ByteArray,
22-
private val bitsPerEntry: Int = 7,
23-
private val maxGroups: Int = 5,
2422
) : Iterator<Int> {
2523
private var index: Int = 0
2624

@@ -31,23 +29,23 @@ class VarIntIterator(
3129
throw NoSuchElementException("No more elements to read")
3230

3331
var value = 0
34-
var bitsRead = 0
32+
var size = 0
3533

36-
val groupMask = (1 shl bitsPerEntry) - 1
37-
val continuationBit = 1 shl bitsPerEntry
38-
39-
var b: Byte
4034
do {
41-
if (index >= bytes.size)
42-
throw NoSuchElementException("Unexpected end of byte array while reading VarInt")
43-
44-
b = bytes[index++]
45-
value = value or ((b.toInt() and groupMask) shl bitsRead)
46-
bitsRead += bitsPerEntry
35+
val b = bytes[index++].toInt()
36+
value = value or ((b and SEGMENT_BIT) shl (size++ * 7))
4737

48-
require(bitsRead <= bitsPerEntry * maxGroups) { "VarInt size cannot exceed $maxGroups bytes" }
49-
} while ((b.toInt() and continuationBit) != 0)
38+
if (size > 5) throw IllegalArgumentException("VarInt size cannot exceed 5 bytes")
39+
} while ((b and CONTINUE_BIT) != 0)
5040

5141
return value
5242
}
43+
44+
companion object {
45+
const val SEGMENT_BIT = 127
46+
const val CONTINUE_BIT = 128
47+
}
5348
}
49+
50+
inline fun ByteArray.varIterator(block: (Int) -> Unit) =
51+
VarIntIterator(this).forEach(block)

common/src/main/kotlin/com/lambda/util/collections/LimitedDecayQueue.kt

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,11 +106,17 @@ class LimitedDecayQueue<E>(
106106
* Updates the maximum allowed size for the queue and triggers a cleanup operation
107107
* to remove elements exceeding the new size or falling outside the allowed time interval.
108108
*
109+
* Elements starting from the head will be removed.
110+
*
109111
* @param newSize The new maximum size for the queue. Must be a non-negative integer.
110112
*/
111-
fun setMaxSize(newSize: Int) {
113+
fun setSizeLimit(newSize: Int) {
112114
sizeLimit = newSize
113115
cleanUp()
116+
117+
while (queue.size > newSize) {
118+
queue.poll()
119+
}
114120
}
115121

116122
/**
@@ -131,4 +137,4 @@ class LimitedDecayQueue<E>(
131137
onDecay(queue.poll().first)
132138
}
133139
}
134-
}
140+
}

common/src/main/kotlin/com/lambda/util/extension/Structures.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ package com.lambda.util.extension
2020
import com.lambda.Lambda.mc
2121
import com.lambda.util.VarIntIterator
2222
import com.lambda.util.math.MathUtils.logCap
23+
import com.lambda.util.varIterator
2324
import com.lambda.util.world.FastVector
2425
import com.lambda.util.world.fastVectorOf
2526
import com.lambda.util.world.x
@@ -117,8 +118,8 @@ private fun StructureTemplate.readSpongeV1OrException(
117118

118119
val newBlocks = NbtList()
119120
var blockIndex = 0
120-
VarIntIterator(nbt.getByteArray("BlockData"))
121-
.forEach { blockId ->
121+
nbt.getByteArray("BlockData")
122+
.varIterator { blockId ->
122123
val blockpos = positionFromIndex(width, length, blockIndex++)
123124

124125
newBlocks.add(NbtCompound().apply {

common/src/main/kotlin/com/lambda/util/math/MathUtils.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ object MathUtils {
2626
private const val PI_FLOAT = 3.141593f
2727

2828
inline val Int.sq: Int get() = this * this
29+
inline val Float.sq: Float get() = this * this
30+
inline val Double.sq: Double get() = this * this
2931

3032
fun Float.toRadian() = this / 180.0f * PI_FLOAT
3133
fun Double.toRadian() = this / 180.0 * PI

common/src/main/kotlin/com/lambda/util/math/Vectors.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,9 @@ infix operator fun Vec3d.times(other: Int): Vec3d = multiply(other.toDouble())
8484

8585
infix operator fun Vec3d.div(other: Vec3d): Vec3d = multiply(1.0 / other.x, 1.0 / other.y, 1.0 / other.z)
8686
infix operator fun Vec3d.div(other: Vec3i): Vec3d = Vec3d(x / other.x, y / other.y, z / other.z)
87-
infix operator fun Vec3d.div(other: Double): Vec3d = times(1 / other)
88-
infix operator fun Vec3d.div(other: Float): Vec3d = times(1 / other)
89-
infix operator fun Vec3d.div(other: Int): Vec3d = times(1 / other)
87+
infix operator fun Vec3d.div(other: Double): Vec3d = times(1.0 / other)
88+
infix operator fun Vec3d.div(other: Float): Vec3d = times(1.0 / other)
89+
infix operator fun Vec3d.div(other: Int): Vec3d = times(1.0 / other)
9090

9191
infix operator fun ClosedRange<Double>.rangeTo(other: Double) = Vec3d(start, endInclusive, other)
9292
infix operator fun ClosedRange<Float>.rangeTo(other: Float) = Vec3d(start.toDouble(), endInclusive.toDouble(), other.toDouble())

0 commit comments

Comments
 (0)